瀏覽代碼

Update axtls

mingodad 11 年之前
父節點
當前提交
4e69312fca
共有 12 個文件被更改,包括 459 次插入276 次删除
  1. 55 32
      myaxtls/asn1.c
  2. 8 8
      myaxtls/axtls.cbp
  3. 1 1
      myaxtls/bigint.c
  4. 13 14
      myaxtls/crypto.h
  5. 31 26
      myaxtls/crypto_misc.c
  6. 2 1
      myaxtls/crypto_misc.h
  7. 0 162
      myaxtls/md2.c
  8. 31 16
      myaxtls/rsa.c
  9. 294 0
      myaxtls/sha256.c
  10. 9 4
      myaxtls/tls1_svr.c
  11. 1 1
      myaxtls/version.h
  12. 14 11
      myaxtls/x509.c

+ 55 - 32
myaxtls/asn1.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, Cameron Rich
+ * Copyright (c) 2007-2014, Cameron Rich
  * 
  * All rights reserved.
  * 
@@ -40,22 +40,23 @@
 #include "crypto.h"
 #include "crypto_misc.h"
 
-#define SIG_OID_PREFIX_SIZE 8
-#define SIG_IIS6_OID_SIZE   5
-#define SIG_SUBJECT_ALT_NAME_SIZE 3
-
-/* Must be an RSA algorithm with either SHA1 or MD5 for verifying to work */
-static const uint8_t sig_oid_prefix[SIG_OID_PREFIX_SIZE] = 
+/* Must be an RSA algorithm with either SHA1/SHA256/MD5 for verifying to work */
+static const uint8_t sig_oid_prefix[] = 
 {
     0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01
 };
 
-static const uint8_t sig_sha1WithRSAEncrypt[SIG_IIS6_OID_SIZE] =
+static const uint8_t sig_sha1WithRSAEncrypt[] =
 {
     0x2b, 0x0e, 0x03, 0x02, 0x1d
 };
 
-static const uint8_t sig_subject_alt_name[SIG_SUBJECT_ALT_NAME_SIZE] =
+static const uint8_t sig_sha256WithRSAEncrypt[] =
+{
+    0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01
+};
+
+static const uint8_t sig_subject_alt_name[] =
 {
     0x55, 0x1d, 0x11
 };
@@ -63,9 +64,10 @@ static const uint8_t sig_subject_alt_name[SIG_SUBJECT_ALT_NAME_SIZE] =
 /* CN, O, OU */
 static const uint8_t g_dn_types[] = { 3, 10, 11 };
 
-int get_asn1_length(const uint8_t *buf, int *offset)
+uint32_t get_asn1_length(const uint8_t *buf, int *offset)
 {
-    int len, i;
+    int i;
+    uint32_t len;
 
     if (!(buf[*offset] & 0x80)) /* short form */
     {
@@ -74,6 +76,9 @@ int get_asn1_length(const uint8_t *buf, int *offset)
     else  /* long form */
     {
         int length_bytes = buf[(*offset)++]&0x7f;
+        if (length_bytes > 4)   /* limit number of bytes */
+            return 0;
+
         len = 0;
         for (i = 0; i < length_bytes; i++)
         {
@@ -332,27 +337,27 @@ static int asn1_get_printable_str(const uint8_t *buf, int *offset, char **str)
             asn1_type != ASN1_UNICODE_STR)
         goto end_pnt_str;
 
-        (*offset)++;
-        len = get_asn1_length(buf, offset);
+    (*offset)++;
+    len = get_asn1_length(buf, offset);
 
     if (asn1_type == ASN1_UNICODE_STR)
-        {
-            int i;
-            *str = (char *)malloc(len/2+1);     /* allow for null */
+    {
+        int i;
+        *str = (char *)malloc(len/2+1);     /* allow for null */
 
-            for (i = 0; i < len; i += 2)
-                (*str)[i/2] = buf[*offset + i + 1];
+        for (i = 0; i < len; i += 2)
+            (*str)[i/2] = buf[*offset + i + 1];
 
-            (*str)[len/2] = 0;                  /* null terminate */
-        }
-        else
-        {
-            *str = (char *)malloc(len+1);       /* allow for null */
-            memcpy(*str, &buf[*offset], len);
-            (*str)[len] = 0;                    /* null terminate */
-        }
+        (*str)[len/2] = 0;                  /* null terminate */
+    }
+    else
+    {
+        *str = (char *)malloc(len+1);       /* allow for null */
+        memcpy(*str, &buf[*offset], len);
+        (*str)[len] = 0;                    /* null terminate */
+    }
 
-        *offset += len;
+    *offset += len;
 
 end_pnt_str:
     return len;
@@ -553,7 +558,7 @@ int asn1_find_oid(const uint8_t* cert, int* offset,
 int asn1_find_subjectaltname(const uint8_t* cert, int offset)
 {
     if (asn1_find_oid(cert, &offset, sig_subject_alt_name, 
-                                SIG_SUBJECT_ALT_NAME_SIZE))
+                                sizeof(sig_subject_alt_name)))
     {
         return offset;
     }
@@ -577,17 +582,35 @@ int asn1_signature_type(const uint8_t *cert,
 
     len = get_asn1_length(cert, offset);
 
-    if (len == 5 && memcmp(sig_sha1WithRSAEncrypt, &cert[*offset], 
-                                    SIG_IIS6_OID_SIZE) == 0)
+    if (len == sizeof(sig_sha1WithRSAEncrypt) && 
+            memcmp(sig_sha1WithRSAEncrypt, &cert[*offset], 
+                                    sizeof(sig_sha1WithRSAEncrypt)) == 0)
     {
         x509_ctx->sig_type = SIG_TYPE_SHA1;
     }
+    else if (len == sizeof(sig_sha256WithRSAEncrypt) && 
+            memcmp(sig_sha256WithRSAEncrypt, &cert[*offset], 
+                                    sizeof(sig_sha256WithRSAEncrypt)) == 0)
+    {
+        x509_ctx->sig_type = SIG_TYPE_SHA256;
+    }
     else
     {
-        if (memcmp(sig_oid_prefix, &cert[*offset], SIG_OID_PREFIX_SIZE))
+        if (memcmp(sig_oid_prefix, &cert[*offset], sizeof(sig_oid_prefix)))
+        {
+#ifdef CONFIG_SSL_FULL_MODE
+            int i;
+            printf("invalid digest: ");
+
+            for (i = 0; i < len; i++)
+                printf("%02x ", cert[*offset + i]);
+
+            printf("\n");
+#endif
             goto end_check_sig;     /* unrecognised cert type */
+        }
 
-        x509_ctx->sig_type = cert[*offset + SIG_OID_PREFIX_SIZE];
+        x509_ctx->sig_type = cert[*offset + sizeof(sig_oid_prefix)];
     }
 
     *offset += len;

+ 8 - 8
myaxtls/axtls.cbp

@@ -7,7 +7,7 @@
 		<Option compiler="gcc" />
 		<Build>
 			<Target title="Debug">
-				<Option output="libaxtls" prefix_auto="1" extension_auto="1" />
+				<Option output="axtls" prefix_auto="1" extension_auto="1" />
 				<Option working_dir="" />
 				<Option object_output="obj/Debug/" />
 				<Option type="2" />
@@ -18,7 +18,7 @@
 				</Compiler>
 			</Target>
 			<Target title="Release">
-				<Option output="libaxtls" prefix_auto="1" extension_auto="1" />
+				<Option output="axtls" prefix_auto="1" extension_auto="1" />
 				<Option working_dir="" />
 				<Option object_output="obj/Release/" />
 				<Option type="2" />
@@ -32,7 +32,7 @@
 				</Linker>
 			</Target>
 			<Target title="Release-lua-jit">
-				<Option output="libaxtls-lua-jit" prefix_auto="1" extension_auto="1" />
+				<Option output="axtls-lua-jit" prefix_auto="1" extension_auto="1" />
 				<Option working_dir="" />
 				<Option object_output="obj/Release/" />
 				<Option type="2" />
@@ -48,7 +48,7 @@
 				</Linker>
 			</Target>
 			<Target title="Debug-lua-jit">
-				<Option output="libaxtls-lua-jit" prefix_auto="1" extension_auto="1" />
+				<Option output="axtls-lua-jit" prefix_auto="1" extension_auto="1" />
 				<Option working_dir="" />
 				<Option object_output="obj/Debug/" />
 				<Option type="2" />
@@ -61,7 +61,7 @@
 				</Compiler>
 			</Target>
 			<Target title="Release O3">
-				<Option output="libaxtls" prefix_auto="1" extension_auto="1" />
+				<Option output="axtls" prefix_auto="1" extension_auto="1" />
 				<Option working_dir="" />
 				<Option object_output="obj/Release/" />
 				<Option type="2" />
@@ -144,9 +144,6 @@
 		<Unit filename="loader.c">
 			<Option compilerVar="CC" />
 		</Unit>
-		<Unit filename="md2.c">
-			<Option compilerVar="CC" />
-		</Unit>
 		<Unit filename="md5.c">
 			<Option compilerVar="CC" />
 		</Unit>
@@ -171,6 +168,9 @@
 		<Unit filename="sha1.c">
 			<Option compilerVar="CC" />
 		</Unit>
+		<Unit filename="sha256.c">
+			<Option compilerVar="CC" />
+		</Unit>
 		<Unit filename="ssl.h" />
 		<Unit filename="tls1.c">
 			<Option compilerVar="CC" />

+ 1 - 1
myaxtls/bigint.c

@@ -724,9 +724,9 @@ void bi_export(BI_CTX *ctx, bigint *x, uint8_t *data, int size)
             if (k < 0)
             {
                 goto buf_done;
+            }
         }
     }
-    }
 buf_done:
 
     bi_free(ctx, x);

+ 13 - 14
myaxtls/crypto.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, Cameron Rich
+ * Copyright (c) 2007-2014, Cameron Rich
  * 
  * All rights reserved.
  * 
@@ -124,22 +124,21 @@ void SHA1_Update(SHA1_CTX *, const uint8_t * msg, int len);
 void SHA1_Final(uint8_t *digest, SHA1_CTX *);
 
 /**************************************************************************
- * MD2 declarations 
+ * SHA256 declarations 
  **************************************************************************/
 
-#define MD2_SIZE 16
+#define SHA256_SIZE   32
 
 typedef struct
 {
-    unsigned char cksum[16];    /* checksum of the data block */
-    unsigned char state[48];    /* intermediate digest state */
-    unsigned char buffer[16];   /* data block being processed */
-    int left;                   /* amount of data in buffer */
-} MD2_CTX;
+    uint32_t total[2];
+    uint32_t state[8];
+    uint8_t buffer[64];
+} SHA256_CTX;
 
-EXP_FUNC void STDCALL MD2_Init(MD2_CTX *ctx);
-EXP_FUNC void STDCALL MD2_Update(MD2_CTX *ctx, const uint8_t *input, int ilen);
-EXP_FUNC void STDCALL MD2_Final(uint8_t *digest, MD2_CTX *ctx);
+void SHA256_Init(SHA256_CTX *c);
+void SHA256_Update(SHA256_CTX *, const uint8_t *input, int len);
+void SHA256_Final(uint8_t digest[32], SHA256_CTX *);
 
 /**************************************************************************
  * MD5 declarations 
@@ -203,7 +202,7 @@ void RSA_pub_key_new(RSA_CTX **rsa_ctx,
         const uint8_t *pub_exp, int pub_len);
 void RSA_free(RSA_CTX *ctx);
 int RSA_decrypt(const RSA_CTX *ctx, const uint8_t *in_data, uint8_t *out_data,
-        int is_decryption);
+        int out_len, int is_decryption);
 bigint *RSA_private(const RSA_CTX *c, bigint *bi_msg);
 #if defined(CONFIG_SSL_CERT_VERIFICATION) || defined(CONFIG_SSL_GENERATE_X509_CERT)
 bigint *RSA_sign_verify(BI_CTX *ctx, const uint8_t *sig, int sig_len,
@@ -220,8 +219,8 @@ void RSA_print(const RSA_CTX *ctx);
 EXP_FUNC void STDCALL RNG_initialize(void);
 EXP_FUNC void STDCALL RNG_custom_init(const uint8_t *seed_buf, int size);
 EXP_FUNC void STDCALL RNG_terminate(void);
-EXP_FUNC void STDCALL get_random(int num_rand_bytes, uint8_t *rand_data);
-void get_random_NZ(int num_rand_bytes, uint8_t *rand_data);
+EXP_FUNC int STDCALL get_random(int num_rand_bytes, uint8_t *rand_data);
+int get_random_NZ(int num_rand_bytes, uint8_t *rand_data);
 
 #ifdef __cplusplus
 }

+ 31 - 26
myaxtls/crypto_misc.c

@@ -102,27 +102,27 @@ int get_file(const char *filename, uint8_t **buf)
  * - If none of these work then use a custom RNG.
  */
 EXP_FUNC void STDCALL RNG_initialize()
-    {
+{
 #if !defined(WIN32) && defined(CONFIG_USE_DEV_URANDOM)
-        rng_fd = ax_open("/dev/urandom", O_RDONLY);
+    rng_fd = ax_open("/dev/urandom", O_RDONLY);
 #elif defined(WIN32) && defined(CONFIG_WIN32_USE_CRYPTO_LIB)
-        if (!CryptAcquireContext(&gCryptProv, 
-                          NULL, NULL, PROV_RSA_FULL, 0))
+    if (!CryptAcquireContext(&gCryptProv, 
+                      NULL, NULL, PROV_RSA_FULL, 0))
+    {
+        if (GetLastError() == NTE_BAD_KEYSET &&
+                !CryptAcquireContext(&gCryptProv, 
+                       NULL, 
+                       NULL, 
+                       PROV_RSA_FULL, 
+                       CRYPT_NEWKEYSET))
         {
-            if (GetLastError() == NTE_BAD_KEYSET &&
-                    !CryptAcquireContext(&gCryptProv, 
-                           NULL, 
-                           NULL, 
-                           PROV_RSA_FULL, 
-                           CRYPT_NEWKEYSET))
-            {
-                printf("CryptoLib: %x\n", unsupported_str, GetLastError());
-                exit(1);
-            }
+            printf("CryptoLib: %x\n", unsupported_str, GetLastError());
+            exit(1);
         }
-#else   
+    }
+#else
     /* start of with a stack to copy across */
-        int i;
+    int i;
     memcpy(entropy_pool, &i, ENTROPY_POOL_SIZE);
     srand((unsigned int)&i); 
 #endif
@@ -139,7 +139,7 @@ EXP_FUNC void STDCALL RNG_custom_init(const uint8_t *seed_buf, int size)
     for (i = 0; i < ENTROPY_POOL_SIZE && i < size; i++)
         entropy_pool[i] ^= seed_buf[i];
 #endif
-    }
+}
 
 /**
  * Terminate the RNG engine.
@@ -147,20 +147,21 @@ EXP_FUNC void STDCALL RNG_custom_init(const uint8_t *seed_buf, int size)
 EXP_FUNC void STDCALL RNG_terminate(void)
 {
 #ifndef WIN32
-        close(rng_fd);
+    close(rng_fd);
 #elif defined(CONFIG_WIN32_USE_CRYPTO_LIB)
-        CryptReleaseContext(gCryptProv, 0);
+    CryptReleaseContext(gCryptProv, 0);
 #endif
-    }
+}
 
 /**
  * Set a series of bytes with a random number. Individual bytes can be 0
  */
-EXP_FUNC void STDCALL get_random(int num_rand_bytes, uint8_t *rand_data)
+EXP_FUNC int STDCALL get_random(int num_rand_bytes, uint8_t *rand_data)
 {   
 #if !defined(WIN32) && defined(CONFIG_USE_DEV_URANDOM)
-    /* use the Linux default */
-    read(rng_fd, rand_data, num_rand_bytes);    /* read from /dev/urandom */
+    /* use the Linux default - read from /dev/urandom */
+    if (read(rng_fd, rand_data, num_rand_bytes) < 0) 
+        return -1;
 #elif defined(WIN32) && defined(CONFIG_WIN32_USE_CRYPTO_LIB)
     /* use Microsoft Crypto Libraries */
     CryptGenRandom(gCryptProv, num_rand_bytes, rand_data);
@@ -198,21 +199,25 @@ EXP_FUNC void STDCALL get_random(int num_rand_bytes, uint8_t *rand_data)
     /* insert the digest at the start of the entropy pool */
     memcpy(entropy_pool, digest, MD5_SIZE);
 #endif
+    return 0;
 }
 
 /**
  * Set a series of bytes with a random number. Individual bytes are not zero.
  */
-void get_random_NZ(int num_rand_bytes, uint8_t *rand_data)
+int get_random_NZ(int num_rand_bytes, uint8_t *rand_data)
 {
     int i;
-    get_random(num_rand_bytes, rand_data);
+    if (get_random(num_rand_bytes, rand_data))
+        return -1;
 
     for (i = 0; i < num_rand_bytes; i++)
     {
         while (rand_data[i] == 0)  /* can't be 0 */
             rand_data[i] = (uint8_t)(rand());
     }
+
+    return 0;
 }
 
 /**
@@ -351,7 +356,7 @@ EXP_FUNC int STDCALL base64_decode(const char *in, int len,
     if (y != 0)
         goto error;
 
-        *outlen = z;
+    *outlen = z;
     ret = 0;
 
 error:

+ 2 - 1
myaxtls/crypto_misc.h

@@ -127,8 +127,9 @@ const char * x509_display_error(int error);
 #define SIG_TYPE_MD2            0x02
 #define SIG_TYPE_MD5            0x04
 #define SIG_TYPE_SHA1           0x05
+#define SIG_TYPE_SHA256         0x0b
 
-int get_asn1_length(const uint8_t *buf, int *offset);
+uint32_t get_asn1_length(const uint8_t *buf, int *offset);
 int asn1_get_private_key(const uint8_t *buf, int len, RSA_CTX **rsa_ctx);
 int asn1_next_obj(const uint8_t *buf, int *offset, int obj_type);
 int asn1_skip_obj(const uint8_t *buf, int *offset, int obj_type);

+ 0 - 162
myaxtls/md2.c

@@ -1,162 +0,0 @@
-/*
- * Copyright (c) 2007, Cameron Rich
- * 
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice, 
- *   this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, 
- *   this list of conditions and the following disclaimer in the documentation 
- *   and/or other materials provided with the distribution.
- * * Neither the name of the axTLS project nor the names of its contributors 
- *   may be used to endorse or promote products derived from this software 
- *   without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- *  RFC 1115/1319 compliant MD2 implementation
- *  The MD2 algorithm was designed by Ron Rivest in 1989.
- *
- *  http://www.ietf.org/rfc/rfc1115.txt
- *  http://www.ietf.org/rfc/rfc1319.txt
- */
-
-#include <string.h>
-#include <stdio.h>
-#include "os_port.h"
-#include "crypto.h"
-
-/**
- * This code is only here to enable the verification of Verisign root
- * certificates. So only enable it for verification mode.
- */
-#ifdef CONFIG_SSL_CERT_VERIFICATION
-
-static const uint8_t PI_SUBST[256] =
-{
-    0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, 0x3D, 0x36,
-    0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13, 0x62, 0xA7, 0x05, 0xF3,
-    0xC0, 0xC7, 0x73, 0x8C, 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C,
-    0x82, 0xCA, 0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16,
-    0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12, 0xBE, 0x4E,
-    0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49, 0xA0, 0xFB, 0xF5, 0x8E,
-    0xBB, 0x2F, 0xEE, 0x7A, 0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2,
-    0x07, 0x3F, 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21,
-    0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27, 0x35, 0x3E,
-    0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03, 0xFF, 0x19, 0x30, 0xB3,
-    0x48, 0xA5, 0xB5, 0xD1, 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56,
-    0xAA, 0xC6, 0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6,
-    0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1, 0x45, 0x9D,
-    0x70, 0x59, 0x64, 0x71, 0x87, 0x20, 0x86, 0x5B, 0xCF, 0x65,
-    0xE6, 0x2D, 0xA8, 0x02, 0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0,
-    0xB9, 0xF6, 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F,
-    0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A, 0xC3, 0x5C,
-    0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26, 0x2C, 0x53, 0x0D, 0x6E,
-    0x85, 0x28, 0x84, 0x09, 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81,
-    0x4D, 0x52, 0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA,
-    0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A, 0x78, 0x88,
-    0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D, 0xE9, 0xCB, 0xD5, 0xFE,
-    0x3B, 0x00, 0x1D, 0x39, 0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58,
-    0xD0, 0xE4, 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A,
-    0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, 0xDB, 0x99,
-    0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14
-};
-
-/*
- * MD2 context setup
- */
-EXP_FUNC void STDCALL MD2_Init(MD2_CTX *ctx)
-{
-    memset(ctx, 0, sizeof *ctx);
-}
-
-static void md2_process(MD2_CTX *ctx)
-{
-    int i, j;
-    uint8_t t = 0;
-
-    for (i = 0; i < 16; i++)
-    {
-        ctx->state[i + 16] = ctx->buffer[i];
-        ctx->state[i + 32] = ctx->buffer[i] ^ ctx->state[i];
-    }
-
-    for (i = 0; i < 18; i++)
-    {
-        for (j = 0; j < 48; j++)
-            t = (ctx->state[j] ^= PI_SUBST[t]);
-
-        t = (t + i) & 0xFF;
-    }
-
-    t = ctx->cksum[15];
-
-    for (i = 0; i < 16; i++)
-        t = (ctx->cksum[i] ^= PI_SUBST[ctx->buffer[i] ^ t]);
-}
-
-/*
- * MD2 process buffer
- */
-EXP_FUNC void STDCALL MD2_Update(MD2_CTX *ctx, const uint8_t *input, int ilen)
-{
-    int fill;
-
-    while (ilen > 0)
-    {
-        if (ctx->left + ilen > 16)
-            fill = 16 - ctx->left;
-        else
-            fill = ilen;
-
-        memcpy(ctx->buffer + ctx->left, input, fill);
-
-        ctx->left += fill;
-        input += fill;
-        ilen  -= fill;
-
-        if (ctx->left == 16)
-        {
-            ctx->left = 0;
-            md2_process(ctx);
-        }
-    }
-}
-
-/*
- * MD2 final digest
- */
-EXP_FUNC void STDCALL MD2_Final(uint8_t *output, MD2_CTX *ctx)
-{
-    int i;
-    uint8_t x;
-
-    x = (uint8_t)(16 - ctx->left);
-
-    for (i = ctx->left; i < 16; i++)
-        ctx->buffer[i] = x;
-
-    md2_process(ctx);
-
-    memcpy(ctx->buffer, ctx->cksum, 16);
-    md2_process(ctx);
-
-    memcpy(output, ctx->state, 16);
-}
-
-#endif

+ 31 - 16
myaxtls/rsa.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, Cameron Rich
+ * Copyright (c) 2007-2014, Cameron Rich
  * 
  * All rights reserved.
  * 
@@ -134,21 +134,26 @@ void RSA_free(RSA_CTX *rsa_ctx)
 /**
  * @brief Use PKCS1.5 for decryption/verification.
  * @param ctx [in] The context
- * @param in_data [in] The data to encrypt (must be < modulus size-11)
- * @param out_data [out] The encrypted data.
+ * @param in_data [in] The data to decrypt (must be < modulus size-11)
+ * @param out_data [out] The decrypted data.
+ * @param out_len [int] The size of the decrypted buffer in bytes
  * @param is_decryption [in] Decryption or verify operation.
  * @return  The number of bytes that were originally encrypted. -1 on error.
  * @see http://www.rsasecurity.com/rsalabs/node.asp?id=2125
  */
 int RSA_decrypt(const RSA_CTX *ctx, const uint8_t *in_data, 
-                            uint8_t *out_data, int is_decryption)
+                            uint8_t *out_data, int out_len, int is_decryption)
 {
     const int byte_size = ctx->num_octets;
-    int i, size;
+    int i = 0, size;
     bigint *decrypted_bi, *dat_bi;
     uint8_t *block = (uint8_t *)alloca(byte_size);
+    int pad_count = 0;
 
-    memset(out_data, 0, byte_size); /* initialise */
+    if (out_len < byte_size)        /* check output has enough size */
+        return -1;
+
+    memset(out_data, 0, out_len);   /* initialise */
 
     /* decrypt */
     dat_bi = bi_import(ctx->bi_ctx, in_data, byte_size);
@@ -162,28 +167,37 @@ int RSA_decrypt(const RSA_CTX *ctx, const uint8_t *in_data,
     /* convert to a normal block */
     bi_export(ctx->bi_ctx, decrypted_bi, block, byte_size);
 
-    i = 10; /* start at the first possible non-padded byte */
+    if (block[i++] != 0)             /* leading 0? */
+        return -1;
 
 #ifdef CONFIG_SSL_CERT_VERIFICATION
     if (is_decryption == 0) /* PKCS1.5 signing pads with "0xff"s */
     {
-        while (block[i++] == 0xff && i < byte_size);
+        if (block[i++] != 0x01)     /* BT correct? */
+            return -1;
 
-        if (block[i-2] != 0xff)
-            i = byte_size;     /*ensure size is 0 */   
+        while (block[i++] == 0xff && i < byte_size)
+            pad_count++;
     }
     else                    /* PKCS1.5 encryption padding is random */
 #endif
     {
-        while (block[i++] && i < byte_size);
+        if (block[i++] != 0x02)     /* BT correct? */
+            return -1;
+
+        while (block[i++] && i < byte_size)
+            pad_count++;
     }
+
+    /* check separator byte 0x00 - and padding must be 8 or more bytes */
+    if (i == byte_size || pad_count < 8) 
+        return -1;
+
     size = byte_size - i;
 
     /* get only the bit we want */
-    if (size > 0)
-        memcpy(out_data, &block[i], size);
-    
-    return size ? size : -1;
+    memcpy(out_data, &block[i], size);
+    return size;
 }
 
 /**
@@ -249,7 +263,8 @@ int RSA_encrypt(const RSA_CTX *ctx, const uint8_t *in_data, uint16_t in_len,
     else /* randomize the encryption padding with non-zero bytes */   
     {
         out_data[1] = 2;
-        get_random_NZ(num_pads_needed, &out_data[2]);
+        if (get_random_NZ(num_pads_needed, &out_data[2]) < 0)
+            return -1;
     }
 
     out_data[2+num_pads_needed] = 0;

+ 294 - 0
myaxtls/sha256.c

@@ -0,0 +1,294 @@
+/*
+ * Copyright (c) 2014, Cameron Rich
+ * 
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, 
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice, 
+ *   this list of conditions and the following disclaimer in the documentation 
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of the axTLS project nor the names of its contributors 
+ *   may be used to endorse or promote products derived from this software 
+ *   without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ *  FIPS-180-2 compliant SHA-256 implementation
+ *
+ *  Copyright (C) 2001-2003  Christophe Devine
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <string.h>
+#include "os_port.h"
+#include "crypto.h"
+
+#define GET_UINT32(n,b,i)                       \
+{                                               \
+    (n) = ((uint32_t) (b)[(i)    ] << 24)       \
+        | ((uint32_t) (b)[(i) + 1] << 16)       \
+        | ((uint32_t) (b)[(i) + 2] <<  8)       \
+        | ((uint32_t) (b)[(i) + 3]      );      \
+}
+
+#define PUT_UINT32(n,b,i)                       \
+{                                               \
+    (b)[(i)    ] = (uint8_t) ((n) >> 24);       \
+    (b)[(i) + 1] = (uint8_t) ((n) >> 16);       \
+    (b)[(i) + 2] = (uint8_t) ((n) >>  8);       \
+    (b)[(i) + 3] = (uint8_t) ((n)      );       \
+}
+
+static const uint8_t sha256_padding[64] =
+{
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/**
+ * Initialize the SHA256 context 
+ */
+void SHA256_Init(SHA256_CTX *ctx)
+{
+    ctx->total[0] = 0;
+    ctx->total[1] = 0;
+
+    ctx->state[0] = 0x6A09E667;
+    ctx->state[1] = 0xBB67AE85;
+    ctx->state[2] = 0x3C6EF372;
+    ctx->state[3] = 0xA54FF53A;
+    ctx->state[4] = 0x510E527F;
+    ctx->state[5] = 0x9B05688C;
+    ctx->state[6] = 0x1F83D9AB;
+    ctx->state[7] = 0x5BE0CD19;
+}
+
+void SHA256_Process(const uint8_t digest[64], SHA256_CTX *ctx)
+{
+    uint32_t temp1, temp2, W[64];
+    uint32_t A, B, C, D, E, F, G, H;
+
+    GET_UINT32(W[0],  digest,  0);
+    GET_UINT32(W[1],  digest,  4);
+    GET_UINT32(W[2],  digest,  8);
+    GET_UINT32(W[3],  digest, 12);
+    GET_UINT32(W[4],  digest, 16);
+    GET_UINT32(W[5],  digest, 20);
+    GET_UINT32(W[6],  digest, 24);
+    GET_UINT32(W[7],  digest, 28);
+    GET_UINT32(W[8],  digest, 32);
+    GET_UINT32(W[9],  digest, 36);
+    GET_UINT32(W[10], digest, 40);
+    GET_UINT32(W[11], digest, 44);
+    GET_UINT32(W[12], digest, 48);
+    GET_UINT32(W[13], digest, 52);
+    GET_UINT32(W[14], digest, 56);
+    GET_UINT32(W[15], digest, 60);
+
+#define  SHR(x,n) ((x & 0xFFFFFFFF) >> n)
+#define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
+
+#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^  SHR(x, 3))
+#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^  SHR(x,10))
+
+#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
+#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
+
+#define F0(x,y,z) ((x & y) | (z & (x | y)))
+#define F1(x,y,z) (z ^ (x & (y ^ z)))
+
+#define R(t)                                    \
+(                                              \
+    W[t] = S1(W[t -  2]) + W[t -  7] +          \
+           S0(W[t - 15]) + W[t - 16]            \
+)
+
+#define P(a,b,c,d,e,f,g,h,x,K)                  \
+{                                               \
+    temp1 = h + S3(e) + F1(e,f,g) + K + x;      \
+    temp2 = S2(a) + F0(a,b,c);                  \
+    d += temp1; h = temp1 + temp2;              \
+}
+
+    A = ctx->state[0];
+    B = ctx->state[1];
+    C = ctx->state[2];
+    D = ctx->state[3];
+    E = ctx->state[4];
+    F = ctx->state[5];
+    G = ctx->state[6];
+    H = ctx->state[7];
+
+    P(A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98);
+    P(H, A, B, C, D, E, F, G, W[ 1], 0x71374491);
+    P(G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF);
+    P(F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5);
+    P(E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B);
+    P(D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1);
+    P(C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4);
+    P(B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5);
+    P(A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98);
+    P(H, A, B, C, D, E, F, G, W[ 9], 0x12835B01);
+    P(G, H, A, B, C, D, E, F, W[10], 0x243185BE);
+    P(F, G, H, A, B, C, D, E, W[11], 0x550C7DC3);
+    P(E, F, G, H, A, B, C, D, W[12], 0x72BE5D74);
+    P(D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE);
+    P(C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7);
+    P(B, C, D, E, F, G, H, A, W[15], 0xC19BF174);
+    P(A, B, C, D, E, F, G, H, R(16), 0xE49B69C1);
+    P(H, A, B, C, D, E, F, G, R(17), 0xEFBE4786);
+    P(G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6);
+    P(F, G, H, A, B, C, D, E, R(19), 0x240CA1CC);
+    P(E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F);
+    P(D, E, F, G, H, A, B, C, R(21), 0x4A7484AA);
+    P(C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC);
+    P(B, C, D, E, F, G, H, A, R(23), 0x76F988DA);
+    P(A, B, C, D, E, F, G, H, R(24), 0x983E5152);
+    P(H, A, B, C, D, E, F, G, R(25), 0xA831C66D);
+    P(G, H, A, B, C, D, E, F, R(26), 0xB00327C8);
+    P(F, G, H, A, B, C, D, E, R(27), 0xBF597FC7);
+    P(E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3);
+    P(D, E, F, G, H, A, B, C, R(29), 0xD5A79147);
+    P(C, D, E, F, G, H, A, B, R(30), 0x06CA6351);
+    P(B, C, D, E, F, G, H, A, R(31), 0x14292967);
+    P(A, B, C, D, E, F, G, H, R(32), 0x27B70A85);
+    P(H, A, B, C, D, E, F, G, R(33), 0x2E1B2138);
+    P(G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC);
+    P(F, G, H, A, B, C, D, E, R(35), 0x53380D13);
+    P(E, F, G, H, A, B, C, D, R(36), 0x650A7354);
+    P(D, E, F, G, H, A, B, C, R(37), 0x766A0ABB);
+    P(C, D, E, F, G, H, A, B, R(38), 0x81C2C92E);
+    P(B, C, D, E, F, G, H, A, R(39), 0x92722C85);
+    P(A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1);
+    P(H, A, B, C, D, E, F, G, R(41), 0xA81A664B);
+    P(G, H, A, B, C, D, E, F, R(42), 0xC24B8B70);
+    P(F, G, H, A, B, C, D, E, R(43), 0xC76C51A3);
+    P(E, F, G, H, A, B, C, D, R(44), 0xD192E819);
+    P(D, E, F, G, H, A, B, C, R(45), 0xD6990624);
+    P(C, D, E, F, G, H, A, B, R(46), 0xF40E3585);
+    P(B, C, D, E, F, G, H, A, R(47), 0x106AA070);
+    P(A, B, C, D, E, F, G, H, R(48), 0x19A4C116);
+    P(H, A, B, C, D, E, F, G, R(49), 0x1E376C08);
+    P(G, H, A, B, C, D, E, F, R(50), 0x2748774C);
+    P(F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5);
+    P(E, F, G, H, A, B, C, D, R(52), 0x391C0CB3);
+    P(D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A);
+    P(C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F);
+    P(B, C, D, E, F, G, H, A, R(55), 0x682E6FF3);
+    P(A, B, C, D, E, F, G, H, R(56), 0x748F82EE);
+    P(H, A, B, C, D, E, F, G, R(57), 0x78A5636F);
+    P(G, H, A, B, C, D, E, F, R(58), 0x84C87814);
+    P(F, G, H, A, B, C, D, E, R(59), 0x8CC70208);
+    P(E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA);
+    P(D, E, F, G, H, A, B, C, R(61), 0xA4506CEB);
+    P(C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7);
+    P(B, C, D, E, F, G, H, A, R(63), 0xC67178F2);
+
+    ctx->state[0] += A;
+    ctx->state[1] += B;
+    ctx->state[2] += C;
+    ctx->state[3] += D;
+    ctx->state[4] += E;
+    ctx->state[5] += F;
+    ctx->state[6] += G;
+    ctx->state[7] += H;
+}
+
+/**
+ * Accepts an array of octets as the next portion of the message.
+ */
+void SHA256_Update(SHA256_CTX *ctx, const uint8_t * msg, int len)
+{
+    uint32_t left = ctx->total[0] & 0x3F;
+    uint32_t fill = 64 - left;
+
+    ctx->total[0] += len;
+    ctx->total[0] &= 0xFFFFFFFF;
+
+    if (ctx->total[0] < len)
+        ctx->total[1]++;
+
+    if (left && len >= fill)
+    {
+        memcpy((void *) (ctx->buffer + left), (void *)msg, fill);
+        SHA256_Process(ctx->buffer, ctx);
+        len -= fill;
+        msg  += fill;
+        left = 0;
+    }
+
+    while (len >= 64)
+    {
+        SHA256_Process(msg, ctx);
+        len -= 64;
+        msg  += 64;
+    }
+
+    if (len)
+    {
+        memcpy((void *) (ctx->buffer + left), (void *) msg, len);
+    }
+}
+
+/**
+ * Return the 256-bit message digest into the user's array
+ */
+void SHA256_Final(uint8_t *digest, SHA256_CTX *ctx)
+{
+    uint32_t last, padn;
+    uint32_t high, low;
+    uint8_t msglen[8];
+
+    high = (ctx->total[0] >> 29)
+         | (ctx->total[1] <<  3);
+    low  = (ctx->total[0] <<  3);
+
+    PUT_UINT32(high, msglen, 0);
+    PUT_UINT32(low,  msglen, 4);
+
+    last = ctx->total[0] & 0x3F;
+    padn = (last < 56) ? (56 - last) : (120 - last);
+
+    SHA256_Update(ctx, sha256_padding, padn);
+    SHA256_Update(ctx, msglen, 8);
+
+    PUT_UINT32(ctx->state[0], digest,  0);
+    PUT_UINT32(ctx->state[1], digest,  4);
+    PUT_UINT32(ctx->state[2], digest,  8);
+    PUT_UINT32(ctx->state[3], digest, 12);
+    PUT_UINT32(ctx->state[4], digest, 16);
+    PUT_UINT32(ctx->state[5], digest, 20);
+    PUT_UINT32(ctx->state[6], digest, 24);
+    PUT_UINT32(ctx->state[7], digest, 28);
+}

+ 9 - 4
myaxtls/tls1_svr.c

@@ -310,7 +310,9 @@ static int send_server_hello(SSL *ssl)
     buf[5] = ssl->version & 0x0f;
 
     /* server random value */
-    get_random(SSL_RANDOM_SIZE, &buf[6]);
+    if (get_random(SSL_RANDOM_SIZE, &buf[6]) < 0)
+        return SSL_NOT_OK;
+
     memcpy(ssl->dc->server_random, &buf[6], SSL_RANDOM_SIZE);
     offset = 6 + SSL_RANDOM_SIZE;
 
@@ -391,7 +393,8 @@ static int process_client_key_xchg(SSL *ssl)
 
     /* rsa_ctx->bi_ctx is not thread-safe */
     SSL_CTX_LOCK(ssl->ssl_ctx->mutex);
-    premaster_size = RSA_decrypt(rsa_ctx, &buf[offset], premaster_secret, 1);
+    premaster_size = RSA_decrypt(rsa_ctx, &buf[offset], premaster_secret,
+            sizeof(premaster_secret), 1);
     SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex);
 
     if (premaster_size != SSL_SECRET_SIZE ||
@@ -400,7 +403,9 @@ static int process_client_key_xchg(SSL *ssl)
                 premaster_secret[1] != (ssl->client_version & 0x0f))
     {
         /* guard against a Bleichenbacher attack */
-        get_random(SSL_SECRET_SIZE, premaster_secret);
+        if (get_random(SSL_SECRET_SIZE, premaster_secret) < 0)
+            return SSL_NOT_OK;
+
         /* and continue - will die eventually when checking the mac */
     }
 
@@ -453,7 +458,7 @@ static int process_cert_verify(SSL *ssl)
 
     /* rsa_ctx->bi_ctx is not thread-safe */
     SSL_CTX_LOCK(ssl->ssl_ctx->mutex);
-    n = RSA_decrypt(x509_ctx->rsa_ctx, &buf[6], dgst_buf, 0);
+    n = RSA_decrypt(x509_ctx->rsa_ctx, &buf[6], dgst_buf, sizeof(dgst_buf), 0);
     SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex);
 
     if (n != SHA1_SIZE + MD5_SIZE)

+ 1 - 1
myaxtls/version.h

@@ -1 +1 @@
-#define AXTLS_VERSION    "1.5.0"
+#define AXTLS_VERSION    "1.5.1"

+ 14 - 11
myaxtls/x509.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, Cameron Rich
+ * Copyright (c) 2007-2014, Cameron Rich
  * 
  * All rights reserved.
  * 
@@ -120,7 +120,7 @@ int x509_new(const uint8_t *cert, int *len, X509_CTX **ctx)
     bi_ctx = x509_ctx->rsa_ctx->bi_ctx;
 
 #ifdef CONFIG_SSL_CERT_VERIFICATION /* only care if doing verification */
-    /* use the appropriate signature algorithm (SHA1/MD5/MD2) */
+    /* use the appropriate signature algorithm (SHA1/MD5/SHA256) */
     if (x509_ctx->sig_type == SIG_TYPE_MD5)
     {
         MD5_CTX md5_ctx;
@@ -139,14 +139,14 @@ int x509_new(const uint8_t *cert, int *len, X509_CTX **ctx)
         SHA1_Final(sha_dgst, &sha_ctx);
         x509_ctx->digest = bi_import(bi_ctx, sha_dgst, SHA1_SIZE);
     }
-    else if (x509_ctx->sig_type == SIG_TYPE_MD2)
+    else if (x509_ctx->sig_type == SIG_TYPE_SHA256)
     {
-        MD2_CTX md2_ctx;
-        uint8_t md2_dgst[MD2_SIZE];
-        MD2_Init(&md2_ctx);
-        MD2_Update(&md2_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
-        MD2_Final(md2_dgst, &md2_ctx);
-        x509_ctx->digest = bi_import(bi_ctx, md2_dgst, MD2_SIZE);
+        SHA256_CTX sha256_ctx;
+        uint8_t sha256_dgst[SHA256_SIZE];
+        SHA256_Init(&sha256_ctx);
+        SHA256_Update(&sha256_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
+        SHA256_Final(sha256_dgst, &sha256_ctx);
+        x509_ctx->digest = bi_import(bi_ctx, sha256_dgst, SHA256_SIZE);
     }
 
     if (cert[offset] == ASN1_V3_DATA)
@@ -483,14 +483,17 @@ void x509_print(const X509_CTX *cert, CA_CERT_CTX *ca_cert_ctx)
     printf("Sig Type:\t\t\t");
     switch (cert->sig_type)
     {
+        case SIG_TYPE_MD2:
+            printf("MD2\n");
+            break;
         case SIG_TYPE_MD5:
             printf("MD5\n");
             break;
         case SIG_TYPE_SHA1:
             printf("SHA1\n");
             break;
-        case SIG_TYPE_MD2:
-            printf("MD2\n");
+        case SIG_TYPE_SHA256:
+            printf("SHA256\n");
             break;
         default:
             printf("Unrecognized: %d\n", cert->sig_type);