/* * See addemdum to NIST SP 800-38A * Generically handle cipher text stealing. Basically this is doing CBC * operations except someone can pass us a partial block. * * Output Order: * CS-1: C1||C2||C3..Cn-1(could be partial)||Cn (NIST) * CS-2: pad == 0 C1||C2||C3...Cn-1(is full)||Cn (Schneier) * CS-2: pad != 0 C1||C2||C3...Cn||Cn-1(is partial)(Schneier) * CS-3: C1||C2||C3...Cn||Cn-1(could be partial) (Kerberos) * * The characteristics of these three options: * - NIST & Schneier (CS-1 & CS-2) are identical to CBC if there are no * partial blocks on input. * - Scheier and Kerberos (CS-2 and CS-3) have no embedded partial blocks, * which make decoding easier. * - NIST & Kerberos (CS-1 and CS-3) have consistent block order independent * of padding. * * PKCS #11 did not specify which version to implement, but points to the NIST * spec, so this code implements CTS-CS-1 from NIST. * * To convert the returned buffer to: * CS-2 (Schneier): do * unsigned char tmp[MAX_BLOCK_SIZE]; * pad = *outlen % blocksize; * if (pad) { * memcpy(tmp, outbuf+*outlen-blocksize, blocksize); * memcpy(outbuf+*outlen-pad,outbuf+*outlen-blocksize-pad, pad); * memcpy(outbuf+*outlen-blocksize-pad, tmp, blocksize); * } * CS-3 (Kerberos): do * unsigned char tmp[MAX_BLOCK_SIZE]; * pad = *outlen % blocksize; * if (pad == 0) { * pad = blocksize; * } * memcpy(tmp, outbuf+*outlen-blocksize, blocksize); * memcpy(outbuf+*outlen-pad,outbuf+*outlen-blocksize-pad, pad); * memcpy(outbuf+*outlen-blocksize-pad, tmp, blocksize); */ SECStatus CTS_EncryptUpdate(CTSContext *cts, unsigned char *outbuf, unsigned int *outlen, unsigned int maxout, const unsigned char *inbuf, unsigned int inlen, unsigned int blocksize) { unsigned char lastBlock[MAX_BLOCK_SIZE]; unsigned int tmp; int fullblocks; int written; unsigned char *saveout = outbuf; SECStatus rv; if (inlen < blocksize) { PORT_SetError(SEC_ERROR_INPUT_LEN); return SECFailure; } if (maxout < inlen) { *outlen = inlen; PORT_SetError(SEC_ERROR_OUTPUT_LEN); return SECFailure; } fullblocks = (inlen / blocksize) * blocksize; rv = (*cts->cipher)(cts->context, outbuf, outlen, maxout, inbuf, fullblocks, blocksize); if (rv != SECSuccess) { return SECFailure; } *outlen = fullblocks; /* AES low level doesn't set outlen */ inbuf += fullblocks; inlen -= fullblocks; if (inlen == 0) { return SECSuccess; } written = *outlen - (blocksize - inlen); outbuf += written; maxout -= written; /* * here's the CTS magic, we pad our final block with zeros, * then do a CBC encrypt. CBC will xor our plain text with * the previous block (Cn-1), capturing part of that block (Cn-1**) as it * xors with the zero pad. We then write this full block, overwritting * (Cn-1**) in our buffer. This allows us to have input data == output * data since Cn contains enough information to reconver Cn-1** when * we decrypt (at the cost of some complexity as you can see in decrypt * below */ PORT_Memcpy(lastBlock, inbuf, inlen); PORT_Memset(lastBlock + inlen, 0, blocksize - inlen); rv = (*cts->cipher)(cts->context, outbuf, &tmp, maxout, lastBlock, blocksize, blocksize); PORT_Memset(lastBlock, 0, blocksize); if (rv == SECSuccess) { *outlen = written + blocksize; } else { PORT_Memset(saveout, 0, written + blocksize); } return rv; }
/* * This function expands the internal state of the prng to fulfill any number * of bytes we need for this request. We only use this call if we need more * than can be supplied by a single call to SHA256_HashBuf. * * This function is specified in NIST SP 800-90 section 10.1.1.4, Hashgen */ static void prng_Hashgen(RNGContext *rng, PRUint8 *returned_bytes, unsigned int no_of_returned_bytes) { PRUint8 data[VSize(rng)]; PRUint8 thisHash[SHA256_LENGTH]; PORT_Memcpy(data, V(rng), VSize(rng)); while (no_of_returned_bytes) { SHA256Context ctx; unsigned int len; unsigned int carry; SHA256_Begin(&ctx); SHA256_Update(&ctx, data, sizeof data); SHA256_End(&ctx, thisHash, &len, SHA256_LENGTH); if (no_of_returned_bytes < SHA256_LENGTH) { len = no_of_returned_bytes; } PORT_Memcpy(returned_bytes, thisHash, len); returned_bytes += len; no_of_returned_bytes -= len; /* The carry parameter is a bool (increment or not). * This increments data if no_of_returned_bytes is not zero */ carry = no_of_returned_bytes; PRNG_ADD_CARRY_ONLY(data, (sizeof data) - 1, carry); } PORT_Memset(data, 0, sizeof data); PORT_Memset(thisHash, 0, sizeof thisHash); }
/* * Generates new random bytes and advances the internal prng state. * additional bytes are only used in algorithm testing. * * This function is specified in NIST SP 800-90 section 10.1.1.4 */ static SECStatus prng_generateNewBytes(RNGContext *rng, PRUint8 *returned_bytes, unsigned int no_of_returned_bytes, const PRUint8 *additional_input, unsigned int additional_input_len) { PRUint8 H[SHA256_LENGTH]; /* both H and w since they * aren't used concurrently */ unsigned int carry; if (!rng->isValid) { PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); return SECFailure; } /* This code only triggers during tests, normal * prng operation does not use additional_input */ if (additional_input) { SHA256Context ctx; /* NIST SP 800-90 defines two temporaries in their calculations, * w and H. These temporaries are the same lengths, and used * at different times, so we use the following macro to collapse * them to the same variable, but keeping their unique names for * easy comparison to the spec */ #define w H rng->V_type = prngAdditionalDataType; SHA256_Begin(&ctx); SHA256_Update(&ctx, rng->V_Data, sizeof rng->V_Data); SHA256_Update(&ctx, additional_input, additional_input_len); SHA256_End(&ctx, w, NULL, sizeof w); PRNG_ADD_BITS_AND_CARRY(V(rng), VSize(rng), w, sizeof w, carry) PORT_Memset(w, 0, sizeof w); #undef w } if (no_of_returned_bytes == SHA256_LENGTH) { /* short_cut to hashbuf and a couple of copies and clears */ SHA256_HashBuf(returned_bytes, V(rng), VSize(rng)); } else { prng_Hashgen(rng, returned_bytes, no_of_returned_bytes); } /* advance our internal state... */ rng->V_type = prngGenerateByteType; SHA256_HashBuf(H, rng->V_Data, sizeof rng->V_Data); PRNG_ADD_BITS_AND_CARRY(V(rng), VSize(rng), H, sizeof H, carry) PRNG_ADD_BITS(V(rng), VSize(rng), rng->C, sizeof rng->C, carry); PRNG_ADD_BITS_AND_CARRY(V(rng), VSize(rng), rng->reseed_counter, sizeof rng->reseed_counter, carry) carry = 1; PRNG_ADD_CARRY_ONLY(rng->reseed_counter, (sizeof rng->reseed_counter) - 1, carry); /* if the prng failed, don't return any output, signal softoken */ if (!rng->isValid) { PORT_Memset(returned_bytes, 0, no_of_returned_bytes); PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); return SECFailure; } return SECSuccess; }
/* Use this function to update the ClientRandom of a client's handshake state * after replacing its ClientHello message. We for example need to do this * when replacing an SSLv3 ClientHello with its SSLv2 equivalent. */ SECStatus SSLInt_UpdateSSLv2ClientRandom(PRFileDesc *fd, uint8_t *rnd, size_t rnd_len, uint8_t *msg, size_t msg_len) { sslSocket *ss = ssl_FindSocket(fd); if (!ss) { return SECFailure; } SECStatus rv = ssl3_InitState(ss); if (rv != SECSuccess) { return rv; } rv = ssl3_RestartHandshakeHashes(ss); if (rv != SECSuccess) { return rv; } // Zero the client_random struct. PORT_Memset(&ss->ssl3.hs.client_random, 0, SSL3_RANDOM_LENGTH); // Copy over the challenge bytes. size_t offset = SSL3_RANDOM_LENGTH - rnd_len; PORT_Memcpy(&ss->ssl3.hs.client_random.rand[offset], rnd, rnd_len); // Rehash the SSLv2 client hello message. return ssl3_UpdateHandshakeHashes(ss, msg, msg_len); }
/* Initialize the extension data block. */ void ssl3_InitExtensionData(TLSExtensionData *xtnData, const sslSocket *ss) { unsigned int advertisedMax; PRCList *cursor; /* Set things up to the right starting state. */ PORT_Memset(xtnData, 0, sizeof(*xtnData)); xtnData->peerSupportsFfdheGroups = PR_FALSE; PR_INIT_CLIST(&xtnData->remoteKeyShares); /* Allocate enough to allow for native extensions, plus any custom ones. */ if (ss->sec.isServer) { advertisedMax = PR_MAX(PR_ARRAY_SIZE(certificateRequestHandlers), PR_ARRAY_SIZE(tls13_cert_req_senders)); } else { advertisedMax = PR_MAX(PR_ARRAY_SIZE(clientHelloHandlers), PR_ARRAY_SIZE(clientHelloSendersTLS)); ++advertisedMax; /* For the RI SCSV, which we also track. */ } for (cursor = PR_NEXT_LINK(&ss->extensionHooks); cursor != &ss->extensionHooks; cursor = PR_NEXT_LINK(cursor)) { ++advertisedMax; } xtnData->advertised = PORT_ZNewArray(PRUint16, advertisedMax); }
NSS_IMPLEMENT PRStatus nssDecodedPKIXCertificate_Destroy ( nssDecodedCert *dc ) { CERTCertificate *cert = (CERTCertificate *)dc->data; /* The decoder may only be half initialized (the case where we find we * could not decode the certificate). In this case, there is not cert to * free, just free the dc structure. */ if (cert) { PRBool freeSlot = cert->ownSlot; PK11SlotInfo *slot = cert->slot; PRArenaPool *arena = cert->arena; /* zero cert before freeing. Any stale references to this cert * after this point will probably cause an exception. */ PORT_Memset(cert, 0, sizeof *cert); /* free the arena that contains the cert. */ PORT_FreeArena(arena, PR_FALSE); if (slot && freeSlot) { PK11_FreeSlot(slot); } } nss_ZFreeIf(dc); return PR_SUCCESS; }
static int test_long_message_sha384(NSSLOWInitContext *initCtx) { PRUint8 results[SHA384_LENGTH]; /* Test vector from FIPS 180-2: appendix B.3. */ /* 9d0e1809716474cb 086e834e310a4a1c ed149e9c00f24852 7972cec5704c2a5b 07b8b3dc38ecc4eb ae97ddd87f3d8985. */ static const PRUint8 expected[SHA384_LENGTH] = { 0x9d, 0x0e, 0x18, 0x09, 0x71, 0x64, 0x74, 0xcb, 0x08, 0x6e, 0x83, 0x4e, 0x31, 0x0a, 0x4a, 0x1c, 0xed, 0x14, 0x9e, 0x9c, 0x00, 0xf2, 0x48, 0x52, 0x79, 0x72, 0xce, 0xc5, 0x70, 0x4c, 0x2a, 0x5b, 0x07, 0xb8, 0xb3, 0xdc, 0x38, 0xec, 0xc4, 0xeb, 0xae, 0x97, 0xdd, 0xd8, 0x7f, 0x3d, 0x89, 0x85 }; unsigned char buf[1000]; (void)PORT_Memset(buf, 'a', sizeof(buf)); return test_long_message(initCtx, HASH_AlgSHA384, SHA384_LENGTH, &expected[0], results); }
CERTGeneralName * CERT_DecodeAltNameExtension(PRArenaPool *reqArena, SECItem *EncodedAltName) { SECStatus rv = SECSuccess; CERTAltNameEncodedContext encodedContext; SECItem* newEncodedAltName; if (!reqArena) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return NULL; } newEncodedAltName = SECITEM_ArenaDupItem(reqArena, EncodedAltName); if (!newEncodedAltName) { return NULL; } encodedContext.encodedGenName = NULL; PORT_Memset(&encodedContext, 0, sizeof(CERTAltNameEncodedContext)); rv = SEC_QuickDERDecodeItem (reqArena, &encodedContext, CERT_GeneralNamesTemplate, newEncodedAltName); if (rv == SECFailure) { goto loser; } if (encodedContext.encodedGenName && encodedContext.encodedGenName[0]) return cert_DecodeGeneralNames(reqArena, encodedContext.encodedGenName); /* Extension contained an empty GeneralNames sequence */ /* Treat as extension not found */ PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND); loser: return NULL; }
/* Initialize the extension data block. */ void ssl3_InitExtensionData(TLSExtensionData *xtnData) { /* Set things up to the right starting state. */ PORT_Memset(xtnData, 0, sizeof(*xtnData)); xtnData->peerSupportsFfdheGroups = PR_FALSE; PR_INIT_CLIST(&xtnData->remoteKeyShares); }
void CTR_DestroyContext(CTRContext *ctr, PRBool freeit) { PORT_Memset(ctr, 0, sizeof(CTRContext)); if (freeit) { PORT_Free(ctr); } }
static void secu_ClearPassword(char *p) { if (p) { PORT_Memset(p, 0, PORT_Strlen(p)); PORT_Free(p); } }
SECStatus CERT_DecodePolicyConstraintsExtension (CERTCertificatePolicyConstraints *decodedValue, const SECItem *encodedValue) { CERTCertificatePolicyConstraints decodeContext; PLArenaPool *arena = NULL; SECStatus rv = SECSuccess; /* initialize so we can tell when an optional component is omitted */ PORT_Memset(&decodeContext, 0, sizeof(decodeContext)); /* make a new arena */ arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); if (!arena) { return SECFailure; } do { /* decode the policy constraints */ rv = SEC_QuickDERDecodeItem(arena, &decodeContext, CERT_PolicyConstraintsTemplate, encodedValue); if ( rv != SECSuccess ) { break; } if (decodeContext.explicitPolicySkipCerts.len == 0) { *(PRInt32 *)decodedValue->explicitPolicySkipCerts.data = -1; } else { *(PRInt32 *)decodedValue->explicitPolicySkipCerts.data = DER_GetInteger(&decodeContext.explicitPolicySkipCerts); } if (decodeContext.inhibitMappingSkipCerts.len == 0) { *(PRInt32 *)decodedValue->inhibitMappingSkipCerts.data = -1; } else { *(PRInt32 *)decodedValue->inhibitMappingSkipCerts.data = DER_GetInteger(&decodeContext.inhibitMappingSkipCerts); } if ((*(PRInt32 *)decodedValue->explicitPolicySkipCerts.data == PR_INT32_MIN) || (*(PRInt32 *)decodedValue->explicitPolicySkipCerts.data == PR_INT32_MAX) || (*(PRInt32 *)decodedValue->inhibitMappingSkipCerts.data == PR_INT32_MIN) || (*(PRInt32 *)decodedValue->inhibitMappingSkipCerts.data == PR_INT32_MAX)) { rv = SECFailure; } } while (0); PORT_FreeArena(arena, PR_FALSE); return(rv); }
SECStatus CERT_DecodeBasicConstraintValue (CERTBasicConstraints *value, SECItem *encodedValue) { EncodedContext decodeContext; PRArenaPool *our_pool; SECStatus rv = SECSuccess; do { PORT_Memset (&decodeContext, 0, sizeof (decodeContext)); /* initialize the value just in case we got "0x30 00", or when the pathLenConstraint is omitted. */ decodeContext.isCA.data =&hexFalse; decodeContext.isCA.len = 1; our_pool = PORT_NewArena (SEC_ASN1_DEFAULT_ARENA_SIZE); if (our_pool == NULL) { PORT_SetError (SEC_ERROR_NO_MEMORY); GEN_BREAK (SECFailure); } rv = SEC_QuickDERDecodeItem (our_pool, &decodeContext, CERTBasicConstraintsTemplate, encodedValue); if (rv == SECFailure) break; value->isCA = decodeContext.isCA.data ? (PRBool)(decodeContext.isCA.data[0] != 0) : PR_FALSE; if (decodeContext.pathLenConstraint.data == NULL) { /* if the pathLenConstraint is not encoded, and the current setting is CA, then the pathLenConstraint should be set to a negative number for unlimited certificate path. */ if (value->isCA) value->pathLenConstraint = CERT_UNLIMITED_PATH_CONSTRAINT; } else if (value->isCA) { long len = DER_GetInteger (&decodeContext.pathLenConstraint); if (len < 0 || len == LONG_MAX) { PORT_SetError (SEC_ERROR_BAD_DER); GEN_BREAK (SECFailure); } value->pathLenConstraint = len; } else { /* here we get an error where the subject is not a CA, but the pathLenConstraint is set */ PORT_SetError (SEC_ERROR_BAD_DER); GEN_BREAK (SECFailure); break; } } while (0); PORT_FreeArena (our_pool, PR_FALSE); return (rv); }
SECStatus PRNGTEST_Uninstantiate() { if (!testContext.isValid) { PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); return SECFailure; } PORT_Memset(&testContext, 0, sizeof testContext); return SECSuccess; }
static int test_long_message_sha256(NSSLOWInitContext *initCtx) { PRUint8 results[SHA256_LENGTH]; /* cdc76e5c 9914fb92 81a1c7e2 84d73e67 f1809a48 a497200e 046d39cc c7112cd0. */ static const PRUint8 expected[SHA256_LENGTH] = { 0xcd,0xc7,0x6e,0x5c, 0x99,0x14,0xfb,0x92, 0x81,0xa1,0xc7,0xe2, 0x84,0xd7,0x3e,0x67, 0xf1,0x80,0x9a,0x48, 0xa4,0x97,0x20,0x0e, 0x04,0x6d,0x39,0xcc, 0xc7,0x11,0x2c,0xd0 }; unsigned char buf[1000]; (void) PORT_Memset(buf, 'a', sizeof(buf)); return test_long_message(initCtx, HASH_AlgSHA256, SHA256_LENGTH, &expected[0], results); }
SECStatus SEC_DerSignData(PRArenaPool *arena, SECItem *result, unsigned char *buf, int len, SECKEYPrivateKey *pk, SECOidTag algID) { SECItem it; CERTSignedData sd; SECStatus rv; it.data = 0; /* XXX We should probably have some asserts here to make sure the key type * and algID match */ if (algID == SEC_OID_UNKNOWN) { switch(pk->keyType) { case rsaKey: algID = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; break; case dsaKey: algID = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST; break; case ecKey: algID = SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST; break; default: PORT_SetError(SEC_ERROR_INVALID_KEY); return SECFailure; } } /* Sign input buffer */ rv = SEC_SignData(&it, buf, len, pk, algID); if (rv) goto loser; /* Fill out SignedData object */ PORT_Memset(&sd, 0, sizeof(sd)); sd.data.data = buf; sd.data.len = len; sd.signature.data = it.data; sd.signature.len = it.len << 3; /* convert to bit string */ rv = SECOID_SetAlgorithmID(arena, &sd.signatureAlgorithm, algID, 0); if (rv) goto loser; /* DER encode the signed data object */ rv = DER_Encode(arena, result, CERTSignedDataTemplate, &sd); /* FALL THROUGH */ loser: PORT_Free(it.data); return rv; }
static int test_long_message_sha1(NSSLOWInitContext *initCtx) { PRUint8 results[SHA1_LENGTH]; /* Test vector from FIPS 180-2: appendix B.3. */ /* 34aa973c d4c4daa4 f61eeb2b dbad2731 6534016f. */ static const PRUint8 expected[SHA256_LENGTH] = { 0x34,0xaa,0x97,0x3c, 0xd4,0xc4,0xda,0xa4, 0xf6,0x1e,0xeb,0x2b, 0xdb,0xad,0x27,0x31, 0x65,0x34,0x01,0x6f }; unsigned char buf[1000]; (void) PORT_Memset(buf, 'a', sizeof(buf)); return test_long_message(initCtx, HASH_AlgSHA1, SHA1_LENGTH, &expected[0], results); }
static SECStatus ssl_canExtractMS(PK11SymKey *pms, PRBool isTLS, PRBool isDH, PRBool *pcbp) { SECStatus rv; PK11SymKey * ms = NULL; SECItem params = {siBuffer, NULL, 0}; CK_SSL3_MASTER_KEY_DERIVE_PARAMS master_params; unsigned char rand[SSL3_RANDOM_LENGTH]; CK_VERSION pms_version; CK_MECHANISM_TYPE master_derive; CK_MECHANISM_TYPE key_derive; CK_FLAGS keyFlags; if (pms == NULL) return(SECFailure); PORT_Memset(rand, 0, SSL3_RANDOM_LENGTH); if (isTLS) { if(isDH) master_derive = CKM_TLS_MASTER_KEY_DERIVE_DH; else master_derive = CKM_TLS_MASTER_KEY_DERIVE; key_derive = CKM_TLS_KEY_AND_MAC_DERIVE; keyFlags = CKF_SIGN | CKF_VERIFY; } else { if (isDH) master_derive = CKM_SSL3_MASTER_KEY_DERIVE_DH; else master_derive = CKM_SSL3_MASTER_KEY_DERIVE; key_derive = CKM_SSL3_KEY_AND_MAC_DERIVE; keyFlags = 0; } master_params.pVersion = &pms_version; master_params.RandomInfo.pClientRandom = rand; master_params.RandomInfo.ulClientRandomLen = SSL3_RANDOM_LENGTH; master_params.RandomInfo.pServerRandom = rand; master_params.RandomInfo.ulServerRandomLen = SSL3_RANDOM_LENGTH; params.data = (unsigned char *) &master_params; params.len = sizeof master_params; ms = PK11_DeriveWithFlags(pms, master_derive, ¶ms, key_derive, CKA_DERIVE, 0, keyFlags); if (ms == NULL) return(SECFailure); rv = PK11_ExtractKeyValue(ms); *pcbp = (rv == SECSuccess); PK11_FreeSymKey(ms); return(rv); }
static int test_long_message_sha512(NSSLOWInitContext *initCtx) { PRUint8 results[SHA512_LENGTH]; /* Test vector from FIPS 180-2: appendix B.3. */ static const PRUint8 expected[SHA512_LENGTH] = { 0xe7,0x18,0x48,0x3d,0x0c,0xe7,0x69,0x64,0x4e,0x2e,0x42,0xc7,0xbc,0x15,0xb4,0x63, 0x8e,0x1f,0x98,0xb1,0x3b,0x20,0x44,0x28,0x56,0x32,0xa8,0x03,0xaf,0xa9,0x73,0xeb, 0xde,0x0f,0xf2,0x44,0x87,0x7e,0xa6,0x0a,0x4c,0xb0,0x43,0x2c,0xe5,0x77,0xc3,0x1b, 0xeb,0x00,0x9c,0x5c,0x2c,0x49,0xaa,0x2e,0x4e,0xad,0xb2,0x17,0xad,0x8c,0xc0,0x9b}; unsigned char buf[1000]; (void) PORT_Memset(buf, 'a', sizeof(buf)); return test_long_message(initCtx, HASH_AlgSHA512, SHA512_LENGTH, &expected[0], results); }
static SECStatus sftkdb_growList(char ***pModuleList, int *useCount, int last) { char **newModuleList; *useCount += SECMOD_STEP; newModuleList = (char **)PORT_Realloc(*pModuleList, *useCount*sizeof(char *)); if (newModuleList == NULL) { return SECFailure; } PORT_Memset(&newModuleList[last],0, sizeof(char *)*SECMOD_STEP); *pModuleList = newModuleList; return SECSuccess; }
void * PORT_ArenaZAlloc(PLArenaPool *arena, size_t size) { void *p; if (size <= 0) size = 1; p = PORT_ArenaAlloc(arena, size); if (p) { PORT_Memset(p, 0, size); } return(p); }
SECStatus CERT_EncodeBasicConstraintValue (PRArenaPool *arena, CERTBasicConstraints *value, SECItem *encodedValue) { EncodedContext encodeContext; PRArenaPool *our_pool = NULL; SECStatus rv = SECSuccess; do { PORT_Memset (&encodeContext, 0, sizeof (encodeContext)); if (!value->isCA && value->pathLenConstraint >= 0) { PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID); GEN_BREAK (SECFailure); } encodeContext.arena = arena; if (value->isCA == PR_TRUE) { encodeContext.isCA.data = &hexTrue ; encodeContext.isCA.len = 1; } /* If the pathLenConstraint is less than 0, then it should be * omitted from the encoding. */ if (value->isCA && value->pathLenConstraint >= 0) { our_pool = PORT_NewArena (SEC_ASN1_DEFAULT_ARENA_SIZE); if (our_pool == NULL) { PORT_SetError (SEC_ERROR_NO_MEMORY); GEN_BREAK (SECFailure); } if (SEC_ASN1EncodeUnsignedInteger (our_pool, &encodeContext.pathLenConstraint, (unsigned long)value->pathLenConstraint) == NULL) { PORT_SetError (SEC_ERROR_NO_MEMORY); GEN_BREAK (SECFailure); } } if (SEC_ASN1EncodeItem (arena, encodedValue, &encodeContext, CERTBasicConstraintsTemplate) == NULL) { GEN_BREAK (SECFailure); } } while (0); if (our_pool) PORT_FreeArena (our_pool, PR_FALSE); return(rv); }
static char * nss_makeFlags(PRBool readOnly, PRBool noCertDB, PRBool noModDB, PRBool forceOpen, PRBool passwordRequired, PRBool optimizeSpace) { char *flags = (char *)PORT_Alloc(NSS_MAX_FLAG_SIZE); PRBool first = PR_TRUE; PORT_Memset(flags, 0, NSS_MAX_FLAG_SIZE); if (readOnly) { PORT_Strcat(flags, "readOnly"); first = PR_FALSE; } if (noCertDB) { if (!first) PORT_Strcat(flags, ","); PORT_Strcat(flags, "noCertDB"); first = PR_FALSE; } if (noModDB) { if (!first) PORT_Strcat(flags, ","); PORT_Strcat(flags, "noModDB"); first = PR_FALSE; } if (forceOpen) { if (!first) PORT_Strcat(flags, ","); PORT_Strcat(flags, "forceOpen"); first = PR_FALSE; } if (passwordRequired) { if (!first) PORT_Strcat(flags, ","); PORT_Strcat(flags, "passwordRequired"); first = PR_FALSE; } if (optimizeSpace) { if (!first) PORT_Strcat(flags, ","); PORT_Strcat(flags, "optimizeSpace"); first = PR_FALSE; } return flags; }
void destroy_thread_data(GlobalThreadMgr *threadMGR) { PORT_Memset(threadMGR->threads, 0, sizeof(threadMGR->threads)); if (threadMGR->threadEndQ) { PR_DestroyCondVar(threadMGR->threadEndQ); threadMGR->threadEndQ = NULL; } if (threadMGR->threadStartQ) { PR_DestroyCondVar(threadMGR->threadStartQ); threadMGR->threadStartQ = NULL; } if (threadMGR->threadLock) { PR_DestroyLock(threadMGR->threadLock); threadMGR->threadLock = NULL; } }
/* * Update the global random number generator with more seeding * material. Use the Hash_DRBG reseed algorithm from NIST SP-800-90 * section 10.1.1.3 * * If entropy is NULL, it is fetched from the noise generator. */ static SECStatus prng_reseed(RNGContext *rng, const PRUint8 *entropy, unsigned int entropy_len, const PRUint8 *additional_input, unsigned int additional_input_len) { PRUint8 noiseData[(sizeof rng->V_Data)+PRNG_SEEDLEN]; PRUint8 *noise = &noiseData[0]; /* if entropy wasn't supplied, fetch it. (normal operation case) */ if (entropy == NULL) { entropy_len = (unsigned int) RNG_SystemRNG( &noiseData[sizeof rng->V_Data], PRNG_SEEDLEN); } else { /* NOTE: this code is only available for testing, not to applications */ /* if entropy was too big for the stack variable, get it from malloc */ if (entropy_len > PRNG_SEEDLEN) { noise = PORT_Alloc(entropy_len + (sizeof rng->V_Data)); if (noise == NULL) { return SECFailure; } } PORT_Memcpy(&noise[sizeof rng->V_Data],entropy, entropy_len); } if (entropy_len < 256/PR_BITS_PER_BYTE) { /* noise == &noiseData[0] at this point, so nothing to free */ PORT_SetError(SEC_ERROR_NEED_RANDOM); return SECFailure; } rng->V_type = prngReseedType; PORT_Memcpy(noise, rng->V_Data, sizeof rng->V_Data); prng_Hash_df(V(rng), VSize(rng), noise, (sizeof rng->V_Data) + entropy_len, additional_input, additional_input_len); /* clear potential CSP */ PORT_Memset(noise, 0, (sizeof rng->V_Data) + entropy_len); rng->V_type = prngCGenerateType; prng_Hash_df(rng->C,sizeof rng->C,rng->V_Data,sizeof rng->V_Data,NULL,0); PRNG_RESET_RESEED_COUNT(rng) if (noise != &noiseData[0]) { PORT_Free(noise); } return SECSuccess; }
SECStatus CERT_EncodeIA5TypeExtension(PRArenaPool *arena, char *value, SECItem *encodedValue) { SECItem encodeContext; SECStatus rv = SECSuccess; PORT_Memset (&encodeContext, 0, sizeof (encodeContext)); if (value != NULL) { encodeContext.data = (unsigned char *)value; encodeContext.len = strlen(value); } if (SEC_ASN1EncodeItem (arena, encodedValue, &encodeContext, CERTIA5TypeTemplate) == NULL) { rv = SECFailure; } return(rv); }
static int test_long_message(NSSLOWInitContext *initCtx, HASH_HashType algoType, unsigned int hashLen, const PRUint8 expected[], PRUint8 results[]) { unsigned int len, i, rv = 0; NSSLOWHASHContext *ctx; /* The message is meant to be 'a' repeated 1,000,000 times. * This is too much to allocate on the stack so we will use a 1,000 char * buffer and call update 1,000 times. */ unsigned char buf[1000]; (void)PORT_Memset(buf, 'a', sizeof(buf)); ctx = NSSLOWHASH_NewContext(initCtx, algoType); if (ctx == NULL) { SECU_PrintError(progName, "Couldn't get hash context\n"); return 1; } NSSLOWHASH_Begin(ctx); for (i = 0; i < 1000; ++i) { NSSLOWHASH_Update(ctx, buf, 1000); } NSSLOWHASH_End(ctx, results, &len, hashLen); PR_ASSERT(len == hashLen); PR_ASSERT(PORT_Memcmp(expected, results, hashLen) == 0); if (PORT_Memcmp(expected, results, len) != 0) { SECU_PrintError(progName, "Hash mismatch\n"); SECU_PrintBuf(stdout, "Expected: ", expected, hashLen); SECU_PrintBuf(stdout, "Actual: ", results, len); rv = 1; } NSSLOWHASH_Destroy(ctx); NSSLOW_Shutdown(initCtx); return rv; }
/* allocate space for a PFX structure and set up initial * arena pool. pfx structure is cleared and a pointer to * the new structure is returned. */ SEC_PKCS12AuthenticatedSafe * sec_pkcs12_new_asafe(PLArenaPool *poolp) { SEC_PKCS12AuthenticatedSafe *asafe = NULL; void *mark; mark = PORT_ArenaMark(poolp); asafe = (SEC_PKCS12AuthenticatedSafe *)PORT_ArenaZAlloc(poolp, sizeof(SEC_PKCS12AuthenticatedSafe)); if(asafe == NULL) goto loser; asafe->poolp = poolp; PORT_Memset(&asafe->old_baggage, 0, sizeof(SEC_PKCS7ContentInfo)); PORT_ArenaUnmark(poolp, mark); return asafe; loser: PORT_ArenaRelease(poolp, mark); return NULL; }
void check(PLArenaPool *arena, const char b64[], const char s[], const char sName[], bool url) { void *mark = NULL; SECItem *b64Item; mark = PORT_ArenaMark(arena); b64Item = SECITEM_AllocItem(arena, NULL, strlen(b64)); if(b64Item == NULL){ printf(">>> Couldn't allocate memore, SECITEM_AllocItem failed.\n"); } strncpy(b64Item->data, b64, b64Item->len); SECItem b64Decoded; PORT_Memset(&b64Decoded, 0, sizeof(b64Decoded)); if (url) { #ifdef NSS_B64_URL_TEST if (!NSSBase64_URL_DecodeBuffer(arena, &b64Decoded, b64Item->data, b64Item->len)) { PORT_FreeArena(arena, 0); printf(">>> Couldn't b64decode, NSSBase64_DecodeBuffer failed (URL).\n"); return; } #endif } else { if (!NSSBase64_DecodeBuffer(arena, &b64Decoded, b64Item->data, b64Item->len)) { PORT_FreeArena(arena, 0); printf(">>> Couldn't b64decode, NSSBase64_DecodeBuffer failed.\n"); return; } } if (strcmp(s,b64Decoded.data) != 0) { printf(">>> DECODING ERROR (%s):/\n>>> expected:\n%s\ngot:\n", sName, s); printf("%.*s---\n---", b64Decoded.len, b64Decoded.data); } else { printf("Successful decoded %s string\n", sName); } PORT_ArenaUnmark(arena, mark); }
/* * This function expands the internal state of the prng to fulfill any number * of bytes we need for this request. We only use this call if we need more * than can be supplied by a single call to SHA256_HashBuf. * * This function is specified in NIST SP 800-90 section 10.1.1.4, Hashgen */ static void prng_Hashgen(RNGContext *rng, PRUint8 *returned_bytes, unsigned int no_of_returned_bytes) { PRUint8 data[VSize(rng)]; PORT_Memcpy(data, V(rng), VSize(rng)); while (no_of_returned_bytes) { SHA256Context ctx; unsigned int len; unsigned int carry; int k1; SHA256_Begin(&ctx); SHA256_Update(&ctx, data, sizeof data); SHA256_End(&ctx, returned_bytes, &len, no_of_returned_bytes); returned_bytes += len; no_of_returned_bytes -= len; /* The carry parameter is a bool (increment or not). * This increments data if no_of_returned_bytes is not zero */ PRNG_ADD_CARRY_ONLY(data, (sizeof data)- 1, no_of_returned_bytes); } PORT_Memset(data, 0, sizeof data); }