in xsec/xenc/impl/XENCAlgorithmHandlerDefault.cpp [859:971]
bool XENCAlgorithmHandlerDefault::doRSAEncryptToSafeBuffer(
TXFMChain* plainText,
XENCEncryptionMethod* encryptionMethod,
const XSECCryptoKey* key,
XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument* doc,
safeBuffer& result
) const {
// Only works with RSA_PRIVATE or PAIR
if (key->getKeyType() == XSECCryptoKey::KEY_RSA_PRIVATE) {
throw XSECException(XSECException::CipherError,
"XENCAlgorithmHandlerDefault - RSA Encrypt must use public key");
}
XSECCryptoKeyRSA* rsa = (XSECCryptoKeyRSA*) key;
// Allocate an output buffer
unsigned char* encBuf;
XSECnew(encBuf, unsigned char[rsa->getLength()]);
ArrayJanitor<unsigned char> j_encBuf(encBuf);
// Input
TXFMBase* b = plainText->getLastTxfm();
safeBuffer plainSB;
plainSB.isSensitive();
XMLByte buf[1024];
unsigned int offset = 0;
unsigned int bytesRead = (unsigned int) b->readBytes(buf, 1024);
while (bytesRead > 0) {
plainSB.sbMemcpyIn(offset, buf, bytesRead);
offset += bytesRead;
bytesRead = (unsigned int) b->readBytes(buf, 1024);
}
unsigned int encryptLen;
// Do encrypt
if (strEquals(encryptionMethod->getAlgorithm(), DSIGConstants::s_unicodeStrURIRSA_1_5)) {
encryptLen = rsa->publicEncrypt(plainSB.rawBuffer(),
encBuf,
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);
encryptLen = rsa->publicEncrypt(plainSB.rawBuffer(),
encBuf,
offset,
rsa->getLength(),
XSECCryptoKeyRSA::PAD_OAEP,
digmeth,
mgfalg,
oaepParamsBuf,
oaepParamsLen);
}
else {
throw XSECException(XSECException::CipherError,
"XENCAlgorithmHandlerDefault::doRSAEncryptToSafeBuffer - Unknown padding type");
}
// Now need to base64 encode
XSECCryptoBase64* b64 =
XSECPlatformUtils::g_cryptoProvider->base64();
Janitor<XSECCryptoBase64> j_b64(b64);
b64->encodeInit();
encryptLen = b64->encode(encBuf, encryptLen, buf, 1024);
result.sbMemcpyIn(buf, encryptLen);
unsigned int finalLen = b64->encodeFinish(buf, 1024);
result.sbMemcpyIn(encryptLen, buf, finalLen);
result[encryptLen + finalLen] = '\0';
// This is a string, so set the buffer correctly
result.setBufferType(safeBuffer::BUFFER_CHAR);
return true;
}