tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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