/* * J A R _ d i g e s t _ f i l e * * Calculates the MD5 and SHA1 digests for a file * present on disk, and returns these in JAR_Digest struct. * */ int JAR_digest_file (char *filename, JAR_Digest *dig) { JAR_FILE fp; PK11Context *md5 = 0; PK11Context *sha1 = 0; unsigned char *buf = (unsigned char *) PORT_ZAlloc (FILECHUNQ); int num; unsigned int md5_length, sha1_length; if (buf == NULL) { /* out of memory */ return JAR_ERR_MEMORY; } if ((fp = JAR_FOPEN (filename, "rb")) == 0) { /* perror (filename); FIX XXX XXX XXX XXX XXX XXX */ PORT_Free (buf); return JAR_ERR_FNF; } md5 = PK11_CreateDigestContext (SEC_OID_MD5); sha1 = PK11_CreateDigestContext (SEC_OID_SHA1); if (md5 == NULL || sha1 == NULL) { /* can't generate digest contexts */ PORT_Free (buf); JAR_FCLOSE (fp); return JAR_ERR_GENERAL; } PK11_DigestBegin (md5); PK11_DigestBegin (sha1); while (1) { if ((num = JAR_FREAD (fp, buf, FILECHUNQ)) == 0) break; PK11_DigestOp (md5, buf, num); PK11_DigestOp (sha1, buf, num); } PK11_DigestFinal (md5, dig->md5, &md5_length, MD5_LENGTH); PK11_DigestFinal (sha1, dig->sha1, &sha1_length, SHA1_LENGTH); PK11_DestroyContext (md5, PR_TRUE); PK11_DestroyContext (sha1, PR_TRUE); PORT_Free (buf); JAR_FCLOSE (fp); return 0; }
char *oauth_body_hash_data(size_t length, const char *data) { PK11SlotInfo *slot = NULL; PK11Context *context = NULL; unsigned char digest[20]; // Is there a way to tell how large the output is? unsigned int len; SECStatus s; char *rv=NULL; oauth_init_nss(); slot = PK11_GetInternalKeySlot(); if (!slot) goto looser; context = PK11_CreateDigestContext(SEC_OID_SHA1); if (!context) goto looser; s = PK11_DigestBegin(context); if (s != SECSuccess) goto looser; s = PK11_DigestOp(context, (unsigned char*) data, length); if (s != SECSuccess) goto looser; s = PK11_DigestFinal(context, digest, &len, sizeof digest); if (s != SECSuccess) goto looser; unsigned char *dgst = xmalloc(len*sizeof(char)); // oauth_body_hash_encode frees the digest.. memcpy(dgst, digest, len); rv=oauth_body_hash_encode(len, dgst); looser: if (context) PK11_DestroyContext(context, PR_TRUE); if (slot) PK11_FreeSlot(slot); return rv; }
static int nss_hash_init(void **pctx, SECOidTag hash_alg) { PK11Context *ctx; /* we have to initialize NSS if not initialized alraedy */ #ifdef HAVE_NSS_INITCONTEXT if(!NSS_IsInitialized() && !nss_context) { static NSSInitParameters params; params.length = sizeof params; nss_context = NSS_InitContext("", "", "", "", ¶ms, NSS_INIT_READONLY | NSS_INIT_NOCERTDB | NSS_INIT_NOMODDB | NSS_INIT_FORCEOPEN | NSS_INIT_NOROOTINIT | NSS_INIT_OPTIMIZESPACE | NSS_INIT_PK11RELOAD); } #endif ctx = PK11_CreateDigestContext(hash_alg); if(!ctx) return /* failure */ 0; if(PK11_DigestBegin(ctx) != SECSuccess) { PK11_DestroyContext(ctx, PR_TRUE); return /* failure */ 0; } *pctx = ctx; return /* success */ 1; }
// Let derIssuer be the DER encoding of the issuer of aCert. // Let derPublicKey be the DER encoding of the public key of aIssuerCert. // Let serialNumber be the bytes of the serial number of aCert. // The value calculated is SHA384(derIssuer || derPublicKey || serialNumber). // Because the DER encodings include the length of the data encoded, // there do not exist A(derIssuerA, derPublicKeyA, serialNumberA) and // B(derIssuerB, derPublicKeyB, serialNumberB) such that the concatenation of // each triplet results in the same string of bytes but where each part in A is // not equal to its counterpart in B. This is important because as a result it // is computationally infeasible to find collisions that would subvert this // cache (given that SHA384 is a cryptographically-secure hash function). static SECStatus CertIDHash(SHA384Buffer& buf, const CertID& certID) { ScopedPK11Context context(PK11_CreateDigestContext(SEC_OID_SHA384)); if (!context) { return SECFailure; } SECStatus rv = PK11_DigestBegin(context.get()); if (rv != SECSuccess) { return rv; } rv = PK11_DigestOp(context.get(), certID.issuer.data, certID.issuer.len); if (rv != SECSuccess) { return rv; } rv = PK11_DigestOp(context.get(), certID.issuerSubjectPublicKeyInfo.data, certID.issuerSubjectPublicKeyInfo.len); if (rv != SECSuccess) { return rv; } rv = PK11_DigestOp(context.get(), certID.serialNumber.data, certID.serialNumber.len); if (rv != SECSuccess) { return rv; } uint32_t outLen = 0; rv = PK11_DigestFinal(context.get(), buf, &outLen, SHA384_LENGTH); if (outLen != SHA384_LENGTH) { return SECFailure; } return rv; }
void hmac_final(u_char *output, struct hmac_ctx *ctx) { unsigned int outlen = 0; SECStatus status = PK11_DigestFinal(ctx->ctx_nss, output, &outlen, ctx->hmac_digest_len); PR_ASSERT(status == SECSuccess); PR_ASSERT(outlen == ctx->hmac_digest_len); PK11_DestroyContext(ctx->ctx_nss, PR_TRUE); ctx->ctx_nss = NULL; ctx->ctx_nss = PK11_CreateDigestContext(nss_hash_oid(ctx->h)); PR_ASSERT(ctx->ctx_nss != NULL); status = PK11_DigestBegin(ctx->ctx_nss); PR_ASSERT(status == SECSuccess); status = PK11_DigestKey(ctx->ctx_nss, ctx->okey); PR_ASSERT(status == SECSuccess); status = PK11_DigestOp(ctx->ctx_nss, output, outlen); PR_ASSERT(status == SECSuccess); status = PK11_DigestFinal(ctx->ctx_nss, output, &outlen, ctx->hmac_digest_len); PR_ASSERT(status == SECSuccess); PR_ASSERT(outlen == ctx->hmac_digest_len); PK11_DestroyContext(ctx->ctx_nss, PR_TRUE); if (ctx->ikey != NULL) PK11_FreeSymKey(ctx->ikey); if (ctx->okey != NULL) PK11_FreeSymKey(ctx->okey); /* DBG(DBG_CRYPT, DBG_log("NSS: hmac final end")); */ }
// Let derIssuer be the DER encoding of the issuer of aCert. // Let derPublicKey be the DER encoding of the public key of aIssuerCert. // Let serialNumber be the bytes of the serial number of aCert. // The value calculated is SHA384(derIssuer || derPublicKey || serialNumber). // Because the DER encodings include the length of the data encoded, // there do not exist A(derIssuerA, derPublicKeyA, serialNumberA) and // B(derIssuerB, derPublicKeyB, serialNumberB) such that the concatenation of // each triplet results in the same string of bytes but where each part in A is // not equal to its counterpart in B. This is important because as a result it // is computationally infeasible to find collisions that would subvert this // cache (given that SHA384 is a cryptographically-secure hash function). static SECStatus CertIDHash(SHA384Buffer& buf, const CERTCertificate* aCert, const CERTCertificate* aIssuerCert) { ScopedPK11Context context(PK11_CreateDigestContext(SEC_OID_SHA384)); if (!context) { return SECFailure; } SECStatus rv = PK11_DigestBegin(context.get()); if (rv != SECSuccess) { return rv; } rv = PK11_DigestOp(context.get(), aCert->derIssuer.data, aCert->derIssuer.len); if (rv != SECSuccess) { return rv; } rv = PK11_DigestOp(context.get(), aIssuerCert->derPublicKey.data, aIssuerCert->derPublicKey.len); if (rv != SECSuccess) { return rv; } rv = PK11_DigestOp(context.get(), aCert->serialNumber.data, aCert->serialNumber.len); if (rv != SECSuccess) { return rv; } uint32_t outLen = 0; rv = PK11_DigestFinal(context.get(), buf, &outLen, SHA384_LENGTH); if (outLen != SHA384_LENGTH) { return SECFailure; } return rv; }
PK11SymKey * PK11_Derive_osw(PK11SymKey *base, CK_MECHANISM_TYPE mechanism , SECItem *param, CK_MECHANISM_TYPE target , CK_ATTRIBUTE_TYPE operation, int keysize) { SECOidTag oid; PK11Context *ctx; unsigned char dkey[HMAC_BUFSIZE]; SECItem dkey_param; SECStatus status; unsigned int len=0; CK_EXTRACT_PARAMS bs; chunk_t dkey_chunk; if( ((mechanism == CKM_SHA256_KEY_DERIVATION) || (mechanism == CKM_SHA384_KEY_DERIVATION)|| (mechanism == CKM_SHA512_KEY_DERIVATION)) && (param == NULL) && (keysize ==0)) { switch (mechanism) { case CKM_SHA256_KEY_DERIVATION: oid = SEC_OID_SHA256; break; case CKM_SHA384_KEY_DERIVATION: oid = SEC_OID_SHA384; break; case CKM_SHA512_KEY_DERIVATION: oid = SEC_OID_SHA512; break; default: DBG(DBG_CRYPT, DBG_log("PK11_Derive_osw: Invalid NSS mechanism ")); break; /*should not reach here*/ } ctx = PK11_CreateDigestContext(oid); PR_ASSERT(ctx!=NULL); status=PK11_DigestBegin(ctx); PR_ASSERT(status == SECSuccess); status=PK11_DigestKey(ctx, base); PR_ASSERT(status == SECSuccess); PK11_DigestFinal(ctx, dkey, &len, sizeof dkey); PK11_DestroyContext(ctx, PR_TRUE); dkey_chunk.ptr = dkey; dkey_chunk.len = len; PK11SymKey *tkey1 = pk11_derive_wrapper_osw(base, CKM_CONCATENATE_DATA_AND_BASE, dkey_chunk, CKM_EXTRACT_KEY_FROM_KEY, CKA_DERIVE, 0); PR_ASSERT(tkey1!=NULL); bs=0; dkey_param.data = (unsigned char*)&bs; dkey_param.len = sizeof (bs); PK11SymKey *tkey2 = PK11_Derive(tkey1, CKM_EXTRACT_KEY_FROM_KEY, &dkey_param, target, operation, len); PR_ASSERT(tkey2!=NULL); if(tkey1!=NULL) { PK11_FreeSymKey(tkey1); } return tkey2; } else { return PK11_Derive(base, mechanism, param, target, operation, keysize); } }
/* * This is to get FIPS compliance until we can convert * libjar to use PK11_ hashing functions. It returns PR_FALSE * if we can't get a PK11 Context. */ PRBool PK11_HashOK(SECOidTag algID) { PK11Context *cx; cx = PK11_CreateDigestContext(algID); if (cx == NULL) return PR_FALSE; PK11_DestroyContext(cx, PR_TRUE); return PR_TRUE; }
CryptoMd5 crypto_md5_init(void) { CryptoMd5 md5 = xmalloc(sizeof(*md5)); md5->context = PK11_CreateDigestContext(SEC_OID_MD5); SECStatus s = PK11_DigestBegin(md5->context); check(s, "Error initializing md5"); return md5; }
CryptoSha1 crypto_sha1_init(void) { CryptoSha1 sha1 = xmalloc(sizeof(*sha1)); sha1->context = PK11_CreateDigestContext(SEC_OID_SHA1); SECStatus s = PK11_DigestBegin(sha1->context); check(s, "Error initializing sha1"); return sha1; }
/* MD5 initialization. Begins an MD5 operation, writing a new context. */ void lsMD5Init(lsMD5_CTX *context) { SECStatus status; context->ctx_nss = PK11_CreateDigestContext(SEC_OID_MD5); passert(context->ctx_nss != NULL); status = PK11_DigestBegin(context->ctx_nss); passert(status == SECSuccess); }
/* Initialize the SHS values */ void shsInit(SHS_INFO *shsInfo) { if (k5_nss_init()) { shsInfo->nss_ctxt = NULL; return; } shsInfo->nss_ctxt = PK11_CreateDigestContext(SEC_OID_SHA1); if (shsInfo->nss_ctxt == NULL) return; PK11_DigestBegin((PK11Context *)shsInfo->nss_ctxt); }
void Curl_nss_md5sum(unsigned char *tmp, /* input */ size_t tmplen, unsigned char *md5sum, /* output */ size_t md5len) { PK11Context *MD5pw = PK11_CreateDigestContext(SEC_OID_MD5); unsigned int MD5out; PK11_DigestOp(MD5pw, tmp, curlx_uztoui(tmplen)); PK11_DigestFinal(MD5pw, md5sum, &MD5out, curlx_uztoui(md5len)); PK11_DestroyContext(MD5pw, PR_TRUE); }
void sha256_init(sha256_context *ctx) { DBG(DBG_CRYPT, DBG_log("NSS: sha256 init start")); SECStatus status; ctx->ctx_nss = NULL; ctx->ctx_nss = PK11_CreateDigestContext(SEC_OID_SHA256); PR_ASSERT(ctx->ctx_nss != NULL); status = PK11_DigestBegin(ctx->ctx_nss); PR_ASSERT(status == SECSuccess); DBG(DBG_CRYPT, DBG_log("NSS: sha256 init end")); }
gboolean crypto_md5_hash (const char *salt, const gsize salt_len, const char *password, gsize password_len, char *buffer, gsize buflen, GError **error) { PK11Context *ctx; int nkey = buflen; unsigned int digest_len; int count = 0; char digest[MD5_HASH_LEN]; char *p = buffer; if (salt) g_return_val_if_fail (salt_len >= 8, FALSE); g_return_val_if_fail (password != NULL, FALSE); g_return_val_if_fail (password_len > 0, FALSE); g_return_val_if_fail (buffer != NULL, FALSE); g_return_val_if_fail (buflen > 0, FALSE); ctx = PK11_CreateDigestContext (SEC_OID_MD5); if (!ctx) { g_set_error (error, NM_CRYPTO_ERROR, NM_CRYPTO_ERR_MD5_INIT_FAILED, _("Failed to initialize the MD5 context: %d."), PORT_GetError ()); return FALSE; } while (nkey > 0) { int i = 0; PK11_DigestBegin (ctx); if (count++) PK11_DigestOp (ctx, (const unsigned char *) digest, digest_len); PK11_DigestOp (ctx, (const unsigned char *) password, password_len); if (salt) PK11_DigestOp (ctx, (const unsigned char *) salt, 8); /* Only use 8 bytes of salt */ PK11_DigestFinal (ctx, (unsigned char *) digest, &digest_len, sizeof (digest)); while (nkey && (i < digest_len)) { *(p++) = digest[i++]; nkey--; } } memset (digest, 0, sizeof (digest)); PK11_DestroyContext (ctx, PR_TRUE); return TRUE; }
sxi_md_ctx *sxi_md_init(void) { sxi_md_ctx *ctx = calloc(1, sizeof(*ctx)); if (!ctx) return NULL; ctx->context = PK11_CreateDigestContext(SEC_OID_SHA1); if (!ctx->context) { free(ctx); return NULL; } return ctx; }
void sxi_sha256(const unsigned char *d, size_t n,unsigned char *md) { unsigned len; PK11Context *context = PK11_CreateDigestContext(SEC_OID_SHA256); if (!context || PK11_DigestBegin(context) != SECSuccess || PK11_DigestOp(context, d, n) != SECSuccess || PK11_DigestFinal(context, md, &len, SHA256_DIGEST_LENGTH) != SECSuccess) { /* TODO: log */ } if (context) PK11_DestroyContext(context, PR_TRUE); }
/* * J A R _ c a l c u l a t e _ d i g e s t * * Quick calculation of a digest for * the specified block of memory. Will calculate * for all supported algorithms, now MD5. * * This version supports huge pointers for WIN16. * */ JAR_Digest * PR_CALLBACK JAR_calculate_digest(void *data, long length) { PK11Context *md5 = 0; PK11Context *sha1 = 0; JAR_Digest *dig = PORT_ZNew(JAR_Digest); long chunq; unsigned int md5_length, sha1_length; if (dig == NULL) { /* out of memory allocating digest */ return NULL; } md5 = PK11_CreateDigestContext(SEC_OID_MD5); sha1 = PK11_CreateDigestContext(SEC_OID_SHA1); if (length >= 0) { PK11_DigestBegin (md5); PK11_DigestBegin (sha1); do { chunq = length; PK11_DigestOp(md5, (unsigned char*)data, chunq); PK11_DigestOp(sha1, (unsigned char*)data, chunq); length -= chunq; data = ((char *) data + chunq); } while (length > 0); PK11_DigestFinal (md5, dig->md5, &md5_length, MD5_LENGTH); PK11_DigestFinal (sha1, dig->sha1, &sha1_length, SHA1_LENGTH); PK11_DestroyContext (md5, PR_TRUE); PK11_DestroyContext (sha1, PR_TRUE); } return dig; }
/* * @param(IN) salt salt in binary format * @param(IN) saltSize number of bytes for the salt * @param(IN) clearPasswd clearPasswd * @param(OUT) the hashed password with salt in ascii b64 format * * #sample keyfile line * j2ee;{SSHA}WRWaz20fzw3zN9x5Uzyyk5Wfvrbe4m40rYTPrA==;staff,eng */ void sshaPasswd(const char* salt, const int saltSize,const char* clearPasswd,NSString& hashed) { //PRBool workaround= PR_FALSE; //PR_TRUE; const int digestLen = SHA1_LENGTH; //20 unsigned char H[512]; char* pwdAndSalt=NULL; hashed.clear(); if (!clearPasswd) { return; } int tobeHashedLen = 0; pwdAndSalt = addSalt(clearPasswd, salt, saltSize,tobeHashedLen); //if (workaround==PR_TRUE) { //https_SHA1_Hash(H,pwdAndSalt); //refer lib/libadmin/password.cpp //} else { //const int keylen = PRIVATE_KEY_LEN; //unsigned char DigestPrivatekey[PRIVATE_KEY_LEN]; //PK11_GenerateRandom(DigestPrivatekey, keylen); PK11Context * SHA1Ctx = PK11_CreateDigestContext(SEC_OID_SHA1); if (SHA1Ctx==NULL) { FREE(pwdAndSalt); return; } PK11_DigestBegin(SHA1Ctx); //PK11_DigestOp(SHA1Ctx, (unsigned char*)pwdAndSalt, strlen(pwdAndSalt) ); PK11_DigestOp(SHA1Ctx, (unsigned char*)pwdAndSalt, tobeHashedLen ); PK11_DigestFinal(SHA1Ctx, (unsigned char *)H, (unsigned int*)&digestLen, sizeof(H)); PK11_DestroyContext(SHA1Ctx, 1); PR_ASSERT(digestLen==20); //} char* base64Val=NULL; if (salt!=NULL && saltSize>0) { memcpy(H+20,salt,saltSize); //append salt to hashed passwd base64Val = BTOA_DataToAscii(H,digestLen+saltSize); //base64.h } else { base64Val = BTOA_DataToAscii(H,digestLen); //base64.h } hashed.append(SSHA_TAG ); hashed.append(base64Val); if (base64Val) PORT_Free(base64Val); base64Val = NULL; FREE(pwdAndSalt); return; }
static int DigestFile(FILE *outFile, FILE *inFile, SECOidData *hashOID) { int nb; unsigned char ibuf[4096], digest[32]; PK11Context *hashcx; unsigned int len; SECStatus rv; hashcx = PK11_CreateDigestContext(hashOID->offset); if (hashcx == NULL) { return -1; } PK11_DigestBegin(hashcx); for (;;) { if (feof(inFile)) break; nb = fread(ibuf, 1, sizeof(ibuf), inFile); if (nb != sizeof(ibuf)) { if (nb == 0) { if (ferror(inFile)) { PORT_SetError(SEC_ERROR_IO); PK11_DestroyContext(hashcx,PR_TRUE); return -1; } /* eof */ break; } } rv = PK11_DigestOp(hashcx, ibuf, nb); if (rv != SECSuccess) { PK11_DestroyContext(hashcx, PR_TRUE); return -1; } } rv = PK11_DigestFinal(hashcx, digest, &len, 32); PK11_DestroyContext(hashcx, PR_TRUE); if (rv != SECSuccess) return -1; nb = fwrite(digest, 1, len, outFile); if (nb != len) { PORT_SetError(SEC_ERROR_IO); return -1; } return 0; }
void hmac_final(u_char *output, struct hmac_ctx *ctx) { #ifndef HAVE_LIBNSS const struct hash_desc *h = ctx->h; h->hash_final(output, &ctx->hash_ctx); h->hash_init(&ctx->hash_ctx); h->hash_update(&ctx->hash_ctx, ctx->buf2, HMAC_BUFSIZE); h->hash_update(&ctx->hash_ctx, output, h->hash_digest_len); h->hash_final(output, &ctx->hash_ctx); #else unsigned int outlen = 0; SECStatus status = PK11_DigestFinal(ctx->ctx_nss, output, &outlen, ctx->hmac_digest_len); PR_ASSERT(status == SECSuccess); PR_ASSERT(outlen == ctx->hmac_digest_len); PK11_DestroyContext(ctx->ctx_nss, PR_TRUE); ctx->ctx_nss = NULL; ctx->ctx_nss = PK11_CreateDigestContext(nss_hash_oid(ctx->h)); PR_ASSERT(ctx->ctx_nss!=NULL); status=PK11_DigestBegin(ctx->ctx_nss); PR_ASSERT(status==SECSuccess); status=PK11_DigestKey(ctx->ctx_nss, ctx->okey); PR_ASSERT(status==SECSuccess); status = PK11_DigestOp(ctx->ctx_nss, output, outlen); PR_ASSERT(status == SECSuccess); status = PK11_DigestFinal(ctx->ctx_nss, output, &outlen, ctx->hmac_digest_len); PR_ASSERT(status == SECSuccess); PR_ASSERT(outlen == ctx->hmac_digest_len); PK11_DestroyContext(ctx->ctx_nss, PR_TRUE); if(ctx->ikey !=NULL) { PK11_FreeSymKey(ctx->ikey); } if(ctx->okey != NULL) { PK11_FreeSymKey(ctx->okey); } /* DBG(DBG_CRYPT, DBG_log("NSS: hmac final end")); */ #endif }
/*********************************************************************** * * PK11MessageDigest.initDigest * */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11MessageDigest_initDigest (JNIEnv *env, jclass clazz, jobject algObj) { SECOidTag alg; PK11Context *context=NULL; alg = JSS_getOidTagFromAlg(env, algObj); PR_ASSERT( alg != SEC_OID_UNKNOWN ); /* we checked already in Java */ context = PK11_CreateDigestContext(alg); if( context == NULL ) { JSS_throwMsg(env, DIGEST_EXCEPTION, "Unable to create digest context"); return NULL; } return JSS_PK11_wrapCipherContextProxy(env, &context); }
int main(int argc, char *argv[]) { qb_list_init (&msg_log_head); qb_list_init (&config_chg_log_head); if (NSS_NoDB_Init(".") != SECSuccess) { qb_log(LOG_ERR, "Couldn't initialize nss"); exit (0); } if ((sha1_context = PK11_CreateDigestContext(SEC_OID_SHA1)) == NULL) { qb_log(LOG_ERR, "Couldn't initialize nss"); exit (0); } return test_agent_run ("cpg_test_agent", 9034, do_command, my_pre_exit); }
void clear() { SECStatus s; PK11_DestroyContext(m_context, PR_TRUE); m_context = PK11_CreateDigestContext(m_hashAlgo); if (! m_context) { qDebug() << "CreateDigestContext failed"; return; } s = PK11_DigestBegin(m_context); if (s != SECSuccess) { qDebug() << "DigestBegin failed"; return; } }
// Let derIssuer be the DER encoding of the issuer of aCert. // Let derPublicKey be the DER encoding of the public key of aIssuerCert. // Let serialNumber be the bytes of the serial number of aCert. // The value calculated is SHA384(derIssuer || derPublicKey || serialNumber). // Because the DER encodings include the length of the data encoded, // there do not exist A(derIssuerA, derPublicKeyA, serialNumberA) and // B(derIssuerB, derPublicKeyB, serialNumberB) such that the concatenation of // each triplet results in the same string of bytes but where each part in A is // not equal to its counterpart in B. This is important because as a result it // is computationally infeasible to find collisions that would subvert this // cache (given that SHA384 is a cryptographically-secure hash function). static SECStatus CertIDHash(SHA384Buffer& buf, const CertID& certID, const char* aIsolationKey) { ScopedPK11Context context(PK11_CreateDigestContext(SEC_OID_SHA384)); if (!context) { return SECFailure; } SECStatus rv = PK11_DigestBegin(context.get()); if (rv != SECSuccess) { return rv; } SECItem certIDIssuer = UnsafeMapInputToSECItem(certID.issuer); rv = PK11_DigestOp(context.get(), certIDIssuer.data, certIDIssuer.len); if (rv != SECSuccess) { return rv; } SECItem certIDIssuerSubjectPublicKeyInfo = UnsafeMapInputToSECItem(certID.issuerSubjectPublicKeyInfo); rv = PK11_DigestOp(context.get(), certIDIssuerSubjectPublicKeyInfo.data, certIDIssuerSubjectPublicKeyInfo.len); if (rv != SECSuccess) { return rv; } SECItem certIDSerialNumber = UnsafeMapInputToSECItem(certID.serialNumber); rv = PK11_DigestOp(context.get(), certIDSerialNumber.data, certIDSerialNumber.len); if (rv != SECSuccess) { return rv; } if (aIsolationKey) { rv = PK11_DigestOp(context.get(), (const unsigned char*) aIsolationKey, strlen(aIsolationKey)); if (rv != SECSuccess) { return rv; } } uint32_t outLen = 0; rv = PK11_DigestFinal(context.get(), buf, &outLen, SHA384_LENGTH); if (outLen != SHA384_LENGTH) { return SECFailure; } return rv; }
SECStatus PK11_HashBuf(SECOidTag hashAlg, unsigned char *out, const unsigned char *in, PRInt32 len) { PK11Context *context; unsigned int max_length; unsigned int out_length; SECStatus rv; /* len will be passed to PK11_DigestOp as unsigned. */ if (len < 0) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } context = PK11_CreateDigestContext(hashAlg); if (context == NULL) return SECFailure; rv = PK11_DigestBegin(context); if (rv != SECSuccess) { PK11_DestroyContext(context, PR_TRUE); return rv; } rv = PK11_DigestOp(context, in, len); if (rv != SECSuccess) { PK11_DestroyContext(context, PR_TRUE); return rv; } /* XXX This really should have been an argument to this function! */ max_length = HASH_ResultLenByOidTag(hashAlg); PORT_Assert(max_length); if (!max_length) max_length = HASH_LENGTH_MAX; rv = PK11_DigestFinal(context, out, &out_length, max_length); PK11_DestroyContext(context, PR_TRUE); return rv; }
char *oauth_body_hash_file(char *filename) { PK11SlotInfo *slot = NULL; PK11Context *context = NULL; unsigned char digest[20]; // Is there a way to tell how large the output is? unsigned int len; SECStatus s; char *rv=NULL; size_t bl; unsigned char fb[BUFSIZ]; FILE *F= fopen(filename, "r"); if (!F) return NULL; oauth_init_nss(); slot = PK11_GetInternalKeySlot(); if (!slot) goto looser; context = PK11_CreateDigestContext(SEC_OID_SHA1); if (!context) goto looser; s = PK11_DigestBegin(context); if (s != SECSuccess) goto looser; while (!feof(F) && (bl=fread(fb,sizeof(char),BUFSIZ, F))>0) { s = PK11_DigestOp(context, (unsigned char*) fb, bl); if (s != SECSuccess) goto looser; } s = PK11_DigestFinal(context, digest, &len, sizeof digest); if (s != SECSuccess) goto looser; unsigned char *dgst = xmalloc(len*sizeof(char)); // oauth_body_hash_encode frees the digest.. memcpy(dgst, digest, len); rv=oauth_body_hash_encode(len, dgst); looser: fclose(F); if (context) PK11_DestroyContext(context, PR_TRUE); if (slot) PK11_FreeSlot(slot); return rv; }
bool gtkhash_hash_lib_nss_is_supported(const enum hash_func_e id) { struct hash_lib_nss_s data; if (!gtkhash_hash_lib_nss_set_alg(id, &data.alg)) return false; if (G_UNLIKELY(!(data.nss = gtkhash_hash_lib_nss_init_context()))) { g_warning("NSS_InitContext failed (%d)", id); return false; } if (G_UNLIKELY(!(data.pk11 = PK11_CreateDigestContext(data.alg)))) { g_warning("PK11_CreateDigestContext failed (%d)", id); NSS_ShutdownContext(data.nss); return false; } PK11_DestroyContext(data.pk11, PR_TRUE); NSS_ShutdownContext(data.nss); return true; }
// Called on the worker thread. nsresult BackgroundFileSaver::ProcessStateChange() { nsresult rv; // We might have been notified because the operation is complete, verify. if (CheckCompletion()) { return NS_OK; } // Get a copy of the current shared state for the worker thread. nsCOMPtr<nsIFile> initialTarget; bool initialTargetKeepPartial; nsCOMPtr<nsIFile> renamedTarget; bool renamedTargetKeepPartial; bool sha256Enabled; bool append; { MutexAutoLock lock(mLock); initialTarget = mInitialTarget; initialTargetKeepPartial = mInitialTargetKeepPartial; renamedTarget = mRenamedTarget; renamedTargetKeepPartial = mRenamedTargetKeepPartial; sha256Enabled = mSha256Enabled; append = mAppend; // From now on, another attention event needs to be posted if state changes. mWorkerThreadAttentionRequested = false; } // The initial target can only be null if it has never been assigned. In this // case, there is nothing to do since we never created any output file. if (!initialTarget) { return NS_OK; } // Determine if we are processing the attention request for the first time. bool isContinuation = !!mActualTarget; if (!isContinuation) { // Assign the target file for the first time. mActualTarget = initialTarget; mActualTargetKeepPartial = initialTargetKeepPartial; } // Verify whether we have actually been instructed to use a different file. // This may happen the first time this function is executed, if SetTarget was // called two times before the worker thread processed the attention request. bool equalToCurrent = false; if (renamedTarget) { rv = mActualTarget->Equals(renamedTarget, &equalToCurrent); NS_ENSURE_SUCCESS(rv, rv); if (!equalToCurrent) { // If we were asked to rename the file but the initial file did not exist, // we simply create the file in the renamed location. We avoid this check // if we have already started writing the output file ourselves. bool exists = true; if (!isContinuation) { rv = mActualTarget->Exists(&exists); NS_ENSURE_SUCCESS(rv, rv); } if (exists) { // We are moving the previous target file to a different location. nsCOMPtr<nsIFile> renamedTargetParentDir; rv = renamedTarget->GetParent(getter_AddRefs(renamedTargetParentDir)); NS_ENSURE_SUCCESS(rv, rv); nsAutoString renamedTargetName; rv = renamedTarget->GetLeafName(renamedTargetName); NS_ENSURE_SUCCESS(rv, rv); // We must delete any existing target file before moving the current // one. rv = renamedTarget->Exists(&exists); NS_ENSURE_SUCCESS(rv, rv); if (exists) { rv = renamedTarget->Remove(false); NS_ENSURE_SUCCESS(rv, rv); } // Move the file. If this fails, we still reference the original file // in mActualTarget, so that it is deleted if requested. If this // succeeds, the nsIFile instance referenced by mActualTarget mutates // and starts pointing to the new file, but we'll discard the reference. rv = mActualTarget->MoveTo(renamedTargetParentDir, renamedTargetName); NS_ENSURE_SUCCESS(rv, rv); } // Now we can update the actual target file name. mActualTarget = renamedTarget; mActualTargetKeepPartial = renamedTargetKeepPartial; } } // Notify if the target file name actually changed. if (!equalToCurrent) { // We must clone the nsIFile instance because mActualTarget is not // immutable, it may change if the target is renamed later. nsCOMPtr<nsIFile> actualTargetToNotify; rv = mActualTarget->Clone(getter_AddRefs(actualTargetToNotify)); NS_ENSURE_SUCCESS(rv, rv); RefPtr<NotifyTargetChangeRunnable> event = new NotifyTargetChangeRunnable(this, actualTargetToNotify); NS_ENSURE_TRUE(event, NS_ERROR_FAILURE); rv = mControlThread->Dispatch(event, NS_DISPATCH_NORMAL); NS_ENSURE_SUCCESS(rv, rv); } if (isContinuation) { // The pending rename operation might be the last task before finishing. We // may return here only if we have already created the target file. if (CheckCompletion()) { return NS_OK; } // Even if the operation did not complete, the pipe input stream may be // empty and may have been closed already. We detect this case using the // Available property, because it never returns an error if there is more // data to be consumed. If the pipe input stream is closed, we just exit // and wait for more calls like SetTarget or Finish to be invoked on the // control thread. However, we still truncate the file or create the // initial digest context if we are expected to do that. uint64_t available; rv = mPipeInputStream->Available(&available); if (NS_FAILED(rv)) { return NS_OK; } } // Create the digest context if requested and NSS hasn't been shut down. if (sha256Enabled && !mDigestContext) { nsNSSShutDownPreventionLock lock; if (!isAlreadyShutDown()) { mDigestContext = UniquePK11Context( PK11_CreateDigestContext(SEC_OID_SHA256)); NS_ENSURE_TRUE(mDigestContext, NS_ERROR_OUT_OF_MEMORY); } } // When we are requested to append to an existing file, we should read the // existing data and ensure we include it as part of the final hash. if (mDigestContext && append && !isContinuation) { nsCOMPtr<nsIInputStream> inputStream; rv = NS_NewLocalFileInputStream(getter_AddRefs(inputStream), mActualTarget, PR_RDONLY | nsIFile::OS_READAHEAD); if (rv != NS_ERROR_FILE_NOT_FOUND) { NS_ENSURE_SUCCESS(rv, rv); char buffer[BUFFERED_IO_SIZE]; while (true) { uint32_t count; rv = inputStream->Read(buffer, BUFFERED_IO_SIZE, &count); NS_ENSURE_SUCCESS(rv, rv); if (count == 0) { // We reached the end of the file. break; } nsNSSShutDownPreventionLock lock; if (isAlreadyShutDown()) { return NS_ERROR_NOT_AVAILABLE; } nsresult rv = MapSECStatus(PK11_DigestOp(mDigestContext.get(), uint8_t_ptr_cast(buffer), count)); NS_ENSURE_SUCCESS(rv, rv); } rv = inputStream->Close(); NS_ENSURE_SUCCESS(rv, rv); } } // We will append to the initial target file only if it was requested by the // caller, but we'll always append on subsequent accesses to the target file. int32_t creationIoFlags; if (isContinuation) { creationIoFlags = PR_APPEND; } else { creationIoFlags = (append ? PR_APPEND : PR_TRUNCATE) | PR_CREATE_FILE; } // Create the target file, or append to it if we already started writing it. // The 0600 permissions are used while the file is being downloaded, and for // interrupted downloads. Those may be located in the system temporary // directory, as well as the target directory, and generally have a ".part" // extension. Those part files should never be group or world-writable even // if the umask allows it. nsCOMPtr<nsIOutputStream> outputStream; rv = NS_NewLocalFileOutputStream(getter_AddRefs(outputStream), mActualTarget, PR_WRONLY | creationIoFlags, 0600); NS_ENSURE_SUCCESS(rv, rv); outputStream = NS_BufferOutputStream(outputStream, BUFFERED_IO_SIZE); if (!outputStream) { return NS_ERROR_FAILURE; } // Wrap the output stream so that it feeds the digest context if needed. if (mDigestContext) { // No need to acquire the NSS lock here, DigestOutputStream must acquire it // in any case before each asynchronous write. Constructing the // DigestOutputStream cannot fail. Passing mDigestContext to // DigestOutputStream is safe, because BackgroundFileSaver always outlives // the outputStream. BackgroundFileSaver is reference-counted before the // call to AsyncCopy, and mDigestContext is never destroyed before // AsyncCopyCallback. outputStream = new DigestOutputStream(outputStream, mDigestContext.get()); } // Start copying our input to the target file. No errors can be raised past // this point if the copy starts, since they should be handled by the thread. { MutexAutoLock lock(mLock); rv = NS_AsyncCopy(mPipeInputStream, outputStream, mWorkerThread, NS_ASYNCCOPY_VIA_READSEGMENTS, 4096, AsyncCopyCallback, this, false, true, getter_AddRefs(mAsyncCopyContext), GetProgressCallback()); if (NS_FAILED(rv)) { NS_WARNING("NS_AsyncCopy failed."); mAsyncCopyContext = nullptr; return rv; } } // If the operation succeeded, we must ensure that we keep this object alive // for the entire duration of the copy, since only the raw pointer will be // provided as the argument of the AsyncCopyCallback function. We can add the // reference now, after NS_AsyncCopy returned, because it always starts // processing asynchronously, and there is no risk that the callback is // invoked before we reach this point. If the operation failed instead, then // AsyncCopyCallback will never be called. NS_ADDREF_THIS(); return NS_OK; }
void hmac_init(struct hmac_ctx *ctx, const struct hash_desc *h, const u_char *key, size_t key_len) { #ifndef HAVE_LIBNSS int k; #endif ctx->h = h; ctx->hmac_digest_len = h->hash_digest_len; #ifdef HAVE_LIBNSS /* DBG(DBG_CRYPT, DBG_log("NSS: hmac init")); */ SECStatus status; PK11SymKey *symkey=NULL, *tkey1=NULL; /* PK11SymKey *tkey1=NULL; */ unsigned int klen; chunk_t hmac_opad, hmac_ipad, hmac_pad; memcpy(&symkey, key, key_len); klen = PK11_GetKeyLength(symkey); hmac_opad = hmac_pads(HMAC_OPAD,HMAC_BUFSIZE); hmac_ipad = hmac_pads(HMAC_IPAD,HMAC_BUFSIZE); hmac_pad = hmac_pads(0x00,HMAC_BUFSIZE-klen); if(klen > HMAC_BUFSIZE) { tkey1 = PK11_Derive_osw(symkey, nss_key_derivation_mech(h) , NULL, CKM_CONCATENATE_BASE_AND_DATA, CKA_DERIVE, 0); } else { tkey1 = symkey; } PK11SymKey *tkey2 = pk11_derive_wrapper_osw(tkey1, CKM_CONCATENATE_BASE_AND_DATA , hmac_pad,CKM_XOR_BASE_AND_DATA, CKA_DERIVE, HMAC_BUFSIZE); PR_ASSERT(tkey2!=NULL); ctx->ikey = pk11_derive_wrapper_osw(tkey2, CKM_XOR_BASE_AND_DATA , hmac_ipad,nss_hash_mech(h), CKA_DIGEST, 0); PR_ASSERT(ctx->ikey !=NULL); ctx->okey = pk11_derive_wrapper_osw(tkey2, CKM_XOR_BASE_AND_DATA , hmac_opad,nss_hash_mech(h), CKA_DIGEST, 0); PR_ASSERT(ctx->okey !=NULL); if(tkey1!=symkey) { PK11_FreeSymKey(tkey1); } PK11_FreeSymKey(tkey2); freeanychunk(hmac_opad); freeanychunk(hmac_ipad); freeanychunk(hmac_pad); ctx->ctx_nss = PK11_CreateDigestContext(nss_hash_oid(h)); PR_ASSERT(ctx->ctx_nss!=NULL); status=PK11_DigestBegin(ctx->ctx_nss); PR_ASSERT(status==SECSuccess); status=PK11_DigestKey(ctx->ctx_nss, ctx->ikey); PR_ASSERT(status==SECSuccess); #else /* Prepare the two pads for the HMAC */ memset(ctx->buf1, '\0', HMAC_BUFSIZE); if (key_len <= HMAC_BUFSIZE) { memcpy(ctx->buf1, key, key_len); } else { h->hash_init(&ctx->hash_ctx); h->hash_update(&ctx->hash_ctx, key, key_len); h->hash_final(ctx->buf1, &ctx->hash_ctx); } memcpy(ctx->buf2, ctx->buf1, HMAC_BUFSIZE); for (k = 0; k < HMAC_BUFSIZE; k++) { ctx->buf1[k] ^= HMAC_IPAD; ctx->buf2[k] ^= HMAC_OPAD; } hmac_reinit(ctx); #endif }