in xsec/dsig/DSIGAlgorithmHandlerDefault.cpp [262:411]
unsigned int DSIGAlgorithmHandlerDefault::signToSafeBuffer(
TXFMChain* inputBytes,
const XMLCh* URI,
const XSECCryptoKey* key,
unsigned int outputLength,
safeBuffer& result) const {
XSECCryptoHash::HashType hashType;
// Map to internal constants
if (!XSECAlgorithmSupport::evalSignatureMethod(URI, key, hashType)) {
safeBuffer sb;
sb.sbTranscodeIn("DSIGAlgorithmHandlerDefault - Unknown or key-incompatible URI : ");
sb.sbXMLChCat(URI);
throw XSECException(XSECException::AlgorithmMapperError,
sb.rawXMLChBuffer());
}
// Now append the appropriate hash transform onto the end of the chain
// If this is an HMAC of some kind - this function will add the appropriate key
TXFMBase * htxfm = addHashTxfm(
hashType,
(key->getKeyType() == XSECCryptoKey::KEY_HMAC ? key : NULL),
inputBytes->getLastTxfm()->getDocument());
inputBytes->appendTxfm(htxfm);
unsigned char hash[4096];
int hashLen = inputBytes->getLastTxfm()->readBytes((XMLByte *) hash, 4096);
// Now check the calculated hash
// For now, use a fixed length buffer, but expand it,
// and detect if the signature size exceeds what we can
// handle.
char b64Buf[MAXB64BUFSIZE];
unsigned int b64Len;
safeBuffer b64SB;
switch (key->getKeyType()) {
case (XSECCryptoKey::KEY_DSA_PRIVATE) :
case (XSECCryptoKey::KEY_DSA_PAIR) :
b64Len = ((XSECCryptoKeyDSA *) key)->signBase64Signature(
hash,
hashLen,
(char *) b64Buf,
MAXB64BUFSIZE);
if (b64Len <= 0) {
throw XSECException(XSECException::AlgorithmMapperError,
"Unknown error occurred during a DSA Signing operation");
}
else if (b64Len >= MAXB64BUFSIZE) {
throw XSECException(XSECException::AlgorithmMapperError,
"DSA Signing operation exceeded size of buffer");
}
if (b64Buf[b64Len-1] == '\n')
b64Buf[b64Len-1] = '\0';
else
b64Buf[b64Len] = '\0';
break;
case (XSECCryptoKey::KEY_RSA_PRIVATE) :
case (XSECCryptoKey::KEY_RSA_PAIR) :
b64Len = ((XSECCryptoKeyRSA *) key)->signSHA1PKCS1Base64Signature(
hash,
hashLen,
(char *) b64Buf,
MAXB64BUFSIZE,
hashType);
if (b64Len <= 0) {
throw XSECException(XSECException::AlgorithmMapperError,
"Unknown error occurred during a RSA Signing operation");
}
else if (b64Len >= MAXB64BUFSIZE) {
throw XSECException(XSECException::AlgorithmMapperError,
"RSA Signing operation exceeded size of buffer");
}
// Clean up some "funnies" and make sure the string is NULL terminated
if (b64Buf[b64Len-1] == '\n')
b64Buf[b64Len-1] = '\0';
else
b64Buf[b64Len] = '\0';
break;
case (XSECCryptoKey::KEY_EC_PRIVATE) :
case (XSECCryptoKey::KEY_EC_PAIR) :
b64Len = ((XSECCryptoKeyEC *) key)->signBase64SignatureDSA(
hash,
hashLen,
(char *) b64Buf,
MAXB64BUFSIZE);
if (b64Len <= 0) {
throw XSECException(XSECException::AlgorithmMapperError,
"Unknown error occurred during an ECDSA Signing operation");
}
else if (b64Len >= MAXB64BUFSIZE) {
throw XSECException(XSECException::AlgorithmMapperError,
"ECDSA Signing operation exceeded size of buffer");
}
if (b64Buf[b64Len-1] == '\n')
b64Buf[b64Len-1] = '\0';
else
b64Buf[b64Len] = '\0';
break;
case (XSECCryptoKey::KEY_HMAC) :
// Signature already created, so just translate to base 64 and enter string
// FIX: CVE-2009-0217
if (outputLength > 0 && (outputLength > (unsigned int)hashLen || outputLength < 80 || outputLength < (unsigned int)hashLen / 2)) {
throw XSECException(XSECException::AlgorithmMapperError,
"HMACOutputLength set to unsafe value.");
}
convertRawToBase64String(b64SB,
hash,
hashLen,
outputLength);
strncpy(b64Buf, (char *) b64SB.rawBuffer(), MAXB64BUFSIZE);
break;
default :
throw XSECException(XSECException::AlgorithmMapperError,
"Key found, but don't know how to sign the document using it");
}
result = b64Buf;
return (unsigned int) strlen(b64Buf);
}