diff --git a/Makefile b/Makefile index 15c5e7223..0cdd8dad2 100644 --- a/Makefile +++ b/Makefile @@ -12,11 +12,13 @@ OBJ_FILES := \ crypto/aes.o \ crypto/bigint.o \ crypto/hmac.o \ - crypto/md2.o \ crypto/md5.o \ crypto/rc4.o \ crypto/rsa.o \ crypto/sha1.o \ + crypto/sha256.o \ + crypto/sha384.o \ + crypto/sha512.o \ ssl/asn1.o \ ssl/gen_cert.o \ ssl/loader.o \ diff --git a/crypto/crypto.h b/crypto/crypto.h index 8a314a332..fcf32c703 100644 --- a/crypto/crypto.h +++ b/crypto/crypto.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Cameron Rich + * Copyright (c) 2007-2015, Cameron Rich * * All rights reserved. * @@ -39,7 +39,6 @@ extern "C" { #endif -#include "config.h" #include "bigint_impl.h" #include "bigint.h" @@ -124,22 +123,58 @@ 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, SHA256_CTX *); + +/************************************************************************** + * SHA512 declarations + **************************************************************************/ + +#define SHA512_SIZE 64 + +typedef struct +{ + union + { + uint64_t h[8]; + uint8_t digest[64]; + } h_dig; + union + { + uint64_t w[80]; + uint8_t buffer[128]; + } w_buf; + size_t size; + uint64_t totalSize; +} SHA512_CTX; + +void SHA512_Init(SHA512_CTX *c); +void SHA512_Update(SHA512_CTX *, const uint8_t *input, int len); +void SHA512_Final(uint8_t *digest, SHA512_CTX *); + +/************************************************************************** + * SHA384 declarations + **************************************************************************/ + +#define SHA384_SIZE 48 + +typedef SHA512_CTX SHA384_CTX; +void SHA384_Init(SHA384_CTX *c); +void SHA384_Update(SHA384_CTX *, const uint8_t *input, int len); +void SHA384_Final(uint8_t *digest, SHA384_CTX *); /************************************************************************** * MD5 declarations @@ -203,7 +238,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 +255,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 } diff --git a/crypto/crypto_misc.c b/crypto/crypto_misc.c index a2ea2e367..621b1f6dc 100644 --- a/crypto/crypto_misc.c +++ b/crypto/crypto_misc.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2007, Cameron Rich - * + * Copyright (c) 2007-2015, Cameron Rich + * * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -162,11 +162,12 @@ EXP_FUNC void STDCALL RNG_terminate(void) /** * 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); @@ -211,15 +212,17 @@ 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++) { @@ -227,6 +230,8 @@ void get_random_NZ(int num_rand_bytes, uint8_t *rand_data) get_random(1, rand_data + i); } } + + return 0; } /** diff --git a/crypto/md2.c b/crypto/md2.c deleted file mode 100644 index dee909a7a..000000000 --- a/crypto/md2.c +++ /dev/null @@ -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 -#include -#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 diff --git a/crypto/os_int.h b/crypto/os_int.h index 878856723..69e06c50e 100644 --- a/crypto/os_int.h +++ b/crypto/os_int.h @@ -56,6 +56,7 @@ typedef INT64 int64_t; #include #else #include +#include #endif /* Not Solaris */ #endif /* Not Win32 */ diff --git a/crypto/rsa.c b/crypto/rsa.c index 9d52c062f..fe09c5828 100644 --- a/crypto/rsa.c +++ b/crypto/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 *)malloc(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,38 @@ 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); + memcpy(out_data, &block[i], size); free(block); - return size ? size : -1; + return size; } /** @@ -249,7 +264,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; diff --git a/crypto/sha256.c b/crypto/sha256.c new file mode 100644 index 000000000..50f5f8cef --- /dev/null +++ b/crypto/sha256.c @@ -0,0 +1,274 @@ +/* + * Copyright (c) 2015, 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. + */ + +#include +#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; +} + +static 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); +} diff --git a/crypto/sha384.c b/crypto/sha384.c new file mode 100644 index 000000000..f1071be93 --- /dev/null +++ b/crypto/sha384.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2015, 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. + */ + +#include +#include "os_port.h" +#include "crypto.h" + +/** +* Initialize the SHA384 context +*/ + void SHA384_Init(SHA384_CTX *ctx) + { + //Set initial hash value + ctx->h_dig.h[0] = 0xCBBB9D5DC1059ED8LL; + ctx->h_dig.h[1] = 0x629A292A367CD507LL; + ctx->h_dig.h[2] = 0x9159015A3070DD17LL; + ctx->h_dig.h[3] = 0x152FECD8F70E5939LL; + ctx->h_dig.h[4] = 0x67332667FFC00B31LL; + ctx->h_dig.h[5] = 0x8EB44A8768581511LL; + ctx->h_dig.h[6] = 0xDB0C2E0D64F98FA7LL; + ctx->h_dig.h[7] = 0x47B5481DBEFA4FA4LL; + + // Number of bytes in the buffer + ctx->size = 0; + // Total length of the message + ctx->totalSize = 0; + } + +/** +* Accepts an array of octets as the next portion of the message. +*/ +void SHA384_Update(SHA384_CTX *ctx, const uint8_t * msg, int len) +{ + // The function is defined in the exact same manner as SHA-512 + SHA512_Update(ctx, msg, len); +} + +/** +* Return the 384-bit message digest into the user's array +*/ +void SHA384_Final(uint8_t *digest, SHA384_CTX *ctx) +{ + // The function is defined in the exact same manner as SHA-512 + SHA512_Final(NULL, ctx); + + // Copy the resulting digest + if (digest != NULL) + memcpy(digest, ctx->h_dig.digest, SHA384_SIZE); +} + diff --git a/crypto/sha512.c b/crypto/sha512.c new file mode 100644 index 000000000..aa2f58938 --- /dev/null +++ b/crypto/sha512.c @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2015, 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. + */ + +#include +#include "os_port.h" +#include "crypto.h" + +#define SHR64(a, n) ((a) >> (n)) +#define ROR64(a, n) (((a) >> (n)) | ((a) << (64 - (n)))) +#define CH(x, y, z) (((x) & (y)) | (~(x) & (z))) +#define MAJ(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) +#define SIGMA1(x) (ROR64(x, 28) ^ ROR64(x, 34) ^ ROR64(x, 39)) +#define SIGMA2(x) (ROR64(x, 14) ^ ROR64(x, 18) ^ ROR64(x, 41)) +#define SIGMA3(x) (ROR64(x, 1) ^ ROR64(x, 8) ^ SHR64(x, 7)) +#define SIGMA4(x) (ROR64(x, 19) ^ ROR64(x, 61) ^ SHR64(x, 6)) +#define MIN(x, y) ((x) < (y) ? x : y) + +static const uint8_t padding[128] = +{ + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static const uint64_t k[80] = +{ + 0x428A2F98D728AE22LL, 0x7137449123EF65CDLL, 0xB5C0FBCFEC4D3B2FLL, 0xE9B5DBA58189DBBCLL, + 0x3956C25BF348B538LL, 0x59F111F1B605D019LL, 0x923F82A4AF194F9BLL, 0xAB1C5ED5DA6D8118LL, + 0xD807AA98A3030242LL, 0x12835B0145706FBELL, 0x243185BE4EE4B28CLL, 0x550C7DC3D5FFB4E2LL, + 0x72BE5D74F27B896FLL, 0x80DEB1FE3B1696B1LL, 0x9BDC06A725C71235LL, 0xC19BF174CF692694LL, + 0xE49B69C19EF14AD2LL, 0xEFBE4786384F25E3LL, 0x0FC19DC68B8CD5B5LL, 0x240CA1CC77AC9C65LL, + 0x2DE92C6F592B0275LL, 0x4A7484AA6EA6E483LL, 0x5CB0A9DCBD41FBD4LL, 0x76F988DA831153B5LL, + 0x983E5152EE66DFABLL, 0xA831C66D2DB43210LL, 0xB00327C898FB213FLL, 0xBF597FC7BEEF0EE4LL, + 0xC6E00BF33DA88FC2LL, 0xD5A79147930AA725LL, 0x06CA6351E003826FLL, 0x142929670A0E6E70LL, + 0x27B70A8546D22FFCLL, 0x2E1B21385C26C926LL, 0x4D2C6DFC5AC42AEDLL, 0x53380D139D95B3DFLL, + 0x650A73548BAF63DELL, 0x766A0ABB3C77B2A8LL, 0x81C2C92E47EDAEE6LL, 0x92722C851482353BLL, + 0xA2BFE8A14CF10364LL, 0xA81A664BBC423001LL, 0xC24B8B70D0F89791LL, 0xC76C51A30654BE30LL, + 0xD192E819D6EF5218LL, 0xD69906245565A910LL, 0xF40E35855771202ALL, 0x106AA07032BBD1B8LL, + 0x19A4C116B8D2D0C8LL, 0x1E376C085141AB53LL, 0x2748774CDF8EEB99LL, 0x34B0BCB5E19B48A8LL, + 0x391C0CB3C5C95A63LL, 0x4ED8AA4AE3418ACBLL, 0x5B9CCA4F7763E373LL, 0x682E6FF3D6B2B8A3LL, + 0x748F82EE5DEFB2FCLL, 0x78A5636F43172F60LL, 0x84C87814A1F0AB72LL, 0x8CC702081A6439ECLL, + 0x90BEFFFA23631E28LL, 0xA4506CEBDE82BDE9LL, 0xBEF9A3F7B2C67915LL, 0xC67178F2E372532BLL, + 0xCA273ECEEA26619CLL, 0xD186B8C721C0C207LL, 0xEADA7DD6CDE0EB1ELL, 0xF57D4F7FEE6ED178LL, + 0x06F067AA72176FBALL, 0x0A637DC5A2C898A6LL, 0x113F9804BEF90DAELL, 0x1B710B35131C471BLL, + 0x28DB77F523047D84LL, 0x32CAAB7B40C72493LL, 0x3C9EBE0A15C9BEBCLL, 0x431D67C49C100D4CLL, + 0x4CC5D4BECB3E42B6LL, 0x597F299CFC657E2ALL, 0x5FCB6FAB3AD6FAECLL, 0x6C44198C4A475817LL +}; + +/** +* Initialize the SHA512 context +*/ +void SHA512_Init(SHA512_CTX *ctx) +{ + ctx->h_dig.h[0] = 0x6A09E667F3BCC908LL; + ctx->h_dig.h[1] = 0xBB67AE8584CAA73BLL; + ctx->h_dig.h[2] = 0x3C6EF372FE94F82BLL; + ctx->h_dig.h[3] = 0xA54FF53A5F1D36F1LL; + ctx->h_dig.h[4] = 0x510E527FADE682D1LL; + ctx->h_dig.h[5] = 0x9B05688C2B3E6C1FLL; + ctx->h_dig.h[6] = 0x1F83D9ABFB41BD6BLL; + ctx->h_dig.h[7] = 0x5BE0CD19137E2179LL; + ctx->size = 0; + ctx->totalSize = 0; +} + +static void SHA512_Process(SHA512_CTX *ctx) +{ + int t; + uint64_t temp1; + uint64_t temp2; + + // Initialize the 8 working registers + uint64_t a = ctx->h_dig.h[0]; + uint64_t b = ctx->h_dig.h[1]; + uint64_t c = ctx->h_dig.h[2]; + uint64_t d = ctx->h_dig.h[3]; + uint64_t e = ctx->h_dig.h[4]; + uint64_t f = ctx->h_dig.h[5]; + uint64_t g = ctx->h_dig.h[6]; + uint64_t h = ctx->h_dig.h[7]; + + // Process message in 16-word blocks + uint64_t *w = ctx->w_buf.w; + + // Convert from big-endian byte order to host byte order + for (t = 0; t < 16; t++) + w[t] = be64toh(w[t]); + + // Prepare the message schedule + for (t = 16; t < 80; t++) + w[t] = SIGMA4(w[t - 2]) + w[t - 7] + SIGMA3(w[t - 15]) + w[t - 16]; + + // SHA-512 hash computation + for (t = 0; t < 80; t++) + { + // Calculate T1 and T2 + temp1 = h + SIGMA2(e) + CH(e, f, g) + k[t] + w[t]; + temp2 = SIGMA1(a) + MAJ(a, b, c); + + // Update the working registers + h = g; + g = f; + f = e; + e = d + temp1; + d = c; + c = b; + b = a; + a = temp1 + temp2; + } + + // Update the hash value + ctx->h_dig.h[0] += a; + ctx->h_dig.h[1] += b; + ctx->h_dig.h[2] += c; + ctx->h_dig.h[3] += d; + ctx->h_dig.h[4] += e; + ctx->h_dig.h[5] += f; + ctx->h_dig.h[6] += g; + ctx->h_dig.h[7] += h; + } + +/** +* Accepts an array of octets as the next portion of the message. +*/ +void SHA512_Update(SHA512_CTX *ctx, const uint8_t * msg, int len) +{ + // Process the incoming data + while (len > 0) + { + // The buffer can hold at most 128 bytes + size_t n = MIN(len, 128 - ctx->size); + + // Copy the data to the buffer + memcpy(ctx->w_buf.buffer + ctx->size, msg, n); + + // Update the SHA-512 ctx + ctx->size += n; + ctx->totalSize += n; + // Advance the data pointer + msg = (uint8_t *) msg + n; + // Remaining bytes to process + len -= n; + + // Process message in 16-word blocks + if (ctx->size == 128) + { + // Transform the 16-word block + SHA512_Process(ctx); + // Empty the buffer + ctx->size = 0; + } + } +} + +/** +* Return the 512-bit message digest into the user's array +*/ +void SHA512_Final(uint8_t *digest, SHA512_CTX *ctx) +{ + int i; + size_t paddingSize; + uint64_t totalSize; + + // Length of the original message (before padding) + totalSize = ctx->totalSize * 8; + + // Pad the message so that its length is congruent to 112 modulo 128 + paddingSize = (ctx->size < 112) ? (112 - ctx->size) : + (128 + 112 - ctx->size); + // Append padding + SHA512_Update(ctx, padding, paddingSize); + + // Append the length of the original message + ctx->w_buf.w[14] = 0; + ctx->w_buf.w[15] = be64toh(totalSize); + + // Calculate the message digest + SHA512_Process(ctx); + + // Convert from host byte order to big-endian byte order + for (i = 0; i < 8; i++) + ctx->h_dig.h[i] = be64toh(ctx->h_dig.h[i]); + + // Copy the resulting digest + if (digest != NULL) + memcpy(digest, ctx->h_dig.digest, SHA512_SIZE); + } + diff --git a/ssl/asn1.c b/ssl/asn1.c index b082275b2..0a139bb51 100644 --- a/ssl/asn1.c +++ b/ssl/asn1.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Cameron Rich + * Copyright (c) 2007-2015, Cameron Rich * * All rights reserved. * @@ -40,22 +40,42 @@ #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] = +/* 1.2.840.113549.1.1 OID prefix - handle the following */ +/* md5WithRSAEncryption(4) */ +/* sha1WithRSAEncryption(5) */ +/* sha256WithRSAEncryption (11) */ +/* sha384WithRSAEncryption (12) */ +/* sha512WithRSAEncryption (13) */ +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] = +/* 1.3.14.3.2.29 SHA1 with RSA signature */ +static const uint8_t sig_sha1WithRSAEncrypt[] = { 0x2b, 0x0e, 0x03, 0x02, 0x1d }; -static const uint8_t sig_subject_alt_name[SIG_SUBJECT_ALT_NAME_SIZE] = +/* 2.16.840.1.101.3.4.2.1 SHA-256 */ +static const uint8_t sig_sha256[] = +{ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01 +}; + +/* 2.16.840.1.101.3.4.2.2 SHA-384 */ +static const uint8_t sig_sha384[] = +{ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02 +}; + +/* 2.16.840.1.101.3.4.2.3 SHA-512 */ +static const uint8_t sig_sha512[] = +{ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03 +}; + +static const uint8_t sig_subject_alt_name[] = { 0x55, 0x1d, 0x11 }; @@ -63,9 +83,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 +95,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++) { @@ -205,30 +229,64 @@ int asn1_get_private_key(const uint8_t *buf, int len, RSA_CTX **rsa_ctx) */ static int asn1_get_utc_time(const uint8_t *buf, int *offset, time_t *t) { - int ret = X509_NOT_OK, len, t_offset; + int ret = X509_NOT_OK, len, t_offset, abs_year; struct tm tm; - if (buf[(*offset)++] != ASN1_UTC_TIME) - goto end_utc_time; - - len = get_asn1_length(buf, offset); - t_offset = *offset; - - memset(&tm, 0, sizeof(struct tm)); - tm.tm_year = (buf[t_offset] - '0')*10 + (buf[t_offset+1] - '0'); - - if (tm.tm_year <= 50) /* 1951-2050 thing */ + /* see http://tools.ietf.org/html/rfc5280#section-4.1.2.5 */ + if (buf[*offset] == ASN1_UTC_TIME) { - tm.tm_year += 100; + (*offset)++; + + len = get_asn1_length(buf, offset); + t_offset = *offset; + + memset(&tm, 0, sizeof(struct tm)); + tm.tm_year = (buf[t_offset] - '0')*10 + (buf[t_offset+1] - '0'); + + if (tm.tm_year <= 50) /* 1951-2050 thing */ + { + tm.tm_year += 100; + } + + tm.tm_mon = (buf[t_offset+2] - '0')*10 + (buf[t_offset+3] - '0') - 1; + tm.tm_mday = (buf[t_offset+4] - '0')*10 + (buf[t_offset+5] - '0'); + *t = mktime(&tm); + *offset += len; + ret = X509_OK; + } + else if (buf[*offset] == ASN1_GENERALIZED_TIME) + { + (*offset)++; + + len = get_asn1_length(buf, offset); + t_offset = *offset; + + memset(&tm, 0, sizeof(struct tm)); + abs_year = ((buf[t_offset] - '0')*1000 + + (buf[t_offset+1] - '0')*100 + (buf[t_offset+2] - '0')*10 + + (buf[t_offset+3] - '0')); + + if (abs_year <= 1901) + { + tm.tm_year = 1; + tm.tm_mon = 0; + tm.tm_mday = 1; + } + else + { + tm.tm_year = abs_year - 1900; + tm.tm_mon = (buf[t_offset+4] - '0')*10 + (buf[t_offset+5] - '0') - 1; + tm.tm_mday = (buf[t_offset+6] - '0')*10 + (buf[t_offset+7] - '0'); + tm.tm_hour = (buf[t_offset+8] - '0')*10 + (buf[t_offset+9] - '0'); + tm.tm_min = (buf[t_offset+10] - '0')*10 + (buf[t_offset+11] - '0'); + tm.tm_sec = (buf[t_offset+12] - '0')*10 + (buf[t_offset+13] - '0'); + *t = mktime(&tm); + } + + *offset += len; + ret = X509_OK; } - tm.tm_mon = (buf[t_offset+2] - '0')*10 + (buf[t_offset+3] - '0') - 1; - tm.tm_mday = (buf[t_offset+4] - '0')*10 + (buf[t_offset+5] - '0'); - *t = mktime(&tm); - *offset += len; - ret = X509_OK; - -end_utc_time: return ret; } @@ -519,7 +577,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; } @@ -543,17 +601,47 @@ 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_sha256) && + memcmp(sig_sha256, &cert[*offset], + sizeof(sig_sha256)) == 0) + { + x509_ctx->sig_type = SIG_TYPE_SHA256; + } + else if (len == sizeof(sig_sha384) && + memcmp(sig_sha384, &cert[*offset], + sizeof(sig_sha384)) == 0) + { + x509_ctx->sig_type = SIG_TYPE_SHA384; + } + else if (len == sizeof(sig_sha512) && + memcmp(sig_sha512, &cert[*offset], + sizeof(sig_sha512)) == 0) + { + x509_ctx->sig_type = SIG_TYPE_SHA512; + } else { - if (memcmp(sig_oid_prefix, &cert[*offset], SIG_OID_PREFIX_SIZE)) - goto end_check_sig; /* unrecognised cert type */ + if (memcmp(sig_oid_prefix, &cert[*offset], sizeof(sig_oid_prefix))) + { +#ifdef CONFIG_SSL_FULL_MODE + int i; + printf("invalid digest: "); - x509_ctx->sig_type = cert[*offset + SIG_OID_PREFIX_SIZE]; + 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 + sizeof(sig_oid_prefix)]; } *offset += len; diff --git a/ssl/crypto_misc.h b/ssl/crypto_misc.h index 0201f5b5e..2129422f6 100644 --- a/ssl/crypto_misc.h +++ b/ssl/crypto_misc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Cameron Rich + * Copyright (c) 2007-2015, Cameron Rich * * All rights reserved. * @@ -55,6 +55,7 @@ extern "C" { #define X509_VFY_ERROR_INVALID_CHAIN -7 #define X509_VFY_ERROR_UNSUPPORTED_DIGEST -8 #define X509_INVALID_PRIV_KEY -9 +#define X509_MAX_CERTS -10 /* * The Distinguished Name @@ -113,6 +114,7 @@ const char * x509_display_error(int error); #define ASN1_TELETEX_STR 0x14 #define ASN1_IA5_STR 0x16 #define ASN1_UTC_TIME 0x17 +#define ASN1_GENERALIZED_TIME 0x18 #define ASN1_UNICODE_STR 0x1e #define ASN1_SEQUENCE 0x30 #define ASN1_CONTEXT_DNSNAME 0x82 @@ -126,8 +128,11 @@ 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 +#define SIG_TYPE_SHA384 0x0c +#define SIG_TYPE_SHA512 0x0d -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); diff --git a/ssl/gen_cert.c b/ssl/gen_cert.c index ef223b27b..093ae9c09 100644 --- a/ssl/gen_cert.c +++ b/ssl/gen_cert.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Cameron Rich + * Copyright (c) 2007-2014, Cameron Rich * * All rights reserved. * @@ -142,7 +142,7 @@ static int gen_dn(const char *name, uint8_t dn_type, buf[(*offset)++] = dn_type; buf[(*offset)++] = ASN1_PRINTABLE_STR; buf[(*offset)++] = name_size; - strcpy(&buf[*offset], name); + strcpy((char *)&buf[*offset], name); *offset += name_size; error: @@ -165,7 +165,13 @@ static int gen_issuer(const char * dn[], uint8_t *buf, int *offset) gethostname(fqdn, sizeof(fqdn)); fqdn_len = strlen(fqdn); fqdn[fqdn_len++] = '.'; - getdomainname(&fqdn[fqdn_len], sizeof(fqdn)-fqdn_len); + + if (getdomainname(&fqdn[fqdn_len], sizeof(fqdn)-fqdn_len) < 0) + { + ret = X509_NOT_OK; + goto error; + } + fqdn_len = strlen(fqdn); if (fqdn[fqdn_len-1] == '.') /* ensure '.' is not last char */ diff --git a/ssl/loader.c b/ssl/loader.c index 6c7a6308c..34ee3248d 100644 --- a/ssl/loader.c +++ b/ssl/loader.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Cameron Rich + * Copyright (c) 2007-2014, Cameron Rich * * All rights reserved. * @@ -82,7 +82,7 @@ EXP_FUNC int STDCALL ssl_obj_load(SSL_CTX *ssl_ctx, int obj_type, #ifdef CONFIG_SSL_HAS_PEM ret = ssl_obj_PEM_load(ssl_ctx, obj_type, ssl_obj, password); #else - printf(unsupported_str); + printf("%s", unsupported_str); ret = SSL_ERROR_NOT_SUPPORTED; #endif } @@ -93,7 +93,7 @@ error: ssl_obj_free(ssl_obj); return ret; #else - printf(unsupported_str); + printf("%s", unsupported_str); return SSL_ERROR_NOT_SUPPORTED; #endif /* CONFIG_SSL_SKELETON_MODE */ } @@ -150,7 +150,7 @@ static int do_obj(SSL_CTX *ssl_ctx, int obj_type, break; #endif default: - printf(unsupported_str); + printf("%s", unsupported_str); ret = SSL_ERROR_NOT_SUPPORTED; break; } diff --git a/ssl/openssl.o b/ssl/openssl.o deleted file mode 100644 index 43ec25c06..000000000 Binary files a/ssl/openssl.o and /dev/null differ diff --git a/ssl/os_port.h b/ssl/os_port.h index c11ec3bd3..e85d42672 100644 --- a/ssl/os_port.h +++ b/ssl/os_port.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2007, Cameron Rich - * + * Copyright (c) 2007-2015, Cameron Rich + * * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -42,6 +42,7 @@ extern "C" { #endif #include "os_int.h" +#include "config.h" #include #ifdef WIN32 @@ -161,12 +162,17 @@ EXP_FUNC int STDCALL getdomainname(char *buf, int buf_size); #include #include #include +#include #define SOCKET_READ(A,B,C) read(A,B,C) #define SOCKET_WRITE(A,B,C) write(A,B,C) #define SOCKET_CLOSE(A) if (A >= 0) close(A) #define TTY_FLUSH() +#ifndef be64toh +#define be64toh(x) __be64_to_cpu(x) +#endif + #endif /* Not Win32 */ /* some functions to mutate the way these work */ diff --git a/ssl/tls1.c b/ssl/tls1.c index f8ec6b0a7..c422f1e68 100644 --- a/ssl/tls1.c +++ b/ssl/tls1.c @@ -323,7 +323,7 @@ int add_cert(SSL_CTX *ssl_ctx, const uint8_t *buf, int len) X509_CTX *cert = NULL; int offset; - while (ssl_ctx->certs[i].buf && i < CONFIG_SSL_MAX_CERTS) + while (i < CONFIG_SSL_MAX_CERTS && ssl_ctx->certs[i].buf) i++; if (i == CONFIG_SSL_MAX_CERTS) /* too many certs */ @@ -369,7 +369,7 @@ error: */ int add_cert_auth(SSL_CTX *ssl_ctx, const uint8_t *buf, int len) { - int ret = SSL_OK; /* ignore errors for now */ + int ret = X509_OK; /* ignore errors for now */ int i = 0; CA_CERT_CTX *ca_cert_ctx; @@ -391,10 +391,10 @@ int add_cert_auth(SSL_CTX *ssl_ctx, const uint8_t *buf, int len) "compile-time configuration required\n", CONFIG_X509_MAX_CA_CERTS); #endif + ret = X509_MAX_CERTS; break; } - /* ignore the return code */ if (x509_new(buf, &offset, &ca_cert_ctx->cert[i]) == X509_OK) { @@ -1099,7 +1099,9 @@ int send_packet(SSL *ssl, uint8_t protocol, const uint8_t *in, int length) uint8_t iv_size = ssl->cipher_info->iv_size; uint8_t *t_buf = malloc(msg_length + iv_size); memcpy(t_buf + iv_size, ssl->bm_data, msg_length); - get_random(iv_size, t_buf); + if (get_random(iv_size, t_buf) < 0) + return SSL_NOT_OK; + msg_length += iv_size; memcpy(ssl->bm_data, t_buf, msg_length); free(t_buf); @@ -1376,25 +1378,26 @@ int basic_read(SSL *ssl, uint8_t **in_data) goto error; } - /* all encrypted from now on */ - SET_SSL_FLAG(SSL_RX_ENCRYPTED); if (set_key_block(ssl, 0) < 0) { ret = SSL_ERROR_INVALID_HANDSHAKE; goto error; } + /* all encrypted from now on */ + SET_SSL_FLAG(SSL_RX_ENCRYPTED); memset(ssl->read_sequence, 0, 8); break; case PT_APP_PROTOCOL_DATA: - if (in_data) + if (in_data && ssl->hs_status == SSL_OK) { *in_data = buf; /* point to the work buffer */ (*in_data)[read_len] = 0; /* null terminate just in case */ + ret = read_len; } - - ret = read_len; + else + ret = SSL_ERROR_INVALID_PROT_MSG; break; case PT_ALERT_PROTOCOL: @@ -1502,10 +1505,14 @@ int send_change_cipher_spec(SSL *ssl) { int ret = send_packet(ssl, PT_CHANGE_CIPHER_SPEC, g_chg_cipher_spec_pkt, sizeof(g_chg_cipher_spec_pkt)); - SET_SSL_FLAG(SSL_TX_ENCRYPTED); if (ret >= 0 && set_key_block(ssl, 1) < 0) ret = SSL_ERROR_INVALID_HANDSHAKE; + + if (ssl->cipher_info) + SET_SSL_FLAG(SSL_TX_ENCRYPTED); + if (ssl->cipher_info) + SET_SSL_FLAG(SSL_TX_ENCRYPTED); memset(ssl->write_sequence, 0, 8); return ret; @@ -2251,7 +2258,7 @@ EXP_FUNC void STDCALL ssl_display_error(int error_code) {} EXP_FUNC SSL * STDCALL ssl_client_new(SSL_CTX *ssl_ctx, int client_fd, const uint8_t *session_id, uint8_t sess_id_size) { - printf(unsupported_str); + printf("%s", unsupported_str); return NULL; } #endif @@ -2259,20 +2266,20 @@ EXP_FUNC SSL * STDCALL ssl_client_new(SSL_CTX *ssl_ctx, int client_fd, const #if !defined(CONFIG_SSL_CERT_VERIFICATION) EXP_FUNC int STDCALL ssl_verify_cert(const SSL *ssl) { - printf(unsupported_str); + printf("%s", unsupported_str); return -1; } EXP_FUNC const char * STDCALL ssl_get_cert_dn(const SSL *ssl, int component) { - printf(unsupported_str); + printf("%s", unsupported_str); return NULL; } EXP_FUNC const char * STDCALL ssl_get_cert_subject_alt_dnsname(const SSL *ssl, int index) { - printf(unsupported_str); + printf("%s", unsupported_str); return NULL; } diff --git a/ssl/tls1.h b/ssl/tls1.h index e03eef9be..abbc93393 100644 --- a/ssl/tls1.h +++ b/ssl/tls1.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Cameron Rich + * Copyright (c) 2007-2014, Cameron Rich * * All rights reserved. * diff --git a/ssl/tls1_clnt.c b/ssl/tls1_clnt.c index c02d903eb..77f11780d 100644 --- a/ssl/tls1_clnt.c +++ b/ssl/tls1_clnt.c @@ -194,7 +194,9 @@ static int send_client_hello(SSL *ssl) *tm_ptr++ = (uint8_t)(((long)tm & 0x00ff0000) >> 16); *tm_ptr++ = (uint8_t)(((long)tm & 0x0000ff00) >> 8); *tm_ptr++ = (uint8_t)(((long)tm & 0x000000ff)); - get_random(SSL_RANDOM_SIZE-4, &buf[10]); + if (get_random(SSL_RANDOM_SIZE-4, &buf[10]) < 0) + return SSL_NOT_OK; + memcpy(ssl->dc->client_random, &buf[6], SSL_RANDOM_SIZE); offset = 6 + SSL_RANDOM_SIZE; @@ -340,7 +342,9 @@ static int send_client_key_xchg(SSL *ssl) premaster_secret[0] = 0x03; /* encode the version number */ premaster_secret[1] = SSL_PROTOCOL_MINOR_VERSION; /* must be TLS 1.1 */ - get_random(SSL_SECRET_SIZE-2, &premaster_secret[2]); + if (get_random(SSL_SECRET_SIZE-2, &premaster_secret[2]) < 0) + return SSL_NOT_OK; + DISPLAY_RSA(ssl, ssl->x509_ctx->rsa_ctx); /* rsa_ctx->bi_ctx is not thread-safe */ @@ -387,6 +391,9 @@ static int send_cert_verify(SSL *ssl) RSA_CTX *rsa_ctx = ssl->ssl_ctx->rsa_ctx; int n = 0, ret; + if (rsa_ctx == NULL) + return SSL_OK; + DISPLAY_RSA(ssl, rsa_ctx); buf[0] = HS_CERT_VERIFY; diff --git a/ssl/tls1_svr.c b/ssl/tls1_svr.c index 51c9d76e8..b4b0f648d 100644 --- a/ssl/tls1_svr.c +++ b/ssl/tls1_svr.c @@ -117,7 +117,6 @@ int do_svr_handshake(SSL *ssl, int handshake_type, uint8_t *buf, int hs_len) static int process_client_hello(SSL *ssl) { uint8_t *buf = ssl->bm_data; - uint8_t *record_buf = ssl->hmac_header; int pkt_size = ssl->bm_index; int i, j, cs_len, id_len, offset = 6 + SSL_RANDOM_SIZE; int ret = SSL_OK; @@ -199,14 +198,14 @@ int process_sslv23_client_hello(SSL *ssl) DISPLAY_BYTES(ssl, "received %d bytes", buf, read_len, read_len); - add_packet(ssl, buf, read_len); - /* connection has gone, so die */ - if (bytes_needed < 0) + if (read_len < 0) { return SSL_ERROR_CONN_LOST; } + add_packet(ssl, buf, read_len); + /* now work out what cipher suite we are going to use */ for (j = 0; j < NUM_PROTOCOLS; j++) { @@ -311,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; @@ -392,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 || @@ -401,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 */ } @@ -454,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) diff --git a/ssl/x509.c b/ssl/x509.c index a291f2012..da0706288 100644 --- a/ssl/x509.c +++ b/ssl/x509.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Cameron Rich + * Copyright (c) 2007-2015, Cameron Rich * * All rights reserved. * @@ -126,33 +126,63 @@ int x509_new(const uint8_t *cert, int *len, X509_CTX **ctx) SHA1_Final(x509_ctx->fingerprint, &sha_fp_ctx); #ifdef CONFIG_SSL_CERT_VERIFICATION /* only care if doing verification */ - /* use the appropriate signature algorithm (SHA1/MD5/MD2) */ - if (x509_ctx->sig_type == SIG_TYPE_MD5) + /* use the appropriate signature algorithm */ + switch (x509_ctx->sig_type) { - MD5_CTX md5_ctx; - uint8_t md5_dgst[MD5_SIZE]; - MD5_Init(&md5_ctx); - MD5_Update(&md5_ctx, &cert[begin_tbs], end_tbs-begin_tbs); - MD5_Final(md5_dgst, &md5_ctx); - x509_ctx->digest = bi_import(bi_ctx, md5_dgst, MD5_SIZE); - } - else if (x509_ctx->sig_type == SIG_TYPE_SHA1) - { - SHA1_CTX sha_ctx; - uint8_t sha_dgst[SHA1_SIZE]; - SHA1_Init(&sha_ctx); - SHA1_Update(&sha_ctx, &cert[begin_tbs], end_tbs-begin_tbs); - 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) - { - 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); + case SIG_TYPE_MD5: + { + MD5_CTX md5_ctx; + uint8_t md5_dgst[MD5_SIZE]; + MD5_Init(&md5_ctx); + MD5_Update(&md5_ctx, &cert[begin_tbs], end_tbs-begin_tbs); + MD5_Final(md5_dgst, &md5_ctx); + x509_ctx->digest = bi_import(bi_ctx, md5_dgst, MD5_SIZE); + } + break; + + case SIG_TYPE_SHA1: + { + SHA1_CTX sha_ctx; + uint8_t sha_dgst[SHA1_SIZE]; + SHA1_Init(&sha_ctx); + SHA1_Update(&sha_ctx, &cert[begin_tbs], end_tbs-begin_tbs); + SHA1_Final(sha_dgst, &sha_ctx); + x509_ctx->digest = bi_import(bi_ctx, sha_dgst, SHA1_SIZE); + } + break; + + case SIG_TYPE_SHA256: + { + 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); + } + break; + + case SIG_TYPE_SHA384: + { + SHA384_CTX sha384_ctx; + uint8_t sha384_dgst[SHA384_SIZE]; + SHA384_Init(&sha384_ctx); + SHA384_Update(&sha384_ctx, &cert[begin_tbs], end_tbs-begin_tbs); + SHA384_Final(sha384_dgst, &sha384_ctx); + x509_ctx->digest = bi_import(bi_ctx, sha384_dgst, SHA384_SIZE); + } + break; + + case SIG_TYPE_SHA512: + { + SHA512_CTX sha512_ctx; + uint8_t sha512_dgst[SHA512_SIZE]; + SHA512_Init(&sha512_ctx); + SHA512_Update(&sha512_ctx, &cert[begin_tbs], end_tbs-begin_tbs); + SHA512_Final(sha512_dgst, &sha512_ctx); + x509_ctx->digest = bi_import(bi_ctx, sha512_dgst, SHA512_SIZE); + } + break; } if (cert[offset] == ASN1_V3_DATA) @@ -494,14 +524,23 @@ 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; + case SIG_TYPE_SHA384: + printf("SHA384\n"); + break; + case SIG_TYPE_SHA512: + printf("SHA512\n"); break; default: printf("Unrecognized: %d\n", cert->sig_type); diff --git a/tools/make_certs.sh b/tools/make_certs.sh old mode 100755 new mode 100644