in xsec/tools/xtest/xtest.cpp [787:977]
void unitTestLongSHA(DOMImplementation * impl) {
// This tests an enveloping signature as the root node, using SHA224/256/384/512
cerr << "Creating long SHA references using HMAC... ";
try {
// Create a document
DOMDocument * doc = impl->createDocument();
// Create the signature
XSECProvider prov;
DSIGSignature *sig;
DOMElement *sigNode;
DSIGReference *ref[4];
sig = prov.newSignature();
sig->setDSIGNSPrefix(MAKE_UNICODE_STRING("ds"));
sig->setPrettyPrint(true);
sigNode = sig->createBlankSignature(doc,
DSIGConstants::s_unicodeStrURIEXC_C14N_COM,
DSIGConstants::s_unicodeStrURIHMAC_SHA512);
doc->appendChild(sigNode);
// Add an object
DSIGObject * obj = sig->appendObject();
obj->setId(MAKE_UNICODE_STRING("ObjectId"));
// Create a text node
DOMText * txt= doc->createTextNode(MAKE_UNICODE_STRING("A test string"));
obj->appendChild(txt);
// Add a Reference
if (XSECPlatformUtils::g_cryptoProvider->algorithmSupported(XSECCryptoHash::HASH_SHA224)) {
cerr << "224 ... ";
ref[0] = sig->createReference(MAKE_UNICODE_STRING("#ObjectId"),
DSIGConstants::s_unicodeStrURISHA224);
}
else {
ref[0] = NULL;
}
if (XSECPlatformUtils::g_cryptoProvider->algorithmSupported(XSECCryptoHash::HASH_SHA256)) {
cerr << "256 ... ";
ref[1] = sig->createReference(MAKE_UNICODE_STRING("#ObjectId"),
DSIGConstants::s_unicodeStrURISHA256);
}
else {
ref[1] = NULL;
}
if (XSECPlatformUtils::g_cryptoProvider->algorithmSupported(XSECCryptoHash::HASH_SHA384)) {
cerr << "384 ... ";
ref[2] = sig->createReference(MAKE_UNICODE_STRING("#ObjectId"),
DSIGConstants::s_unicodeStrURISHA384);
}
else {
ref[2] = NULL;
}
if (XSECPlatformUtils::g_cryptoProvider->algorithmSupported(XSECCryptoHash::HASH_SHA512)) {
cerr << "512 ... ";
ref[3] = sig->createReference(MAKE_UNICODE_STRING("#ObjectId"),
DSIGConstants::s_unicodeStrURISHA512);
}
else {
ref[3] = NULL;
}
// Get a key
cerr << "signing ... ";
sig->setSigningKey(createHMACKey((unsigned char *) "secret"));
sig->sign();
cerr << "validating ... ";
if (!sig->verify()) {
cerr << "bad verify!" << endl;
exit(1);
}
cerr << "OK ... serialise and re-verify ... ";
if (!reValidateSig(impl, doc, createHMACKey((unsigned char *) "secret"))) {
cerr << "bad verify!" << endl;
exit(1);
}
cerr << "OK ... ";
// Now set to bad
txt->setNodeValue(MAKE_UNICODE_STRING("A bad string"));
cerr << "verify bad data ... ";
if (sig->verify()) {
cerr << "bad - should have failed!" << endl;
exit(1);
}
cerr << "OK (verify false) ... serialize and re-verify ... ";
if (reValidateSig(impl, doc, createHMACKey((unsigned char *) "secret"))) {
cerr << "bad - should have failed" << endl;
exit(1);
}
cerr << "OK" << endl;
// Reset to OK
txt->setNodeValue(MAKE_UNICODE_STRING("A test string"));
// Now check the references
cerr << " Checking reference values against known good" << endl;
unsigned char buf[128];
int len;
const char * shastrings[] = {
"SHA224",
"SHA256",
"SHA384",
"SHA512"
};
/*
* Validate the reference hash values from known good
*/
int i;
for (i = 0; i < 4; ++i) {
if (ref[i] == NULL) {
continue;
}
cerr << " Calculating hash for reference " << shastrings[i] << " ... ";
len = (int) ref[i]->calculateHash(buf, 128);
cerr << " Done\n Checking -> ";
if (len < 20) {
cerr << "Bad (Length = " << len << ")" << endl;
exit (1);
}
for (int j = 0; j < len; ++j) {
if (buf[j] != longShaRefs[i][j]) {
cerr << "Bad at location " << j << endl;
for (j = 0; j < len; ++j) {
fprintf(stderr, "0x%02x, ", buf[j]);
}
exit (1);
}
}
cerr << "Good.\n";
}
outputDoc(impl, doc);
doc->release();
}
catch (const XSECException &e)
{
cerr << "An error occurred during signature processing\n Message: ";
char * ce = XMLString::transcode(e.getMsg());
cerr << ce << endl;
delete ce;
exit(1);
}
catch (const XSECCryptoException &e)
{
cerr << "A cryptographic error occurred during signature processing\n Message: "
<< e.getMsg() << endl;
exit(1);
}
}