Beispiel #1
0
nsresult
CryptoKey::PublicKeyToSpki(SECKEYPublicKey* aPubKey,
                     CryptoBuffer& aRetVal,
                     const nsNSSShutDownPreventionLock& /*proofOfLock*/)
{
  ScopedCERTSubjectPublicKeyInfo spki(SECKEY_CreateSubjectPublicKeyInfo(aPubKey));
  if (!spki) {
    return NS_ERROR_DOM_OPERATION_ERR;
  }

  // Per WebCrypto spec we must export ECDH SPKIs with the algorithm OID
  // id-ecDH (1.3.132.112). NSS doesn't know about that OID and there is
  // no way to specify the algorithm to use when exporting a public key.
  if (aPubKey->keyType == ecKey) {
    SECStatus rv = SECITEM_CopyItem(spki->arena, &spki->algorithm.algorithm,
                                    &SEC_OID_DATA_EC_DH);
    if (rv != SECSuccess) {
      return NS_ERROR_DOM_OPERATION_ERR;
    }
  }

  const SEC_ASN1Template* tpl = SEC_ASN1_GET(CERT_SubjectPublicKeyInfoTemplate);
  ScopedSECItem spkiItem(SEC_ASN1EncodeItem(nullptr, nullptr, spki, tpl));

  aRetVal.Assign(spkiItem.get());
  return NS_OK;
}
Beispiel #2
0
SECKEYPublicKey*
CryptoKey::PublicKeyFromSpki(CryptoBuffer& aKeyData,
                       const nsNSSShutDownPreventionLock& /*proofOfLock*/)
{
  ScopedSECItem spkiItem(aKeyData.ToSECItem());
  if (!spkiItem) {
    return nullptr;
  }

  ScopedCERTSubjectPublicKeyInfo spki(SECKEY_DecodeDERSubjectPublicKeyInfo(spkiItem.get()));
  if (!spki) {
    return nullptr;
  }

  // Check for id-ecDH. Per the WebCrypto spec we must support it but NSS
  // does unfortunately not know about it. Let's change the algorithm to
  // id-ecPublicKey to make NSS happy.
  if (SECITEM_ItemsAreEqual(&SEC_OID_DATA_EC_DH, &spki->algorithm.algorithm)) {
    // Retrieve OID data for id-ecPublicKey (1.2.840.10045.2.1).
    SECOidData* oidData = SECOID_FindOIDByTag(SEC_OID_ANSIX962_EC_PUBLIC_KEY);
    if (!oidData) {
      return nullptr;
    }

    SECStatus rv = SECITEM_CopyItem(spki->arena, &spki->algorithm.algorithm,
                                    &oidData->oid);
    if (rv != SECSuccess) {
      return nullptr;
    }
  }

  return SECKEY_ExtractPublicKey(spki.get());
}
Beispiel #3
0
nsresult
CryptoKey::PublicKeyToSpki(SECKEYPublicKey* aPubKey,
                     CryptoBuffer& aRetVal,
                     const nsNSSShutDownPreventionLock& /*proofOfLock*/)
{
  ScopedSECItem spkiItem(PK11_DEREncodePublicKey(aPubKey));
  if (!spkiItem.get()) {
    return NS_ERROR_DOM_INVALID_ACCESS_ERR;
  }

  aRetVal.Assign(spkiItem.get());
  return NS_OK;
}
Beispiel #4
0
SECKEYPublicKey*
CryptoKey::PublicKeyFromSpki(CryptoBuffer& aKeyData,
                       const nsNSSShutDownPreventionLock& /*proofOfLock*/)
{
  ScopedSECItem spkiItem(aKeyData.ToSECItem());
  if (!spkiItem) {
    return nullptr;
  }

  ScopedCERTSubjectPublicKeyInfo spki(SECKEY_DecodeDERSubjectPublicKeyInfo(spkiItem.get()));
  if (!spki) {
    return nullptr;
  }

  return SECKEY_ExtractPublicKey(spki.get());
}
Beispiel #5
0
nsresult
CryptoKey::PublicKeyToSpki(SECKEYPublicKey* aPubKey,
                           CryptoBuffer& aRetVal,
                           const nsNSSShutDownPreventionLock& /*proofOfLock*/)
{
  ScopedCERTSubjectPublicKeyInfo spki;

  // NSS doesn't support exporting DH public keys.
  if (aPubKey->keyType == dhKey) {
    // Mimic the behavior of SECKEY_CreateSubjectPublicKeyInfo() and create
    // a new arena for the SPKI object.
    ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
    if (!arena) {
      return NS_ERROR_DOM_OPERATION_ERR;
    }

    spki = PORT_ArenaZNew(arena, CERTSubjectPublicKeyInfo);
    if (!spki) {
      return NS_ERROR_DOM_OPERATION_ERR;
    }

    // Assign |arena| to |spki| and null the variable afterwards so that the
    // arena created above that holds the SPKI object is free'd when |spki|
    // goes out of scope, not when |arena| does.
    spki->arena = arena.forget();

    nsresult rv = PublicDhKeyToSpki(aPubKey, spki);
    NS_ENSURE_SUCCESS(rv, rv);
  } else {
    spki = SECKEY_CreateSubjectPublicKeyInfo(aPubKey);
    if (!spki) {
      return NS_ERROR_DOM_OPERATION_ERR;
    }
  }

  // Per WebCrypto spec we must export ECDH SPKIs with the algorithm OID
  // id-ecDH (1.3.132.112) and DH SPKIs with OID dhKeyAgreement
  // (1.2.840.113549.1.3.1). NSS doesn't know about these OIDs and there is
  // no way to specify the algorithm to use when exporting a public key.
  if (aPubKey->keyType == ecKey || aPubKey->keyType == dhKey) {
    const SECItem* oidData = nullptr;
    if (aPubKey->keyType == ecKey) {
      oidData = &SEC_OID_DATA_EC_DH;
    } else if (aPubKey->keyType == dhKey) {
      oidData = &SEC_OID_DATA_DH_KEY_AGREEMENT;
    } else {
      MOZ_ASSERT(false);
    }

    SECStatus rv = SECITEM_CopyItem(spki->arena, &spki->algorithm.algorithm,
                                    oidData);
    if (rv != SECSuccess) {
      return NS_ERROR_DOM_OPERATION_ERR;
    }
  }

  const SEC_ASN1Template* tpl = SEC_ASN1_GET(CERT_SubjectPublicKeyInfoTemplate);
  ScopedSECItem spkiItem(SEC_ASN1EncodeItem(nullptr, nullptr, spki, tpl));

  aRetVal.Assign(spkiItem.get());
  return NS_OK;
}