in xsec/enc/NSS/NSSCryptoKeyRSA.cpp [306:404]
unsigned int NSSCryptoKeyRSA::signSHA1PKCS1Base64Signature(unsigned char * hashBuf,
unsigned int hashLen,
char * base64SignatureBuf,
unsigned int base64SignatureBufLen,
XSECCryptoHash::HashType type) const {
// Sign a pre-calculated hash using this key
if (mp_privkey == 0) {
throw XSECCryptoException(XSECCryptoException::RSAError,
"NSS:RSA - Attempt to sign data using a public or un-loaded key");
}
unsigned char * rawSig;
XSECnew(rawSig, unsigned char[base64SignatureBufLen]);
ArrayJanitor<unsigned char> j_rawSig(rawSig);
SECItem signature;
signature.type = siBuffer;
signature.data = rawSig;
signature.len = base64SignatureBufLen;
SECItem data;
data.data = 0;
SECOidTag hashalg;
PRArenaPool * arena = 0;
SGNDigestInfo *di = 0;
SECItem * res;
switch (type) {
case (XSECCryptoHash::HASH_MD5):
hashalg = SEC_OID_MD5;
break;
case (XSECCryptoHash::HASH_SHA1):
hashalg = SEC_OID_SHA1;
break;
case (XSECCryptoHash::HASH_SHA256):
hashalg = SEC_OID_SHA256;
break;
case (XSECCryptoHash::HASH_SHA384):
hashalg = SEC_OID_SHA384;
break;
case (XSECCryptoHash::HASH_SHA512):
hashalg = SEC_OID_SHA512;
break;
default:
throw XSECCryptoException(XSECCryptoException::RSAError,
"NSS:RSA - Unsupported hash algorithm in RSA sign");
}
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (!arena) {
throw XSECCryptoException(XSECCryptoException::RSAError,
"NSS:RSA - Error creating arena");
}
di = SGN_CreateDigestInfo(hashalg, hashBuf, hashLen);
if (di == NULL) {
PORT_FreeArena(arena, PR_FALSE);
throw XSECCryptoException(XSECCryptoException::RSAError,
"NSS:RSA - Error creating digest info");
}
res = SEC_ASN1EncodeItem(arena, &data, di, NSS_Get_sgn_DigestInfoTemplate(NULL, 0));
if (!res) {
SGN_DestroyDigestInfo(di);
PORT_FreeArena(arena, PR_FALSE);
throw XSECCryptoException(XSECCryptoException::RSAError,
"NSS:RSA - Error encoding digest info for RSA sign");
}
/* data.type = siBuffer;
data.data = hashBuf;
data.len = hashLen;*/
/* As of V1.3.1 - create a DigestInfo block */
SECStatus s = PK11_Sign(mp_privkey, &signature, &data);
SGN_DestroyDigestInfo(di);
PORT_FreeArena(arena, PR_FALSE);
if (s != SECSuccess) {
throw XSECCryptoException(XSECCryptoException::RSAError,
"NSS:RSA - Error during signing operation");
}
// Now encode
XSCryptCryptoBase64 b64;
b64.encodeInit();
unsigned int ret = b64.encode(signature.data, signature.len, (unsigned char *) base64SignatureBuf, base64SignatureBufLen);
ret += b64.encodeFinish((unsigned char *) &base64SignatureBuf[ret], base64SignatureBufLen - ret);
return ret;
}