diff --git a/migration/convert.go b/migration/convert.go index 85a5fa6..1bb0f3d 100644 --- a/migration/convert.go +++ b/migration/convert.go @@ -6,23 +6,6 @@ import ( "net/url" ) -var ( - typeString = map[Payload_OtpParameters_OtpType]string{ - Payload_OtpParameters_OTP_TYPE_HOTP: "hotp", - Payload_OtpParameters_OTP_TYPE_TOTP: "totp", - } - algString = map[Payload_OtpParameters_Algorithm]string{ - Payload_OtpParameters_ALGORITHM_SHA1: "SHA1", - Payload_OtpParameters_ALGORITHM_SHA256: "SHA256", - Payload_OtpParameters_ALGORITHM_SHA512: "SHA512", - Payload_OtpParameters_ALGORITHM_MD5: "MD5", - } - digitsString = map[Payload_OtpParameters_DigitCount]string{ - Payload_OtpParameters_DIGIT_COUNT_SIX: "6", - Payload_OtpParameters_DIGIT_COUNT_EIGHT: "8", - } -) - // SecretString returns Secret as a base32 encoded String func (op *Payload_OtpParameters) SecretString() string { return base32.StdEncoding.WithPadding(base32.NoPadding).EncodeToString(op.Secret) @@ -50,11 +33,11 @@ func (op *Payload_OtpParameters) URL() *url.URL { } // optional if op.Algorithm != Payload_OtpParameters_ALGORITHM_UNSPECIFIED { - v.Add("algorithm", algString[op.Algorithm]) + v.Add("algorithm", op.Algorithm.Name()) } // optional if op.Digits != Payload_OtpParameters_DIGIT_COUNT_UNSPECIFIED { - v.Add("digits", digitsString[op.Digits]) + v.Add("digits", fmt.Sprint(op.Digits.Count())) } // required if type is hotp if op.Type == Payload_OtpParameters_OTP_TYPE_HOTP { @@ -66,7 +49,7 @@ func (op *Payload_OtpParameters) URL() *url.URL { } return &url.URL{ Scheme: "otpauth", - Host: typeString[op.Type], + Host: op.Type.Name(), Path: op.Name, RawQuery: v.Encode(), } diff --git a/migration/evaluate.go b/migration/evaluate.go index 750c367..0ee3f46 100644 --- a/migration/evaluate.go +++ b/migration/evaluate.go @@ -2,37 +2,12 @@ package migration import ( "crypto/hmac" - "crypto/md5" - "crypto/sha1" - "crypto/sha256" - "crypto/sha512" "encoding/binary" "fmt" - "hash" "math" "time" ) -var ( - hashFunc = map[Payload_OtpParameters_Algorithm]func() hash.Hash{ - Payload_OtpParameters_ALGORITHM_UNSPECIFIED: sha1.New, // default - Payload_OtpParameters_ALGORITHM_SHA1: sha1.New, - Payload_OtpParameters_ALGORITHM_SHA256: sha256.New, - Payload_OtpParameters_ALGORITHM_SHA512: sha512.New, - Payload_OtpParameters_ALGORITHM_MD5: md5.New, - } - digitCount = map[Payload_OtpParameters_DigitCount]int{ - Payload_OtpParameters_DIGIT_COUNT_UNSPECIFIED: 6, // default - Payload_OtpParameters_DIGIT_COUNT_SIX: 6, - Payload_OtpParameters_DIGIT_COUNT_EIGHT: 8, - } - countFunc = map[Payload_OtpParameters_OtpType]func(*Payload_OtpParameters) uint64{ - Payload_OtpParameters_OTP_TYPE_UNSPECIFIED: totp, // default - Payload_OtpParameters_OTP_TYPE_HOTP: hotp, - Payload_OtpParameters_OTP_TYPE_TOTP: totp, - } -) - const ( offset = 5 * time.Second // offset into future period = 30 * time.Second // default value period @@ -56,15 +31,15 @@ func (op *Payload_OtpParameters) Seconds() float64 { // Evaluate OTP parameters func (op *Payload_OtpParameters) Evaluate() int { - h := hmac.New(hashFunc[op.Algorithm], op.Secret) - binary.Write(h, binary.BigEndian, countFunc[op.Type](op)) + h := hmac.New(op.Algorithm.Hash(), op.Secret) + binary.Write(h, binary.BigEndian, op.Type.Count(op)) hashed := h.Sum(nil) offset := hashed[h.Size()-1] & 15 result := binary.BigEndian.Uint32(hashed[offset:]) & (1<<31 - 1) - return int(result) % int(math.Pow10(digitCount[op.Digits])) + return int(result) % int(math.Pow10(op.Digits.Count())) } // EvaluateString returns OTP as formatted string func (op *Payload_OtpParameters) EvaluateString() string { - return fmt.Sprintf("%0*d", digitCount[op.Digits], op.Evaluate()) + return fmt.Sprintf("%0*d", op.Digits.Count(), op.Evaluate()) } diff --git a/migration/generate.go b/migration/generate.go deleted file mode 100644 index 37c3f5c..0000000 --- a/migration/generate.go +++ /dev/null @@ -1,3 +0,0 @@ -package migration - -//go:generate protoc --go_out=. --go_opt=paths=source_relative migration.proto diff --git a/migration/migration.go b/migration/migration.go new file mode 100644 index 0000000..5eb6851 --- /dev/null +++ b/migration/migration.go @@ -0,0 +1,65 @@ +package migration + +import ( + "crypto/md5" + "crypto/sha1" + "crypto/sha256" + "crypto/sha512" + "hash" +) + +//go:generate protoc --go_out=. --go_opt=paths=source_relative migration.proto + +var algorithmHash = []func() hash.Hash{ + Payload_OtpParameters_ALGORITHM_UNSPECIFIED: sha1.New, + Payload_OtpParameters_ALGORITHM_SHA1: sha1.New, + Payload_OtpParameters_ALGORITHM_SHA256: sha256.New, + Payload_OtpParameters_ALGORITHM_SHA512: sha512.New, + Payload_OtpParameters_ALGORITHM_MD5: md5.New, +} + +func (x Payload_OtpParameters_Algorithm) Hash() func() hash.Hash { + return algorithmHash[x] +} + +var algorithmNames = []string{ + Payload_OtpParameters_ALGORITHM_UNSPECIFIED: "SHA1", + Payload_OtpParameters_ALGORITHM_SHA1: "SHA1", + Payload_OtpParameters_ALGORITHM_SHA256: "SHA256", + Payload_OtpParameters_ALGORITHM_SHA512: "SHA512", + Payload_OtpParameters_ALGORITHM_MD5: "MD5", +} + +func (x Payload_OtpParameters_Algorithm) Name() string { + return algorithmNames[x] +} + +var digitCount = []int{ + Payload_OtpParameters_DIGIT_COUNT_UNSPECIFIED: 6, + Payload_OtpParameters_DIGIT_COUNT_SIX: 6, + Payload_OtpParameters_DIGIT_COUNT_EIGHT: 8, +} + +func (x Payload_OtpParameters_DigitCount) Count() int { + return digitCount[x] +} + +var otpTypeFunc = []func(*Payload_OtpParameters) uint64{ + Payload_OtpParameters_OTP_TYPE_UNSPECIFIED: totp, + Payload_OtpParameters_OTP_TYPE_HOTP: hotp, + Payload_OtpParameters_OTP_TYPE_TOTP: totp, +} + +func (x Payload_OtpParameters_OtpType) Count(op *Payload_OtpParameters) uint64 { + return otpTypeFunc[x](op) +} + +var otpTypeNames = []string{ + Payload_OtpParameters_OTP_TYPE_UNSPECIFIED: "totp", + Payload_OtpParameters_OTP_TYPE_HOTP: "hotp", + Payload_OtpParameters_OTP_TYPE_TOTP: "totp", +} + +func (x Payload_OtpParameters_OtpType) Name() string { + return otpTypeNames[x] +}