summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--challenge/c13.go88
-rw-r--r--lib/web.go94
2 files changed, 82 insertions, 100 deletions
diff --git a/challenge/c13.go b/challenge/c13.go
index 4c9a6f7..130499d 100644
--- a/challenge/c13.go
+++ b/challenge/c13.go
@@ -10,18 +10,94 @@ import (
)
func C13() {
+ type Profile map[string]string
+
+ key, err := lib.RandomBytes(16)
+ if err != nil {
+ fmt.Printf("key generation error: %v\n", err)
+ }
+ counter := int64(10000)
+ profiles := make(map[string]Profile, 0)
+
+ genUid := func() int64 {
+ uid := counter
+ counter += 1
+
+ return uid
+ }
+ parse := func(encoded string) map[string]string {
+ m := make(map[string]string, 0)
+
+ kvs := lib.StrSplitAt('&', encoded)
+ for i := 0; i < len(kvs); i++ {
+ kv := lib.StrSplitAt('=', kvs[i])
+ m[lib.StripSpaceChars(kv[0])] = kv[1]
+ }
+ return m
+ }
+ encode := func(p Profile) string {
+ ep := "email=" + p["email"] // Encoded profile.
+ ep += "&uid=" + p["uid"]
+ ep += "&role=" + p["role"]
+ return ep
+ }
+ decode := func(encoded string) Profile {
+ return parse(encoded)
+ }
+ encrypt := func(encoded string) []byte {
+ return lib.AESEncryptECB(lib.StrToBytes(encoded), key)
+ }
+ decrypt := func(cipher []byte) string {
+ return lib.BytesToStr(lib.AESDecryptECB(cipher, key))
+ }
+ sanitize := func(email string) string {
+ if len(email) < 1 {
+ return ""
+ }
+ se := "" // sanitized email
+
+ // Strip meta characters
+ for i := 0; i < len(email); i++ {
+ if email[i] == '&' || email[i] == '=' {
+ continue
+ }
+ se += string(email[i])
+ }
+ return se
+ }
+ profileFor := func(email string) string {
+ e := sanitize(email)
+ if len(e) == 0 {
+ panic("email invalid")
+ }
+
+ if p, ok := profiles[e]; ok {
+ // Profile already exists.
+ return encode(p)
+ }
+
+ // Create profile.
+ p := make(Profile, 0)
+ p["email"] = e
+ p["uid"] = lib.NumToStr(genUid())
+ p["role"] = "user"
+ profiles[e] = p
+
+ return encode(p)
+ }
+
adminBlock := lib.BytesToStr(lib.Pkcs7Padding(lib.StrToBytes("admin"), 16))
- ep := lib.WebProfileFor("foo@abacus" + adminBlock)
- encryptedEP := lib.WebEncryptProfile(ep)
+ ep := profileFor("foo@abacus" + adminBlock)
+ encryptedEP := encrypt(ep)
adminBlockCipher := encryptedEP[16:32] // Second block in the cipher
- ep = lib.WebProfileFor("foo@abacus")
- encryptedEP = lib.WebEncryptProfile(ep)
+ ep = profileFor("foo@abacus")
+ encryptedEP = encrypt(ep)
for i := 0; i < 16; i++ { // Replace last block with the admin cipher block.
encryptedEP[32+i] = adminBlockCipher[i]
}
- adminEP := lib.WebDecryptProfile(encryptedEP)
- adminProfile := lib.WebDecodeProfile(adminEP)
+ adminEP := decrypt(encryptedEP)
+ adminProfile := decode(adminEP)
fmt.Printf("Admin Encoded Profile: %v\n", adminEP)
fmt.Printf("Admin Profile: %v\n", adminProfile)
}
diff --git a/lib/web.go b/lib/web.go
deleted file mode 100644
index 814d016..0000000
--- a/lib/web.go
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright © 2020 rsiddharth <s@ricketyspace.net>
-// SPDX-License-Identifier: ISC
-
-package lib
-
-type Profile map[string]string
-
-var webSessionEncryptionKey []byte
-var webUidCounter int64
-var webUserProfiles map[string]Profile = make(map[string]Profile, 0)
-
-func init() {
- var err error
-
- webSessionEncryptionKey, err = RandomBytes(16)
- if err != nil {
- panic(err)
- }
- webUidCounter = 10000
-}
-
-func WebGenUid() int64 {
- uid := webUidCounter
- webUidCounter += 1
-
- return uid
-}
-
-func WebParseKeyValue(encoded string) map[string]string {
- m := make(map[string]string, 0)
-
- kvs := StrSplitAt('&', encoded)
- for i := 0; i < len(kvs); i++ {
- kv := StrSplitAt('=', kvs[i])
- m[StripSpaceChars(kv[0])] = kv[1]
- }
- return m
-}
-
-func WebProfileFor(email string) string {
- e := WebSanitizeEmail(email)
- if len(e) == 0 {
- panic("email invalid")
- }
-
- if p, ok := webUserProfiles[e]; ok {
- // Profile already exists.
- return WebEncodeProfile(p)
- }
-
- // Create profile.
- p := make(Profile, 0)
- p["email"] = e
- p["uid"] = NumToStr(WebGenUid())
- p["role"] = "user"
- webUserProfiles[e] = p
-
- return WebEncodeProfile(p)
-}
-
-func WebEncodeProfile(p Profile) string {
- ep := "email=" + p["email"] // Encoded profile.
- ep += "&uid=" + p["uid"]
- ep += "&role=" + p["role"]
- return ep
-}
-
-func WebDecodeProfile(encoded string) Profile {
- return WebParseKeyValue(encoded)
-}
-
-func WebEncryptProfile(encoded string) []byte {
- return AESEncryptECB(StrToBytes(encoded), webSessionEncryptionKey)
-}
-
-func WebDecryptProfile(cipher []byte) string {
- return BytesToStr(AESDecryptECB(cipher, webSessionEncryptionKey))
-}
-
-func WebSanitizeEmail(email string) string {
- if len(email) < 1 {
- return ""
- }
- se := "" // sanitized email
-
- // Strip meta characters
- for i := 0; i < len(email); i++ {
- if email[i] == '&' || email[i] == '=' {
- continue
- }
- se += string(email[i])
- }
- return se
-}