KeyAlgorithmProxy.cpp (8600B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "mozilla/dom/KeyAlgorithmProxy.h" 8 9 #include "js/StructuredClone.h" 10 #include "mozilla/Assertions.h" 11 #include "mozilla/dom/StructuredCloneHolder.h" 12 #include "mozilla/dom/WebCryptoCommon.h" 13 14 namespace mozilla::dom { 15 16 bool KeyAlgorithmProxy::WriteStructuredClone( 17 JSStructuredCloneWriter* aWriter) const { 18 if (!StructuredCloneHolder::WriteString(aWriter, mName) || 19 !JS_WriteUint32Pair(aWriter, mType, KEY_ALGORITHM_SC_VERSION)) { 20 return false; 21 } 22 23 switch (mType) { 24 case AES: 25 return JS_WriteUint32Pair(aWriter, mAes.mLength, 0); 26 case KDF: 27 return true; 28 case HMAC: 29 return JS_WriteUint32Pair(aWriter, mHmac.mLength, 0) && 30 StructuredCloneHolder::WriteString(aWriter, mHmac.mHash.mName); 31 case RSA: { 32 return JS_WriteUint32Pair(aWriter, mRsa.mModulusLength, 0) && 33 WriteBuffer(aWriter, mRsa.mPublicExponent) && 34 StructuredCloneHolder::WriteString(aWriter, mRsa.mHash.mName); 35 } 36 case EC: 37 return StructuredCloneHolder::WriteString(aWriter, mEc.mNamedCurve); 38 case OKP: 39 return true; 40 } 41 42 return false; 43 } 44 45 bool KeyAlgorithmProxy::ReadStructuredClone(JSStructuredCloneReader* aReader) { 46 uint32_t type, version, dummy; 47 if (!StructuredCloneHolder::ReadString(aReader, mName) || 48 !JS_ReadUint32Pair(aReader, &type, &version)) { 49 return false; 50 } 51 52 if (version != KEY_ALGORITHM_SC_VERSION) { 53 return false; 54 } 55 56 switch (type) { 57 case AES: { 58 mType = AES; 59 60 uint32_t length; 61 if (!JS_ReadUint32Pair(aReader, &length, &dummy)) { 62 return false; 63 } 64 65 mAes.mLength = length; 66 mAes.mName = mName; 67 return true; 68 } 69 case KDF: 70 mType = KDF; 71 mKDF.mName = mName; 72 return true; 73 case HMAC: { 74 mType = HMAC; 75 76 if (!JS_ReadUint32Pair(aReader, &mHmac.mLength, &dummy) || 77 !StructuredCloneHolder::ReadString(aReader, mHmac.mHash.mName)) { 78 return false; 79 } 80 81 mHmac.mName = mName; 82 return true; 83 } 84 case RSA: { 85 mType = RSA; 86 87 uint32_t modulusLength; 88 nsString hashName; 89 if (!JS_ReadUint32Pair(aReader, &modulusLength, &dummy) || 90 !ReadBuffer(aReader, mRsa.mPublicExponent) || 91 !StructuredCloneHolder::ReadString(aReader, mRsa.mHash.mName)) { 92 return false; 93 } 94 95 mRsa.mModulusLength = modulusLength; 96 mRsa.mName = mName; 97 return true; 98 } 99 case EC: { 100 mType = EC; 101 102 nsString namedCurve; 103 if (!StructuredCloneHolder::ReadString(aReader, mEc.mNamedCurve)) { 104 return false; 105 } 106 107 mEc.mName = mName; 108 return true; 109 } 110 111 case OKP: { 112 mType = OKP; 113 mEd.mName = mName; 114 return true; 115 } 116 } 117 118 return false; 119 } 120 121 CK_MECHANISM_TYPE 122 KeyAlgorithmProxy::Mechanism() const { 123 if (mType == HMAC) { 124 return GetMechanism(mHmac); 125 } 126 return MapAlgorithmNameToMechanism(mName); 127 } 128 129 nsString KeyAlgorithmProxy::JwkAlg() const { 130 if (mName.EqualsLiteral(WEBCRYPTO_ALG_AES_CBC)) { 131 switch (mAes.mLength) { 132 case 128: 133 return NS_LITERAL_STRING_FROM_CSTRING(JWK_ALG_A128CBC); 134 case 192: 135 return NS_LITERAL_STRING_FROM_CSTRING(JWK_ALG_A192CBC); 136 case 256: 137 return NS_LITERAL_STRING_FROM_CSTRING(JWK_ALG_A256CBC); 138 } 139 } 140 141 if (mName.EqualsLiteral(WEBCRYPTO_ALG_AES_CTR)) { 142 switch (mAes.mLength) { 143 case 128: 144 return NS_LITERAL_STRING_FROM_CSTRING(JWK_ALG_A128CTR); 145 case 192: 146 return NS_LITERAL_STRING_FROM_CSTRING(JWK_ALG_A192CTR); 147 case 256: 148 return NS_LITERAL_STRING_FROM_CSTRING(JWK_ALG_A256CTR); 149 } 150 } 151 152 if (mName.EqualsLiteral(WEBCRYPTO_ALG_AES_GCM)) { 153 switch (mAes.mLength) { 154 case 128: 155 return NS_LITERAL_STRING_FROM_CSTRING(JWK_ALG_A128GCM); 156 case 192: 157 return NS_LITERAL_STRING_FROM_CSTRING(JWK_ALG_A192GCM); 158 case 256: 159 return NS_LITERAL_STRING_FROM_CSTRING(JWK_ALG_A256GCM); 160 } 161 } 162 163 if (mName.EqualsLiteral(WEBCRYPTO_ALG_AES_KW)) { 164 switch (mAes.mLength) { 165 case 128: 166 return NS_LITERAL_STRING_FROM_CSTRING(JWK_ALG_A128KW); 167 case 192: 168 return NS_LITERAL_STRING_FROM_CSTRING(JWK_ALG_A192KW); 169 case 256: 170 return NS_LITERAL_STRING_FROM_CSTRING(JWK_ALG_A256KW); 171 } 172 } 173 174 if (mName.EqualsLiteral(WEBCRYPTO_ALG_HMAC)) { 175 nsString hashName = mHmac.mHash.mName; 176 if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA1)) { 177 return NS_LITERAL_STRING_FROM_CSTRING(JWK_ALG_HS1); 178 } else if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA256)) { 179 return NS_LITERAL_STRING_FROM_CSTRING(JWK_ALG_HS256); 180 } else if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA384)) { 181 return NS_LITERAL_STRING_FROM_CSTRING(JWK_ALG_HS384); 182 } else if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA512)) { 183 return NS_LITERAL_STRING_FROM_CSTRING(JWK_ALG_HS512); 184 } 185 } 186 187 if (mName.EqualsLiteral(WEBCRYPTO_ALG_RSASSA_PKCS1)) { 188 nsString hashName = mRsa.mHash.mName; 189 if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA1)) { 190 return NS_LITERAL_STRING_FROM_CSTRING(JWK_ALG_RS1); 191 } else if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA256)) { 192 return NS_LITERAL_STRING_FROM_CSTRING(JWK_ALG_RS256); 193 } else if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA384)) { 194 return NS_LITERAL_STRING_FROM_CSTRING(JWK_ALG_RS384); 195 } else if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA512)) { 196 return NS_LITERAL_STRING_FROM_CSTRING(JWK_ALG_RS512); 197 } 198 } 199 200 if (mName.EqualsLiteral(WEBCRYPTO_ALG_RSA_OAEP)) { 201 nsString hashName = mRsa.mHash.mName; 202 if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA1)) { 203 return NS_LITERAL_STRING_FROM_CSTRING(JWK_ALG_RSA_OAEP); 204 } else if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA256)) { 205 return NS_LITERAL_STRING_FROM_CSTRING(JWK_ALG_RSA_OAEP_256); 206 } else if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA384)) { 207 return NS_LITERAL_STRING_FROM_CSTRING(JWK_ALG_RSA_OAEP_384); 208 } else if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA512)) { 209 return NS_LITERAL_STRING_FROM_CSTRING(JWK_ALG_RSA_OAEP_512); 210 } 211 } 212 213 if (mName.EqualsLiteral(WEBCRYPTO_ALG_RSA_PSS)) { 214 nsString hashName = mRsa.mHash.mName; 215 if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA1)) { 216 return NS_LITERAL_STRING_FROM_CSTRING(JWK_ALG_PS1); 217 } else if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA256)) { 218 return NS_LITERAL_STRING_FROM_CSTRING(JWK_ALG_PS256); 219 } else if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA384)) { 220 return NS_LITERAL_STRING_FROM_CSTRING(JWK_ALG_PS384); 221 } else if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA512)) { 222 return NS_LITERAL_STRING_FROM_CSTRING(JWK_ALG_PS512); 223 } 224 } 225 226 if (mName.EqualsLiteral(WEBCRYPTO_ALG_ECDSA)) { 227 nsString curveName = mEc.mNamedCurve; 228 if (curveName.EqualsLiteral(WEBCRYPTO_NAMED_CURVE_P256)) { 229 return NS_LITERAL_STRING_FROM_CSTRING(JWK_ALG_ECDSA_P_256); 230 } 231 if (curveName.EqualsLiteral(WEBCRYPTO_NAMED_CURVE_P384)) { 232 return NS_LITERAL_STRING_FROM_CSTRING(JWK_ALG_ECDSA_P_384); 233 } 234 if (curveName.EqualsLiteral(WEBCRYPTO_NAMED_CURVE_P521)) { 235 return NS_LITERAL_STRING_FROM_CSTRING(JWK_ALG_ECDSA_P_521); 236 } 237 } 238 239 if (mName.EqualsLiteral(WEBCRYPTO_ALG_ED25519)) { 240 return NS_LITERAL_STRING_FROM_CSTRING(JWK_ALG_ED25519); 241 } 242 243 return nsString(); 244 } 245 246 CK_MECHANISM_TYPE 247 KeyAlgorithmProxy::GetMechanism(const KeyAlgorithm& aAlgorithm) { 248 // For everything but HMAC, the name determines the mechanism 249 // HMAC is handled by the specialization below 250 return MapAlgorithmNameToMechanism(aAlgorithm.mName); 251 } 252 253 CK_MECHANISM_TYPE 254 KeyAlgorithmProxy::GetMechanism(const HmacKeyAlgorithm& aAlgorithm) { 255 // The use of HmacKeyAlgorithm doesn't completely prevent this 256 // method from being called with dictionaries that don't really 257 // represent HMAC key algorithms. 258 MOZ_ASSERT(aAlgorithm.mName.EqualsLiteral(WEBCRYPTO_ALG_HMAC)); 259 260 CK_MECHANISM_TYPE hashMech; 261 hashMech = MapAlgorithmNameToMechanism(aAlgorithm.mHash.mName); 262 263 switch (hashMech) { 264 case CKM_SHA_1: 265 return CKM_SHA_1_HMAC; 266 case CKM_SHA256: 267 return CKM_SHA256_HMAC; 268 case CKM_SHA384: 269 return CKM_SHA384_HMAC; 270 case CKM_SHA512: 271 return CKM_SHA512_HMAC; 272 } 273 return UNKNOWN_CK_MECHANISM; 274 } 275 276 } // namespace mozilla::dom