LCOV - code coverage report
Current view: top level - dom/crypto - WebCryptoCommon.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 135 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 9 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : #ifndef mozilla_dom_WebCryptoCommon_h
       8             : #define mozilla_dom_WebCryptoCommon_h
       9             : 
      10             : #include "js/StructuredClone.h"
      11             : #include "mozilla/ArrayUtils.h"
      12             : #include "mozilla/dom/CryptoBuffer.h"
      13             : #include "nsContentUtils.h"
      14             : #include "nsString.h"
      15             : #include "pk11pub.h"
      16             : 
      17             : // WebCrypto algorithm names
      18             : #define WEBCRYPTO_ALG_AES_CBC       "AES-CBC"
      19             : #define WEBCRYPTO_ALG_AES_CTR       "AES-CTR"
      20             : #define WEBCRYPTO_ALG_AES_GCM       "AES-GCM"
      21             : #define WEBCRYPTO_ALG_AES_KW        "AES-KW"
      22             : #define WEBCRYPTO_ALG_SHA1          "SHA-1"
      23             : #define WEBCRYPTO_ALG_SHA256        "SHA-256"
      24             : #define WEBCRYPTO_ALG_SHA384        "SHA-384"
      25             : #define WEBCRYPTO_ALG_SHA512        "SHA-512"
      26             : #define WEBCRYPTO_ALG_HMAC          "HMAC"
      27             : #define WEBCRYPTO_ALG_HKDF          "HKDF"
      28             : #define WEBCRYPTO_ALG_PBKDF2        "PBKDF2"
      29             : #define WEBCRYPTO_ALG_RSASSA_PKCS1  "RSASSA-PKCS1-v1_5"
      30             : #define WEBCRYPTO_ALG_RSA_OAEP      "RSA-OAEP"
      31             : #define WEBCRYPTO_ALG_RSA_PSS       "RSA-PSS"
      32             : #define WEBCRYPTO_ALG_ECDH          "ECDH"
      33             : #define WEBCRYPTO_ALG_ECDSA         "ECDSA"
      34             : #define WEBCRYPTO_ALG_DH            "DH"
      35             : 
      36             : // WebCrypto key formats
      37             : #define WEBCRYPTO_KEY_FORMAT_RAW    "raw"
      38             : #define WEBCRYPTO_KEY_FORMAT_PKCS8  "pkcs8"
      39             : #define WEBCRYPTO_KEY_FORMAT_SPKI   "spki"
      40             : #define WEBCRYPTO_KEY_FORMAT_JWK    "jwk"
      41             : 
      42             : // WebCrypto key types
      43             : #define WEBCRYPTO_KEY_TYPE_PUBLIC  "public"
      44             : #define WEBCRYPTO_KEY_TYPE_PRIVATE "private"
      45             : #define WEBCRYPTO_KEY_TYPE_SECRET  "secret"
      46             : 
      47             : // WebCrypto key usages
      48             : #define WEBCRYPTO_KEY_USAGE_ENCRYPT     "encrypt"
      49             : #define WEBCRYPTO_KEY_USAGE_DECRYPT     "decrypt"
      50             : #define WEBCRYPTO_KEY_USAGE_SIGN        "sign"
      51             : #define WEBCRYPTO_KEY_USAGE_VERIFY      "verify"
      52             : #define WEBCRYPTO_KEY_USAGE_DERIVEKEY   "deriveKey"
      53             : #define WEBCRYPTO_KEY_USAGE_DERIVEBITS  "deriveBits"
      54             : #define WEBCRYPTO_KEY_USAGE_WRAPKEY     "wrapKey"
      55             : #define WEBCRYPTO_KEY_USAGE_UNWRAPKEY   "unwrapKey"
      56             : 
      57             : // WebCrypto named curves
      58             : #define WEBCRYPTO_NAMED_CURVE_P256  "P-256"
      59             : #define WEBCRYPTO_NAMED_CURVE_P384  "P-384"
      60             : #define WEBCRYPTO_NAMED_CURVE_P521  "P-521"
      61             : 
      62             : // JWK key types
      63             : #define JWK_TYPE_SYMMETRIC          "oct"
      64             : #define JWK_TYPE_RSA                "RSA"
      65             : #define JWK_TYPE_EC                 "EC"
      66             : 
      67             : // JWK algorithms
      68             : #define JWK_ALG_A128CBC             "A128CBC"  // CBC
      69             : #define JWK_ALG_A192CBC             "A192CBC"
      70             : #define JWK_ALG_A256CBC             "A256CBC"
      71             : #define JWK_ALG_A128CTR             "A128CTR"  // CTR
      72             : #define JWK_ALG_A192CTR             "A192CTR"
      73             : #define JWK_ALG_A256CTR             "A256CTR"
      74             : #define JWK_ALG_A128GCM             "A128GCM"  // GCM
      75             : #define JWK_ALG_A192GCM             "A192GCM"
      76             : #define JWK_ALG_A256GCM             "A256GCM"
      77             : #define JWK_ALG_A128KW              "A128KW"   // KW
      78             : #define JWK_ALG_A192KW              "A192KW"
      79             : #define JWK_ALG_A256KW              "A256KW"
      80             : #define JWK_ALG_HS1                 "HS1"      // HMAC
      81             : #define JWK_ALG_HS256               "HS256"
      82             : #define JWK_ALG_HS384               "HS384"
      83             : #define JWK_ALG_HS512               "HS512"
      84             : #define JWK_ALG_RS1                 "RS1"      // RSASSA-PKCS1
      85             : #define JWK_ALG_RS256               "RS256"
      86             : #define JWK_ALG_RS384               "RS384"
      87             : #define JWK_ALG_RS512               "RS512"
      88             : #define JWK_ALG_RSA_OAEP            "RSA-OAEP" // RSA-OAEP
      89             : #define JWK_ALG_RSA_OAEP_256        "RSA-OAEP-256"
      90             : #define JWK_ALG_RSA_OAEP_384        "RSA-OAEP-384"
      91             : #define JWK_ALG_RSA_OAEP_512        "RSA-OAEP-512"
      92             : #define JWK_ALG_PS1                 "PS1"      // RSA-PSS
      93             : #define JWK_ALG_PS256               "PS256"
      94             : #define JWK_ALG_PS384               "PS384"
      95             : #define JWK_ALG_PS512               "PS512"
      96             : #define JWK_ALG_ECDSA_P_256         "ES256"
      97             : #define JWK_ALG_ECDSA_P_384         "ES384"
      98             : #define JWK_ALG_ECDSA_P_521         "ES521"
      99             : 
     100             : // JWK usages
     101             : #define JWK_USE_ENC                 "enc"
     102             : #define JWK_USE_SIG                 "sig"
     103             : 
     104             : // Define an unknown mechanism type
     105             : #define UNKNOWN_CK_MECHANISM        CKM_VENDOR_DEFINED+1
     106             : 
     107             : // python security/pkix/tools/DottedOIDToCode.py id-ecDH 1.3.132.112
     108             : static const uint8_t id_ecDH[] = { 0x2b, 0x81, 0x04, 0x70 };
     109             : const SECItem SEC_OID_DATA_EC_DH = { siBuffer, (unsigned char*)id_ecDH,
     110             :                                      static_cast<unsigned int>(
     111             :                                        mozilla::ArrayLength(id_ecDH)) };
     112             : 
     113             : // python security/pkix/tools/DottedOIDToCode.py dhKeyAgreement 1.2.840.113549.1.3.1
     114             : static const uint8_t dhKeyAgreement[] = {
     115             :   0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x03, 0x01
     116             : };
     117             : const SECItem SEC_OID_DATA_DH_KEY_AGREEMENT = { siBuffer,
     118             :                                                 (unsigned char*)dhKeyAgreement,
     119             :                                                 static_cast<unsigned int>(
     120             :                                                   mozilla::ArrayLength(dhKeyAgreement)) };
     121             : 
     122             : namespace mozilla {
     123             : namespace dom {
     124             : 
     125             : // Helper functions for structured cloning
     126             : inline bool
     127           0 : ReadString(JSStructuredCloneReader* aReader, nsString& aString)
     128             : {
     129             :   bool read;
     130             :   uint32_t nameLength, zero;
     131           0 :   read = JS_ReadUint32Pair(aReader, &nameLength, &zero);
     132           0 :   if (!read) {
     133           0 :     return false;
     134             :   }
     135             : 
     136           0 :   aString.SetLength(nameLength);
     137           0 :   size_t charSize = sizeof(nsString::char_type);
     138           0 :   read = JS_ReadBytes(aReader, (void*) aString.BeginWriting(), nameLength * charSize);
     139           0 :   if (!read) {
     140           0 :     return false;
     141             :   }
     142             : 
     143           0 :   return true;
     144             : }
     145             : 
     146             : inline bool
     147           0 : WriteString(JSStructuredCloneWriter* aWriter, const nsString& aString)
     148             : {
     149           0 :   size_t charSize = sizeof(nsString::char_type);
     150           0 :   return JS_WriteUint32Pair(aWriter, aString.Length(), 0) &&
     151           0 :          JS_WriteBytes(aWriter, aString.get(), aString.Length() * charSize);
     152             : }
     153             : 
     154             : inline bool
     155           0 : ReadBuffer(JSStructuredCloneReader* aReader, CryptoBuffer& aBuffer)
     156             : {
     157             :   uint32_t length, zero;
     158           0 :   bool ret = JS_ReadUint32Pair(aReader, &length, &zero);
     159           0 :   if (!ret) {
     160           0 :     return false;
     161             :   }
     162             : 
     163           0 :   if (length > 0) {
     164           0 :     if (!aBuffer.SetLength(length, fallible)) {
     165           0 :       return false;
     166             :     }
     167           0 :     ret = JS_ReadBytes(aReader, aBuffer.Elements(), aBuffer.Length());
     168             :   }
     169           0 :   return ret;
     170             : }
     171             : 
     172             : inline bool
     173           0 : WriteBuffer(JSStructuredCloneWriter* aWriter, const uint8_t* aBuffer, size_t aLength)
     174             : {
     175           0 :   bool ret = JS_WriteUint32Pair(aWriter, aLength, 0);
     176           0 :   if (ret && aLength > 0) {
     177           0 :     ret = JS_WriteBytes(aWriter, aBuffer, aLength);
     178             :   }
     179           0 :   return ret;
     180             : }
     181             : 
     182             : inline bool
     183           0 : WriteBuffer(JSStructuredCloneWriter* aWriter, const CryptoBuffer& aBuffer)
     184             : {
     185           0 :   return WriteBuffer(aWriter, aBuffer.Elements(), aBuffer.Length());
     186             : }
     187             : 
     188             : inline CK_MECHANISM_TYPE
     189           0 : MapAlgorithmNameToMechanism(const nsString& aName)
     190             : {
     191           0 :   CK_MECHANISM_TYPE mechanism(UNKNOWN_CK_MECHANISM);
     192             : 
     193             :   // Set mechanism based on algorithm name
     194           0 :   if (aName.EqualsLiteral(WEBCRYPTO_ALG_AES_CBC)) {
     195           0 :     mechanism = CKM_AES_CBC_PAD;
     196           0 :   } else if (aName.EqualsLiteral(WEBCRYPTO_ALG_AES_CTR)) {
     197           0 :     mechanism = CKM_AES_CTR;
     198           0 :   } else if (aName.EqualsLiteral(WEBCRYPTO_ALG_AES_GCM)) {
     199           0 :     mechanism = CKM_AES_GCM;
     200           0 :   } else if (aName.EqualsLiteral(WEBCRYPTO_ALG_AES_KW)) {
     201           0 :     mechanism = CKM_NSS_AES_KEY_WRAP;
     202           0 :   } else if (aName.EqualsLiteral(WEBCRYPTO_ALG_SHA1)) {
     203           0 :     mechanism = CKM_SHA_1;
     204           0 :   } else if (aName.EqualsLiteral(WEBCRYPTO_ALG_SHA256)) {
     205           0 :     mechanism = CKM_SHA256;
     206           0 :   } else if (aName.EqualsLiteral(WEBCRYPTO_ALG_SHA384)) {
     207           0 :     mechanism = CKM_SHA384;
     208           0 :   } else if (aName.EqualsLiteral(WEBCRYPTO_ALG_SHA512)) {
     209           0 :     mechanism = CKM_SHA512;
     210           0 :   } else if (aName.EqualsLiteral(WEBCRYPTO_ALG_PBKDF2)) {
     211           0 :     mechanism = CKM_PKCS5_PBKD2;
     212           0 :   } else if (aName.EqualsLiteral(WEBCRYPTO_ALG_RSASSA_PKCS1)) {
     213           0 :     mechanism = CKM_RSA_PKCS;
     214           0 :   } else if (aName.EqualsLiteral(WEBCRYPTO_ALG_RSA_OAEP)) {
     215           0 :     mechanism = CKM_RSA_PKCS_OAEP;
     216           0 :   } else if (aName.EqualsLiteral(WEBCRYPTO_ALG_RSA_PSS)) {
     217           0 :     mechanism = CKM_RSA_PKCS_PSS;
     218           0 :   } else if (aName.EqualsLiteral(WEBCRYPTO_ALG_ECDH)) {
     219           0 :     mechanism = CKM_ECDH1_DERIVE;
     220           0 :   } else if (aName.EqualsLiteral(WEBCRYPTO_ALG_DH)) {
     221           0 :     mechanism = CKM_DH_PKCS_DERIVE;
     222             :   }
     223             : 
     224           0 :   return mechanism;
     225             : }
     226             : 
     227             : #define NORMALIZED_EQUALS(aTest, aConst) \
     228             :         nsContentUtils::EqualsIgnoreASCIICase(aTest, NS_LITERAL_STRING(aConst))
     229             : 
     230             : inline bool
     231           0 : NormalizeToken(const nsString& aName, nsString& aDest)
     232             : {
     233             :   // Algorithm names
     234           0 :   if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_AES_CBC)) {
     235           0 :     aDest.AssignLiteral(WEBCRYPTO_ALG_AES_CBC);
     236           0 :   } else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_AES_CTR)) {
     237           0 :     aDest.AssignLiteral(WEBCRYPTO_ALG_AES_CTR);
     238           0 :   } else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_AES_GCM)) {
     239           0 :     aDest.AssignLiteral(WEBCRYPTO_ALG_AES_GCM);
     240           0 :   } else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_AES_KW)) {
     241           0 :     aDest.AssignLiteral(WEBCRYPTO_ALG_AES_KW);
     242           0 :   } else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_SHA1)) {
     243           0 :     aDest.AssignLiteral(WEBCRYPTO_ALG_SHA1);
     244           0 :   } else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_SHA256)) {
     245           0 :     aDest.AssignLiteral(WEBCRYPTO_ALG_SHA256);
     246           0 :   } else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_SHA384)) {
     247           0 :     aDest.AssignLiteral(WEBCRYPTO_ALG_SHA384);
     248           0 :   } else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_SHA512)) {
     249           0 :     aDest.AssignLiteral(WEBCRYPTO_ALG_SHA512);
     250           0 :   } else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_HMAC)) {
     251           0 :     aDest.AssignLiteral(WEBCRYPTO_ALG_HMAC);
     252           0 :   } else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_HKDF)) {
     253           0 :     aDest.AssignLiteral(WEBCRYPTO_ALG_HKDF);
     254           0 :   } else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_PBKDF2)) {
     255           0 :     aDest.AssignLiteral(WEBCRYPTO_ALG_PBKDF2);
     256           0 :   } else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_RSASSA_PKCS1)) {
     257           0 :     aDest.AssignLiteral(WEBCRYPTO_ALG_RSASSA_PKCS1);
     258           0 :   } else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_RSA_OAEP)) {
     259           0 :     aDest.AssignLiteral(WEBCRYPTO_ALG_RSA_OAEP);
     260           0 :   } else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_RSA_PSS)) {
     261           0 :     aDest.AssignLiteral(WEBCRYPTO_ALG_RSA_PSS);
     262           0 :   } else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_ECDH)) {
     263           0 :     aDest.AssignLiteral(WEBCRYPTO_ALG_ECDH);
     264           0 :   } else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_ECDSA)) {
     265           0 :     aDest.AssignLiteral(WEBCRYPTO_ALG_ECDSA);
     266           0 :   } else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_DH)) {
     267           0 :     aDest.AssignLiteral(WEBCRYPTO_ALG_DH);
     268             :   // Named curve values
     269           0 :   } else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_NAMED_CURVE_P256)) {
     270           0 :     aDest.AssignLiteral(WEBCRYPTO_NAMED_CURVE_P256);
     271           0 :   } else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_NAMED_CURVE_P384)) {
     272           0 :     aDest.AssignLiteral(WEBCRYPTO_NAMED_CURVE_P384);
     273           0 :   } else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_NAMED_CURVE_P521)) {
     274           0 :     aDest.AssignLiteral(WEBCRYPTO_NAMED_CURVE_P521);
     275             :   } else {
     276           0 :     return false;
     277             :   }
     278             : 
     279           0 :   return true;
     280             : }
     281             : 
     282             : inline bool
     283           0 : CheckEncodedECParameters(const SECItem* aEcParams)
     284             : {
     285             :   // Need at least two bytes for a valid ASN.1 encoding.
     286           0 :   if (aEcParams->len < 2) {
     287           0 :     return false;
     288             :   }
     289             : 
     290             :   // Check the ASN.1 tag.
     291           0 :   if (aEcParams->data[0] != SEC_ASN1_OBJECT_ID) {
     292           0 :     return false;
     293             :   }
     294             : 
     295             :   // OID tags are short, we never need more than one length byte.
     296           0 :   if (aEcParams->data[1] >= 128) {
     297           0 :     return false;
     298             :   }
     299             : 
     300             :   // Check that the SECItem's length is correct.
     301           0 :   if (aEcParams->len != (unsigned)aEcParams->data[1] + 2) {
     302           0 :     return false;
     303             :   }
     304             : 
     305           0 :   return true;
     306             : }
     307             : 
     308             : inline SECItem*
     309           0 : CreateECParamsForCurve(const nsString& aNamedCurve, PLArenaPool* aArena)
     310             : {
     311           0 :   MOZ_ASSERT(aArena);
     312             :   SECOidTag curveOIDTag;
     313             : 
     314           0 :   if (aNamedCurve.EqualsLiteral(WEBCRYPTO_NAMED_CURVE_P256)) {
     315           0 :     curveOIDTag = SEC_OID_SECG_EC_SECP256R1;
     316           0 :   } else if (aNamedCurve.EqualsLiteral(WEBCRYPTO_NAMED_CURVE_P384)) {
     317           0 :     curveOIDTag = SEC_OID_SECG_EC_SECP384R1;
     318           0 :   } else if (aNamedCurve.EqualsLiteral(WEBCRYPTO_NAMED_CURVE_P521)) {
     319           0 :     curveOIDTag = SEC_OID_SECG_EC_SECP521R1;
     320             :   } else {
     321           0 :     return nullptr;
     322             :   }
     323             : 
     324             :   // Retrieve curve data by OID tag.
     325           0 :   SECOidData* oidData = SECOID_FindOIDByTag(curveOIDTag);
     326           0 :   if (!oidData) {
     327           0 :     return nullptr;
     328             :   }
     329             : 
     330             :   // Create parameters.
     331           0 :   SECItem* params = ::SECITEM_AllocItem(aArena, nullptr, 2 + oidData->oid.len);
     332           0 :   if (!params) {
     333           0 :     return nullptr;
     334             :   }
     335             : 
     336             :   // Set parameters.
     337           0 :   params->data[0] = SEC_ASN1_OBJECT_ID;
     338           0 :   params->data[1] = oidData->oid.len;
     339           0 :   memcpy(params->data + 2, oidData->oid.data, oidData->oid.len);
     340             : 
     341             :   // Sanity check the params we just created.
     342           0 :   if (!CheckEncodedECParameters(params)) {
     343           0 :     return nullptr;
     344             :   }
     345             : 
     346           0 :   return params;
     347             : }
     348             : 
     349             : } // namespace dom
     350             : } // namespace mozilla
     351             : 
     352             : #endif // mozilla_dom_WebCryptoCommon_h

Generated by: LCOV version 1.13