nsresult DtlsIdentity::ComputeFingerprint(const UniqueCERTCertificate& cert, const std::string algorithm, uint8_t *digest, size_t size, size_t *digest_length) { MOZ_ASSERT(cert); HASH_HashType ht; if (algorithm == "sha-1") { ht = HASH_AlgSHA1; } else if (algorithm == "sha-224") { ht = HASH_AlgSHA224; } else if (algorithm == "sha-256") { ht = HASH_AlgSHA256; } else if (algorithm == "sha-384") { ht = HASH_AlgSHA384; } else if (algorithm == "sha-512") { ht = HASH_AlgSHA512; } else { return NS_ERROR_INVALID_ARG; } const SECHashObject *ho = HASH_GetHashObject(ht); MOZ_ASSERT(ho); if (!ho) { return NS_ERROR_INVALID_ARG; } MOZ_ASSERT(ho->length >= 20); // Double check if (size < ho->length) { return NS_ERROR_INVALID_ARG; } SECStatus rv = HASH_HashBuf(ho->type, digest, cert->derCert.data, cert->derCert.len); if (rv != SECSuccess) { return NS_ERROR_FAILURE; } *digest_length = ho->length; return NS_OK; }
static int nr_crypto_nss_md5(UCHAR *buf, int bufl, UCHAR *result) { int err = R_INTERNAL; SECStatus rv; const SECHashObject *ho = HASH_GetHashObject(HASH_AlgMD5); MOZ_ASSERT(ho); if (!ho) goto abort; MOZ_ASSERT(ho->length == 16); rv = HASH_HashBuf(ho->type, result, buf, bufl); if (rv != SECSuccess) goto abort; err = 0; abort: return err; }
static int CreateDigest(SECItem *data, char *digestdata, unsigned int *len, unsigned int maxlen) { const SECHashObject *hashObj; void *hashcx; /* XXX probably want to extend interface to allow other hash algorithms */ hashObj = HASH_GetHashObject(HASH_AlgSHA1); hashcx = (* hashObj->create)(); if (hashcx == NULL) return -1; (* hashObj->begin)(hashcx); (* hashObj->update)(hashcx, data->data, data->len); (* hashObj->end)(hashcx, (unsigned char *)digestdata, len, maxlen); (* hashObj->destroy)(hashcx, PR_TRUE); return 0; }
static int DigestFile(unsigned char *digest, unsigned int *len, unsigned int maxLen, FILE *inFile, HASH_HashType hashType) { int nb; unsigned char ibuf[4096]; const SECHashObject *hashObj; void *hashcx; hashObj = HASH_GetHashObject(hashType); hashcx = (* hashObj->create)(); if (hashcx == NULL) return -1; (* hashObj->begin)(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); (* hashObj->destroy)(hashcx, PR_TRUE); return -1; } /* eof */ break; } } (* hashObj->update)(hashcx, ibuf, nb); } (* hashObj->end)(hashcx, digest, len, maxLen); (* hashObj->destroy)(hashcx, PR_TRUE); return 0; }
int jar_create_pk7(CERTCertDBHandle *certdb, void *keydb, CERTCertificate *cert, char *password, JAR_FILE infp, JAR_FILE outfp) { SEC_PKCS7ContentInfo *cinfo; const SECHashObject *hashObj; char *errstring; void *mw = NULL; void *hashcx; unsigned int len; int status = 0; SECStatus rv; SECItem digest; unsigned char digestdata[32]; unsigned char buffer[4096]; if (outfp == NULL || infp == NULL || cert == NULL) return JAR_ERR_GENERAL; /* we sign with SHA */ hashObj = HASH_GetHashObject(HASH_AlgSHA1); hashcx = (* hashObj->create)(); if (hashcx == NULL) return JAR_ERR_GENERAL; (* hashObj->begin)(hashcx); while (1) { int nb = JAR_FREAD(infp, buffer, sizeof buffer); if (nb == 0) { /* eof */ break; } (* hashObj->update) (hashcx, buffer, nb); } (* hashObj->end)(hashcx, digestdata, &len, 32); (* hashObj->destroy)(hashcx, PR_TRUE); digest.data = digestdata; digest.len = len; /* signtool must use any old context it can find since it's calling from inside javaland. */ PORT_SetError (0); cinfo = SEC_PKCS7CreateSignedData(cert, certUsageObjectSigner, NULL, SEC_OID_SHA1, &digest, NULL, mw); if (cinfo == NULL) return JAR_ERR_PK7; rv = SEC_PKCS7IncludeCertChain(cinfo, NULL); if (rv != SECSuccess) { status = PORT_GetError(); SEC_PKCS7DestroyContentInfo(cinfo); return status; } /* Having this here forces signtool to always include signing time. */ rv = SEC_PKCS7AddSigningTime(cinfo); /* don't check error */ PORT_SetError(0); /* if calling from mozilla thread*/ rv = SEC_PKCS7Encode(cinfo, jar_pk7_out, outfp, NULL, NULL, mw); if (rv != SECSuccess) status = PORT_GetError(); SEC_PKCS7DestroyContentInfo (cinfo); if (rv != SECSuccess) { errstring = JAR_get_error (status); return ((status < 0) ? status : JAR_ERR_GENERAL); } return 0; }
/********************************************************************** * * S i g n F i l e */ static int SignFile (FILE *outFile, FILE *inFile, CERTCertificate *cert) { int nb; char ibuf[4096], digestdata[32]; const SECHashObject *hashObj; void *hashcx; unsigned int len; SECItem digest; SEC_PKCS7ContentInfo * cinfo; SECStatus rv; if (outFile == NULL || inFile == NULL || cert == NULL) return - 1; /* XXX probably want to extend interface to allow other hash algorithms */ hashObj = HASH_GetHashObject(HASH_AlgSHA1); hashcx = (*hashObj->create)(); if (hashcx == NULL) return - 1; (*hashObj->begin)(hashcx); for (; ; ) { if (feof(inFile)) break; nb = fread(ibuf, 1, sizeof(ibuf), inFile); if (nb == 0) { if (ferror(inFile)) { PORT_SetError(SEC_ERROR_IO); (*hashObj->destroy)(hashcx, PR_TRUE); return - 1; } /* eof */ break; } (*hashObj->update)(hashcx, (unsigned char *) ibuf, nb); } (*hashObj->end)(hashcx, (unsigned char *) digestdata, &len, 32); (*hashObj->destroy)(hashcx, PR_TRUE); digest.data = (unsigned char *) digestdata; digest.len = len; cinfo = SEC_PKCS7CreateSignedData (cert, certUsageObjectSigner, NULL, SEC_OID_SHA1, &digest, NULL, NULL); if (cinfo == NULL) return - 1; rv = SEC_PKCS7IncludeCertChain (cinfo, NULL); if (rv != SECSuccess) { SEC_PKCS7DestroyContentInfo (cinfo); return - 1; } if (no_time == 0) { rv = SEC_PKCS7AddSigningTime (cinfo); if (rv != SECSuccess) { /* don't check error */ } } rv = SEC_PKCS7Encode(cinfo, SignOut, outFile, NULL, NULL, &pwdata); SEC_PKCS7DestroyContentInfo (cinfo); if (rv != SECSuccess) return - 1; return 0; }