aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKamil Dudka <kdudka@redhat.com>2012-10-30 14:59:48 +0100
committerKamil Dudka <kdudka@redhat.com>2012-11-09 10:42:54 +0100
commit49c37e6c1c11962102edb44ef36bce4b1b21af53 (patch)
treef2a88265e2414c9e13540f303f8fdf4870d63d20 /src
parentdca8ae5f02a849b0d64befc2023876439396adee (diff)
tool_metalink: allow to use hash algorithms provided by NSS
Fixes bug #3578163: http://sourceforge.net/tracker/?func=detail&atid=100976&aid=3578163&group_id=976
Diffstat (limited to 'src')
-rw-r--r--src/tool_metalink.c104
1 files changed, 104 insertions, 0 deletions
diff --git a/src/tool_metalink.c b/src/tool_metalink.c
index 6cec8d543..bf4bd107f 100644
--- a/src/tool_metalink.c
+++ b/src/tool_metalink.c
@@ -52,6 +52,15 @@
# define MD5_CTX gcry_md_hd_t
# define SHA_CTX gcry_md_hd_t
# define SHA256_CTX gcry_md_hd_t
+#elif defined(USE_NSS)
+# include <nss.h>
+# include <pk11pub.h>
+# define MD5_CTX void *
+# define SHA_CTX void *
+# define SHA256_CTX void *
+# ifdef HAVE_NSS_INITCONTEXT
+ static NSSInitContext *nss_context;
+# endif
#elif defined(__MAC_10_4) || defined(__IPHONE_5_0)
/* For Apple operating systems: CommonCrypto has the functions we need.
The library's headers are even backward-compatible with OpenSSL's
@@ -225,6 +234,95 @@ static void SHA256_Final(unsigned char digest[32], SHA256_CTX *ctx)
gcry_md_close(*ctx);
}
+#elif defined(USE_NSS)
+
+static int nss_hash_init(void **pctx, SECOidTag hash_alg)
+{
+ PK11Context *ctx;
+
+ /* we have to initialize NSS if not initialized alraedy */
+#ifdef HAVE_NSS_INITCONTEXT
+ if(!NSS_IsInitialized() && !nss_context) {
+ static NSSInitParameters params;
+ params.length = sizeof params;
+ nss_context = NSS_InitContext("", "", "", "", &params, NSS_INIT_READONLY
+ | NSS_INIT_NOCERTDB | NSS_INIT_NOMODDB | NSS_INIT_FORCEOPEN
+ | NSS_INIT_NOROOTINIT | NSS_INIT_OPTIMIZESPACE | NSS_INIT_PK11RELOAD);
+ }
+#endif
+
+ ctx = PK11_CreateDigestContext(hash_alg);
+ if(!ctx)
+ return -1;
+
+ if(PK11_DigestBegin(ctx) != SECSuccess) {
+ PK11_DestroyContext(ctx, PR_TRUE);
+ return -1;
+ }
+
+ *pctx = ctx;
+ return 0;
+}
+
+static void nss_hash_final(void **pctx, unsigned char *out, unsigned int len)
+{
+ PK11Context *ctx = *pctx;
+ unsigned int outlen;
+ PK11_DigestFinal(ctx, out, &outlen, len);
+ PK11_DestroyContext(ctx, PR_TRUE);
+}
+
+static int MD5_Init(MD5_CTX *pctx)
+{
+ return nss_hash_init(pctx, SEC_OID_MD5);
+}
+
+static void MD5_Update(MD5_CTX *pctx,
+ const unsigned char *input,
+ unsigned int input_len)
+{
+ PK11_DigestOp(*pctx, input, input_len);
+}
+
+static void MD5_Final(unsigned char digest[16], MD5_CTX *pctx)
+{
+ nss_hash_final(pctx, digest, 16);
+}
+
+static int SHA1_Init(SHA_CTX *pctx)
+{
+ return nss_hash_init(pctx, SEC_OID_SHA1);
+}
+
+static void SHA1_Update(SHA_CTX *pctx,
+ const unsigned char *input,
+ unsigned int input_len)
+{
+ PK11_DigestOp(*pctx, input, input_len);
+}
+
+static void SHA1_Final(unsigned char digest[20], SHA_CTX *pctx)
+{
+ nss_hash_final(pctx, digest, 20);
+}
+
+static int SHA256_Init(SHA256_CTX *pctx)
+{
+ return nss_hash_init(pctx, SEC_OID_SHA256);
+}
+
+static void SHA256_Update(SHA256_CTX *pctx,
+ const unsigned char *input,
+ unsigned int input_len)
+{
+ PK11_DigestOp(*pctx, input, input_len);
+}
+
+static void SHA256_Final(unsigned char digest[32], SHA256_CTX *pctx)
+{
+ nss_hash_final(pctx, digest, 32);
+}
+
#elif defined(_WIN32) && !defined(USE_SSLEAY)
static void win32_crypto_final(struct win32_crypto_hash *ctx,
@@ -797,6 +895,12 @@ void clean_metalink(struct Configurable *config)
void metalink_cleanup(void)
{
+#if defined(USE_NSS) && defined(HAVE_NSS_INITCONTEXT)
+ if(nss_context) {
+ NSS_ShutdownContext(nss_context);
+ nss_context = NULL;
+ }
+#endif
}
#endif /* USE_METALINK */