unsigned int NSSCryptoKeyRSA::signSHA1PKCS1Base64Signature()

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;
}