From 14753f7d10de72e91680f3c8f4fdddb46ab9d953 Mon Sep 17 00:00:00 2001 From: Rajon Ahmed Date: Fri, 28 Aug 2026 12:55:10 +0800 Subject: [PATCH] upd: essential/file updated helper key updated --- essential/visible/service/helper/key/key.go | 445 ++++++++++++++++++++ 1 file changed, 445 insertions(+) diff --git a/essential/visible/service/helper/key/key.go b/essential/visible/service/helper/key/key.go index e69de29..5ad2f95 100644 --- a/essential/visible/service/helper/key/key.go +++ b/essential/visible/service/helper/key/key.go @@ -0,0 +1,445 @@ +/* +|-------------------------------------------------------------------------- +| Description +|-------------------------------------------------------------------------- +| +| Name: +| - Key +| +| Purpose: +| - Generate cryptographic key material through a type-driven dispatch +| model supporting symmetric and asymmetric key generation. +| +|-------------------------------------------------------------------------- +*/ + +/* +|-------------------------------------------------------------------------- +| Instruction +|-------------------------------------------------------------------------- +| +| Guideline: +| - Use the utility to generate cryptographically secure symmetric or +| asymmetric key material. +| - Use the "symmetric" type with the supported AES algorithm and +| 128, 192, or 256 bit key sizes. +| - Use the "asymmetric" type with the supported ECC algorithm using +| the EdDSA curve. +| - Provide the type-specific configuration required for the selected +| key generation workflow. +| +| Example: +| - ObrimKey("symmetric", map[string]any{ +| "algorithm": "aes", +| "key_size": 256, +| }) +| +| - ObrimKey("asymmetric", map[string]any{ +| "algorithm": "ecc", +| }) +| +|-------------------------------------------------------------------------- +*/ + +/* +|-------------------------------------------------------------------------- +| Credit +|-------------------------------------------------------------------------- +| +| Contributor: +| - Rajon Ahmed +| - Blockonite +| +|-------------------------------------------------------------------------- +*/ + +package key + +import ( + "crypto/aes" + "crypto/ed25519" + "crypto/rand" + "encoding/base64" + "time" +) + +const ( + obrimKeyTypeSymmetric = "symmetric" + obrimKeyTypeAsymmetric = "asymmetric" + + obrimKeyAlgorithmAES = "aes" + obrimKeyAlgorithmECC = "ecc" + obrimKeyCurveEdDSA = "eddsa" + + obrimKeySize128 = 128 + obrimKeySize192 = 192 + obrimKeySize256 = 256 +) + +const ( + obrimKeySuccessSymmetricGenerated = "SUCCESS_SYMMETRIC_KEY_GENERATED" + obrimKeySuccessAsymmetricGenerated = "SUCCESS_ASYMMETRIC_KEY_GENERATED" + + obrimKeyFailureInvalidType = "FAILURE_INVALID_TYPE" + obrimKeyFailureInvalidConfig = "FAILURE_INVALID_CONFIG" + obrimKeyFailureMissingAlgorithm = "FAILURE_MISSING_ALGORITHM" + obrimKeyFailureInvalidAlgorithm = "FAILURE_INVALID_ALGORITHM" + obrimKeyFailureMissingKeySize = "FAILURE_MISSING_KEY_SIZE" + obrimKeyFailureInvalidKeySize = "FAILURE_INVALID_KEY_SIZE" + obrimKeyFailureKeyGeneration = "FAILURE_KEY_GENERATION" + obrimKeyFailureAsymmetricKeyGeneration = "FAILURE_ASYMMETRIC_KEY_GENERATION" + obrimKeyFailureUnsupportedOperation = "FAILURE_UNSUPPORTED_OPERATION" +) + +const ( + obrimKeyConfigAlgorithm = "algorithm" + obrimKeyConfigKeySize = "key_size" +) + +type obrimKeySymmetricConfig struct { + algorithm string + keySize int +} + +type obrimKeyAsymmetricConfig struct { + algorithm string +} + +type obrimKeySymmetricPayload struct { + Type string `json:"type"` + Algorithm string `json:"algorithm"` + KeySize int `json:"key_size"` + KeyMaterial string `json:"key_material"` + GeneratedAt string `json:"generated_at"` +} + +type obrimKeyAsymmetricPayload struct { + Type string `json:"type"` + Algorithm string `json:"algorithm"` + Curve string `json:"curve"` + PublicKey string `json:"public_key"` + PrivateKey string `json:"private_key"` + GeneratedAt string `json:"generated_at"` +} + +type obrimKeyOutput struct { + Status bool `json:"status"` + Code string `json:"code"` + Payload any `json:"payload"` +} + +func ObrimKey(keyType string, config map[string]any) map[string]any { + if code := obrimKeyValidateInput(keyType, config); code != "" { + return obrimKeyBuildOutput(false, code, nil) + } + + return obrimKeyRouteRequest(keyType, config) +} + +func obrimKeyValidateInput(keyType string, config map[string]any) string { + switch keyType { + case obrimKeyTypeSymmetric: + if config == nil { + return obrimKeyFailureInvalidConfig + } + + algorithm, ok := config[obrimKeyConfigAlgorithm] + if !ok { + return obrimKeyFailureMissingAlgorithm + } + + algorithmValue, ok := algorithm.(string) + if !ok || algorithmValue == "" { + return obrimKeyFailureInvalidAlgorithm + } + + switch algorithmValue { + case obrimKeyAlgorithmAES: + default: + return obrimKeyFailureInvalidAlgorithm + } + + keySize, ok := config[obrimKeyConfigKeySize] + if !ok { + return obrimKeyFailureMissingKeySize + } + + switch value := keySize.(type) { + case int: + switch value { + case obrimKeySize128, obrimKeySize192, obrimKeySize256: + default: + return obrimKeyFailureInvalidKeySize + } + case int8: + switch value { + case obrimKeySize128, obrimKeySize192, obrimKeySize256: + default: + return obrimKeyFailureInvalidKeySize + } + case int16: + switch value { + case obrimKeySize128, obrimKeySize192, obrimKeySize256: + default: + return obrimKeyFailureInvalidKeySize + } + case int32: + switch value { + case obrimKeySize128, obrimKeySize192, obrimKeySize256: + default: + return obrimKeyFailureInvalidKeySize + } + case int64: + switch value { + case obrimKeySize128, obrimKeySize192, obrimKeySize256: + default: + return obrimKeyFailureInvalidKeySize + } + case uint: + switch value { + case obrimKeySize128, obrimKeySize192, obrimKeySize256: + default: + return obrimKeyFailureInvalidKeySize + } + case uint8: + switch value { + case obrimKeySize128, obrimKeySize192, obrimKeySize256: + default: + return obrimKeyFailureInvalidKeySize + } + case uint16: + switch value { + case obrimKeySize128, obrimKeySize192, obrimKeySize256: + default: + return obrimKeyFailureInvalidKeySize + } + case uint32: + switch value { + case obrimKeySize128, obrimKeySize192, obrimKeySize256: + default: + return obrimKeyFailureInvalidKeySize + } + case uint64: + switch value { + case obrimKeySize128, obrimKeySize192, obrimKeySize256: + default: + return obrimKeyFailureInvalidKeySize + } + default: + return obrimKeyFailureInvalidKeySize + } + + case obrimKeyTypeAsymmetric: + if config == nil { + return obrimKeyFailureInvalidConfig + } + + algorithm, ok := config[obrimKeyConfigAlgorithm] + if !ok { + return obrimKeyFailureMissingAlgorithm + } + + algorithmValue, ok := algorithm.(string) + if !ok || algorithmValue == "" { + return obrimKeyFailureInvalidAlgorithm + } + + switch algorithmValue { + case obrimKeyAlgorithmECC: + default: + return obrimKeyFailureInvalidAlgorithm + } + + default: + return obrimKeyFailureInvalidType + } + + return "" +} + +func obrimKeyRouteRequest(keyType string, config map[string]any) map[string]any { + switch keyType { + case obrimKeyTypeSymmetric: + normalized, code := obrimKeyNormalizeSymmetricConfig(config) + if code != "" { + return obrimKeyBuildOutput(false, code, nil) + } + + payload, code := obrimKeyGenerateSymmetric(normalized) + if code != "" { + return obrimKeyBuildOutput(false, code, nil) + } + + return obrimKeyBuildOutput( + true, + obrimKeySuccessSymmetricGenerated, + payload, + ) + + case obrimKeyTypeAsymmetric: + normalized, code := obrimKeyNormalizeAsymmetricConfig(config) + if code != "" { + return obrimKeyBuildOutput(false, code, nil) + } + + payload, code := obrimKeyGenerateAsymmetric(normalized) + if code != "" { + return obrimKeyBuildOutput(false, code, nil) + } + + return obrimKeyBuildOutput( + true, + obrimKeySuccessAsymmetricGenerated, + payload, + ) + + default: + return obrimKeyBuildOutput(false, obrimKeyFailureUnsupportedOperation, nil) + } +} + +func obrimKeyBuildOutput(status bool, code string, payload any) map[string]any { + output := obrimKeyOutput{ + Status: status, + Code: code, + Payload: payload, + } + + return map[string]any{ + "status": output.Status, + "code": output.Code, + "payload": output.Payload, + } +} + +func obrimKeyNormalizeSymmetricConfig(config map[string]any) (obrimKeySymmetricConfig, string) { + algorithm, ok := config[obrimKeyConfigAlgorithm].(string) + if !ok || algorithm == "" { + return obrimKeySymmetricConfig{}, obrimKeyFailureInvalidAlgorithm + } + + keySizeValue, ok := config[obrimKeyConfigKeySize] + if !ok { + return obrimKeySymmetricConfig{}, obrimKeyFailureMissingKeySize + } + + keySize, ok := obrimKeyNormalizeKeySize(keySizeValue) + if !ok { + return obrimKeySymmetricConfig{}, obrimKeyFailureInvalidKeySize + } + + return obrimKeySymmetricConfig{ + algorithm: algorithm, + keySize: keySize, + }, "" +} + +func obrimKeyNormalizeKeySize(value any) (int, bool) { + switch keySize := value.(type) { + case int: + return keySize, true + case int8: + return int(keySize), true + case int16: + return int(keySize), true + case int32: + return int(keySize), true + case int64: + return int(keySize), true + case uint: + return int(keySize), true + case uint8: + return int(keySize), true + case uint16: + return int(keySize), true + case uint32: + return int(keySize), true + case uint64: + return int(keySize), true + default: + return 0, false + } +} + +func obrimKeyGenerateSymmetric(config obrimKeySymmetricConfig) (map[string]any, string) { + switch config.algorithm { + case obrimKeyAlgorithmAES: + return obrimKeyGenerateAES(config.keySize) + default: + return nil, obrimKeyFailureInvalidAlgorithm + } +} + +func obrimKeyGenerateAES(keySize int) (map[string]any, string) { + keyLength := keySize / 8 + + keyMaterial := make([]byte, keyLength) + if _, err := rand.Read(keyMaterial); err != nil { + return nil, obrimKeyFailureKeyGeneration + } + + if _, err := aes.NewCipher(keyMaterial); err != nil { + return nil, obrimKeyFailureKeyGeneration + } + + payload := obrimKeySymmetricPayload{ + Type: obrimKeyTypeSymmetric, + Algorithm: obrimKeyAlgorithmAES, + KeySize: keySize, + KeyMaterial: base64.StdEncoding.EncodeToString(keyMaterial), + GeneratedAt: time.Now().UTC().Format(time.RFC3339Nano), + } + + return map[string]any{ + "type": payload.Type, + "algorithm": payload.Algorithm, + "key_size": payload.KeySize, + "key_material": payload.KeyMaterial, + "generated_at": payload.GeneratedAt, + }, "" +} + +func obrimKeyNormalizeAsymmetricConfig(config map[string]any) (obrimKeyAsymmetricConfig, string) { + algorithm, ok := config[obrimKeyConfigAlgorithm].(string) + if !ok || algorithm == "" { + return obrimKeyAsymmetricConfig{}, obrimKeyFailureInvalidAlgorithm + } + + return obrimKeyAsymmetricConfig{ + algorithm: algorithm, + }, "" +} + +func obrimKeyGenerateAsymmetric(config obrimKeyAsymmetricConfig) (map[string]any, string) { + switch config.algorithm { + case obrimKeyAlgorithmECC: + return obrimKeyGenerateECC() + default: + return nil, obrimKeyFailureInvalidAlgorithm + } +} + +func obrimKeyGenerateECC() (map[string]any, string) { + publicKey, privateKey, err := ed25519.GenerateKey(rand.Reader) + if err != nil { + return nil, obrimKeyFailureAsymmetricKeyGeneration + } + + payload := obrimKeyAsymmetricPayload{ + Type: obrimKeyTypeAsymmetric, + Algorithm: obrimKeyAlgorithmECC, + Curve: obrimKeyCurveEdDSA, + PublicKey: base64.StdEncoding.EncodeToString(publicKey), + PrivateKey: base64.StdEncoding.EncodeToString(privateKey), + GeneratedAt: time.Now().UTC().Format(time.RFC3339Nano), + } + + return map[string]any{ + "type": payload.Type, + "algorithm": payload.Algorithm, + "curve": payload.Curve, + "public_key": payload.PublicKey, + "private_key": payload.PrivateKey, + "generated_at": payload.GeneratedAt, + }, "" +}