https://bugs.internet2.edu/jira/browse/SSPCPP-249
authorcantor <cantor@de75baf8-a10c-0410-a50a-987c0e22f00f>
Mon, 2 Nov 2009 19:59:39 +0000 (19:59 +0000)
committercantor <cantor@de75baf8-a10c-0410-a50a-987c0e22f00f>
Mon, 2 Nov 2009 19:59:39 +0000 (19:59 +0000)
git-svn-id: https://svn.middleware.georgetown.edu/cpp-xmltooling/branches/REL_1@670 de75baf8-a10c-0410-a50a-987c0e22f00f

xmltooling/security/SecurityHelper.h
xmltooling/security/impl/SecurityHelper.cpp

index babf720..54faf54 100644 (file)
@@ -133,6 +133,16 @@ namespace xmltooling {
         static bool matches(const XSECCryptoKey& key1, const XSECCryptoKey& key2);
 
         /**
+         * Performs a hash operation over the supplied data and returns a hex-encoded string.
+         *
+         * @param hashAlg   name of hash algorithm, syntax specific to crypto provider
+         * @param buf       input data to hash
+         * @param buflen    length of input data
+         * @return  hex-encoded result of hash operation, or an empty string
+         */
+        static std::string doHash(const char* hashAlg, const char* buf, unsigned long buflen);
+
+        /**
          * Returns the base64-encoded DER encoding of a public key in SubjectPublicKeyInfo format.
          * <p>If a hash algorithm is provided, the data is digested before being base64-encoded.
          *
index 69acde6..91bc3b4 100644 (file)
@@ -484,6 +484,40 @@ bool SecurityHelper::matches(const XSECCryptoKey& key1, const XSECCryptoKey& key
     return false;
 }
 
+string SecurityHelper::doHash(const char* hashAlg, const char* buf, unsigned long buflen)
+{
+    static char DIGITS[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+    string ret;
+
+    const EVP_MD* md = EVP_get_digestbyname(hashAlg);
+    if (!md) {
+        Category::getInstance(XMLTOOLING_LOGCAT".SecurityHelper").error("hash algorithm (%s) not available", hashAlg);
+        return ret;
+    }
+
+    BIO* chain = BIO_new(BIO_s_mem());
+    BIO* b = BIO_new(BIO_f_md());
+    BIO_set_md(b, md);
+    chain = BIO_push(b, chain);
+    BIO_write(chain, buf, buflen);
+    BIO_flush(chain);
+
+    char digest[EVP_MAX_MD_SIZE];
+    int len = BIO_gets(chain, digest, EVP_MD_size(md));
+    BIO_free_all(chain);
+    if (len != EVP_MD_size(md)) {
+        Category::getInstance(XMLTOOLING_LOGCAT".SecurityHelper").error(
+            "hash result length (%d) did not match expected value (%d)", len, EVP_MD_size(md)
+            );
+        return ret;
+    }
+    for (unsigned int i=0; i < len; ++i) {
+        ret+=(DIGITS[((unsigned char)(0xF0 & digest[i])) >> 4 ]);
+        ret+=(DIGITS[0x0F & digest[i]]);
+    }
+    return ret;
+}
+
 string SecurityHelper::getDEREncoding(const XSECCryptoKey& key, const char* hash, bool nowrap)
 {
     string ret;