]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Add support MD5/SHA1/SHA256/SHA384/SHA512 on Windows.
authorMichihiro NAKAJIMA <ggcueroad@gmail.com>
Mon, 2 Feb 2009 12:18:15 +0000 (07:18 -0500)
committerMichihiro NAKAJIMA <ggcueroad@gmail.com>
Mon, 2 Feb 2009 12:18:15 +0000 (07:18 -0500)
It use CryptoAPI. Unfortunately, SHA256 nor SHA384 nor
SHA512 are not supported on Windows XP and Windows 2000,
and therefore I haven't tested those functions yet.

SVN-Revision: 535

libarchive/archive_windows.c
libarchive/archive_windows.h

index 47e720ca4822d7cebccfb2db34dfcf9abf1c5a91..c91ebdfeea5afc5993ac92ea324ac7cb7364dca7 100644 (file)
@@ -918,4 +918,103 @@ la_write(int fd, const void *buf, size_t nbytes)
        return (bytes_written);
 }
 
+#if !defined(HAVE_OPENSSL_MD5_H) && !defined(HAVE_OPENSSL_SHA_H)
+/*
+ * Message digest functions.
+ */
+static void
+Digest_Init(Digest_CTX *ctx, ALG_ID algId)
+{
+
+       ctx->valid = 0;
+       if (!CryptAcquireContext(&ctx->cryptProv, NULL, NULL,
+           PROV_RSA_FULL, 0)) {
+               if (GetLastError() != NTE_BAD_KEYSET)
+                       return;
+               if (!CryptAcquireContext(&ctx->cryptProv, NULL, NULL,
+                   PROV_RSA_FULL, CRYPT_NEWKEYSET))
+                       return;
+       }
+
+       if (!CryptCreateHash(ctx->cryptProv, algId, 0, 0, &ctx->hash)) {
+               CryptReleaseContext(ctx->cryptProv, 0);
+               return;
+       }
+
+       ctx->valid = 1;
+}
+
+static void
+Digest_Update(Digest_CTX *ctx, const unsigned char *buf, size_t len)
+{
+
+       if (!ctx->valid)
+       return;
+
+       CryptHashData(ctx->hash, buf, (DWORD)len, 0);
+}
+
+static void
+Digest_Final(unsigned char *buf, int bufsize, Digest_CTX *ctx)
+{
+       DWORD siglen = bufsize;
+
+       if (!ctx->valid)
+               return;
+
+       CryptGetHashParam(ctx->hash, HP_HASHVAL, buf, &siglen, 0);
+       CryptDestroyHash(ctx->hash);
+       CryptReleaseContext(ctx->cryptProv, 0);
+       ctx->valid = 0;
+}
+
+#define DIGEST_INIT(name, algid) \
+void name ## _Init(Digest_CTX *ctx)\
+{\
+       Digest_Init(ctx, algid);\
+}
+
+#define DIGEST_UPDATE(name) \
+void name ## _Update(Digest_CTX *ctx, const unsigned char *buf, size_t len)\
+{\
+       Digest_Update(ctx, buf, len);\
+}
+
+#define DIGEST_FINAL(name, size) \
+void name ## _Final(unsigned char buf[size], Digest_CTX *ctx)\
+{\
+       Digest_Final(buf, size, ctx);\
+}
+
+DIGEST_INIT(MD5, CALG_MD5)
+DIGEST_UPDATE(MD5)
+DIGEST_FINAL(MD5, MD5_DIGEST_LENGTH)
+
+DIGEST_INIT(SHA1, CALG_SHA1)
+DIGEST_UPDATE(SHA1)
+DIGEST_FINAL(SHA1, SHA1_DIGEST_LENGTH)
+
+/*
+ * SHA256 nor SHA384 nor SHA512 are not supported on Windows XP and Windows 2000.
+ */
+#ifdef CALG_SHA256
+DIGEST_INIT(SHA256, CALG_SHA256)
+DIGEST_UPDATE(SHA256)
+DIGEST_FINAL(SHA256, SHA256_DIGEST_LENGTH)
+#endif
+
+#ifdef CALG_SHA384
+DIGEST_INIT(SHA384, CALG_SHA384)
+DIGEST_UPDATE(SHA384)
+DIGEST_FINAL(SHA384, SHA384_DIGEST_LENGTH)
+#endif
+
+#ifdef CALG_SHA512
+DIGEST_INIT(SHA512, CALG_SHA512)
+DIGEST_UPDATE(SHA512)
+DIGEST_FINAL(SHA512, SHA384_DIGEST_LENGTH)
+#endif
+
+#endif /* !HAVE_OPENSSL_MD5_H && !HAVE_OPENSSL_SHA_H */
+
 #endif /* _WIN32 */
index 956d1dde362dab097887ac7ca78978db9b29e277..02455d91ccc56506905460657cc67c7defdf5b4f 100644 (file)
@@ -1,4 +1,5 @@
 /*-
+ * Copyright (c) 2009 Michihiro NAKAJIMA
  * Copyright (c) 2003-2006 Tim Kientzle
  * All rights reserved.
  *
@@ -39,7 +40,7 @@
 #include <sys/stat.h>
 #include <process.h>
 #include <direct.h>
-
+#include <windows.h>
 //#define      EFTYPE 7
 
 #if !defined(STDIN_FILENO)
@@ -252,6 +253,43 @@ struct _timeval64i32 {
 
 #define SYSTEM_PATH_CHAR       '\\'
 
+/* Message digest define */
+#if !defined(HAVE_OPENSSL_MD5_H) && !defined(HAVE_OPENSSL_SHA_H)
+typedef struct {
+       int             valid;
+       HCRYPTPROV cryptProv;
+       HCRYPTHASH hash;
+} Digest_CTX;
+#endif
+
+#if !defined(HAVE_OPENSSL_MD5_H) && defined(CALG_MD5)
+#define MD5_DIGEST_LENGTH      16
+#define HAVE_MD5 1
+#define MD5_CTX Digest_CTX
+#endif
+#ifndef HAVE_OPENSSL_SHA_H
+#ifdef CALG_SHA1
+#define SHA1_DIGEST_LENGTH     20
+#define HAVE_SHA1 1
+#define SHA1_CTX Digest_CTX
+#endif
+#ifdef CALG_SHA256
+#define SHA256_DIGEST_LENGTH   32
+#define HAVE_SHA256 1
+#define SHA256_CTX Digest_CTX
+#endif
+#ifdef CALG_SHA384
+#define SHA384_DIGEST_LENGTH   48
+#define HAVE_SHA384 1
+#define SHA384_CTX Digest_CTX
+#endif
+#ifdef CALG_SHA512
+#define SHA512_DIGEST_LENGTH   64
+#define HAVE_SHA512 1
+#define SHA512_CTX Digest_CTX
+#endif
+#endif /* HAVE_OPENSSL_SHA_H */
+
 /* End of Win32 definitions. */
 
 #ifdef __cplusplus
@@ -285,6 +323,45 @@ extern ssize_t      la_write(int fd, const void *buf, size_t nbytes);
 /* Convertion a Win32 API error code */
 extern int _dosmaperr(unsigned long);
 
+/* Message digest function */
+#if !defined(HAVE_OPENSSL_MD5_H) && !defined(HAVE_OPENSSL_SHA_H)
+#ifdef MD5_DIGEST_LENGTH
+extern void     MD5_Init(Digest_CTX *ctx);
+extern void     MD5_Update(Digest_CTX *ctx, const unsigned char *buf,
+                    size_t len);
+extern void     MD5_Final(unsigned char buf[MD5_DIGEST_LENGTH],
+                    Digest_CTX *ctx);
+#endif
+#ifdef SHA1_DIGEST_LENGTH
+extern void     SHA1_Init(Digest_CTX *ctx);
+extern void     SHA1_Update(Digest_CTX *ctx, const unsigned char *buf,
+                    size_t len);
+extern void     SHA1_Final(unsigned char buf[SHA1_DIGEST_LENGTH],
+                    Digest_CTX *ctx);
+#endif
+#ifdef SHA256_DIGEST_LENGTH
+extern void     SHA256_Init(Digest_CTX *ctx);
+extern void     SHA256_Update(Digest_CTX *ctx, const unsigned char *buf,
+                    size_t len);
+extern void     SHA256_Final(unsigned char buf[SHA256_DIGEST_LENGTH],
+                    Digest_CTX *ctx);
+#endif
+#ifdef SHA384_DIGEST_LENGTH
+extern void     SHA384_Init(Digest_CTX *ctx);
+extern void     SHA384_Update(Digest_CTX *ctx, const unsigned char *buf,
+                    size_t len);
+extern void     SHA384_Final(unsigned char buf[SHA384_DIGEST_LENGTH],
+                    Digest_CTX *ctx);
+#endif
+#ifdef SHA512_DIGEST_LENGTH
+extern void     SHA512_Init(Digest_CTX *ctx);
+extern void     SHA512_Update(Digest_CTX *ctx, const unsigned char *buf,
+                    size_t len);
+extern void     SHA512_Final(unsigned char buf[SHA512_DIGEST_LENGTH],
+                    Digest_CTX *ctx);
+#endif
+#endif
+
 #ifdef __cplusplus
 }
 #endif