fakekms/kms_enums.go (208 lines of code) (raw):

// Copyright 2021 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package fakekms import ( "crypto" "crypto/elliptic" "crypto/rsa" "fmt" "cloud.google.com/go/kms/apiv1/kmspb" ) // algDef contains details about a KMS algorithm type algDef struct { Purpose kmspb.CryptoKey_CryptoKeyPurpose KeyFactory keyFactory Opts interface{} } func (a algDef) Asymmetric() bool { switch a.Purpose { case kmspb.CryptoKey_ASYMMETRIC_DECRYPT, kmspb.CryptoKey_ASYMMETRIC_SIGN: return true default: return false } } // algorithms maps KMS algorithms to their definitions var algorithms = map[kmspb.CryptoKeyVersion_CryptoKeyVersionAlgorithm]algDef{ // ENCRYPT_DECRYPT kmspb.CryptoKeyVersion_GOOGLE_SYMMETRIC_ENCRYPTION: { Purpose: kmspb.CryptoKey_ENCRYPT_DECRYPT, KeyFactory: symmetricKeyFactory(256), }, // RAW_ENCRYPT_DECRYPT kmspb.CryptoKeyVersion_AES_128_GCM: { Purpose: kmspb.CryptoKey_RAW_ENCRYPT_DECRYPT, KeyFactory: symmetricKeyFactory(128), }, kmspb.CryptoKeyVersion_AES_256_GCM: { Purpose: kmspb.CryptoKey_RAW_ENCRYPT_DECRYPT, KeyFactory: symmetricKeyFactory(256), }, kmspb.CryptoKeyVersion_AES_128_CTR: { Purpose: kmspb.CryptoKey_RAW_ENCRYPT_DECRYPT, KeyFactory: symmetricKeyFactory(128), }, kmspb.CryptoKeyVersion_AES_256_CTR: { Purpose: kmspb.CryptoKey_RAW_ENCRYPT_DECRYPT, KeyFactory: symmetricKeyFactory(256), }, kmspb.CryptoKeyVersion_AES_128_CBC: { Purpose: kmspb.CryptoKey_RAW_ENCRYPT_DECRYPT, KeyFactory: symmetricKeyFactory(128), }, kmspb.CryptoKeyVersion_AES_256_CBC: { Purpose: kmspb.CryptoKey_RAW_ENCRYPT_DECRYPT, KeyFactory: symmetricKeyFactory(256), }, // ASYMMETRIC_DECRYPT kmspb.CryptoKeyVersion_RSA_DECRYPT_OAEP_2048_SHA256: { Purpose: kmspb.CryptoKey_ASYMMETRIC_DECRYPT, KeyFactory: rsaKeyFactory(2048), Opts: &rsa.OAEPOptions{Hash: crypto.SHA256}, }, kmspb.CryptoKeyVersion_RSA_DECRYPT_OAEP_3072_SHA256: { Purpose: kmspb.CryptoKey_ASYMMETRIC_DECRYPT, KeyFactory: rsaKeyFactory(3072), Opts: &rsa.OAEPOptions{Hash: crypto.SHA256}, }, kmspb.CryptoKeyVersion_RSA_DECRYPT_OAEP_4096_SHA256: { Purpose: kmspb.CryptoKey_ASYMMETRIC_DECRYPT, KeyFactory: rsaKeyFactory(4096), Opts: &rsa.OAEPOptions{Hash: crypto.SHA256}, }, kmspb.CryptoKeyVersion_RSA_DECRYPT_OAEP_4096_SHA512: { Purpose: kmspb.CryptoKey_ASYMMETRIC_DECRYPT, KeyFactory: rsaKeyFactory(4096), Opts: &rsa.OAEPOptions{Hash: crypto.SHA512}, }, // ASYMMETRIC_SIGN // ECDSA kmspb.CryptoKeyVersion_CryptoKeyVersionAlgorithm(11): // EC_SIGN_P224_SHA256 { Purpose: kmspb.CryptoKey_ASYMMETRIC_SIGN, KeyFactory: &ecKeyFactory{elliptic.P224()}, Opts: crypto.SHA256, }, kmspb.CryptoKeyVersion_EC_SIGN_P256_SHA256: { Purpose: kmspb.CryptoKey_ASYMMETRIC_SIGN, KeyFactory: &ecKeyFactory{elliptic.P256()}, Opts: crypto.SHA256, }, kmspb.CryptoKeyVersion_EC_SIGN_P384_SHA384: { Purpose: kmspb.CryptoKey_ASYMMETRIC_SIGN, KeyFactory: &ecKeyFactory{elliptic.P384()}, Opts: crypto.SHA384, }, kmspb.CryptoKeyVersion_CryptoKeyVersionAlgorithm(14): // EC_SIGN_P521_SHA512 { Purpose: kmspb.CryptoKey_ASYMMETRIC_SIGN, KeyFactory: &ecKeyFactory{elliptic.P521()}, Opts: crypto.SHA512, }, // RSASSA-PKCS1-v1_5 kmspb.CryptoKeyVersion_RSA_SIGN_PKCS1_2048_SHA256: { Purpose: kmspb.CryptoKey_ASYMMETRIC_SIGN, KeyFactory: rsaKeyFactory(2048), Opts: crypto.SHA256, }, kmspb.CryptoKeyVersion_RSA_SIGN_PKCS1_3072_SHA256: { Purpose: kmspb.CryptoKey_ASYMMETRIC_SIGN, KeyFactory: rsaKeyFactory(3072), Opts: crypto.SHA256, }, kmspb.CryptoKeyVersion_RSA_SIGN_PKCS1_4096_SHA256: { Purpose: kmspb.CryptoKey_ASYMMETRIC_SIGN, KeyFactory: rsaKeyFactory(4096), Opts: crypto.SHA256, }, kmspb.CryptoKeyVersion_RSA_SIGN_PKCS1_4096_SHA512: { Purpose: kmspb.CryptoKey_ASYMMETRIC_SIGN, KeyFactory: rsaKeyFactory(4096), Opts: crypto.SHA512, }, // RSASSA-PSS kmspb.CryptoKeyVersion_RSA_SIGN_PSS_2048_SHA256: { Purpose: kmspb.CryptoKey_ASYMMETRIC_SIGN, KeyFactory: rsaKeyFactory(2048), Opts: &rsa.PSSOptions{Hash: crypto.SHA256, SaltLength: rsa.PSSSaltLengthEqualsHash}, }, kmspb.CryptoKeyVersion_RSA_SIGN_PSS_3072_SHA256: { Purpose: kmspb.CryptoKey_ASYMMETRIC_SIGN, KeyFactory: rsaKeyFactory(3072), Opts: &rsa.PSSOptions{Hash: crypto.SHA256, SaltLength: rsa.PSSSaltLengthEqualsHash}, }, kmspb.CryptoKeyVersion_RSA_SIGN_PSS_4096_SHA256: { Purpose: kmspb.CryptoKey_ASYMMETRIC_SIGN, KeyFactory: rsaKeyFactory(4096), Opts: &rsa.PSSOptions{Hash: crypto.SHA256, SaltLength: rsa.PSSSaltLengthEqualsHash}, }, kmspb.CryptoKeyVersion_RSA_SIGN_PSS_4096_SHA512: { Purpose: kmspb.CryptoKey_ASYMMETRIC_SIGN, KeyFactory: rsaKeyFactory(4096), Opts: &rsa.PSSOptions{Hash: crypto.SHA512, SaltLength: rsa.PSSSaltLengthEqualsHash}, }, // RSASSA-PKCS1-v1_5 (Raw) kmspb.CryptoKeyVersion_RSA_SIGN_RAW_PKCS1_2048: { Purpose: kmspb.CryptoKey_ASYMMETRIC_SIGN, KeyFactory: rsaKeyFactory(2048), Opts: crypto.Hash(0), }, kmspb.CryptoKeyVersion_RSA_SIGN_RAW_PKCS1_3072: { Purpose: kmspb.CryptoKey_ASYMMETRIC_SIGN, KeyFactory: rsaKeyFactory(3072), Opts: crypto.Hash(0), }, kmspb.CryptoKeyVersion_RSA_SIGN_RAW_PKCS1_4096: { Purpose: kmspb.CryptoKey_ASYMMETRIC_SIGN, KeyFactory: rsaKeyFactory(4096), Opts: crypto.Hash(0), }, // MAC kmspb.CryptoKeyVersion_HMAC_SHA1: { Purpose: kmspb.CryptoKey_MAC, KeyFactory: symmetricKeyFactory(160), Opts: crypto.SHA1, }, kmspb.CryptoKeyVersion_HMAC_SHA224: { Purpose: kmspb.CryptoKey_MAC, KeyFactory: symmetricKeyFactory(224), Opts: crypto.SHA224, }, kmspb.CryptoKeyVersion_HMAC_SHA256: { Purpose: kmspb.CryptoKey_MAC, KeyFactory: symmetricKeyFactory(256), Opts: crypto.SHA256, }, kmspb.CryptoKeyVersion_HMAC_SHA384: { Purpose: kmspb.CryptoKey_MAC, KeyFactory: symmetricKeyFactory(384), Opts: crypto.SHA384, }, kmspb.CryptoKeyVersion_HMAC_SHA512: { Purpose: kmspb.CryptoKey_MAC, KeyFactory: symmetricKeyFactory(512), Opts: crypto.SHA512, }, } // nameForValue retrieves the mapped name corresponding to value, or a string representation // of the numeric value if the value is unknown. func nameForValue(names map[int32]string, value int32) string { if name, ok := names[value]; ok { return name } return fmt.Sprintf("%d", value) } // validateProtectionLevel returns nil on success, or Unimplemented if the supplied protection // level is not supported. Note that PROTECTION_LEVEL_UNSPECIFIED is not a supported level. func validateProtectionLevel(pl kmspb.ProtectionLevel) error { switch pl { case kmspb.ProtectionLevel_SOFTWARE, kmspb.ProtectionLevel_HSM: return nil default: return errUnimplemented("unsupported protection level: %s", nameForValue(kmspb.ProtectionLevel_name, int32(pl))) } } // algorithmDef returns an algDef corresponding to the supplied algorithm, or Unimplemented // if the algorithm is not supported. func algorithmDef(alg kmspb.CryptoKeyVersion_CryptoKeyVersionAlgorithm) (algDef, error) { def, ok := algorithms[alg] if !ok { return algDef{}, errUnimplemented("unsupported algorithm: %s", nameForValue(kmspb.CryptoKeyVersion_CryptoKeyVersionAlgorithm_name, int32(alg))) } return def, nil } // validateAlgorithm returns nil on success, Unimplemented if the supplied algorithm is not // supported, or InvalidArgument if the algorithm is inconsistent with the supplied purpose. // Note that CRYPTO_KEY_VERSION_ALGORITHM_UNSPECIFIED is not a supported algorithm. func validateAlgorithm(alg kmspb.CryptoKeyVersion_CryptoKeyVersionAlgorithm, purpose kmspb.CryptoKey_CryptoKeyPurpose) error { def, err := algorithmDef(alg) if err != nil { return err } if purpose != def.Purpose { return errInvalidArgument("algorithm %s is not valid for purpose %s", nameForValue(kmspb.CryptoKeyVersion_CryptoKeyVersionAlgorithm_name, int32(alg)), nameForValue(kmspb.CryptoKey_CryptoKeyPurpose_name, int32(purpose))) } return nil }