unsigned int XENCAlgorithmHandlerDefault::doRSADecryptToSafeBuffer()

in xsec/xenc/impl/XENCAlgorithmHandlerDefault.cpp [657:760]


unsigned int XENCAlgorithmHandlerDefault::doRSADecryptToSafeBuffer(
        TXFMChain* cipherText,
        XENCEncryptionMethod* encryptionMethod,
        const XSECCryptoKey* key,
        DOMDocument* doc,
        safeBuffer& result) const {

    // Only works with RSA_PRIVATE or PAIR
    if (key->getKeyType() == XSECCryptoKey::KEY_RSA_PUBLIC) {
        throw XSECException(XSECException::CipherError,
            "XENCAlgorithmHandlerDefault - RSA Decrypt must use private key");
    }

    // Know this is an RSA key, so just cast

    XSECCryptoKeyRSA* rsa = (XSECCryptoKeyRSA*) key;

    // Allocate an output buffer
    unsigned char* decBuf;
    XSECnew(decBuf, unsigned char[rsa->getLength()]);
    ArrayJanitor<unsigned char> j_decBuf(decBuf);

    // Input
    TXFMBase* b = cipherText->getLastTxfm();
    safeBuffer cipherSB;
    XMLByte buf[1024];
    unsigned int offset = 0;

    unsigned int bytesRead = (unsigned int) b->readBytes(buf, 1024);
    while (bytesRead > 0) {
        cipherSB.sbMemcpyIn(offset, buf, bytesRead);
        offset += bytesRead;
        bytesRead = (unsigned int) b->readBytes(buf, 1024);
    }

    unsigned int decryptLen;

    // Now we find out what kind of padding
    if (strEquals(encryptionMethod->getAlgorithm(), DSIGConstants::s_unicodeStrURIRSA_1_5)) {

        // Do decrypt
        decryptLen = rsa->privateDecrypt(cipherSB.rawBuffer(),
                                                  decBuf,
                                                  offset,
                                                  rsa->getLength(),
                                                  XSECCryptoKeyRSA::PAD_PKCS_1_5);
    }
    else if (strEquals(encryptionMethod->getAlgorithm(), DSIGConstants::s_unicodeStrURIRSA_OAEP_MGFP1) ||
             strEquals(encryptionMethod->getAlgorithm(), DSIGConstants::s_unicodeStrURIRSA_OAEP)) {

        const XMLCh* digmeth = encryptionMethod->getDigestMethod();
        if (!digmeth|| !*digmeth) {
            digmeth = DSIGConstants::s_unicodeStrURISHA1;
        }

        const XMLCh* mgfalg = encryptionMethod->getMGF();
        if (!mgfalg || !*mgfalg) {
            mgfalg = DSIGConstants::s_unicodeStrURIMGF1_SHA1;
        }

        // Read out any OAEP params
        unsigned char* oaepParamsBuf = NULL;
        unsigned int oaepParamsLen = 0;

        const XMLCh* oaepParams = encryptionMethod->getOAEPparams();
        if (oaepParams != NULL) {
            XSECAutoPtrChar oaepParamsStr(oaepParams);

            unsigned int bufLen = (unsigned int) strlen(oaepParamsStr.get());
            oaepParamsBuf = new unsigned char[bufLen];

            XSECCryptoBase64* b64 = XSECPlatformUtils::g_cryptoProvider->base64();
            Janitor<XSECCryptoBase64> j_b64(b64);

            b64->decodeInit();
            oaepParamsLen = b64->decode((unsigned char*) oaepParamsStr.get(), bufLen, oaepParamsBuf, bufLen);
            oaepParamsLen += b64->decodeFinish(&oaepParamsBuf[oaepParamsLen], bufLen - oaepParamsLen);
        }

        ArrayJanitor<unsigned char> j_oaepParamsBuf(oaepParamsBuf);

        decryptLen = rsa->privateDecrypt(cipherSB.rawBuffer(),
                                                  decBuf,
                                                  offset,
                                                  rsa->getLength(),
                                                  XSECCryptoKeyRSA::PAD_OAEP,
                                                  digmeth,
                                                  mgfalg,
                                                  oaepParamsBuf,
                                                  oaepParamsLen);

    }

    else {
        throw XSECException(XSECException::CipherError,
            "XENCAlgorithmHandlerDefault::doRSADecryptToSafeBuffer - Unknown padding type");
    }
    // Copy to output
    result.sbMemcpyIn(decBuf, decryptLen);

    memset(decBuf, 0, decryptLen);

    return decryptLen;
}