void unitTestLongSHA()

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

}