Exemplo n.º 1
0
/* searches both the baggage and the safe areas looking for
 * object of specified type matching either the nickname or the 
 * thumbprint specified.
 *
 * safe and baggage store certs and keys
 * objType is the OID for the bag type to be searched:
 *   SEC_OID_PKCS12_KEY_BAG_ID, or 
 *   SEC_OID_PKCS12_CERT_AND_CRL_BAG_ID
 * nickname and thumbprint are the search criteria
 * 
 * if no match found, NULL returned and error set
 */
void *
sec_pkcs12_find_object(SEC_PKCS12SafeContents *safe,
			SEC_PKCS12Baggage *baggage,
			SECOidTag objType,
			SECItem *nickname,
			SGNDigestInfo *thumbprint)
{
    int i, j;
    void *retItem;
   
    if(((safe == NULL) && (thumbprint == NULL)) ||
       ((nickname == NULL) && (thumbprint == NULL))) {
	return NULL;
    }    

    i = 0;
    if((safe != NULL) && (safe->contents != NULL)) {
	while(safe->contents[i] != NULL) {
	    SECOidTag bagType = SECOID_FindOIDTag(&safe->contents[i]->safeBagType);
	    retItem = sec_pkcs12_try_find(safe, NULL, objType, bagType, i,
	    				  nickname, thumbprint);
	    if(retItem != NULL) {
		return retItem;
	    }
	    i++;
	}
    }

    if((baggage != NULL) && (baggage->bags != NULL)) {
	i = 0;
	while(baggage->bags[i] != NULL) {
	    SEC_PKCS12BaggageItem *xbag = baggage->bags[i];
	    j = 0;
	    if(xbag->unencSecrets != NULL) {
		while(xbag->unencSecrets[j] != NULL) {
		    SECOidTag bagType;
		    bagType = SECOID_FindOIDTag(&xbag->unencSecrets[j]->safeBagType);
		    retItem = sec_pkcs12_try_find(NULL, xbag, objType, bagType,
		    				  j, nickname, thumbprint);
		    if(retItem != NULL) {
			return retItem;
		    }
		    j++;
		}
	    }
	    i++;
	}
    }

    PORT_SetError(SEC_ERROR_PKCS12_UNABLE_TO_LOCATE_OBJECT_BY_NAME);
    return NULL;
}
Exemplo n.º 2
0
// Find the first policy OID that is known to be an EV policy OID.
SECStatus
GetFirstEVPolicy(CERTCertificate* cert,
                 /*out*/ mozilla::pkix::CertPolicyId& policy,
                 /*out*/ SECOidTag& policyOidTag)
{
  if (!cert) {
    PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
    return SECFailure;
  }

  if (cert->extensions) {
    for (int i=0; cert->extensions[i]; i++) {
      const SECItem* oid = &cert->extensions[i]->id;

      SECOidTag oidTag = SECOID_FindOIDTag(oid);
      if (oidTag != SEC_OID_X509_CERTIFICATE_POLICIES)
        continue;

      SECItem* value = &cert->extensions[i]->value;

      CERTCertificatePolicies* policies;
      CERTPolicyInfo** policyInfos;

      policies = CERT_DecodeCertificatePoliciesExtension(value);
      if (!policies)
        continue;

      policyInfos = policies->policyInfos;

      bool found = false;
      while (*policyInfos) {
        const CERTPolicyInfo* policyInfo = *policyInfos++;

        SECOidTag oid_tag = policyInfo->oid;
        if (oid_tag != SEC_OID_UNKNOWN && isEVPolicy(oid_tag)) {
          const SECOidData* oidData = SECOID_FindOIDByTag(oid_tag);
          PR_ASSERT(oidData);
          PR_ASSERT(oidData->oid.data);
          PR_ASSERT(oidData->oid.len > 0);
          PR_ASSERT(oidData->oid.len <= mozilla::pkix::CertPolicyId::MAX_BYTES);
          if (oidData && oidData->oid.data && oidData->oid.len > 0 &&
              oidData->oid.len <= mozilla::pkix::CertPolicyId::MAX_BYTES) {
            policy.numBytes = static_cast<uint16_t>(oidData->oid.len);
            memcpy(policy.bytes, oidData->oid.data, policy.numBytes);
            policyOidTag = oid_tag;
            found = true;
          }
          break;
        }
      }
      CERT_DestroyCertificatePoliciesExtension(policies);
      if (found) {
        return SECSuccess;
      }
    }
  }

  PR_SetError(SEC_ERROR_POLICY_VALIDATION_FAILED, 0);
  return SECFailure;
}
Exemplo n.º 3
0
static unsigned long
nss_SMIME_FindCipherForSMIMECap(NSSSMIMECapability *cap)
{
    int i;
    SECOidTag capIDTag;

    /* we need the OIDTag here */
    capIDTag = SECOID_FindOIDTag(&(cap->capabilityID));

    /* go over all the SMIME ciphers we know and see if we find a match */
    for (i = 0; i < smime_cipher_map_count; i++) {
	if (smime_cipher_map[i].algtag != capIDTag)
	    continue;
	/*
	 * XXX If SECITEM_CompareItem allowed NULLs as arguments (comparing
	 * 2 NULLs as equal and NULL and non-NULL as not equal), we could
	 * use that here instead of all of the following comparison code.
	 */
	if (cap->parameters.Data == NULL && smime_cipher_map[i].parms == NULL)
	    break;	/* both empty: bingo */

	if (cap->parameters.Data != NULL && smime_cipher_map[i].parms != NULL &&
	    cap->parameters.Length == smime_cipher_map[i].parms->Length &&
	    PORT_Memcmp (cap->parameters.Data, smime_cipher_map[i].parms->Data,
			     cap->parameters.Length) == 0)
	{
	    break;	/* both not empty, same length & equal content: bingo */
	}
    }

    if (i == smime_cipher_map_count)
	return 0;				/* no match found */
    else
	return smime_cipher_map[i].cipher;	/* match found, point to cipher */
}
Exemplo n.º 4
0
const SECHashObject *
NSS_CMSUtil_GetHashObjByAlgID(SECAlgorithmID *algid)
{
    SECOidTag oidTag = SECOID_FindOIDTag(&(algid->algorithm));
    const SECHashObject *digobj = HASH_GetHashObjectByOidTag(oidTag);

    return digobj;
}
SECOidTag
SECOID_GetAlgorithmTag(SECAlgorithmID *id)
{
    if (id == NULL || id->algorithm.data == NULL)
	return SEC_OID_UNKNOWN;

    return SECOID_FindOIDTag (&(id->algorithm));
}
Exemplo n.º 6
0
// Find the first policy OID that is known to be an EV policy OID.
static SECStatus getFirstEVPolicy(CERTCertificate *cert, SECOidTag &outOidTag)
{
  if (!cert)
    return SECFailure;

  if (cert->extensions) {
    for (int i=0; cert->extensions[i] != nsnull; i++) {
      const SECItem *oid = &cert->extensions[i]->id;

      SECOidTag oidTag = SECOID_FindOIDTag(oid);
      if (oidTag != SEC_OID_X509_CERTIFICATE_POLICIES)
        continue;

      SECItem *value = &cert->extensions[i]->value;

      CERTCertificatePolicies *policies;
      CERTPolicyInfo **policyInfos, *policyInfo;
    
      policies = CERT_DecodeCertificatePoliciesExtension(value);
      if (!policies)
        continue;
    
      policyInfos = policies->policyInfos;

      PRBool found = PR_FALSE;
      while (*policyInfos != NULL) {
        policyInfo = *policyInfos++;

        SECOidTag oid_tag = SECOID_FindOIDTag(&policyInfo->policyID);
        if (oid_tag != SEC_OID_UNKNOWN && isEVPolicy(oid_tag)) {
          // in our list of OIDs accepted for EV
          outOidTag = oid_tag;
          found = PR_TRUE;
          break;
        }
      }
      CERT_DestroyCertificatePoliciesExtension(policies);
      if (found)
        return SECSuccess;
    }
  }

  return SECFailure;
}
Exemplo n.º 7
0
PRBool
CERT_GovtApprovedBitSet(CERTCertificate *cert)
{
    SECStatus rv;
    SECItem extItem;
    CERTOidSequence *oidSeq = NULL;
    PRBool ret;
    SECItem **oids;
    SECItem *oid;
    SECOidTag oidTag;
    
    extItem.data = NULL;
    rv = CERT_FindCertExtension(cert, SEC_OID_X509_EXT_KEY_USAGE, &extItem);
    if ( rv != SECSuccess ) {
	goto loser;
    }

    oidSeq = CERT_DecodeOidSequence(&extItem);
    if ( oidSeq == NULL ) {
	goto loser;
    }

    oids = oidSeq->oids;
    while ( oids != NULL && *oids != NULL ) {
	oid = *oids;
	
	oidTag = SECOID_FindOIDTag(oid);
	
	if ( oidTag == SEC_OID_NS_KEY_USAGE_GOVT_APPROVED ) {
	    goto success;
	}
	
	oids++;
    }

loser:
    ret = PR_FALSE;
    goto done;
success:
    ret = PR_TRUE;
done:
    if ( oidSeq != NULL ) {
	CERT_DestroyOidSequence(oidSeq);
    }
    if (extItem.data != NULL) {
	PORT_Free(extItem.data);
    }
    return(ret);
}
Exemplo n.º 8
0
CK_MECHANISM_TYPE
crmf_get_mechanism_from_public_key(SECKEYPublicKey *inPubKey)
{
    CERTSubjectPublicKeyInfo *spki = NULL;
    SECOidTag tag;

    spki = SECKEY_CreateSubjectPublicKeyInfo(inPubKey);
    if (spki == NULL) {
        return CKM_INVALID_MECHANISM;
    }
    tag = SECOID_FindOIDTag(&spki->algorithm.algorithm);
    SECKEY_DestroySubjectPublicKeyInfo(spki);
    spki = NULL;
    return PK11_AlgtagToMechanism(tag);
}
Exemplo n.º 9
0
int
sv_PrintSubjectPublicKeyInfo(FILE *out, PLArenaPool *arena,
                             CERTSubjectPublicKeyInfo *i, char *msg)
{
    SECKEYPublicKey *pk;
    int rv;
    char mm[200];

    sprintf(mm, "%s.publicKeyAlgorithm=", msg);
    sv_PrintAlgorithmID(out, &i->algorithm, mm);

    pk = (SECKEYPublicKey *)PORT_ZAlloc(sizeof(SECKEYPublicKey));
    if (!pk)
        return PORT_GetError();

    DER_ConvertBitString(&i->subjectPublicKey);
    switch (SECOID_FindOIDTag(&i->algorithm.algorithm)) {
        case SEC_OID_PKCS1_RSA_ENCRYPTION:
            rv = SEC_ASN1DecodeItem(arena, pk,
                                    SEC_ASN1_GET(SECKEY_RSAPublicKeyTemplate),
                                    &i->subjectPublicKey);
            if (rv)
                return rv;
            sprintf(mm, "%s.rsaPublicKey.", msg);
            sv_PrintRSAPublicKey(out, pk, mm);
            break;
        case SEC_OID_ANSIX9_DSA_SIGNATURE:
            rv = SEC_ASN1DecodeItem(arena, pk,
                                    SEC_ASN1_GET(SECKEY_DSAPublicKeyTemplate),
                                    &i->subjectPublicKey);
            if (rv)
                return rv;
            sprintf(mm, "%s.dsaPublicKey.", msg);
            sv_PrintDSAPublicKey(out, pk, mm);
            break;
        default:
            fprintf(out, "%s=bad SPKI algorithm type\n", msg);
            return 0;
    }

    return 0;
}
Exemplo n.º 10
0
static nsresult
GetCertFingerprintByDottedOidString(CERTCertificate* nsscert,
                                    const nsCString &dottedOid,
                                    nsCString &fp)
{
    SECItem oid;
    oid.data = nsnull;
    oid.len = 0;
    SECStatus srv = SEC_StringToOID(nsnull, &oid,
                                    dottedOid.get(), dottedOid.Length());
    if (srv != SECSuccess)
        return NS_ERROR_FAILURE;

    SECOidTag oid_tag = SECOID_FindOIDTag(&oid);
    SECITEM_FreeItem(&oid, PR_FALSE);

    if (oid_tag == SEC_OID_UNKNOWN)
        return NS_ERROR_FAILURE;

    return GetCertFingerprintByOidTag(nsscert, oid_tag, fp);
}
Exemplo n.º 11
0
SECStatus
NSS_CMSSignedData_Decode_BeforeData(NSSCMSSignedData *sigd)
{
    SECStatus rv;
    if (!sigd) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    rv = NSS_CMSContentInfo_Private_Init(&sigd->contentInfo);
    if (rv != SECSuccess) {
	return SECFailure;
    }
    /* handle issue with Windows 2003 servers and kerberos */
    if (sigd->digestAlgorithms != NULL) {
	int i;
	for (i=0; sigd->digestAlgorithms[i] != NULL; i++) {
	    SECAlgorithmID *algid = sigd->digestAlgorithms[i];
	    SECOidTag senttag= SECOID_FindOIDTag(&algid->algorithm);
	    SECOidTag maptag = NSS_CMSUtil_MapSignAlgs(senttag);

	    if (maptag != senttag) {
		SECOidData *hashoid = SECOID_FindOIDByTag(maptag);
		rv = SECITEM_CopyItem(sigd->cmsg->poolp, &algid->algorithm 
							,&hashoid->oid);
		if (rv != SECSuccess) {
		    return rv;
		}
	    }
	}
    }

    /* set up the digests */
    if (sigd->digestAlgorithms != NULL && sigd->digests == NULL) {
	/* if digests are already there, do nothing */
	sigd->contentInfo.privateInfo->digcx = NSS_CMSDigestContext_StartMultiple(sigd->digestAlgorithms);
	if (sigd->contentInfo.privateInfo->digcx == NULL)
	    return SECFailure;
    }
    return SECSuccess;
}
Exemplo n.º 12
0
static void
smime_fill_capability(smime_capability *cap)
{
    unsigned long cipher;
    SECOidTag algtag;
    int i;

    algtag = SECOID_FindOIDTag(&(cap->capabilityID));

    for (i = 0; i < smime_symmetric_count; i++) {
        if (smime_cipher_maps[i].algtag != algtag)
            continue;
        /*
         * XXX If SECITEM_CompareItem allowed NULLs as arguments (comparing
         * 2 NULLs as equal and NULL and non-NULL as not equal), we could
         * use that here instead of all of the following comparison code.
         */
        if (cap->parameters.data != NULL) {
            if (smime_cipher_maps[i].parms == NULL)
                continue;
            if (cap->parameters.len != smime_cipher_maps[i].parms->len)
                continue;
            if (PORT_Memcmp(cap->parameters.data,
                            smime_cipher_maps[i].parms->data,
                            cap->parameters.len) == 0)
                break;
        } else if (smime_cipher_maps[i].parms == NULL) {
            break;
        }
    }

    if (i == smime_symmetric_count)
        cipher = 0;
    else
        cipher = smime_cipher_maps[i].cipher;

    cap->cipher = cipher;
    cap->capIDTag = algtag;
}
Exemplo n.º 13
0
/*
 * smaller version of EC_FillParams. In this code, we only need
 * oid and DER data.
 */
SECStatus
LGEC_FillParams(PLArenaPool *arena, const SECItem *encodedParams,
    ECParams *params)
{
    SECOidTag tag;
    SECItem oid = { siBuffer, NULL, 0};

#if EC_DEBUG
    int i;

    printf("Encoded params in EC_DecodeParams: ");
    for (i = 0; i < encodedParams->len; i++) {
	    printf("%02x:", encodedParams->data[i]);
    }
    printf("\n");
#endif

    oid.len = encodedParams->len - 2;
    oid.data = encodedParams->data + 2;
    if ((encodedParams->data[0] != SEC_ASN1_OBJECT_ID) ||
	((tag = SECOID_FindOIDTag(&oid)) == SEC_OID_UNKNOWN)) { 
	    PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
	    return SECFailure;
    }

    params->arena = arena;

    /* For named curves, fill out curveOID */
    params->curveOID.len = oid.len;
    params->curveOID.data = (unsigned char *) PORT_ArenaAlloc(arena, oid.len);
    if (params->curveOID.data == NULL)  {
	return SECFailure;
    }
    memcpy(params->curveOID.data, oid.data, oid.len);

    return SECSuccess;
}
Exemplo n.º 14
0
int
sv_PrintExtensions(FILE *out, CERTCertExtension **extensions, char *msg)
{
    SECOidTag oidTag;

    if (extensions) {

        while (*extensions) {
            SECItem *tmpitem;

            fprintf(out, "%sname=", msg);

            tmpitem = &(*extensions)->id;
            sv_PrintObjectID(out, tmpitem, NULL);

            tmpitem = &(*extensions)->critical;
            if (tmpitem->len)
                fprintf(out, "%scritical=%s\n", msg,
                        (tmpitem->data && tmpitem->data[0]) ? "True" : "False");

            oidTag = SECOID_FindOIDTag(&((*extensions)->id));

            fprintf(out, "%s", msg);
            tmpitem = &((*extensions)->value);
            if (oidTag == SEC_OID_X509_INVALID_DATE)
                sv_PrintInvalidDateExten(out, tmpitem, "invalidExt");
            else
                sv_PrintAsHex(out, tmpitem, "data=");

            /*fprintf(out, "\n");*/
            extensions++;
        }
    }

    return 0;
}
Exemplo n.º 15
0
SECStatus
EC_FillParams(PLArenaPool *arena, const SECItem *encodedParams,
              ECParams *params)
{
    SECStatus rv = SECFailure;
    SECOidTag tag;
    SECItem oid = { siBuffer, NULL, 0 };

#if EC_DEBUG
    int i;

    printf("Encoded params in EC_DecodeParams: ");
    for (i = 0; i < encodedParams->len; i++) {
        printf("%02x:", encodedParams->data[i]);
    }
    printf("\n");
#endif

    if ((encodedParams->len != ANSI_X962_CURVE_OID_TOTAL_LEN) &&
        (encodedParams->len != SECG_CURVE_OID_TOTAL_LEN) &&
        (encodedParams->len != PKIX_NEWCURVES_OID_TOTAL_LEN)) {
        PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
        return SECFailure;
    };

    oid.len = encodedParams->len - 2;
    oid.data = encodedParams->data + 2;
    if ((encodedParams->data[0] != SEC_ASN1_OBJECT_ID) ||
        ((tag = SECOID_FindOIDTag(&oid)) == SEC_OID_UNKNOWN)) {
        PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
        return SECFailure;
    }

    params->arena = arena;
    params->cofactor = 0;
    params->type = ec_params_named;
    params->name = ECCurve_noName;

    /* Fill out curveOID */
    params->curveOID.len = oid.len;
    params->curveOID.data = (unsigned char *)PORT_ArenaAlloc(arena, oid.len);
    if (params->curveOID.data == NULL)
        goto cleanup;
    memcpy(params->curveOID.data, oid.data, oid.len);

#if EC_DEBUG
    printf("Curve: %s\n", SECOID_FindOIDTagDescription(tag));
#endif

    switch (tag) {
        case SEC_OID_ANSIX962_EC_PRIME256V1:
            /* Populate params for prime256v1 aka secp256r1
             * (the NIST P-256 curve)
             */
            CHECK_SEC_OK(gf_populate_params(ECCurve_X9_62_PRIME_256V1, ec_field_GFp,
                                            params));
            break;

        case SEC_OID_SECG_EC_SECP384R1:
            /* Populate params for secp384r1
             * (the NIST P-384 curve)
             */
            CHECK_SEC_OK(gf_populate_params(ECCurve_SECG_PRIME_384R1, ec_field_GFp,
                                            params));
            break;

        case SEC_OID_SECG_EC_SECP521R1:
            /* Populate params for secp521r1
             * (the NIST P-521 curve)
             */
            CHECK_SEC_OK(gf_populate_params(ECCurve_SECG_PRIME_521R1, ec_field_GFp,
                                            params));
            break;

        case SEC_OID_CURVE25519:
            /* Populate params for Curve25519 */
            CHECK_SEC_OK(gf_populate_params(ECCurve25519, ec_field_plain, params));
            break;

        default:
            break;
    };

cleanup:
    if (!params->cofactor) {
        PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
#if EC_DEBUG
        printf("Unrecognized curve, returning NULL params\n");
#endif
    }

    return rv;
}
Exemplo n.º 16
0
static CERTCertificatePolicies *
secu_DecodeCertificatePoliciesExtension(SECItem *extnValue)
{
    PRArenaPool *arena = NULL;
    SECStatus rv;
    CERTCertificatePolicies *policies;
    CERTPolicyInfo **policyInfos, *policyInfo;
    CERTPolicyQualifier **policyQualifiers, *policyQualifier;
    SECItem newExtnValue;
    
    /* make a new arena */
    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    
    if ( !arena ) {
	goto loser;
    }

    /* allocate the certifiate policies structure */
    policies = PORT_ArenaZNew(arena, CERTCertificatePolicies);
    if ( policies == NULL ) {
	goto loser;
    }
    
    policies->arena = arena;

    /* copy the DER into the arena, since Quick DER returns data that points
       into the DER input, which may get freed by the caller */
    rv = SECITEM_CopyItem(arena, &newExtnValue, extnValue);
    if ( rv != SECSuccess ) {
	goto loser;
    }

    /* decode the policy info */
    rv = SEC_QuickDERDecodeItem(arena, policies, 
                                secu_CertificatePoliciesTemplate,
			        &newExtnValue);

    if ( rv != SECSuccess ) {
	goto loser;
    }

    /* initialize the oid tags */
    policyInfos = policies->policyInfos;
    while (policyInfos != NULL && *policyInfos != NULL ) {
	policyInfo = *policyInfos;
	policyInfo->oid = SECOID_FindOIDTag(&policyInfo->policyID);
	policyQualifiers = policyInfo->policyQualifiers;
	while ( policyQualifiers && *policyQualifiers != NULL ) {
	    policyQualifier = *policyQualifiers;
	    policyQualifier->oid =
		SECOID_FindOIDTag(&policyQualifier->qualifierID);
	    policyQualifiers++;
	}
	policyInfos++;
    }

    return(policies);
    
loser:
    if ( arena != NULL ) {
	PORT_FreeArena(arena, PR_FALSE);
    }
    
    return(NULL);
}
Exemplo n.º 17
0
// 4.2.1.12. Extended Key Usage (id-ce-extKeyUsage)
// 4.2.1.12. Extended Key Usage (id-ce-extKeyUsage)
Result
CheckExtendedKeyUsage(EndEntityOrCA endEntityOrCA, const SECItem* encodedEKUs,
                      SECOidTag requiredEKU)
{
  // TODO: Either do not allow anyExtendedKeyUsage to be passed as requiredEKU,
  // or require that callers pass anyExtendedKeyUsage instead of
  // SEC_OID_UNKNWON and disallow SEC_OID_UNKNWON.

  // XXX: We're using SEC_ERROR_INADEQUATE_CERT_TYPE here so that callers can
  // distinguish EKU mismatch from KU mismatch from basic constraints mismatch.
  // We should probably add a new error code that is more clear for this type
  // of problem.

  bool foundOCSPSigning = false;

  if (encodedEKUs) {
    ScopedPtr<CERTOidSequence, CERT_DestroyOidSequence>
      seq(CERT_DecodeOidSequence(encodedEKUs));
    if (!seq) {
      PR_SetError(SEC_ERROR_INADEQUATE_CERT_TYPE, 0);
      return RecoverableError;
    }

    bool found = false;

    // XXX: We allow duplicate entries.
    for (const SECItem* const* oids = seq->oids; oids && *oids; ++oids) {
      SECOidTag oidTag = SECOID_FindOIDTag(*oids);
      if (requiredEKU != SEC_OID_UNKNOWN && oidTag == requiredEKU) {
        found = true;
      } else {
        // Treat CA certs with step-up OID as also having SSL server type.
        // COMODO has issued certificates that require this behavior
        // that don't expire until June 2020!
        // TODO 982932: Limit this expection to old certificates
        if (endEntityOrCA == MustBeCA &&
            requiredEKU == SEC_OID_EXT_KEY_USAGE_SERVER_AUTH &&
            oidTag == SEC_OID_NS_KEY_USAGE_GOVT_APPROVED) {
          found = true;
        }
      }
      if (oidTag == SEC_OID_OCSP_RESPONDER) {
        foundOCSPSigning = true;
      }
    }

    // If the EKU extension was included, then the required EKU must be in the
    // list.
    if (!found) {
      PR_SetError(SEC_ERROR_INADEQUATE_CERT_TYPE, 0);
      return RecoverableError;
    }
  }

  // pkixocsp.cpp depends on the following additional checks.

  if (endEntityOrCA == MustBeEndEntity) {
    // When validating anything other than an delegated OCSP signing cert,
    // reject any cert that also claims to be an OCSP responder, because such
    // a cert does not make sense. For example, if an SSL certificate were to
    // assert id-kp-OCSPSigning then it could sign OCSP responses for itself,
    // if not for this check.
    // That said, we accept CA certificates with id-kp-OCSPSigning because
    // some CAs in Mozilla's CA program have issued such intermediate
    // certificates, and because some CAs have reported some Microsoft server
    // software wrongly requires CA certificates to have id-kp-OCSPSigning.
    // Allowing this exception does not cause any security issues because we
    // require delegated OCSP response signing certificates to be end-entity
    // certificates.
    if (foundOCSPSigning && requiredEKU != SEC_OID_OCSP_RESPONDER) {
      PR_SetError(SEC_ERROR_INADEQUATE_CERT_TYPE, 0);
      return RecoverableError;
    }
    // http://tools.ietf.org/html/rfc6960#section-4.2.2.2:
    // "OCSP signing delegation SHALL be designated by the inclusion of
    // id-kp-OCSPSigning in an extended key usage certificate extension
    // included in the OCSP response signer's certificate."
    //
    // id-kp-OCSPSigning is the only EKU that isn't implicitly assumed when the
    // EKU extension is missing from an end-entity certificate. However, any CA
    // certificate can issue a delegated OCSP response signing certificate, so
    // we can't require the EKU be explicitly included for CA certificates.
    if (!foundOCSPSigning && requiredEKU == SEC_OID_OCSP_RESPONDER) {
      PR_SetError(SEC_ERROR_INADEQUATE_CERT_TYPE, 0);
      return RecoverableError;
    }
  }

  return Success;
}
Exemplo n.º 18
0
// 4.2.1.12. Extended Key Usage (id-ce-extKeyUsage)
// 4.2.1.12. Extended Key Usage (id-ce-extKeyUsage)
Result
CheckExtendedKeyUsage(EndEntityOrCA endEntityOrCA, const SECItem* encodedEKUs,
                      SECOidTag requiredEKU)
{
  // TODO: Either do not allow anyExtendedKeyUsage to be passed as requiredEKU,
  // or require that callers pass anyExtendedKeyUsage instead of
  // SEC_OID_UNKNWON and disallow SEC_OID_UNKNWON.

  // XXX: We're using SEC_ERROR_INADEQUATE_CERT_TYPE here so that callers can
  // distinguish EKU mismatch from KU mismatch from basic constraints mismatch.
  // We should probably add a new error code that is more clear for this type
  // of problem.

  bool foundOCSPSigning = false;

  if (encodedEKUs) {
    ScopedPtr<CERTOidSequence, CERT_DestroyOidSequence>
      seq(CERT_DecodeOidSequence(encodedEKUs));
    if (!seq) {
      PR_SetError(SEC_ERROR_INADEQUATE_CERT_TYPE, 0);
      return RecoverableError;
    }

    bool found = false;

    // XXX: We allow duplicate entries.
    for (const SECItem* const* oids = seq->oids; oids && *oids; ++oids) {
      SECOidTag oidTag = SECOID_FindOIDTag(*oids);
      if (requiredEKU != SEC_OID_UNKNOWN && oidTag == requiredEKU) {
        found = true;
      }
      if (oidTag == SEC_OID_OCSP_RESPONDER) {
        foundOCSPSigning = true;
      }
    }

    // If the EKU extension was included, then the required EKU must be in the
    // list.
    if (!found) {
      PR_SetError(SEC_ERROR_INADEQUATE_CERT_TYPE, 0);
      return RecoverableError;
    }
  }

  // pkixocsp.cpp depends on the following additional checks.

  if (foundOCSPSigning) {
    // When validating anything other than an delegated OCSP signing cert,
    // reject any cert that also claims to be an OCSP responder, because such
    // a cert does not make sense. For example, if an SSL certificate were to
    // assert id-kp-OCSPSigning then it could sign OCSP responses for itself,
    // if not for this check.
    if (requiredEKU != SEC_OID_OCSP_RESPONDER) {
      PR_SetError(SEC_ERROR_INADEQUATE_CERT_TYPE, 0);
      return RecoverableError;
    }
  } else if (requiredEKU == SEC_OID_OCSP_RESPONDER &&
             endEntityOrCA == MustBeEndEntity) {
    // http://tools.ietf.org/html/rfc6960#section-4.2.2.2:
    // "OCSP signing delegation SHALL be designated by the inclusion of
    // id-kp-OCSPSigning in an extended key usage certificate extension
    // included in the OCSP response signer's certificate."
    //
    // id-kp-OCSPSigning is the only EKU that isn't implicitly assumed when the
    // EKU extension is missing from an end-entity certificate. However, any CA
    // certificate can issue a delegated OCSP response signing certificate, so
    // we can't require the EKU be explicitly included for CA certificates.
    PR_SetError(SEC_ERROR_INADEQUATE_CERT_TYPE, 0);
    return RecoverableError;
  }

  return Success;
}
Exemplo n.º 19
0
/* search a certificate list for a nickname, a thumbprint, or both
 * within a certificate bag.  if the certificate could not be
 * found or an error occurs, NULL is returned;
 */
static SEC_PKCS12CertAndCRL *
sec_pkcs12_find_cert_in_certbag(SEC_PKCS12CertAndCRLBag *certbag,
				SECItem *nickname, SGNDigestInfo *thumbprint)
{
    PRBool search_both = PR_FALSE, search_nickname = PR_FALSE;
    int i, j;

    if((certbag == NULL) || ((nickname == NULL) && (thumbprint == NULL))) {
	return NULL;
    }

    if(thumbprint && nickname) {
	search_both = PR_TRUE;
    }

    if(nickname) {
	search_nickname = PR_TRUE;
    }

search_again:  
    i = 0;
    while(certbag->certAndCRLs[i] != NULL) {
	SEC_PKCS12CertAndCRL *cert = certbag->certAndCRLs[i];

	if(SECOID_FindOIDTag(&cert->BagID) == SEC_OID_PKCS12_X509_CERT_CRL_BAG) {

	    /* check nicknames */
	    if(search_nickname) {
		if(SECITEM_CompareItem(nickname, &cert->nickname) == SECEqual) {
		    return cert;
		}
	    } else {
	    /* check thumbprints */
		SECItem **derCertList;

		/* get pointer to certificate list, does not need to
		 * be freed since it is within the arena which will
		 * be freed later.
		 */
		derCertList = SEC_PKCS7GetCertificateList(&cert->value.x509->certOrCRL);
		j = 0;
		if(derCertList != NULL) {
		    while(derCertList[j] != NULL) {
			SECComparison eq;
			SGNDigestInfo *di;
			di = sec_pkcs12_compute_thumbprint(derCertList[j]);
			if(di) {
			    eq = SGN_CompareDigestInfo(thumbprint, di);
			    SGN_DestroyDigestInfo(di);
			    if(eq == SECEqual) {
				/* copy the derCert for later reference */
				cert->value.x509->derLeafCert = derCertList[j];
				return cert;
			    }
			} else {
			    /* an error occurred */
			    return NULL;
			}
			j++;
		    }
		}
	    }
	}

	i++;
    }

    if(search_both) {
	search_both = PR_FALSE;
	search_nickname = PR_FALSE;
	goto search_again;
    }

    return NULL;
}
Exemplo n.º 20
0
SECStatus
EC_FillParams(PRArenaPool *arena, const SECItem *encodedParams,
    ECParams *params, int kmflag)
{
    SECStatus rv = SECFailure;
    ECCurveName tag;
    SECItem oid = { siBuffer, NULL, 0};

#if EC_DEBUG
    int i;

    printf("Encoded params in EC_DecodeParams: ");
    for (i = 0; i < encodedParams->len; i++) {
            printf("%02x:", encodedParams->data[i]);
    }
    printf("\n");
#endif

    if ((encodedParams->len != ANSI_X962_CURVE_OID_TOTAL_LEN) &&
        (encodedParams->len != SECG_CURVE_OID_TOTAL_LEN)) {
            PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
            return SECFailure;
    };

    oid.len = encodedParams->len - 2;
    oid.data = encodedParams->data + 2;
    if ((encodedParams->data[0] != SEC_ASN1_OBJECT_ID) ||
        ((tag = SECOID_FindOIDTag(&oid)) == ECCurve_noName)) {
            PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
            return SECFailure;
    }

    params->arena = arena;
    params->cofactor = 0;
    params->type = ec_params_named;
    params->name = ECCurve_noName;

    /* For named curves, fill out curveOID */
    params->curveOID.len = oid.len;
    params->curveOID.data = (unsigned char *) PORT_ArenaAlloc(NULL, oid.len,
        kmflag);
    if (params->curveOID.data == NULL) goto cleanup;
    memcpy(params->curveOID.data, oid.data, oid.len);

#if EC_DEBUG
#ifndef SECOID_FindOIDTagDescription
    printf("Curve: %s\n", ecCurve_map[tag]->text);
#else
    printf("Curve: %s\n", SECOID_FindOIDTagDescription(tag));
#endif
#endif

    switch (tag) {

    /* Binary curves */

    case ECCurve_X9_62_CHAR2_PNB163V1:
        /* Populate params for c2pnb163v1 */
        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB163V1, ec_field_GF2m,
            params, kmflag) );
        break;

    case ECCurve_X9_62_CHAR2_PNB163V2:
        /* Populate params for c2pnb163v2 */
        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB163V2, ec_field_GF2m,
            params, kmflag) );
        break;

    case ECCurve_X9_62_CHAR2_PNB163V3:
        /* Populate params for c2pnb163v3 */
        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB163V3, ec_field_GF2m,
            params, kmflag) );
        break;

    case ECCurve_X9_62_CHAR2_PNB176V1:
        /* Populate params for c2pnb176v1 */
        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB176V1, ec_field_GF2m,
            params, kmflag) );
        break;

    case ECCurve_X9_62_CHAR2_TNB191V1:
        /* Populate params for c2tnb191v1 */
        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB191V1, ec_field_GF2m,
            params, kmflag) );
        break;

    case ECCurve_X9_62_CHAR2_TNB191V2:
        /* Populate params for c2tnb191v2 */
        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB191V2, ec_field_GF2m,
            params, kmflag) );
        break;

    case ECCurve_X9_62_CHAR2_TNB191V3:
        /* Populate params for c2tnb191v3 */
        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB191V3, ec_field_GF2m,
            params, kmflag) );
        break;

    case ECCurve_X9_62_CHAR2_PNB208W1:
        /* Populate params for c2pnb208w1 */
        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB208W1, ec_field_GF2m,
            params, kmflag) );
        break;

    case ECCurve_X9_62_CHAR2_TNB239V1:
        /* Populate params for c2tnb239v1 */
        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB239V1, ec_field_GF2m,
            params, kmflag) );
        break;

    case ECCurve_X9_62_CHAR2_TNB239V2:
        /* Populate params for c2tnb239v2 */
        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB239V2, ec_field_GF2m,
            params, kmflag) );
        break;

    case ECCurve_X9_62_CHAR2_TNB239V3:
        /* Populate params for c2tnb239v3 */
        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB239V3, ec_field_GF2m,
            params, kmflag) );
        break;

    case ECCurve_X9_62_CHAR2_PNB272W1:
        /* Populate params for c2pnb272w1 */
        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB272W1, ec_field_GF2m,
            params, kmflag) );
        break;

    case ECCurve_X9_62_CHAR2_PNB304W1:
        /* Populate params for c2pnb304w1 */
        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB304W1, ec_field_GF2m,
            params, kmflag) );
        break;

    case ECCurve_X9_62_CHAR2_TNB359V1:
        /* Populate params for c2tnb359v1 */
        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB359V1, ec_field_GF2m,
            params, kmflag) );
        break;

    case ECCurve_X9_62_CHAR2_PNB368W1:
        /* Populate params for c2pnb368w1 */
        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB368W1, ec_field_GF2m,
            params, kmflag) );
        break;

    case ECCurve_X9_62_CHAR2_TNB431R1:
        /* Populate params for c2tnb431r1 */
        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB431R1, ec_field_GF2m,
            params, kmflag) );
        break;

    case ECCurve_SECG_CHAR2_113R1:
        /* Populate params for sect113r1 */
        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_113R1, ec_field_GF2m,
            params, kmflag) );
        break;

    case ECCurve_SECG_CHAR2_113R2:
        /* Populate params for sect113r2 */
        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_113R2, ec_field_GF2m,
            params, kmflag) );
        break;

    case ECCurve_SECG_CHAR2_131R1:
        /* Populate params for sect131r1 */
        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_131R1, ec_field_GF2m,
            params, kmflag) );
        break;

    case ECCurve_SECG_CHAR2_131R2:
        /* Populate params for sect131r2 */
        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_131R2, ec_field_GF2m,
            params, kmflag) );
        break;

    case ECCurve_SECG_CHAR2_163K1:
        /* Populate params for sect163k1
         * (the NIST K-163 curve)
         */
        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_163K1, ec_field_GF2m,
            params, kmflag) );
        break;

    case ECCurve_SECG_CHAR2_163R1:
        /* Populate params for sect163r1 */
        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_163R1, ec_field_GF2m,
            params, kmflag) );
        break;

    case ECCurve_SECG_CHAR2_163R2:
        /* Populate params for sect163r2
         * (the NIST B-163 curve)
         */
        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_163R2, ec_field_GF2m,
            params, kmflag) );
        break;

    case ECCurve_SECG_CHAR2_193R1:
        /* Populate params for sect193r1 */
        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_193R1, ec_field_GF2m,
            params, kmflag) );
        break;

    case ECCurve_SECG_CHAR2_193R2:
        /* Populate params for sect193r2 */
        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_193R2, ec_field_GF2m,
            params, kmflag) );
        break;

    case ECCurve_SECG_CHAR2_233K1:
        /* Populate params for sect233k1
         * (the NIST K-233 curve)
         */
        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_233K1, ec_field_GF2m,
            params, kmflag) );
        break;

    case ECCurve_SECG_CHAR2_233R1:
        /* Populate params for sect233r1
         * (the NIST B-233 curve)
         */
        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_233R1, ec_field_GF2m,
            params, kmflag) );
        break;

    case ECCurve_SECG_CHAR2_239K1:
        /* Populate params for sect239k1 */
        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_239K1, ec_field_GF2m,
            params, kmflag) );
        break;

    case ECCurve_SECG_CHAR2_283K1:
        /* Populate params for sect283k1
         * (the NIST K-283 curve)
         */
        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_283K1, ec_field_GF2m,
            params, kmflag) );
        break;

    case ECCurve_SECG_CHAR2_283R1:
        /* Populate params for sect283r1
         * (the NIST B-283 curve)
         */
        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_283R1, ec_field_GF2m,
            params, kmflag) );
        break;

    case ECCurve_SECG_CHAR2_409K1:
        /* Populate params for sect409k1
         * (the NIST K-409 curve)
         */
        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_409K1, ec_field_GF2m,
            params, kmflag) );
        break;

    case ECCurve_SECG_CHAR2_409R1:
        /* Populate params for sect409r1
         * (the NIST B-409 curve)
         */
        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_409R1, ec_field_GF2m,
            params, kmflag) );
        break;

    case ECCurve_SECG_CHAR2_571K1:
        /* Populate params for sect571k1
         * (the NIST K-571 curve)
         */
        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_571K1, ec_field_GF2m,
            params, kmflag) );
        break;

    case ECCurve_SECG_CHAR2_571R1:
        /* Populate params for sect571r1
         * (the NIST B-571 curve)
         */
        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_571R1, ec_field_GF2m,
            params, kmflag) );
        break;

    /* Prime curves */

    case ECCurve_X9_62_PRIME_192V1:
        /* Populate params for prime192v1 aka secp192r1
         * (the NIST P-192 curve)
         */
        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_192V1, ec_field_GFp,
            params, kmflag) );
        break;

    case ECCurve_X9_62_PRIME_192V2:
        /* Populate params for prime192v2 */
        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_192V2, ec_field_GFp,
            params, kmflag) );
        break;

    case ECCurve_X9_62_PRIME_192V3:
        /* Populate params for prime192v3 */
        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_192V3, ec_field_GFp,
            params, kmflag) );
        break;

    case ECCurve_X9_62_PRIME_239V1:
        /* Populate params for prime239v1 */
        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_239V1, ec_field_GFp,
            params, kmflag) );
        break;

    case ECCurve_X9_62_PRIME_239V2:
        /* Populate params for prime239v2 */
        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_239V2, ec_field_GFp,
            params, kmflag) );
        break;

    case ECCurve_X9_62_PRIME_239V3:
        /* Populate params for prime239v3 */
        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_239V3, ec_field_GFp,
            params, kmflag) );
        break;

    case ECCurve_X9_62_PRIME_256V1:
        /* Populate params for prime256v1 aka secp256r1
         * (the NIST P-256 curve)
         */
        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_256V1, ec_field_GFp,
            params, kmflag) );
        break;

    case ECCurve_SECG_PRIME_112R1:
        /* Populate params for secp112r1 */
        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_112R1, ec_field_GFp,
            params, kmflag) );
        break;

    case ECCurve_SECG_PRIME_112R2:
        /* Populate params for secp112r2 */
        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_112R2, ec_field_GFp,
            params, kmflag) );
        break;

    case ECCurve_SECG_PRIME_128R1:
        /* Populate params for secp128r1 */
        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_128R1, ec_field_GFp,
            params, kmflag) );
        break;

    case ECCurve_SECG_PRIME_128R2:
        /* Populate params for secp128r2 */
        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_128R2, ec_field_GFp,
            params, kmflag) );
        break;

    case ECCurve_SECG_PRIME_160K1:
        /* Populate params for secp160k1 */
        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_160K1, ec_field_GFp,
            params, kmflag) );
        break;

    case ECCurve_SECG_PRIME_160R1:
        /* Populate params for secp160r1 */
        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_160R1, ec_field_GFp,
            params, kmflag) );
        break;

    case ECCurve_SECG_PRIME_160R2:
        /* Populate params for secp160r1 */
        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_160R2, ec_field_GFp,
            params, kmflag) );
        break;

    case ECCurve_SECG_PRIME_192K1:
        /* Populate params for secp192k1 */
        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_192K1, ec_field_GFp,
            params, kmflag) );
        break;

    case ECCurve_SECG_PRIME_224K1:
        /* Populate params for secp224k1 */
        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_224K1, ec_field_GFp,
            params, kmflag) );
        break;

    case ECCurve_SECG_PRIME_224R1:
        /* Populate params for secp224r1
         * (the NIST P-224 curve)
         */
        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_224R1, ec_field_GFp,
            params, kmflag) );
        break;

    case ECCurve_SECG_PRIME_256K1:
        /* Populate params for secp256k1 */
        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_256K1, ec_field_GFp,
            params, kmflag) );
        break;

    case ECCurve_SECG_PRIME_384R1:
        /* Populate params for secp384r1
         * (the NIST P-384 curve)
         */
        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_384R1, ec_field_GFp,
            params, kmflag) );
        break;

    case ECCurve_SECG_PRIME_521R1:
        /* Populate params for secp521r1
         * (the NIST P-521 curve)
         */
        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_521R1, ec_field_GFp,
            params, kmflag) );
        break;

    default:
        break;
    };

cleanup:
    if (!params->cofactor) {
        PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
#if EC_DEBUG
        printf("Unrecognized curve, returning NULL params\n");
#endif
    }

    return rv;
}
Exemplo n.º 21
0
bool
ECKeyToJwk(const PK11ObjectType aKeyType, void* aKey, const SECItem* aEcParams,
           const SECItem* aPublicValue, JsonWebKey& aRetVal)
{
  aRetVal.mX.Construct();
  aRetVal.mY.Construct();

  // Check that the given EC parameters are valid.
  if (!CheckEncodedECParameters(aEcParams)) {
    return false;
  }

  // Construct the OID tag.
  SECItem oid = { siBuffer, nullptr, 0 };
  oid.len = aEcParams->data[1];
  oid.data = aEcParams->data + 2;

  uint32_t flen;
  switch (SECOID_FindOIDTag(&oid)) {
    case SEC_OID_SECG_EC_SECP256R1:
      flen = 32; // bytes
      aRetVal.mCrv.Construct(NS_LITERAL_STRING(WEBCRYPTO_NAMED_CURVE_P256));
      break;
    case SEC_OID_SECG_EC_SECP384R1:
      flen = 48; // bytes
      aRetVal.mCrv.Construct(NS_LITERAL_STRING(WEBCRYPTO_NAMED_CURVE_P384));
      break;
    case SEC_OID_SECG_EC_SECP521R1:
      flen = 66; // bytes
      aRetVal.mCrv.Construct(NS_LITERAL_STRING(WEBCRYPTO_NAMED_CURVE_P521));
      break;
    default:
      return false;
  }

  // No support for compressed points.
  if (aPublicValue->data[0] != EC_POINT_FORM_UNCOMPRESSED) {
    return false;
  }

  // Check length of uncompressed point coordinates.
  if (aPublicValue->len != (2 * flen + 1)) {
    return false;
  }

  ScopedSECItem ecPointX(::SECITEM_AllocItem(nullptr, nullptr, flen));
  ScopedSECItem ecPointY(::SECITEM_AllocItem(nullptr, nullptr, flen));
  if (!ecPointX || !ecPointY) {
    return false;
  }

  // Extract point data.
  memcpy(ecPointX->data, aPublicValue->data + 1, flen);
  memcpy(ecPointY->data, aPublicValue->data + 1 + flen, flen);

  CryptoBuffer x, y;
  if (!x.Assign(ecPointX) || NS_FAILED(x.ToJwkBase64(aRetVal.mX.Value())) ||
      !y.Assign(ecPointY) || NS_FAILED(y.ToJwkBase64(aRetVal.mY.Value()))) {
    return false;
  }

  aRetVal.mKty = NS_LITERAL_STRING(JWK_TYPE_EC);
  return true;
}
Exemplo n.º 22
0
static SEC_PKCS7EncoderContext *
sec_pkcs7_encoder_start_contexts (SEC_PKCS7ContentInfo *cinfo,
				  PK11SymKey *bulkkey)
{
    SEC_PKCS7EncoderContext *p7ecx;
    SECOidTag kind;
    PRBool encrypt;
    SECItem **digests;
    SECAlgorithmID *digestalg, **digestalgs;

    p7ecx = 
      (SEC_PKCS7EncoderContext*)PORT_ZAlloc (sizeof(SEC_PKCS7EncoderContext));
    if (p7ecx == NULL)
	return NULL;

    digests = NULL;
    digestalg = NULL;
    digestalgs = NULL;
    encrypt = PR_FALSE;

    kind = SEC_PKCS7ContentType (cinfo);
    switch (kind) {
      default:
      case SEC_OID_PKCS7_DATA:
	break;
      case SEC_OID_PKCS7_DIGESTED_DATA:
	digestalg = &(cinfo->content.digestedData->digestAlg);
	break;
      case SEC_OID_PKCS7_SIGNED_DATA:
	digests = cinfo->content.signedData->digests;
	digestalgs = cinfo->content.signedData->digestAlgorithms;
	break;
      case SEC_OID_PKCS7_ENCRYPTED_DATA:
      case SEC_OID_PKCS7_ENVELOPED_DATA:
	encrypt = PR_TRUE;
	break;
      case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA:
	digests = cinfo->content.signedAndEnvelopedData->digests;
	digestalgs = cinfo->content.signedAndEnvelopedData->digestAlgorithms;
	encrypt = PR_TRUE;
	break;
    }

    if (encrypt) {
	p7ecx->encryptobj = sec_pkcs7_encoder_start_encrypt (cinfo, bulkkey);
	if (p7ecx->encryptobj == NULL) {
	    PORT_Free (p7ecx);
	    return NULL;
	}
    }

    if (digestalgs != NULL) {
	if (digests != NULL) {
	    /* digests already created (probably for detached data) */
	    digestalg = NULL;
	} else {
	    /*
	     * XXX Some day we should handle multiple digests; for now,
	     * assume only one will be done.
	     */
	    PORT_Assert (digestalgs[0] != NULL && digestalgs[1] == NULL);
	    digestalg = digestalgs[0];
	}
    }

    if (digestalg != NULL) {
	SECOidTag  oidTag = SECOID_FindOIDTag(&(digestalg->algorithm));

	p7ecx->digestobj = HASH_GetHashObjectByOidTag(oidTag);
	if (p7ecx->digestobj != NULL) {
	    p7ecx->digestcx = (* p7ecx->digestobj->create) ();
	    if (p7ecx->digestcx == NULL)
		p7ecx->digestobj = NULL;
	    else
		(* p7ecx->digestobj->begin) (p7ecx->digestcx);
	}
	if (p7ecx->digestobj == NULL) {
	    if (p7ecx->encryptobj != NULL)
		sec_PKCS7DestroyEncryptObject (p7ecx->encryptobj);
	    PORT_Free (p7ecx);
	    return NULL;
	}
    }

    p7ecx->cinfo = cinfo;
    return p7ecx;
}