/* * Given a DER encoded DHParameterBlock, extract the prime and generator. * modulus and public exponent. * This will work with either PKCS-1 encoded DHParameterBlock or * openssl-style DHParameter. */ OSStatus sslDecodeDhParams( const SSLBuffer *blob, /* PKCS-1 encoded */ SSLBuffer *prime, /* data mallocd and RETURNED */ SSLBuffer *generator) /* data mallocd and RETURNED */ { SECStatus rv; OSStatus srtn; NSS_DHParameterBlock paramBlock = {}; PLArenaPool *pool; assert(blob != NULL); assert(prime != NULL); assert(generator != NULL); pool = PORT_NewArena(CHUNKSIZE_DEF); /* * Since the common case here is to decode a parameter block coming * over the wire, which is in openssl format, let's try that format first. */ rv = SEC_ASN1Decode(pool, ¶mBlock.params, kSecAsn1DHParameterTemplate, (const char *)blob->data, blob->length); if (rv != SECSuccess) { /* * OK, that failed when trying as a CDSA_formatted parameter * block DHParameterBlock). Openssl uses a subset of that, * a DHParameter. Try that instead. */ memset(¶mBlock, 0, sizeof(paramBlock)); rv = SEC_ASN1Decode(pool, ¶mBlock, kSecAsn1DHParameterBlockTemplate, (const char *)blob->data, blob->length); } if (rv != SECSuccess) { /* Ah well, we tried. */ sslErrorLog("sslDecodeDhParams: both CDSA and openssl format" "failed\n"); srtn = errSSLCrypto; } else { /* copy out components */ srtn = SSLCopyBufferFromData(paramBlock.params.prime.Data, paramBlock.params.prime.Length, prime); if(!srtn) { srtn = SSLCopyBufferFromData(paramBlock.params.base.Data, paramBlock.params.base.Length, generator); } } PORT_FreeArena(pool, PR_TRUE); return srtn; }
CMMFPOPODecKeyRespContent* CMMF_CreatePOPODecKeyRespContentFromDER(const char *buf, long len) { PRArenaPool *poolp; CMMFPOPODecKeyRespContent *decKeyResp; SECStatus rv; poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE); if (poolp == NULL) { return NULL; } decKeyResp = PORT_ArenaZNew(poolp, CMMFPOPODecKeyRespContent); if (decKeyResp == NULL) { goto loser; } decKeyResp->poolp = poolp; rv = SEC_ASN1Decode(poolp, decKeyResp, CMMFPOPODecKeyRespContentTemplate, buf, len); if (rv != SECSuccess) { goto loser; } return decKeyResp; loser: if (poolp != NULL) { PORT_FreeArena(poolp, PR_FALSE); } return NULL; }
OSStatus sslDecodeRsaBlob( const SSLBuffer *blob, /* PKCS-1 encoded */ SSLBuffer *modulus, /* data mallocd and RETURNED */ SSLBuffer *exponent) /* data mallocd and RETURNED */ { SECStatus rv; OSStatus srtn; NSS_RSAPublicKeyPKCS1 nssPubKey = {}; PLArenaPool *pool; assert(blob != NULL); assert(modulus != NULL); assert(exponent != NULL); /* DER-decode the blob */ pool = PORT_NewArena(CHUNKSIZE_DEF); rv = SEC_ASN1Decode(pool, &nssPubKey, kSecAsn1RSAPublicKeyPKCS1Template, (const char *)blob->data, blob->length); if (rv != SECSuccess) srtn = errSSLBadCert; else { /* malloc & copy components */ srtn = SSLCopyBufferFromData(nssPubKey.modulus.Data, nssPubKey.modulus.Length, modulus); if(!srtn) { srtn = SSLCopyBufferFromData(nssPubKey.publicExponent.Data, nssPubKey.publicExponent.Length, exponent); } } PORT_FreeArena(pool, PR_TRUE); return srtn; }
/* * DER decode an untyped item per the specified template array. * The result is allocated in this SecAsn1Coder's memory pool and * is freed when this object is released. * * The dest pointer is a template-specific struct allocated by the caller * and must be zeroed by the caller. */ OSStatus SecAsn1Decode( SecAsn1CoderRef coder, const void *src, // DER-encoded source size_t len, const SecAsn1Template *templ, void *dest) { if((coder == NULL) || (src == NULL) || (templ == NULL) || (dest == NULL)) { return errSecParam; } SECStatus prtn = SEC_ASN1Decode(coder->mPool, dest, templ, (const char *)src, len); if(prtn) { return errSecDecode; } else { return errSecSuccess; } }
CMMFKeyRecRepContent* CMMF_CreateKeyRecRepContentFromDER(CERTCertDBHandle *db, const char *buf, long len) { PRArenaPool *poolp; CMMFKeyRecRepContent *keyRecContent; SECStatus rv; poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE); if (poolp == NULL) { return NULL; } keyRecContent = PORT_ArenaZNew(poolp, CMMFKeyRecRepContent); if (keyRecContent == NULL) { goto loser; } keyRecContent->poolp = poolp; rv = SEC_ASN1Decode(poolp, keyRecContent, CMMFKeyRecRepContentTemplate, buf, len); if (rv != SECSuccess) { goto loser; } if (keyRecContent->keyPairHist != NULL) { while(keyRecContent->keyPairHist[keyRecContent->numKeyPairs] != NULL) { rv = cmmf_decode_process_certified_key_pair(poolp, db, keyRecContent->keyPairHist[keyRecContent->numKeyPairs]); if (rv != SECSuccess) { goto loser; } keyRecContent->numKeyPairs++; } keyRecContent->allocKeyPairs = keyRecContent->numKeyPairs; } keyRecContent->isDecoded = PR_TRUE; return keyRecContent; loser: if (poolp != NULL) { PORT_FreeArena(poolp, PR_FALSE); } return NULL; }
static PQGParams * decode_pqg_params(char *aStr) { unsigned char *buf = nullptr; unsigned int len; PLArenaPool *arena = nullptr; PQGParams *params = nullptr; SECStatus status; arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (!arena) return nullptr; params = static_cast<PQGParams*>(PORT_ArenaZAlloc(arena, sizeof(PQGParams))); if (!params) goto loser; params->arena = arena; buf = ATOB_AsciiToData(aStr, &len); if ((!buf) || (len == 0)) goto loser; status = SEC_ASN1Decode(arena, params, SECKEY_PQGParamsTemplate, (const char*)buf, len); if (status != SECSuccess) goto loser; return params; loser: if (arena) { PORT_FreeArena(arena, false); } if (buf) { PR_Free(buf); } return nullptr; }