mirror of
				https://github.com/esp8266/Arduino.git
				synced 2025-11-03 14:33:37 +03:00 
			
		
		
		
	Import axTLS 1.4.9
This commit is contained in:
		
							
								
								
									
										24
									
								
								LICENSE
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								LICENSE
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
				
			|||||||
 | 
					Copyright (c) 2008, 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 REGENTS 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.
 | 
				
			||||||
							
								
								
									
										457
									
								
								crypto/aes.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										457
									
								
								crypto/aes.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,457 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * AES implementation - this is a small code version. There are much faster
 | 
				
			||||||
 | 
					 * versions around but they are much larger in size (i.e. they use large 
 | 
				
			||||||
 | 
					 * submix tables).
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include "os_port.h"
 | 
				
			||||||
 | 
					#include "crypto.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* all commented out in skeleton mode */
 | 
				
			||||||
 | 
					#ifndef CONFIG_SSL_SKELETON_MODE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define rot1(x) (((x) << 24) | ((x) >> 8))
 | 
				
			||||||
 | 
					#define rot2(x) (((x) << 16) | ((x) >> 16))
 | 
				
			||||||
 | 
					#define rot3(x) (((x) <<  8) | ((x) >> 24))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 
 | 
				
			||||||
 | 
					 * This cute trick does 4 'mul by two' at once.  Stolen from
 | 
				
			||||||
 | 
					 * Dr B. R. Gladman <brg@gladman.uk.net> but I'm sure the u-(u>>7) is
 | 
				
			||||||
 | 
					 * a standard graphics trick
 | 
				
			||||||
 | 
					 * The key to this is that we need to xor with 0x1b if the top bit is set.
 | 
				
			||||||
 | 
					 * a 1xxx xxxx   0xxx 0xxx First we mask the 7bit,
 | 
				
			||||||
 | 
					 * b 1000 0000   0000 0000 then we shift right by 7 putting the 7bit in 0bit,
 | 
				
			||||||
 | 
					 * c 0000 0001   0000 0000 we then subtract (c) from (b)
 | 
				
			||||||
 | 
					 * d 0111 1111   0000 0000 and now we and with our mask
 | 
				
			||||||
 | 
					 * e 0001 1011   0000 0000
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define mt  0x80808080
 | 
				
			||||||
 | 
					#define ml  0x7f7f7f7f
 | 
				
			||||||
 | 
					#define mh  0xfefefefe
 | 
				
			||||||
 | 
					#define mm  0x1b1b1b1b
 | 
				
			||||||
 | 
					#define mul2(x,t)	((t)=((x)&mt), \
 | 
				
			||||||
 | 
								((((x)+(x))&mh)^(((t)-((t)>>7))&mm)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define inv_mix_col(x,f2,f4,f8,f9) (\
 | 
				
			||||||
 | 
								(f2)=mul2(x,f2), \
 | 
				
			||||||
 | 
								(f4)=mul2(f2,f4), \
 | 
				
			||||||
 | 
								(f8)=mul2(f4,f8), \
 | 
				
			||||||
 | 
								(f9)=(x)^(f8), \
 | 
				
			||||||
 | 
								(f8)=((f2)^(f4)^(f8)), \
 | 
				
			||||||
 | 
								(f2)^=(f9), \
 | 
				
			||||||
 | 
								(f4)^=(f9), \
 | 
				
			||||||
 | 
								(f8)^=rot3(f2), \
 | 
				
			||||||
 | 
								(f8)^=rot2(f4), \
 | 
				
			||||||
 | 
								(f8)^rot1(f9))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * AES S-box
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static const uint8_t aes_sbox[256] =
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						0x63,0x7C,0x77,0x7B,0xF2,0x6B,0x6F,0xC5,
 | 
				
			||||||
 | 
						0x30,0x01,0x67,0x2B,0xFE,0xD7,0xAB,0x76,
 | 
				
			||||||
 | 
						0xCA,0x82,0xC9,0x7D,0xFA,0x59,0x47,0xF0,
 | 
				
			||||||
 | 
						0xAD,0xD4,0xA2,0xAF,0x9C,0xA4,0x72,0xC0,
 | 
				
			||||||
 | 
						0xB7,0xFD,0x93,0x26,0x36,0x3F,0xF7,0xCC,
 | 
				
			||||||
 | 
						0x34,0xA5,0xE5,0xF1,0x71,0xD8,0x31,0x15,
 | 
				
			||||||
 | 
						0x04,0xC7,0x23,0xC3,0x18,0x96,0x05,0x9A,
 | 
				
			||||||
 | 
						0x07,0x12,0x80,0xE2,0xEB,0x27,0xB2,0x75,
 | 
				
			||||||
 | 
						0x09,0x83,0x2C,0x1A,0x1B,0x6E,0x5A,0xA0,
 | 
				
			||||||
 | 
						0x52,0x3B,0xD6,0xB3,0x29,0xE3,0x2F,0x84,
 | 
				
			||||||
 | 
						0x53,0xD1,0x00,0xED,0x20,0xFC,0xB1,0x5B,
 | 
				
			||||||
 | 
						0x6A,0xCB,0xBE,0x39,0x4A,0x4C,0x58,0xCF,
 | 
				
			||||||
 | 
						0xD0,0xEF,0xAA,0xFB,0x43,0x4D,0x33,0x85,
 | 
				
			||||||
 | 
						0x45,0xF9,0x02,0x7F,0x50,0x3C,0x9F,0xA8,
 | 
				
			||||||
 | 
						0x51,0xA3,0x40,0x8F,0x92,0x9D,0x38,0xF5,
 | 
				
			||||||
 | 
						0xBC,0xB6,0xDA,0x21,0x10,0xFF,0xF3,0xD2,
 | 
				
			||||||
 | 
						0xCD,0x0C,0x13,0xEC,0x5F,0x97,0x44,0x17,
 | 
				
			||||||
 | 
						0xC4,0xA7,0x7E,0x3D,0x64,0x5D,0x19,0x73,
 | 
				
			||||||
 | 
						0x60,0x81,0x4F,0xDC,0x22,0x2A,0x90,0x88,
 | 
				
			||||||
 | 
						0x46,0xEE,0xB8,0x14,0xDE,0x5E,0x0B,0xDB,
 | 
				
			||||||
 | 
						0xE0,0x32,0x3A,0x0A,0x49,0x06,0x24,0x5C,
 | 
				
			||||||
 | 
						0xC2,0xD3,0xAC,0x62,0x91,0x95,0xE4,0x79,
 | 
				
			||||||
 | 
						0xE7,0xC8,0x37,0x6D,0x8D,0xD5,0x4E,0xA9,
 | 
				
			||||||
 | 
						0x6C,0x56,0xF4,0xEA,0x65,0x7A,0xAE,0x08,
 | 
				
			||||||
 | 
						0xBA,0x78,0x25,0x2E,0x1C,0xA6,0xB4,0xC6,
 | 
				
			||||||
 | 
						0xE8,0xDD,0x74,0x1F,0x4B,0xBD,0x8B,0x8A,
 | 
				
			||||||
 | 
						0x70,0x3E,0xB5,0x66,0x48,0x03,0xF6,0x0E,
 | 
				
			||||||
 | 
						0x61,0x35,0x57,0xB9,0x86,0xC1,0x1D,0x9E,
 | 
				
			||||||
 | 
						0xE1,0xF8,0x98,0x11,0x69,0xD9,0x8E,0x94,
 | 
				
			||||||
 | 
						0x9B,0x1E,0x87,0xE9,0xCE,0x55,0x28,0xDF,
 | 
				
			||||||
 | 
						0x8C,0xA1,0x89,0x0D,0xBF,0xE6,0x42,0x68,
 | 
				
			||||||
 | 
						0x41,0x99,0x2D,0x0F,0xB0,0x54,0xBB,0x16,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * AES is-box
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static const uint8_t aes_isbox[256] = 
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38,
 | 
				
			||||||
 | 
					    0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb,
 | 
				
			||||||
 | 
					    0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87,
 | 
				
			||||||
 | 
					    0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb,
 | 
				
			||||||
 | 
					    0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d,
 | 
				
			||||||
 | 
					    0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e,
 | 
				
			||||||
 | 
					    0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2,
 | 
				
			||||||
 | 
					    0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25,
 | 
				
			||||||
 | 
					    0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16,
 | 
				
			||||||
 | 
					    0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92,
 | 
				
			||||||
 | 
					    0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda,
 | 
				
			||||||
 | 
					    0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84,
 | 
				
			||||||
 | 
					    0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a,
 | 
				
			||||||
 | 
					    0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06,
 | 
				
			||||||
 | 
					    0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02,
 | 
				
			||||||
 | 
					    0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b,
 | 
				
			||||||
 | 
					    0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea,
 | 
				
			||||||
 | 
					    0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73,
 | 
				
			||||||
 | 
					    0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85,
 | 
				
			||||||
 | 
					    0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e,
 | 
				
			||||||
 | 
					    0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89,
 | 
				
			||||||
 | 
					    0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b,
 | 
				
			||||||
 | 
					    0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20,
 | 
				
			||||||
 | 
					    0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4,
 | 
				
			||||||
 | 
					    0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31,
 | 
				
			||||||
 | 
					    0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f,
 | 
				
			||||||
 | 
					    0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d,
 | 
				
			||||||
 | 
					    0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef,
 | 
				
			||||||
 | 
					    0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0,
 | 
				
			||||||
 | 
					    0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61,
 | 
				
			||||||
 | 
					    0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26,
 | 
				
			||||||
 | 
					    0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const unsigned char Rcon[30]=
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,
 | 
				
			||||||
 | 
						0x1b,0x36,0x6c,0xd8,0xab,0x4d,0x9a,0x2f,
 | 
				
			||||||
 | 
						0x5e,0xbc,0x63,0xc6,0x97,0x35,0x6a,0xd4,
 | 
				
			||||||
 | 
						0xb3,0x7d,0xfa,0xef,0xc5,0x91,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* ----- static functions ----- */
 | 
				
			||||||
 | 
					static void AES_encrypt(const AES_CTX *ctx, uint32_t *data);
 | 
				
			||||||
 | 
					static void AES_decrypt(const AES_CTX *ctx, uint32_t *data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Perform doubling in Galois Field GF(2^8) using the irreducible polynomial
 | 
				
			||||||
 | 
					   x^8+x^4+x^3+x+1 */
 | 
				
			||||||
 | 
					static unsigned char AES_xtime(uint32_t x)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return (x&0x80) ? (x<<1)^0x1b : x<<1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Set up AES with the key/iv and cipher size.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void AES_set_key(AES_CTX *ctx, const uint8_t *key, 
 | 
				
			||||||
 | 
					        const uint8_t *iv, AES_MODE mode)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int i, ii;
 | 
				
			||||||
 | 
					    uint32_t *W, tmp, tmp2;
 | 
				
			||||||
 | 
					    const unsigned char *ip;
 | 
				
			||||||
 | 
					    int words;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    switch (mode)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        case AES_MODE_128:
 | 
				
			||||||
 | 
					            i = 10;
 | 
				
			||||||
 | 
					            words = 4;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case AES_MODE_256:
 | 
				
			||||||
 | 
					            i = 14;
 | 
				
			||||||
 | 
					            words = 8;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        default:        /* fail silently */
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ctx->rounds = i;
 | 
				
			||||||
 | 
					    ctx->key_size = words;
 | 
				
			||||||
 | 
					    W = ctx->ks;
 | 
				
			||||||
 | 
					    for (i = 0; i < words; i+=2)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        W[i+0]=	((uint32_t)key[ 0]<<24)|
 | 
				
			||||||
 | 
					            ((uint32_t)key[ 1]<<16)|
 | 
				
			||||||
 | 
					            ((uint32_t)key[ 2]<< 8)|
 | 
				
			||||||
 | 
					            ((uint32_t)key[ 3]    );
 | 
				
			||||||
 | 
					        W[i+1]=	((uint32_t)key[ 4]<<24)|
 | 
				
			||||||
 | 
					            ((uint32_t)key[ 5]<<16)|
 | 
				
			||||||
 | 
					            ((uint32_t)key[ 6]<< 8)|
 | 
				
			||||||
 | 
					            ((uint32_t)key[ 7]    );
 | 
				
			||||||
 | 
					        key += 8;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ip = Rcon;
 | 
				
			||||||
 | 
					    ii = 4 * (ctx->rounds+1);
 | 
				
			||||||
 | 
					    for (i = words; i<ii; i++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        tmp = W[i-1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ((i % words) == 0)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            tmp2 =(uint32_t)aes_sbox[(tmp    )&0xff]<< 8;
 | 
				
			||||||
 | 
					            tmp2|=(uint32_t)aes_sbox[(tmp>> 8)&0xff]<<16;
 | 
				
			||||||
 | 
					            tmp2|=(uint32_t)aes_sbox[(tmp>>16)&0xff]<<24;
 | 
				
			||||||
 | 
					            tmp2|=(uint32_t)aes_sbox[(tmp>>24)     ];
 | 
				
			||||||
 | 
					            tmp=tmp2^(((unsigned int)*ip)<<24);
 | 
				
			||||||
 | 
					            ip++;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ((words == 8) && ((i % words) == 4))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            tmp2 =(uint32_t)aes_sbox[(tmp    )&0xff]    ;
 | 
				
			||||||
 | 
					            tmp2|=(uint32_t)aes_sbox[(tmp>> 8)&0xff]<< 8;
 | 
				
			||||||
 | 
					            tmp2|=(uint32_t)aes_sbox[(tmp>>16)&0xff]<<16;
 | 
				
			||||||
 | 
					            tmp2|=(uint32_t)aes_sbox[(tmp>>24)     ]<<24;
 | 
				
			||||||
 | 
					            tmp=tmp2;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        W[i]=W[i-words]^tmp;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* copy the iv across */
 | 
				
			||||||
 | 
					    memcpy(ctx->iv, iv, 16);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Change a key for decryption.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void AES_convert_key(AES_CTX *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					    uint32_t *k,w,t1,t2,t3,t4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    k = ctx->ks;
 | 
				
			||||||
 | 
					    k += 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i= ctx->rounds*4; i > 4; i--)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        w= *k;
 | 
				
			||||||
 | 
					        w = inv_mix_col(w,t1,t2,t3,t4);
 | 
				
			||||||
 | 
					        *k++ =w;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Encrypt a byte sequence (with a block size 16) using the AES cipher.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void AES_cbc_encrypt(AES_CTX *ctx, const uint8_t *msg, uint8_t *out, int length)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					    uint32_t tin[4], tout[4], iv[4];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memcpy(iv, ctx->iv, AES_IV_SIZE);
 | 
				
			||||||
 | 
					    for (i = 0; i < 4; i++)
 | 
				
			||||||
 | 
					        tout[i] = ntohl(iv[i]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (length -= AES_BLOCKSIZE; length >= 0; length -= AES_BLOCKSIZE)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        uint32_t msg_32[4];
 | 
				
			||||||
 | 
					        uint32_t out_32[4];
 | 
				
			||||||
 | 
					        memcpy(msg_32, msg, AES_BLOCKSIZE);
 | 
				
			||||||
 | 
					        msg += AES_BLOCKSIZE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (i = 0; i < 4; i++)
 | 
				
			||||||
 | 
					            tin[i] = ntohl(msg_32[i])^tout[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        AES_encrypt(ctx, tin);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (i = 0; i < 4; i++)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            tout[i] = tin[i]; 
 | 
				
			||||||
 | 
					            out_32[i] = htonl(tout[i]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        memcpy(out, out_32, AES_BLOCKSIZE);
 | 
				
			||||||
 | 
					        out += AES_BLOCKSIZE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0; i < 4; i++)
 | 
				
			||||||
 | 
					        iv[i] = htonl(tout[i]);
 | 
				
			||||||
 | 
					    memcpy(ctx->iv, iv, AES_IV_SIZE);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Decrypt a byte sequence (with a block size 16) using the AES cipher.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void AES_cbc_decrypt(AES_CTX *ctx, const uint8_t *msg, uint8_t *out, int length)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					    uint32_t tin[4], xor[4], tout[4], data[4], iv[4];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memcpy(iv, ctx->iv, AES_IV_SIZE);
 | 
				
			||||||
 | 
					    for (i = 0; i < 4; i++)
 | 
				
			||||||
 | 
					        xor[i] = ntohl(iv[i]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (length -= 16; length >= 0; length -= 16)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        uint32_t msg_32[4];
 | 
				
			||||||
 | 
					        uint32_t out_32[4];
 | 
				
			||||||
 | 
					        memcpy(msg_32, msg, AES_BLOCKSIZE);
 | 
				
			||||||
 | 
					        msg += AES_BLOCKSIZE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (i = 0; i < 4; i++)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            tin[i] = ntohl(msg_32[i]);
 | 
				
			||||||
 | 
					            data[i] = tin[i];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        AES_decrypt(ctx, data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (i = 0; i < 4; i++)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            tout[i] = data[i]^xor[i];
 | 
				
			||||||
 | 
					            xor[i] = tin[i];
 | 
				
			||||||
 | 
					            out_32[i] = htonl(tout[i]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        memcpy(out, out_32, AES_BLOCKSIZE);
 | 
				
			||||||
 | 
					        out += AES_BLOCKSIZE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0; i < 4; i++)
 | 
				
			||||||
 | 
					        iv[i] = htonl(xor[i]);
 | 
				
			||||||
 | 
					    memcpy(ctx->iv, iv, AES_IV_SIZE);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Encrypt a single block (16 bytes) of data
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static void AES_encrypt(const AES_CTX *ctx, uint32_t *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /* To make this code smaller, generate the sbox entries on the fly.
 | 
				
			||||||
 | 
					     * This will have a really heavy effect upon performance.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    uint32_t tmp[4];
 | 
				
			||||||
 | 
					    uint32_t tmp1, old_a0, a0, a1, a2, a3, row;
 | 
				
			||||||
 | 
					    int curr_rnd;
 | 
				
			||||||
 | 
					    int rounds = ctx->rounds; 
 | 
				
			||||||
 | 
					    const uint32_t *k = ctx->ks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Pre-round key addition */
 | 
				
			||||||
 | 
					    for (row = 0; row < 4; row++)
 | 
				
			||||||
 | 
					        data[row] ^= *(k++);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Encrypt one block. */
 | 
				
			||||||
 | 
					    for (curr_rnd = 0; curr_rnd < rounds; curr_rnd++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /* Perform ByteSub and ShiftRow operations together */
 | 
				
			||||||
 | 
					        for (row = 0; row < 4; row++)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            a0 = (uint32_t)aes_sbox[(data[row%4]>>24)&0xFF];
 | 
				
			||||||
 | 
					            a1 = (uint32_t)aes_sbox[(data[(row+1)%4]>>16)&0xFF];
 | 
				
			||||||
 | 
					            a2 = (uint32_t)aes_sbox[(data[(row+2)%4]>>8)&0xFF]; 
 | 
				
			||||||
 | 
					            a3 = (uint32_t)aes_sbox[(data[(row+3)%4])&0xFF];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            /* Perform MixColumn iff not last round */
 | 
				
			||||||
 | 
					            if (curr_rnd < (rounds - 1))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                tmp1 = a0 ^ a1 ^ a2 ^ a3;
 | 
				
			||||||
 | 
					                old_a0 = a0;
 | 
				
			||||||
 | 
					                a0 ^= tmp1 ^ AES_xtime(a0 ^ a1);
 | 
				
			||||||
 | 
					                a1 ^= tmp1 ^ AES_xtime(a1 ^ a2);
 | 
				
			||||||
 | 
					                a2 ^= tmp1 ^ AES_xtime(a2 ^ a3);
 | 
				
			||||||
 | 
					                a3 ^= tmp1 ^ AES_xtime(a3 ^ old_a0);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            tmp[row] = ((a0 << 24) | (a1 << 16) | (a2 << 8) | a3);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* KeyAddition - note that it is vital that this loop is separate from
 | 
				
			||||||
 | 
					           the MixColumn operation, which must be atomic...*/ 
 | 
				
			||||||
 | 
					        for (row = 0; row < 4; row++)
 | 
				
			||||||
 | 
					            data[row] = tmp[row] ^ *(k++);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Decrypt a single block (16 bytes) of data
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static void AES_decrypt(const AES_CTX *ctx, uint32_t *data)
 | 
				
			||||||
 | 
					{ 
 | 
				
			||||||
 | 
					    uint32_t tmp[4];
 | 
				
			||||||
 | 
					    uint32_t xt0,xt1,xt2,xt3,xt4,xt5,xt6;
 | 
				
			||||||
 | 
					    uint32_t a0, a1, a2, a3, row;
 | 
				
			||||||
 | 
					    int curr_rnd;
 | 
				
			||||||
 | 
					    int rounds = ctx->rounds;
 | 
				
			||||||
 | 
					    const uint32_t *k = ctx->ks + ((rounds+1)*4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* pre-round key addition */
 | 
				
			||||||
 | 
					    for (row=4; row > 0;row--)
 | 
				
			||||||
 | 
					        data[row-1] ^= *(--k);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Decrypt one block */
 | 
				
			||||||
 | 
					    for (curr_rnd = 0; curr_rnd < rounds; curr_rnd++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /* Perform ByteSub and ShiftRow operations together */
 | 
				
			||||||
 | 
					        for (row = 4; row > 0; row--)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            a0 = aes_isbox[(data[(row+3)%4]>>24)&0xFF];
 | 
				
			||||||
 | 
					            a1 = aes_isbox[(data[(row+2)%4]>>16)&0xFF];
 | 
				
			||||||
 | 
					            a2 = aes_isbox[(data[(row+1)%4]>>8)&0xFF];
 | 
				
			||||||
 | 
					            a3 = aes_isbox[(data[row%4])&0xFF];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            /* Perform MixColumn iff not last round */
 | 
				
			||||||
 | 
					            if (curr_rnd<(rounds-1))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                /* The MDS cofefficients (0x09, 0x0B, 0x0D, 0x0E)
 | 
				
			||||||
 | 
					                   are quite large compared to encryption; this 
 | 
				
			||||||
 | 
					                   operation slows decryption down noticeably. */
 | 
				
			||||||
 | 
					                xt0 = AES_xtime(a0^a1);
 | 
				
			||||||
 | 
					                xt1 = AES_xtime(a1^a2);
 | 
				
			||||||
 | 
					                xt2 = AES_xtime(a2^a3);
 | 
				
			||||||
 | 
					                xt3 = AES_xtime(a3^a0);
 | 
				
			||||||
 | 
					                xt4 = AES_xtime(xt0^xt1);
 | 
				
			||||||
 | 
					                xt5 = AES_xtime(xt1^xt2);
 | 
				
			||||||
 | 
					                xt6 = AES_xtime(xt4^xt5);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                xt0 ^= a1^a2^a3^xt4^xt6;
 | 
				
			||||||
 | 
					                xt1 ^= a0^a2^a3^xt5^xt6;
 | 
				
			||||||
 | 
					                xt2 ^= a0^a1^a3^xt4^xt6;
 | 
				
			||||||
 | 
					                xt3 ^= a0^a1^a2^xt5^xt6;
 | 
				
			||||||
 | 
					                tmp[row-1] = ((xt0<<24)|(xt1<<16)|(xt2<<8)|xt3);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                tmp[row-1] = ((a0<<24)|(a1<<16)|(a2<<8)|a3);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (row = 4; row > 0; row--)
 | 
				
			||||||
 | 
					            data[row-1] = tmp[row-1] ^ *(--k);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								crypto/aes.o
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								crypto/aes.o
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										1512
									
								
								crypto/bigint.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1512
									
								
								crypto/bigint.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										99
									
								
								crypto/bigint.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								crypto/bigint.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,99 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef BIGINT_HEADER
 | 
				
			||||||
 | 
					#define BIGINT_HEADER
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "crypto.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BI_CTX *bi_initialize(void);
 | 
				
			||||||
 | 
					void bi_terminate(BI_CTX *ctx);
 | 
				
			||||||
 | 
					void bi_permanent(bigint *bi);
 | 
				
			||||||
 | 
					void bi_depermanent(bigint *bi);
 | 
				
			||||||
 | 
					void bi_clear_cache(BI_CTX *ctx);
 | 
				
			||||||
 | 
					void bi_free(BI_CTX *ctx, bigint *bi);
 | 
				
			||||||
 | 
					bigint *bi_copy(bigint *bi);
 | 
				
			||||||
 | 
					bigint *bi_clone(BI_CTX *ctx, const bigint *bi);
 | 
				
			||||||
 | 
					void bi_export(BI_CTX *ctx, bigint *bi, uint8_t *data, int size);
 | 
				
			||||||
 | 
					bigint *bi_import(BI_CTX *ctx, const uint8_t *data, int len);
 | 
				
			||||||
 | 
					bigint *int_to_bi(BI_CTX *ctx, comp i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* the functions that actually do something interesting */
 | 
				
			||||||
 | 
					bigint *bi_add(BI_CTX *ctx, bigint *bia, bigint *bib);
 | 
				
			||||||
 | 
					bigint *bi_subtract(BI_CTX *ctx, bigint *bia, 
 | 
				
			||||||
 | 
					        bigint *bib, int *is_negative);
 | 
				
			||||||
 | 
					bigint *bi_divide(BI_CTX *ctx, bigint *bia, bigint *bim, int is_mod);
 | 
				
			||||||
 | 
					bigint *bi_multiply(BI_CTX *ctx, bigint *bia, bigint *bib);
 | 
				
			||||||
 | 
					bigint *bi_mod_power(BI_CTX *ctx, bigint *bi, bigint *biexp);
 | 
				
			||||||
 | 
					bigint *bi_mod_power2(BI_CTX *ctx, bigint *bi, bigint *bim, bigint *biexp);
 | 
				
			||||||
 | 
					int bi_compare(bigint *bia, bigint *bib);
 | 
				
			||||||
 | 
					void bi_set_mod(BI_CTX *ctx, bigint *bim, int mod_offset);
 | 
				
			||||||
 | 
					void bi_free_mod(BI_CTX *ctx, int mod_offset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_FULL_MODE
 | 
				
			||||||
 | 
					void bi_print(const char *label, bigint *bi);
 | 
				
			||||||
 | 
					bigint *bi_str_import(BI_CTX *ctx, const char *data);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @def bi_mod
 | 
				
			||||||
 | 
					 * Find the residue of B. bi_set_mod() must be called before hand.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define bi_mod(A, B)      bi_divide(A, B, ctx->bi_mod[ctx->mod_offset], 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * bi_residue() is technically the same as bi_mod(), but it uses the
 | 
				
			||||||
 | 
					 * appropriate reduction technique (which is bi_mod() when doing classical
 | 
				
			||||||
 | 
					 * reduction).
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#if defined(CONFIG_BIGINT_MONTGOMERY)
 | 
				
			||||||
 | 
					#define bi_residue(A, B)         bi_mont(A, B)
 | 
				
			||||||
 | 
					bigint *bi_mont(BI_CTX *ctx, bigint *bixy);
 | 
				
			||||||
 | 
					#elif defined(CONFIG_BIGINT_BARRETT)
 | 
				
			||||||
 | 
					#define bi_residue(A, B)         bi_barrett(A, B)
 | 
				
			||||||
 | 
					bigint *bi_barrett(BI_CTX *ctx, bigint *bi);
 | 
				
			||||||
 | 
					#else /* if defined(CONFIG_BIGINT_CLASSICAL) */
 | 
				
			||||||
 | 
					#define bi_residue(A, B)         bi_mod(A, B)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_BIGINT_SQUARE
 | 
				
			||||||
 | 
					bigint *bi_square(BI_CTX *ctx, bigint *bi);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define bi_square(A, B)     bi_multiply(A, bi_copy(B), B)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_BIGINT_CRT
 | 
				
			||||||
 | 
					bigint *bi_crt(BI_CTX *ctx, bigint *bi,
 | 
				
			||||||
 | 
					        bigint *dP, bigint *dQ,
 | 
				
			||||||
 | 
					        bigint *p, bigint *q,
 | 
				
			||||||
 | 
					        bigint *qInv);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								crypto/bigint.o
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								crypto/bigint.o
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										131
									
								
								crypto/bigint_impl.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								crypto/bigint_impl.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,131 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef BIGINT_IMPL_HEADER
 | 
				
			||||||
 | 
					#define BIGINT_IMPL_HEADER
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Maintain a number of precomputed variables when doing reduction */
 | 
				
			||||||
 | 
					#define BIGINT_M_OFFSET     0    /**< Normal modulo offset. */
 | 
				
			||||||
 | 
					#ifdef CONFIG_BIGINT_CRT
 | 
				
			||||||
 | 
					#define BIGINT_P_OFFSET     1    /**< p modulo offset. */
 | 
				
			||||||
 | 
					#define BIGINT_Q_OFFSET     2    /**< q module offset. */
 | 
				
			||||||
 | 
					#define BIGINT_NUM_MODS     3    /**< The number of modulus constants used. */
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define BIGINT_NUM_MODS     1    
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Architecture specific functions for big ints */
 | 
				
			||||||
 | 
					#if defined(CONFIG_INTEGER_8BIT)
 | 
				
			||||||
 | 
					#define COMP_RADIX          256U       /**< Max component + 1 */
 | 
				
			||||||
 | 
					#define COMP_MAX            0xFFFFU/**< (Max dbl comp -1) */
 | 
				
			||||||
 | 
					#define COMP_BIT_SIZE       8   /**< Number of bits in a component. */
 | 
				
			||||||
 | 
					#define COMP_BYTE_SIZE      1   /**< Number of bytes in a component. */
 | 
				
			||||||
 | 
					#define COMP_NUM_NIBBLES    2   /**< Used For diagnostics only. */
 | 
				
			||||||
 | 
					typedef uint8_t comp;	        /**< A single precision component. */
 | 
				
			||||||
 | 
					typedef uint16_t long_comp;     /**< A double precision component. */
 | 
				
			||||||
 | 
					typedef int16_t slong_comp;     /**< A signed double precision component. */
 | 
				
			||||||
 | 
					#elif defined(CONFIG_INTEGER_16BIT)
 | 
				
			||||||
 | 
					#define COMP_RADIX          65536U       /**< Max component + 1 */
 | 
				
			||||||
 | 
					#define COMP_MAX            0xFFFFFFFFU/**< (Max dbl comp -1) */
 | 
				
			||||||
 | 
					#define COMP_BIT_SIZE       16  /**< Number of bits in a component. */
 | 
				
			||||||
 | 
					#define COMP_BYTE_SIZE      2   /**< Number of bytes in a component. */
 | 
				
			||||||
 | 
					#define COMP_NUM_NIBBLES    4   /**< Used For diagnostics only. */
 | 
				
			||||||
 | 
					typedef uint16_t comp;	        /**< A single precision component. */
 | 
				
			||||||
 | 
					typedef uint32_t long_comp;     /**< A double precision component. */
 | 
				
			||||||
 | 
					typedef int32_t slong_comp;     /**< A signed double precision component. */
 | 
				
			||||||
 | 
					#else /* regular 32 bit */
 | 
				
			||||||
 | 
					#ifdef WIN32
 | 
				
			||||||
 | 
					#define COMP_RADIX          4294967296i64         
 | 
				
			||||||
 | 
					#define COMP_MAX            0xFFFFFFFFFFFFFFFFui64
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define COMP_RADIX          4294967296ULL         /**< Max component + 1 */
 | 
				
			||||||
 | 
					#define COMP_MAX            0xFFFFFFFFFFFFFFFFULL/**< (Max dbl comp -1) */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#define COMP_BIT_SIZE       32  /**< Number of bits in a component. */
 | 
				
			||||||
 | 
					#define COMP_BYTE_SIZE      4   /**< Number of bytes in a component. */
 | 
				
			||||||
 | 
					#define COMP_NUM_NIBBLES    8   /**< Used For diagnostics only. */
 | 
				
			||||||
 | 
					typedef uint32_t comp;	        /**< A single precision component. */
 | 
				
			||||||
 | 
					typedef uint64_t long_comp;     /**< A double precision component. */
 | 
				
			||||||
 | 
					typedef int64_t slong_comp;     /**< A signed double precision component. */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @struct  _bigint
 | 
				
			||||||
 | 
					 * @brief A big integer basic object
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct _bigint
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    struct _bigint* next;       /**< The next bigint in the cache. */
 | 
				
			||||||
 | 
					    short size;                 /**< The number of components in this bigint. */
 | 
				
			||||||
 | 
					    short max_comps;            /**< The heapsize allocated for this bigint */
 | 
				
			||||||
 | 
					    int refs;                   /**< An internal reference count. */
 | 
				
			||||||
 | 
					    comp* comps;                /**< A ptr to the actual component data */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct _bigint bigint;  /**< An alias for _bigint */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Maintains the state of the cache, and a number of variables used in 
 | 
				
			||||||
 | 
					 * reduction.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					typedef struct /**< A big integer "session" context. */
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    bigint *active_list;                    /**< Bigints currently used. */
 | 
				
			||||||
 | 
					    bigint *free_list;                      /**< Bigints not used. */
 | 
				
			||||||
 | 
					    bigint *bi_radix;                       /**< The radix used. */
 | 
				
			||||||
 | 
					    bigint *bi_mod[BIGINT_NUM_MODS];        /**< modulus */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(CONFIG_BIGINT_MONTGOMERY)
 | 
				
			||||||
 | 
					    bigint *bi_RR_mod_m[BIGINT_NUM_MODS];   /**< R^2 mod m */
 | 
				
			||||||
 | 
					    bigint *bi_R_mod_m[BIGINT_NUM_MODS];    /**< R mod m */
 | 
				
			||||||
 | 
					    comp N0_dash[BIGINT_NUM_MODS];
 | 
				
			||||||
 | 
					#elif defined(CONFIG_BIGINT_BARRETT)
 | 
				
			||||||
 | 
					    bigint *bi_mu[BIGINT_NUM_MODS];         /**< Storage for mu */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    bigint *bi_normalised_mod[BIGINT_NUM_MODS]; /**< Normalised mod storage. */
 | 
				
			||||||
 | 
					    bigint **g;                 /**< Used by sliding-window. */
 | 
				
			||||||
 | 
					    int window;                 /**< The size of the sliding window */
 | 
				
			||||||
 | 
					    int active_count;           /**< Number of active bigints. */
 | 
				
			||||||
 | 
					    int free_count;             /**< Number of free bigints. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_BIGINT_MONTGOMERY
 | 
				
			||||||
 | 
					    uint8_t use_classical;      /**< Use classical reduction. */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    uint8_t mod_offset;         /**< The mod offset we are using */
 | 
				
			||||||
 | 
					} BI_CTX;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef WIN32
 | 
				
			||||||
 | 
					#define max(a,b) ((a)>(b)?(a):(b))  /**< Find the maximum of 2 numbers. */
 | 
				
			||||||
 | 
					#define min(a,b) ((a)<(b)?(a):(b))  /**< Find the minimum of 2 numbers. */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define PERMANENT           0x7FFF55AA  /**< A magic number for permanents. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										230
									
								
								crypto/crypto.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										230
									
								
								crypto/crypto.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,230 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @file crypto.h
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef HEADER_CRYPTO_H
 | 
				
			||||||
 | 
					#define HEADER_CRYPTO_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					extern "C" {
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					#include "bigint_impl.h"
 | 
				
			||||||
 | 
					#include "bigint.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef STDCALL
 | 
				
			||||||
 | 
					#define STDCALL
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#ifndef EXP_FUNC
 | 
				
			||||||
 | 
					#define EXP_FUNC
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* enable features based on a 'super-set' capbaility. */
 | 
				
			||||||
 | 
					#if defined(CONFIG_SSL_FULL_MODE) 
 | 
				
			||||||
 | 
					#define CONFIG_SSL_ENABLE_CLIENT
 | 
				
			||||||
 | 
					#define CONFIG_SSL_CERT_VERIFICATION
 | 
				
			||||||
 | 
					#elif defined(CONFIG_SSL_ENABLE_CLIENT)
 | 
				
			||||||
 | 
					#define CONFIG_SSL_CERT_VERIFICATION
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**************************************************************************
 | 
				
			||||||
 | 
					 * AES declarations 
 | 
				
			||||||
 | 
					 **************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define AES_MAXROUNDS			14
 | 
				
			||||||
 | 
					#define AES_BLOCKSIZE           16
 | 
				
			||||||
 | 
					#define AES_IV_SIZE             16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct aes_key_st 
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint16_t rounds;
 | 
				
			||||||
 | 
					    uint16_t key_size;
 | 
				
			||||||
 | 
					    uint32_t ks[(AES_MAXROUNDS+1)*8];
 | 
				
			||||||
 | 
					    uint8_t iv[AES_IV_SIZE];
 | 
				
			||||||
 | 
					} AES_CTX;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    AES_MODE_128,
 | 
				
			||||||
 | 
					    AES_MODE_256
 | 
				
			||||||
 | 
					} AES_MODE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void AES_set_key(AES_CTX *ctx, const uint8_t *key, 
 | 
				
			||||||
 | 
					        const uint8_t *iv, AES_MODE mode);
 | 
				
			||||||
 | 
					void AES_cbc_encrypt(AES_CTX *ctx, const uint8_t *msg, 
 | 
				
			||||||
 | 
					        uint8_t *out, int length);
 | 
				
			||||||
 | 
					void AES_cbc_decrypt(AES_CTX *ks, const uint8_t *in, uint8_t *out, int length);
 | 
				
			||||||
 | 
					void AES_convert_key(AES_CTX *ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**************************************************************************
 | 
				
			||||||
 | 
					 * RC4 declarations 
 | 
				
			||||||
 | 
					 **************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct 
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint8_t x, y, m[256];
 | 
				
			||||||
 | 
					} RC4_CTX;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void RC4_setup(RC4_CTX *s, const uint8_t *key, int length);
 | 
				
			||||||
 | 
					void RC4_crypt(RC4_CTX *s, const uint8_t *msg, uint8_t *data, int length);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**************************************************************************
 | 
				
			||||||
 | 
					 * SHA1 declarations 
 | 
				
			||||||
 | 
					 **************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SHA1_SIZE   20
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 *  This structure will hold context information for the SHA-1
 | 
				
			||||||
 | 
					 *  hashing operation
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					typedef struct 
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint32_t Intermediate_Hash[SHA1_SIZE/4]; /* Message Digest */
 | 
				
			||||||
 | 
					    uint32_t Length_Low;            /* Message length in bits */
 | 
				
			||||||
 | 
					    uint32_t Length_High;           /* Message length in bits */
 | 
				
			||||||
 | 
					    uint16_t Message_Block_Index;   /* Index into message block array   */
 | 
				
			||||||
 | 
					    uint8_t Message_Block[64];      /* 512-bit message blocks */
 | 
				
			||||||
 | 
					} SHA1_CTX;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SHA1_Init(SHA1_CTX *);
 | 
				
			||||||
 | 
					void SHA1_Update(SHA1_CTX *, const uint8_t * msg, int len);
 | 
				
			||||||
 | 
					void SHA1_Final(uint8_t *digest, SHA1_CTX *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**************************************************************************
 | 
				
			||||||
 | 
					 * MD2 declarations 
 | 
				
			||||||
 | 
					 **************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MD2_SIZE 16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**************************************************************************
 | 
				
			||||||
 | 
					 * MD5 declarations 
 | 
				
			||||||
 | 
					 **************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MD5_SIZE    16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct 
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  uint32_t state[4];        /* state (ABCD) */
 | 
				
			||||||
 | 
					  uint32_t count[2];        /* number of bits, modulo 2^64 (lsb first) */
 | 
				
			||||||
 | 
					  uint8_t buffer[64];       /* input buffer */
 | 
				
			||||||
 | 
					} MD5_CTX;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EXP_FUNC void STDCALL MD5_Init(MD5_CTX *);
 | 
				
			||||||
 | 
					EXP_FUNC void STDCALL MD5_Update(MD5_CTX *, const uint8_t *msg, int len);
 | 
				
			||||||
 | 
					EXP_FUNC void STDCALL MD5_Final(uint8_t *digest, MD5_CTX *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**************************************************************************
 | 
				
			||||||
 | 
					 * HMAC declarations 
 | 
				
			||||||
 | 
					 **************************************************************************/
 | 
				
			||||||
 | 
					void hmac_md5(const uint8_t *msg, int length, const uint8_t *key, 
 | 
				
			||||||
 | 
					        int key_len, uint8_t *digest);
 | 
				
			||||||
 | 
					void hmac_sha1(const uint8_t *msg, int length, const uint8_t *key, 
 | 
				
			||||||
 | 
					        int key_len, uint8_t *digest);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**************************************************************************
 | 
				
			||||||
 | 
					 * RSA declarations 
 | 
				
			||||||
 | 
					 **************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct 
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    bigint *m;              /* modulus */
 | 
				
			||||||
 | 
					    bigint *e;              /* public exponent */
 | 
				
			||||||
 | 
					    bigint *d;              /* private exponent */
 | 
				
			||||||
 | 
					#ifdef CONFIG_BIGINT_CRT
 | 
				
			||||||
 | 
					    bigint *p;              /* p as in m = pq */
 | 
				
			||||||
 | 
					    bigint *q;              /* q as in m = pq */
 | 
				
			||||||
 | 
					    bigint *dP;             /* d mod (p-1) */
 | 
				
			||||||
 | 
					    bigint *dQ;             /* d mod (q-1) */
 | 
				
			||||||
 | 
					    bigint *qInv;           /* q^-1 mod p */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    int num_octets;
 | 
				
			||||||
 | 
					    BI_CTX *bi_ctx;
 | 
				
			||||||
 | 
					} RSA_CTX;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void RSA_priv_key_new(RSA_CTX **rsa_ctx, 
 | 
				
			||||||
 | 
					        const uint8_t *modulus, int mod_len,
 | 
				
			||||||
 | 
					        const uint8_t *pub_exp, int pub_len,
 | 
				
			||||||
 | 
					        const uint8_t *priv_exp, int priv_len
 | 
				
			||||||
 | 
					#ifdef CONFIG_BIGINT_CRT
 | 
				
			||||||
 | 
					      , const uint8_t *p, int p_len,
 | 
				
			||||||
 | 
					        const uint8_t *q, int q_len,
 | 
				
			||||||
 | 
					        const uint8_t *dP, int dP_len,
 | 
				
			||||||
 | 
					        const uint8_t *dQ, int dQ_len,
 | 
				
			||||||
 | 
					        const uint8_t *qInv, int qInv_len
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					void RSA_pub_key_new(RSA_CTX **rsa_ctx, 
 | 
				
			||||||
 | 
					        const uint8_t *modulus, int mod_len,
 | 
				
			||||||
 | 
					        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);
 | 
				
			||||||
 | 
					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,
 | 
				
			||||||
 | 
					        bigint *modulus, bigint *pub_exp);
 | 
				
			||||||
 | 
					bigint *RSA_public(const RSA_CTX * c, bigint *bi_msg);
 | 
				
			||||||
 | 
					int RSA_encrypt(const RSA_CTX *ctx, const uint8_t *in_data, uint16_t in_len, 
 | 
				
			||||||
 | 
					        uint8_t *out_data, int is_signing);
 | 
				
			||||||
 | 
					void RSA_print(const RSA_CTX *ctx);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**************************************************************************
 | 
				
			||||||
 | 
					 * RNG declarations 
 | 
				
			||||||
 | 
					 **************************************************************************/
 | 
				
			||||||
 | 
					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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif 
 | 
				
			||||||
							
								
								
									
										367
									
								
								crypto/crypto_misc.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										367
									
								
								crypto/crypto_misc.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,367 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Some misc. routines to help things out
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <stdarg.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include "os_port.h"
 | 
				
			||||||
 | 
					#include "crypto_misc.h"
 | 
				
			||||||
 | 
					#ifdef CONFIG_WIN32_USE_CRYPTO_LIB
 | 
				
			||||||
 | 
					#include "wincrypt.h"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef WIN32
 | 
				
			||||||
 | 
					static int rng_fd = -1;
 | 
				
			||||||
 | 
					#elif defined(CONFIG_WIN32_USE_CRYPTO_LIB)
 | 
				
			||||||
 | 
					static HCRYPTPROV gCryptProv;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if (!defined(CONFIG_USE_DEV_URANDOM) && !defined(CONFIG_WIN32_USE_CRYPTO_LIB))
 | 
				
			||||||
 | 
					/* change to processor registers as appropriate */
 | 
				
			||||||
 | 
					#define ENTROPY_POOL_SIZE 32
 | 
				
			||||||
 | 
					#define ENTROPY_COUNTER1 ((((uint64_t)tv.tv_sec)<<32) | tv.tv_usec)
 | 
				
			||||||
 | 
					#define ENTROPY_COUNTER2 rand()
 | 
				
			||||||
 | 
					static uint8_t entropy_pool[ENTROPY_POOL_SIZE];
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const char * const unsupported_str = "Error: Feature not supported\n";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef CONFIG_SSL_SKELETON_MODE
 | 
				
			||||||
 | 
					/** 
 | 
				
			||||||
 | 
					 * Retrieve a file and put it into memory
 | 
				
			||||||
 | 
					 * @return The size of the file, or -1 on failure.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int get_file(const char *filename, uint8_t **buf)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int total_bytes = 0;
 | 
				
			||||||
 | 
					    int bytes_read = 0; 
 | 
				
			||||||
 | 
					    int filesize;
 | 
				
			||||||
 | 
					    FILE *stream = fopen(filename, "rb");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (stream == NULL)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_FULL_MODE         
 | 
				
			||||||
 | 
					        printf("file '%s' does not exist\n", filename); TTY_FLUSH();
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Win CE doesn't support stat() */
 | 
				
			||||||
 | 
					    fseek(stream, 0, SEEK_END);
 | 
				
			||||||
 | 
					    filesize = ftell(stream);
 | 
				
			||||||
 | 
					    *buf = (uint8_t *)malloc(filesize);
 | 
				
			||||||
 | 
					    fseek(stream, 0, SEEK_SET);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    do
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        bytes_read = fread(*buf+total_bytes, 1, filesize-total_bytes, stream);
 | 
				
			||||||
 | 
					        total_bytes += bytes_read;
 | 
				
			||||||
 | 
					    } while (total_bytes < filesize && bytes_read > 0);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    fclose(stream);
 | 
				
			||||||
 | 
					    return filesize;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Initialise the Random Number Generator engine.
 | 
				
			||||||
 | 
					 * - On Win32 use the platform SDK's crypto engine.
 | 
				
			||||||
 | 
					 * - On Linux use /dev/urandom
 | 
				
			||||||
 | 
					 * - 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);
 | 
				
			||||||
 | 
					#elif defined(WIN32) && defined(CONFIG_WIN32_USE_CRYPTO_LIB)
 | 
				
			||||||
 | 
					    if (!CryptAcquireContext(&gCryptProv, 
 | 
				
			||||||
 | 
					                      NULL, NULL, PROV_RSA_FULL, 0))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (GetLastError() == NTE_BAD_KEYSET &&
 | 
				
			||||||
 | 
					                !CryptAcquireContext(&gCryptProv, 
 | 
				
			||||||
 | 
					                       NULL, 
 | 
				
			||||||
 | 
					                       NULL, 
 | 
				
			||||||
 | 
					                       PROV_RSA_FULL, 
 | 
				
			||||||
 | 
					                       CRYPT_NEWKEYSET))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            printf("CryptoLib: %x\n", unsupported_str, GetLastError());
 | 
				
			||||||
 | 
					            exit(1);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					    /* start of with a stack to copy across */
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					    memcpy(entropy_pool, &i, ENTROPY_POOL_SIZE);
 | 
				
			||||||
 | 
					    srand((unsigned int)&i); 
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * If no /dev/urandom, then initialise the RNG with something interesting.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EXP_FUNC void STDCALL RNG_custom_init(const uint8_t *seed_buf, int size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#if defined(WIN32) || defined(CONFIG_WIN32_USE_CRYPTO_LIB)
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0; i < ENTROPY_POOL_SIZE && i < size; i++)
 | 
				
			||||||
 | 
					        entropy_pool[i] ^= seed_buf[i];
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Terminate the RNG engine.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EXP_FUNC void STDCALL RNG_terminate(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#ifndef WIN32
 | 
				
			||||||
 | 
					    close(rng_fd);
 | 
				
			||||||
 | 
					#elif defined(CONFIG_WIN32_USE_CRYPTO_LIB)
 | 
				
			||||||
 | 
					    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)
 | 
				
			||||||
 | 
					{   
 | 
				
			||||||
 | 
					#if !defined(WIN32) && defined(CONFIG_USE_DEV_URANDOM)
 | 
				
			||||||
 | 
					    /* use the Linux default */
 | 
				
			||||||
 | 
					    read(rng_fd, rand_data, num_rand_bytes);    /* read from /dev/urandom */
 | 
				
			||||||
 | 
					#elif defined(WIN32) && defined(CONFIG_WIN32_USE_CRYPTO_LIB)
 | 
				
			||||||
 | 
					    /* use Microsoft Crypto Libraries */
 | 
				
			||||||
 | 
					    CryptGenRandom(gCryptProv, num_rand_bytes, rand_data);
 | 
				
			||||||
 | 
					#else   /* nothing else to use, so use a custom RNG */
 | 
				
			||||||
 | 
					    /* The method we use when we've got nothing better. Use RC4, time 
 | 
				
			||||||
 | 
					       and a couple of random seeds to generate a random sequence */
 | 
				
			||||||
 | 
					    RC4_CTX rng_ctx;
 | 
				
			||||||
 | 
					    struct timeval tv;
 | 
				
			||||||
 | 
					    MD5_CTX rng_digest_ctx;
 | 
				
			||||||
 | 
					    uint8_t digest[MD5_SIZE];
 | 
				
			||||||
 | 
					    uint64_t *ep;
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* A proper implementation would use counters etc for entropy */
 | 
				
			||||||
 | 
					    gettimeofday(&tv, NULL);    
 | 
				
			||||||
 | 
					    ep = (uint64_t *)entropy_pool;
 | 
				
			||||||
 | 
					    ep[0] ^= ENTROPY_COUNTER1;
 | 
				
			||||||
 | 
					    ep[1] ^= ENTROPY_COUNTER2; 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* use a digested version of the entropy pool as a key */
 | 
				
			||||||
 | 
					    MD5_Init(&rng_digest_ctx);
 | 
				
			||||||
 | 
					    MD5_Update(&rng_digest_ctx, entropy_pool, ENTROPY_POOL_SIZE);
 | 
				
			||||||
 | 
					    MD5_Final(digest, &rng_digest_ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* come up with the random sequence */
 | 
				
			||||||
 | 
					    RC4_setup(&rng_ctx, digest, MD5_SIZE); /* use as a key */
 | 
				
			||||||
 | 
					    memcpy(rand_data, entropy_pool, num_rand_bytes < ENTROPY_POOL_SIZE ?
 | 
				
			||||||
 | 
									num_rand_bytes : ENTROPY_POOL_SIZE);
 | 
				
			||||||
 | 
					    RC4_crypt(&rng_ctx, rand_data, rand_data, num_rand_bytes);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* move things along */
 | 
				
			||||||
 | 
					    for (i = ENTROPY_POOL_SIZE-1; i >= MD5_SIZE ; i--)
 | 
				
			||||||
 | 
					        entropy_pool[i] = entropy_pool[i-MD5_SIZE];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* insert the digest at the start of the entropy pool */
 | 
				
			||||||
 | 
					    memcpy(entropy_pool, digest, MD5_SIZE);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 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 i;
 | 
				
			||||||
 | 
					    get_random(num_rand_bytes, rand_data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0; i < num_rand_bytes; i++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        while (rand_data[i] == 0)  /* can't be 0 */
 | 
				
			||||||
 | 
					            rand_data[i] = (uint8_t)(rand());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Some useful diagnostic routines
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#if defined(CONFIG_SSL_FULL_MODE) || defined(CONFIG_DEBUG)
 | 
				
			||||||
 | 
					int hex_finish;
 | 
				
			||||||
 | 
					int hex_index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void print_hex_init(int finish)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    hex_finish = finish;
 | 
				
			||||||
 | 
					    hex_index = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void print_hex(uint8_t hex)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    static int column;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (hex_index == 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        column = 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    printf("%02x ", hex);
 | 
				
			||||||
 | 
					    if (++column == 8)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        printf(": ");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (column >= 16)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        printf("\n");
 | 
				
			||||||
 | 
					        column = 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (++hex_index >= hex_finish && column > 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        printf("\n");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Spit out a blob of data for diagnostics. The data is is a nice column format
 | 
				
			||||||
 | 
					 * for easy reading.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param format   [in]    The string (with possible embedded format characters)
 | 
				
			||||||
 | 
					 * @param size     [in]    The number of numbers to print
 | 
				
			||||||
 | 
					 * @param data     [in]    The start of data to use
 | 
				
			||||||
 | 
					 * @param ...      [in]    Any additional arguments
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EXP_FUNC void STDCALL print_blob(const char *format, 
 | 
				
			||||||
 | 
					        const uint8_t *data, int size, ...)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					    char tmp[80];
 | 
				
			||||||
 | 
					    va_list(ap);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    va_start(ap, size);
 | 
				
			||||||
 | 
					    sprintf(tmp, "%s\n", format);
 | 
				
			||||||
 | 
					    vprintf(tmp, ap);
 | 
				
			||||||
 | 
					    print_hex_init(size);
 | 
				
			||||||
 | 
					    for (i = 0; i < size; i++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        print_hex(data[i]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    va_end(ap);
 | 
				
			||||||
 | 
					    TTY_FLUSH();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#elif defined(WIN32)
 | 
				
			||||||
 | 
					/* VC6.0 doesn't handle variadic macros */
 | 
				
			||||||
 | 
					EXP_FUNC void STDCALL print_blob(const char *format, const unsigned char *data,
 | 
				
			||||||
 | 
					        int size, ...) {}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(CONFIG_SSL_HAS_PEM) || defined(CONFIG_HTTP_HAS_AUTHORIZATION)
 | 
				
			||||||
 | 
					/* base64 to binary lookup table */
 | 
				
			||||||
 | 
					static const uint8_t map[128] =
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
 | 
				
			||||||
 | 
					    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
 | 
				
			||||||
 | 
					    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
 | 
				
			||||||
 | 
					    255, 255, 255, 255, 255, 255, 255,  62, 255, 255, 255,  63,
 | 
				
			||||||
 | 
					    52,  53,  54,  55,  56,  57,  58,  59,  60,  61, 255, 255,
 | 
				
			||||||
 | 
					    255, 254, 255, 255, 255,   0,   1,   2,   3,   4,   5,   6,
 | 
				
			||||||
 | 
					    7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,  18,
 | 
				
			||||||
 | 
					    19,  20,  21,  22,  23,  24,  25, 255, 255, 255, 255, 255,
 | 
				
			||||||
 | 
					    255,  26,  27,  28,  29,  30,  31,  32,  33,  34,  35,  36,
 | 
				
			||||||
 | 
					    37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,  48,
 | 
				
			||||||
 | 
					    49,  50,  51, 255, 255, 255, 255, 255
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EXP_FUNC int STDCALL base64_decode(const char *in, int len,
 | 
				
			||||||
 | 
					                    uint8_t *out, int *outlen)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int g, t, x, y, z;
 | 
				
			||||||
 | 
					    uint8_t c;
 | 
				
			||||||
 | 
					    int ret = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g = 3;
 | 
				
			||||||
 | 
					    for (x = y = z = t = 0; x < len; x++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ((c = map[in[x]&0x7F]) == 0xff)
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (c == 254)   /* this is the end... */
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            c = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (--g < 0)
 | 
				
			||||||
 | 
					                goto error;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else if (g != 3) /* only allow = at end */
 | 
				
			||||||
 | 
					            goto error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        t = (t<<6) | c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (++y == 4)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            out[z++] = (uint8_t)((t>>16)&255);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (g > 1)
 | 
				
			||||||
 | 
					                out[z++] = (uint8_t)((t>>8)&255);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (g > 2)
 | 
				
			||||||
 | 
					                out[z++] = (uint8_t)(t&255);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            y = t = 0;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* check that we don't go past the output buffer */
 | 
				
			||||||
 | 
					        if (z > *outlen) 
 | 
				
			||||||
 | 
					            goto error;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (y != 0)
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    *outlen = z;
 | 
				
			||||||
 | 
					    ret = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error:
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_FULL_MODE
 | 
				
			||||||
 | 
					    if (ret < 0)
 | 
				
			||||||
 | 
					        printf("Error: Invalid base64\n"); TTY_FLUSH();
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    TTY_FLUSH();
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										105
									
								
								crypto/hmac.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								crypto/hmac.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,105 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * HMAC implementation - This code was originally taken from RFC2104
 | 
				
			||||||
 | 
					 * See http://www.ietf.org/rfc/rfc2104.txt and
 | 
				
			||||||
 | 
					 * http://www.faqs.org/rfcs/rfc2202.html
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include "os_port.h"
 | 
				
			||||||
 | 
					#include "crypto.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Perform HMAC-MD5
 | 
				
			||||||
 | 
					 * NOTE: does not handle keys larger than the block size.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void hmac_md5(const uint8_t *msg, int length, const uint8_t *key, 
 | 
				
			||||||
 | 
					        int key_len, uint8_t *digest)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    MD5_CTX context;
 | 
				
			||||||
 | 
					    uint8_t k_ipad[64];
 | 
				
			||||||
 | 
					    uint8_t k_opad[64];
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memset(k_ipad, 0, sizeof k_ipad);
 | 
				
			||||||
 | 
					    memset(k_opad, 0, sizeof k_opad);
 | 
				
			||||||
 | 
					    memcpy(k_ipad, key, key_len);
 | 
				
			||||||
 | 
					    memcpy(k_opad, key, key_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0; i < 64; i++) 
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        k_ipad[i] ^= 0x36;
 | 
				
			||||||
 | 
					        k_opad[i] ^= 0x5c;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    MD5_Init(&context);
 | 
				
			||||||
 | 
					    MD5_Update(&context, k_ipad, 64);
 | 
				
			||||||
 | 
					    MD5_Update(&context, msg, length);
 | 
				
			||||||
 | 
					    MD5_Final(digest, &context);
 | 
				
			||||||
 | 
					    MD5_Init(&context);
 | 
				
			||||||
 | 
					    MD5_Update(&context, k_opad, 64);
 | 
				
			||||||
 | 
					    MD5_Update(&context, digest, MD5_SIZE);
 | 
				
			||||||
 | 
					    MD5_Final(digest, &context);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Perform HMAC-SHA1
 | 
				
			||||||
 | 
					 * NOTE: does not handle keys larger than the block size.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void hmac_sha1(const uint8_t *msg, int length, const uint8_t *key, 
 | 
				
			||||||
 | 
					        int key_len, uint8_t *digest)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    SHA1_CTX context;
 | 
				
			||||||
 | 
					    uint8_t k_ipad[64];
 | 
				
			||||||
 | 
					    uint8_t k_opad[64];
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memset(k_ipad, 0, sizeof k_ipad);
 | 
				
			||||||
 | 
					    memset(k_opad, 0, sizeof k_opad);
 | 
				
			||||||
 | 
					    memcpy(k_ipad, key, key_len);
 | 
				
			||||||
 | 
					    memcpy(k_opad, key, key_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0; i < 64; i++) 
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        k_ipad[i] ^= 0x36;
 | 
				
			||||||
 | 
					        k_opad[i] ^= 0x5c;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    SHA1_Init(&context);
 | 
				
			||||||
 | 
					    SHA1_Update(&context, k_ipad, 64);
 | 
				
			||||||
 | 
					    SHA1_Update(&context, msg, length);
 | 
				
			||||||
 | 
					    SHA1_Final(digest, &context);
 | 
				
			||||||
 | 
					    SHA1_Init(&context);
 | 
				
			||||||
 | 
					    SHA1_Update(&context, k_opad, 64);
 | 
				
			||||||
 | 
					    SHA1_Update(&context, digest, SHA1_SIZE);
 | 
				
			||||||
 | 
					    SHA1_Final(digest, &context);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								crypto/hmac.o
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								crypto/hmac.o
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										162
									
								
								crypto/md2.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								crypto/md2.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,162 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								crypto/md2.o
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								crypto/md2.o
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										294
									
								
								crypto/md5.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										294
									
								
								crypto/md5.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,294 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * This file implements the MD5 algorithm as defined in RFC1321
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include "os_port.h"
 | 
				
			||||||
 | 
					#include "crypto.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Constants for MD5Transform routine.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define S11 7
 | 
				
			||||||
 | 
					#define S12 12
 | 
				
			||||||
 | 
					#define S13 17
 | 
				
			||||||
 | 
					#define S14 22
 | 
				
			||||||
 | 
					#define S21 5
 | 
				
			||||||
 | 
					#define S22 9
 | 
				
			||||||
 | 
					#define S23 14
 | 
				
			||||||
 | 
					#define S24 20
 | 
				
			||||||
 | 
					#define S31 4
 | 
				
			||||||
 | 
					#define S32 11
 | 
				
			||||||
 | 
					#define S33 16
 | 
				
			||||||
 | 
					#define S34 23
 | 
				
			||||||
 | 
					#define S41 6
 | 
				
			||||||
 | 
					#define S42 10
 | 
				
			||||||
 | 
					#define S43 15
 | 
				
			||||||
 | 
					#define S44 21
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* ----- static functions ----- */
 | 
				
			||||||
 | 
					static void MD5Transform(uint32_t state[4], const uint8_t block[64]);
 | 
				
			||||||
 | 
					static void Encode(uint8_t *output, uint32_t *input, uint32_t len);
 | 
				
			||||||
 | 
					static void Decode(uint32_t *output, const uint8_t *input, uint32_t len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const uint8_t 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
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* F, G, H and I are basic MD5 functions.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
 | 
				
			||||||
 | 
					#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
 | 
				
			||||||
 | 
					#define H(x, y, z) ((x) ^ (y) ^ (z))
 | 
				
			||||||
 | 
					#define I(x, y, z) ((y) ^ ((x) | (~z)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* ROTATE_LEFT rotates x left n bits.  */
 | 
				
			||||||
 | 
					#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
 | 
				
			||||||
 | 
					   Rotation is separate from addition to prevent recomputation.  */
 | 
				
			||||||
 | 
					#define FF(a, b, c, d, x, s, ac) { \
 | 
				
			||||||
 | 
					    (a) += F ((b), (c), (d)) + (x) + (uint32_t)(ac); \
 | 
				
			||||||
 | 
					    (a) = ROTATE_LEFT ((a), (s)); \
 | 
				
			||||||
 | 
					    (a) += (b); \
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					#define GG(a, b, c, d, x, s, ac) { \
 | 
				
			||||||
 | 
					    (a) += G ((b), (c), (d)) + (x) + (uint32_t)(ac); \
 | 
				
			||||||
 | 
					    (a) = ROTATE_LEFT ((a), (s)); \
 | 
				
			||||||
 | 
					    (a) += (b); \
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					#define HH(a, b, c, d, x, s, ac) { \
 | 
				
			||||||
 | 
					    (a) += H ((b), (c), (d)) + (x) + (uint32_t)(ac); \
 | 
				
			||||||
 | 
					    (a) = ROTATE_LEFT ((a), (s)); \
 | 
				
			||||||
 | 
					    (a) += (b); \
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					#define II(a, b, c, d, x, s, ac) { \
 | 
				
			||||||
 | 
					    (a) += I ((b), (c), (d)) + (x) + (uint32_t)(ac); \
 | 
				
			||||||
 | 
					    (a) = ROTATE_LEFT ((a), (s)); \
 | 
				
			||||||
 | 
					    (a) += (b); \
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * MD5 initialization - begins an MD5 operation, writing a new ctx.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EXP_FUNC void STDCALL MD5_Init(MD5_CTX *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ctx->count[0] = ctx->count[1] = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Load magic initialization constants.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    ctx->state[0] = 0x67452301;
 | 
				
			||||||
 | 
					    ctx->state[1] = 0xefcdab89;
 | 
				
			||||||
 | 
					    ctx->state[2] = 0x98badcfe;
 | 
				
			||||||
 | 
					    ctx->state[3] = 0x10325476;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Accepts an array of octets as the next portion of the message.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EXP_FUNC void STDCALL MD5_Update(MD5_CTX *ctx, const uint8_t * msg, int len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint32_t x;
 | 
				
			||||||
 | 
					    int i, partLen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Compute number of bytes mod 64 */
 | 
				
			||||||
 | 
					    x = (uint32_t)((ctx->count[0] >> 3) & 0x3F);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Update number of bits */
 | 
				
			||||||
 | 
					    if ((ctx->count[0] += ((uint32_t)len << 3)) < ((uint32_t)len << 3))
 | 
				
			||||||
 | 
					        ctx->count[1]++;
 | 
				
			||||||
 | 
					    ctx->count[1] += ((uint32_t)len >> 29);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    partLen = 64 - x;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Transform as many times as possible.  */
 | 
				
			||||||
 | 
					    if (len >= partLen) 
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        memcpy(&ctx->buffer[x], msg, partLen);
 | 
				
			||||||
 | 
					        MD5Transform(ctx->state, ctx->buffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (i = partLen; i + 63 < len; i += 64)
 | 
				
			||||||
 | 
					            MD5Transform(ctx->state, &msg[i]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        x = 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        i = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Buffer remaining input */
 | 
				
			||||||
 | 
					    memcpy(&ctx->buffer[x], &msg[i], len-i);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Return the 128-bit message digest into the user's array
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EXP_FUNC void STDCALL MD5_Final(uint8_t *digest, MD5_CTX *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint8_t bits[8];
 | 
				
			||||||
 | 
					    uint32_t x, padLen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Save number of bits */
 | 
				
			||||||
 | 
					    Encode(bits, ctx->count, 8);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Pad out to 56 mod 64.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    x = (uint32_t)((ctx->count[0] >> 3) & 0x3f);
 | 
				
			||||||
 | 
					    padLen = (x < 56) ? (56 - x) : (120 - x);
 | 
				
			||||||
 | 
					    MD5_Update(ctx, PADDING, padLen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Append length (before padding) */
 | 
				
			||||||
 | 
					    MD5_Update(ctx, bits, 8);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Store state in digest */
 | 
				
			||||||
 | 
					    Encode(digest, ctx->state, MD5_SIZE);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * MD5 basic transformation. Transforms state based on block.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static void MD5Transform(uint32_t state[4], const uint8_t block[64])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint32_t a = state[0], b = state[1], c = state[2], 
 | 
				
			||||||
 | 
					             d = state[3], x[MD5_SIZE];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Decode(x, block, 64);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Round 1 */
 | 
				
			||||||
 | 
					    FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
 | 
				
			||||||
 | 
					    FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
 | 
				
			||||||
 | 
					    FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
 | 
				
			||||||
 | 
					    FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
 | 
				
			||||||
 | 
					    FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
 | 
				
			||||||
 | 
					    FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
 | 
				
			||||||
 | 
					    FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
 | 
				
			||||||
 | 
					    FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
 | 
				
			||||||
 | 
					    FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
 | 
				
			||||||
 | 
					    FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
 | 
				
			||||||
 | 
					    FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
 | 
				
			||||||
 | 
					    FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
 | 
				
			||||||
 | 
					    FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
 | 
				
			||||||
 | 
					    FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
 | 
				
			||||||
 | 
					    FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
 | 
				
			||||||
 | 
					    FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Round 2 */
 | 
				
			||||||
 | 
					    GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
 | 
				
			||||||
 | 
					    GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
 | 
				
			||||||
 | 
					    GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
 | 
				
			||||||
 | 
					    GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
 | 
				
			||||||
 | 
					    GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
 | 
				
			||||||
 | 
					    GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
 | 
				
			||||||
 | 
					    GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
 | 
				
			||||||
 | 
					    GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
 | 
				
			||||||
 | 
					    GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
 | 
				
			||||||
 | 
					    GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
 | 
				
			||||||
 | 
					    GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
 | 
				
			||||||
 | 
					    GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
 | 
				
			||||||
 | 
					    GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
 | 
				
			||||||
 | 
					    GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
 | 
				
			||||||
 | 
					    GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
 | 
				
			||||||
 | 
					    GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Round 3 */
 | 
				
			||||||
 | 
					    HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
 | 
				
			||||||
 | 
					    HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
 | 
				
			||||||
 | 
					    HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
 | 
				
			||||||
 | 
					    HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
 | 
				
			||||||
 | 
					    HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
 | 
				
			||||||
 | 
					    HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
 | 
				
			||||||
 | 
					    HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
 | 
				
			||||||
 | 
					    HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
 | 
				
			||||||
 | 
					    HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
 | 
				
			||||||
 | 
					    HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
 | 
				
			||||||
 | 
					    HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
 | 
				
			||||||
 | 
					    HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
 | 
				
			||||||
 | 
					    HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
 | 
				
			||||||
 | 
					    HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
 | 
				
			||||||
 | 
					    HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
 | 
				
			||||||
 | 
					    HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Round 4 */
 | 
				
			||||||
 | 
					    II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
 | 
				
			||||||
 | 
					    II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
 | 
				
			||||||
 | 
					    II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
 | 
				
			||||||
 | 
					    II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
 | 
				
			||||||
 | 
					    II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
 | 
				
			||||||
 | 
					    II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
 | 
				
			||||||
 | 
					    II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
 | 
				
			||||||
 | 
					    II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
 | 
				
			||||||
 | 
					    II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
 | 
				
			||||||
 | 
					    II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
 | 
				
			||||||
 | 
					    II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
 | 
				
			||||||
 | 
					    II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
 | 
				
			||||||
 | 
					    II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
 | 
				
			||||||
 | 
					    II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
 | 
				
			||||||
 | 
					    II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
 | 
				
			||||||
 | 
					    II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    state[0] += a;
 | 
				
			||||||
 | 
					    state[1] += b;
 | 
				
			||||||
 | 
					    state[2] += c;
 | 
				
			||||||
 | 
					    state[3] += d;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Encodes input (uint32_t) into output (uint8_t). Assumes len is
 | 
				
			||||||
 | 
					 *   a multiple of 4.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static void Encode(uint8_t *output, uint32_t *input, uint32_t len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint32_t i, j;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0, j = 0; j < len; i++, j += 4) 
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        output[j] = (uint8_t)(input[i] & 0xff);
 | 
				
			||||||
 | 
					        output[j+1] = (uint8_t)((input[i] >> 8) & 0xff);
 | 
				
			||||||
 | 
					        output[j+2] = (uint8_t)((input[i] >> 16) & 0xff);
 | 
				
			||||||
 | 
					        output[j+3] = (uint8_t)((input[i] >> 24) & 0xff);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 *  Decodes input (uint8_t) into output (uint32_t). Assumes len is
 | 
				
			||||||
 | 
					 *   a multiple of 4.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static void Decode(uint32_t *output, const uint8_t *input, uint32_t len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint32_t i, j;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0, j = 0; j < len; i++, j += 4)
 | 
				
			||||||
 | 
					        output[i] = ((uint32_t)input[j]) | (((uint32_t)input[j+1]) << 8) |
 | 
				
			||||||
 | 
					            (((uint32_t)input[j+2]) << 16) | (((uint32_t)input[j+3]) << 24);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								crypto/md5.o
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								crypto/md5.o
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										67
									
								
								crypto/os_int.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								crypto/os_int.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,67 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2012, 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @file os_int.h
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Ensure a consistent bit size 
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef HEADER_OS_INT_H
 | 
				
			||||||
 | 
					#define HEADER_OS_INT_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					extern "C" {
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(WIN32)
 | 
				
			||||||
 | 
					typedef UINT8 uint8_t;
 | 
				
			||||||
 | 
					typedef INT8 int8_t;
 | 
				
			||||||
 | 
					typedef UINT16 uint16_t;
 | 
				
			||||||
 | 
					typedef INT16 int16_t;
 | 
				
			||||||
 | 
					typedef UINT32 uint32_t;
 | 
				
			||||||
 | 
					typedef INT32 int32_t;
 | 
				
			||||||
 | 
					typedef UINT64 uint64_t;
 | 
				
			||||||
 | 
					typedef INT64 int64_t;
 | 
				
			||||||
 | 
					#else   /* Not Win32 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_PLATFORM_SOLARIS
 | 
				
			||||||
 | 
					#include <inttypes.h>
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					#endif /* Not Solaris */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* Not Win32 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif 
 | 
				
			||||||
							
								
								
									
										92
									
								
								crypto/rc4.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								crypto/rc4.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,92 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * An implementation of the RC4/ARC4 algorithm.
 | 
				
			||||||
 | 
					 * Originally written by Christophe Devine.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include "os_port.h"
 | 
				
			||||||
 | 
					#include "crypto.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Get ready for an encrypt/decrypt operation
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void RC4_setup(RC4_CTX *ctx, const uint8_t *key, int length)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int i, j = 0, k = 0, a;
 | 
				
			||||||
 | 
					    uint8_t *m;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ctx->x = 0;
 | 
				
			||||||
 | 
					    ctx->y = 0;
 | 
				
			||||||
 | 
					    m = ctx->m;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0; i < 256; i++)
 | 
				
			||||||
 | 
					        m[i] = i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0; i < 256; i++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        a = m[i];
 | 
				
			||||||
 | 
					        j = (uint8_t)(j + a + key[k]);
 | 
				
			||||||
 | 
					        m[i] = m[j]; 
 | 
				
			||||||
 | 
					        m[j] = a;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (++k >= length) 
 | 
				
			||||||
 | 
					            k = 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Perform the encrypt/decrypt operation (can use it for either since
 | 
				
			||||||
 | 
					 * this is a stream cipher).
 | 
				
			||||||
 | 
					 * NOTE: *msg and *out must be the same pointer (performance tweak)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void RC4_crypt(RC4_CTX *ctx, const uint8_t *msg, uint8_t *out, int length)
 | 
				
			||||||
 | 
					{ 
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					    uint8_t *m, x, y, a, b;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    x = ctx->x;
 | 
				
			||||||
 | 
					    y = ctx->y;
 | 
				
			||||||
 | 
					    m = ctx->m;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0; i < length; i++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        a = m[++x];
 | 
				
			||||||
 | 
					        y += a;
 | 
				
			||||||
 | 
					        m[x] = b = m[y];
 | 
				
			||||||
 | 
					        m[y] = a;
 | 
				
			||||||
 | 
					        out[i] ^= m[(uint8_t)(a + b)];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ctx->x = x;
 | 
				
			||||||
 | 
					    ctx->y = y;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								crypto/rc4.o
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								crypto/rc4.o
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										269
									
								
								crypto/rsa.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										269
									
								
								crypto/rsa.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,269 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Implements the RSA public encryption algorithm. Uses the bigint library to
 | 
				
			||||||
 | 
					 * perform its calculations.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <time.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include "os_port.h"
 | 
				
			||||||
 | 
					#include "crypto.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void RSA_priv_key_new(RSA_CTX **ctx, 
 | 
				
			||||||
 | 
					        const uint8_t *modulus, int mod_len,
 | 
				
			||||||
 | 
					        const uint8_t *pub_exp, int pub_len,
 | 
				
			||||||
 | 
					        const uint8_t *priv_exp, int priv_len
 | 
				
			||||||
 | 
					#if CONFIG_BIGINT_CRT
 | 
				
			||||||
 | 
					      , const uint8_t *p, int p_len,
 | 
				
			||||||
 | 
					        const uint8_t *q, int q_len,
 | 
				
			||||||
 | 
					        const uint8_t *dP, int dP_len,
 | 
				
			||||||
 | 
					        const uint8_t *dQ, int dQ_len,
 | 
				
			||||||
 | 
					        const uint8_t *qInv, int qInv_len
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    RSA_CTX *rsa_ctx;
 | 
				
			||||||
 | 
					    BI_CTX *bi_ctx;
 | 
				
			||||||
 | 
					    RSA_pub_key_new(ctx, modulus, mod_len, pub_exp, pub_len);
 | 
				
			||||||
 | 
					    rsa_ctx = *ctx;
 | 
				
			||||||
 | 
					    bi_ctx = rsa_ctx->bi_ctx;
 | 
				
			||||||
 | 
					    rsa_ctx->d = bi_import(bi_ctx, priv_exp, priv_len);
 | 
				
			||||||
 | 
					    bi_permanent(rsa_ctx->d);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_BIGINT_CRT
 | 
				
			||||||
 | 
					    rsa_ctx->p = bi_import(bi_ctx, p, p_len);
 | 
				
			||||||
 | 
					    rsa_ctx->q = bi_import(bi_ctx, q, q_len);
 | 
				
			||||||
 | 
					    rsa_ctx->dP = bi_import(bi_ctx, dP, dP_len);
 | 
				
			||||||
 | 
					    rsa_ctx->dQ = bi_import(bi_ctx, dQ, dQ_len);
 | 
				
			||||||
 | 
					    rsa_ctx->qInv = bi_import(bi_ctx, qInv, qInv_len);
 | 
				
			||||||
 | 
					    bi_permanent(rsa_ctx->dP);
 | 
				
			||||||
 | 
					    bi_permanent(rsa_ctx->dQ);
 | 
				
			||||||
 | 
					    bi_permanent(rsa_ctx->qInv);
 | 
				
			||||||
 | 
					    bi_set_mod(bi_ctx, rsa_ctx->p, BIGINT_P_OFFSET);
 | 
				
			||||||
 | 
					    bi_set_mod(bi_ctx, rsa_ctx->q, BIGINT_Q_OFFSET);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void RSA_pub_key_new(RSA_CTX **ctx, 
 | 
				
			||||||
 | 
					        const uint8_t *modulus, int mod_len,
 | 
				
			||||||
 | 
					        const uint8_t *pub_exp, int pub_len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    RSA_CTX *rsa_ctx;
 | 
				
			||||||
 | 
					    BI_CTX *bi_ctx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (*ctx)   /* if we load multiple certs, dump the old one */
 | 
				
			||||||
 | 
					        RSA_free(*ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bi_ctx = bi_initialize();
 | 
				
			||||||
 | 
					    *ctx = (RSA_CTX *)calloc(1, sizeof(RSA_CTX));
 | 
				
			||||||
 | 
					    rsa_ctx = *ctx;
 | 
				
			||||||
 | 
					    rsa_ctx->bi_ctx = bi_ctx;
 | 
				
			||||||
 | 
					    rsa_ctx->num_octets = mod_len;
 | 
				
			||||||
 | 
					    rsa_ctx->m = bi_import(bi_ctx, modulus, mod_len);
 | 
				
			||||||
 | 
					    bi_set_mod(bi_ctx, rsa_ctx->m, BIGINT_M_OFFSET);
 | 
				
			||||||
 | 
					    rsa_ctx->e = bi_import(bi_ctx, pub_exp, pub_len);
 | 
				
			||||||
 | 
					    bi_permanent(rsa_ctx->e);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Free up any RSA context resources.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void RSA_free(RSA_CTX *rsa_ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    BI_CTX *bi_ctx;
 | 
				
			||||||
 | 
					    if (rsa_ctx == NULL)                /* deal with ptrs that are null */
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bi_ctx = rsa_ctx->bi_ctx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bi_depermanent(rsa_ctx->e);
 | 
				
			||||||
 | 
					    bi_free(bi_ctx, rsa_ctx->e);
 | 
				
			||||||
 | 
					    bi_free_mod(rsa_ctx->bi_ctx, BIGINT_M_OFFSET);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (rsa_ctx->d)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        bi_depermanent(rsa_ctx->d);
 | 
				
			||||||
 | 
					        bi_free(bi_ctx, rsa_ctx->d);
 | 
				
			||||||
 | 
					#ifdef CONFIG_BIGINT_CRT
 | 
				
			||||||
 | 
					        bi_depermanent(rsa_ctx->dP);
 | 
				
			||||||
 | 
					        bi_depermanent(rsa_ctx->dQ);
 | 
				
			||||||
 | 
					        bi_depermanent(rsa_ctx->qInv);
 | 
				
			||||||
 | 
					        bi_free(bi_ctx, rsa_ctx->dP);
 | 
				
			||||||
 | 
					        bi_free(bi_ctx, rsa_ctx->dQ);
 | 
				
			||||||
 | 
					        bi_free(bi_ctx, rsa_ctx->qInv);
 | 
				
			||||||
 | 
					        bi_free_mod(rsa_ctx->bi_ctx, BIGINT_P_OFFSET);
 | 
				
			||||||
 | 
					        bi_free_mod(rsa_ctx->bi_ctx, BIGINT_Q_OFFSET);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bi_terminate(bi_ctx);
 | 
				
			||||||
 | 
					    free(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 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)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    const int byte_size = ctx->num_octets;
 | 
				
			||||||
 | 
					    int i, size;
 | 
				
			||||||
 | 
					    bigint *decrypted_bi, *dat_bi;
 | 
				
			||||||
 | 
					    uint8_t *block = (uint8_t *)alloca(byte_size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memset(out_data, 0, byte_size); /* initialise */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* decrypt */
 | 
				
			||||||
 | 
					    dat_bi = bi_import(ctx->bi_ctx, in_data, byte_size);
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_CERT_VERIFICATION
 | 
				
			||||||
 | 
					    decrypted_bi = is_decryption ?  /* decrypt or verify? */
 | 
				
			||||||
 | 
					            RSA_private(ctx, dat_bi) : RSA_public(ctx, dat_bi);
 | 
				
			||||||
 | 
					#else   /* always a decryption */
 | 
				
			||||||
 | 
					    decrypted_bi = RSA_private(ctx, dat_bi);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* 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 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#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-2] != 0xff)
 | 
				
			||||||
 | 
					            i = byte_size;     /*ensure size is 0 */   
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else                    /* PKCS1.5 encryption padding is random */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        while (block[i++] && i < byte_size);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    size = byte_size - i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* get only the bit we want */
 | 
				
			||||||
 | 
					    if (size > 0)
 | 
				
			||||||
 | 
					        memcpy(out_data, &block[i], size);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    return size ? size : -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Performs m = c^d mod n
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bigint *RSA_private(const RSA_CTX *c, bigint *bi_msg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#ifdef CONFIG_BIGINT_CRT
 | 
				
			||||||
 | 
					    return bi_crt(c->bi_ctx, bi_msg, c->dP, c->dQ, c->p, c->q, c->qInv);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					    BI_CTX *ctx = c->bi_ctx;
 | 
				
			||||||
 | 
					    ctx->mod_offset = BIGINT_M_OFFSET;
 | 
				
			||||||
 | 
					    return bi_mod_power(ctx, bi_msg, c->d);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_FULL_MODE
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Used for diagnostics.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void RSA_print(const RSA_CTX *rsa_ctx) 
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (rsa_ctx == NULL)
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    printf("-----------------   RSA DEBUG   ----------------\n");
 | 
				
			||||||
 | 
					    printf("Size:\t%d\n", rsa_ctx->num_octets);
 | 
				
			||||||
 | 
					    bi_print("Modulus", rsa_ctx->m);
 | 
				
			||||||
 | 
					    bi_print("Public Key", rsa_ctx->e);
 | 
				
			||||||
 | 
					    bi_print("Private Key", rsa_ctx->d);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(CONFIG_SSL_CERT_VERIFICATION) || defined(CONFIG_SSL_GENERATE_X509_CERT)
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Performs c = m^e mod n
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bigint *RSA_public(const RSA_CTX * c, bigint *bi_msg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    c->bi_ctx->mod_offset = BIGINT_M_OFFSET;
 | 
				
			||||||
 | 
					    return bi_mod_power(c->bi_ctx, bi_msg, c->e);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Use PKCS1.5 for encryption/signing.
 | 
				
			||||||
 | 
					 * see http://www.rsasecurity.com/rsalabs/node.asp?id=2125
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int RSA_encrypt(const RSA_CTX *ctx, const uint8_t *in_data, uint16_t in_len, 
 | 
				
			||||||
 | 
					        uint8_t *out_data, int is_signing)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int byte_size = ctx->num_octets;
 | 
				
			||||||
 | 
					    int num_pads_needed = byte_size-in_len-3;
 | 
				
			||||||
 | 
					    bigint *dat_bi, *encrypt_bi;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* note: in_len+11 must be > byte_size */
 | 
				
			||||||
 | 
					    out_data[0] = 0;     /* ensure encryption block is < modulus */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (is_signing)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        out_data[1] = 1;        /* PKCS1.5 signing pads with "0xff"'s */
 | 
				
			||||||
 | 
					        memset(&out_data[2], 0xff, num_pads_needed);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else /* randomize the encryption padding with non-zero bytes */   
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        out_data[1] = 2;
 | 
				
			||||||
 | 
					        get_random_NZ(num_pads_needed, &out_data[2]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    out_data[2+num_pads_needed] = 0;
 | 
				
			||||||
 | 
					    memcpy(&out_data[3+num_pads_needed], in_data, in_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* now encrypt it */
 | 
				
			||||||
 | 
					    dat_bi = bi_import(ctx->bi_ctx, out_data, byte_size);
 | 
				
			||||||
 | 
					    encrypt_bi = is_signing ? RSA_private(ctx, dat_bi) : 
 | 
				
			||||||
 | 
					                              RSA_public(ctx, dat_bi);
 | 
				
			||||||
 | 
					    bi_export(ctx->bi_ctx, encrypt_bi, out_data, byte_size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* save a few bytes of memory */
 | 
				
			||||||
 | 
					    bi_clear_cache(ctx->bi_ctx);
 | 
				
			||||||
 | 
					    return byte_size;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif  /* CONFIG_SSL_CERT_VERIFICATION */
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								crypto/rsa.o
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								crypto/rsa.o
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										249
									
								
								crypto/sha1.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										249
									
								
								crypto/sha1.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,249 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * SHA1 implementation - as defined in FIPS PUB 180-1 published April 17, 1995.
 | 
				
			||||||
 | 
					 * This code was originally taken from RFC3174
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include "os_port.h"
 | 
				
			||||||
 | 
					#include "crypto.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 *  Define the SHA1 circular left shift macro
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define SHA1CircularShift(bits,word) \
 | 
				
			||||||
 | 
					                (((word) << (bits)) | ((word) >> (32-(bits))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* ----- static functions ----- */
 | 
				
			||||||
 | 
					static void SHA1PadMessage(SHA1_CTX *ctx);
 | 
				
			||||||
 | 
					static void SHA1ProcessMessageBlock(SHA1_CTX *ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Initialize the SHA1 context 
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void SHA1_Init(SHA1_CTX *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ctx->Length_Low             = 0;
 | 
				
			||||||
 | 
					    ctx->Length_High            = 0;
 | 
				
			||||||
 | 
					    ctx->Message_Block_Index    = 0;
 | 
				
			||||||
 | 
					    ctx->Intermediate_Hash[0]   = 0x67452301;
 | 
				
			||||||
 | 
					    ctx->Intermediate_Hash[1]   = 0xEFCDAB89;
 | 
				
			||||||
 | 
					    ctx->Intermediate_Hash[2]   = 0x98BADCFE;
 | 
				
			||||||
 | 
					    ctx->Intermediate_Hash[3]   = 0x10325476;
 | 
				
			||||||
 | 
					    ctx->Intermediate_Hash[4]   = 0xC3D2E1F0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Accepts an array of octets as the next portion of the message.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void SHA1_Update(SHA1_CTX *ctx, const uint8_t *msg, int len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    while (len--)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ctx->Message_Block[ctx->Message_Block_Index++] = (*msg & 0xFF);
 | 
				
			||||||
 | 
					        ctx->Length_Low += 8;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (ctx->Length_Low == 0)
 | 
				
			||||||
 | 
					            ctx->Length_High++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (ctx->Message_Block_Index == 64)
 | 
				
			||||||
 | 
					            SHA1ProcessMessageBlock(ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        msg++;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Return the 160-bit message digest into the user's array
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void SHA1_Final(uint8_t *digest, SHA1_CTX *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    SHA1PadMessage(ctx);
 | 
				
			||||||
 | 
					    memset(ctx->Message_Block, 0, 64);
 | 
				
			||||||
 | 
					    ctx->Length_Low = 0;    /* and clear length */
 | 
				
			||||||
 | 
					    ctx->Length_High = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for  (i = 0; i < SHA1_SIZE; i++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        digest[i] = ctx->Intermediate_Hash[i>>2] >> 8 * ( 3 - ( i & 0x03 ) );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Process the next 512 bits of the message stored in the array.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static void SHA1ProcessMessageBlock(SHA1_CTX *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    const uint32_t K[] =    {       /* Constants defined in SHA-1   */
 | 
				
			||||||
 | 
					                            0x5A827999,
 | 
				
			||||||
 | 
					                            0x6ED9EBA1,
 | 
				
			||||||
 | 
					                            0x8F1BBCDC,
 | 
				
			||||||
 | 
					                            0xCA62C1D6
 | 
				
			||||||
 | 
					                            };
 | 
				
			||||||
 | 
					    int        t;                 /* Loop counter                */
 | 
				
			||||||
 | 
					    uint32_t      temp;              /* Temporary word value        */
 | 
				
			||||||
 | 
					    uint32_t      W[80];             /* Word sequence               */
 | 
				
			||||||
 | 
					    uint32_t      A, B, C, D, E;     /* Word buffers                */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     *  Initialize the first 16 words in the array W
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    for  (t = 0; t < 16; t++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        W[t] = ctx->Message_Block[t * 4] << 24;
 | 
				
			||||||
 | 
					        W[t] |= ctx->Message_Block[t * 4 + 1] << 16;
 | 
				
			||||||
 | 
					        W[t] |= ctx->Message_Block[t * 4 + 2] << 8;
 | 
				
			||||||
 | 
					        W[t] |= ctx->Message_Block[t * 4 + 3];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (t = 16; t < 80; t++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					       W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    A = ctx->Intermediate_Hash[0];
 | 
				
			||||||
 | 
					    B = ctx->Intermediate_Hash[1];
 | 
				
			||||||
 | 
					    C = ctx->Intermediate_Hash[2];
 | 
				
			||||||
 | 
					    D = ctx->Intermediate_Hash[3];
 | 
				
			||||||
 | 
					    E = ctx->Intermediate_Hash[4];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (t = 0; t < 20; t++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        temp =  SHA1CircularShift(5,A) +
 | 
				
			||||||
 | 
					                ((B & C) | ((~B) & D)) + E + W[t] + K[0];
 | 
				
			||||||
 | 
					        E = D;
 | 
				
			||||||
 | 
					        D = C;
 | 
				
			||||||
 | 
					        C = SHA1CircularShift(30,B);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        B = A;
 | 
				
			||||||
 | 
					        A = temp;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (t = 20; t < 40; t++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
 | 
				
			||||||
 | 
					        E = D;
 | 
				
			||||||
 | 
					        D = C;
 | 
				
			||||||
 | 
					        C = SHA1CircularShift(30,B);
 | 
				
			||||||
 | 
					        B = A;
 | 
				
			||||||
 | 
					        A = temp;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (t = 40; t < 60; t++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        temp = SHA1CircularShift(5,A) +
 | 
				
			||||||
 | 
					               ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
 | 
				
			||||||
 | 
					        E = D;
 | 
				
			||||||
 | 
					        D = C;
 | 
				
			||||||
 | 
					        C = SHA1CircularShift(30,B);
 | 
				
			||||||
 | 
					        B = A;
 | 
				
			||||||
 | 
					        A = temp;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (t = 60; t < 80; t++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
 | 
				
			||||||
 | 
					        E = D;
 | 
				
			||||||
 | 
					        D = C;
 | 
				
			||||||
 | 
					        C = SHA1CircularShift(30,B);
 | 
				
			||||||
 | 
					        B = A;
 | 
				
			||||||
 | 
					        A = temp;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ctx->Intermediate_Hash[0] += A;
 | 
				
			||||||
 | 
					    ctx->Intermediate_Hash[1] += B;
 | 
				
			||||||
 | 
					    ctx->Intermediate_Hash[2] += C;
 | 
				
			||||||
 | 
					    ctx->Intermediate_Hash[3] += D;
 | 
				
			||||||
 | 
					    ctx->Intermediate_Hash[4] += E;
 | 
				
			||||||
 | 
					    ctx->Message_Block_Index = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * According to the standard, the message must be padded to an even
 | 
				
			||||||
 | 
					 * 512 bits.  The first padding bit must be a '1'.  The last 64
 | 
				
			||||||
 | 
					 * bits represent the length of the original message.  All bits in
 | 
				
			||||||
 | 
					 * between should be 0.  This function will pad the message
 | 
				
			||||||
 | 
					 * according to those rules by filling the Message_Block array
 | 
				
			||||||
 | 
					 * accordingly.  It will also call the ProcessMessageBlock function
 | 
				
			||||||
 | 
					 * provided appropriately.  When it returns, it can be assumed that
 | 
				
			||||||
 | 
					 * the message digest has been computed.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param ctx [in, out] The SHA1 context
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static void SHA1PadMessage(SHA1_CTX *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     *  Check to see if the current message block is too small to hold
 | 
				
			||||||
 | 
					     *  the initial padding bits and length.  If so, we will pad the
 | 
				
			||||||
 | 
					     *  block, process it, and then continue padding into a second
 | 
				
			||||||
 | 
					     *  block.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    if (ctx->Message_Block_Index > 55)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ctx->Message_Block[ctx->Message_Block_Index++] = 0x80;
 | 
				
			||||||
 | 
					        while(ctx->Message_Block_Index < 64)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            ctx->Message_Block[ctx->Message_Block_Index++] = 0;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        SHA1ProcessMessageBlock(ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        while (ctx->Message_Block_Index < 56)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            ctx->Message_Block[ctx->Message_Block_Index++] = 0;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ctx->Message_Block[ctx->Message_Block_Index++] = 0x80;
 | 
				
			||||||
 | 
					        while(ctx->Message_Block_Index < 56)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            ctx->Message_Block[ctx->Message_Block_Index++] = 0;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     *  Store the message length as the last 8 octets
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    ctx->Message_Block[56] = ctx->Length_High >> 24;
 | 
				
			||||||
 | 
					    ctx->Message_Block[57] = ctx->Length_High >> 16;
 | 
				
			||||||
 | 
					    ctx->Message_Block[58] = ctx->Length_High >> 8;
 | 
				
			||||||
 | 
					    ctx->Message_Block[59] = ctx->Length_High;
 | 
				
			||||||
 | 
					    ctx->Message_Block[60] = ctx->Length_Low >> 24;
 | 
				
			||||||
 | 
					    ctx->Message_Block[61] = ctx->Length_Low >> 16;
 | 
				
			||||||
 | 
					    ctx->Message_Block[62] = ctx->Length_Low >> 8;
 | 
				
			||||||
 | 
					    ctx->Message_Block[63] = ctx->Length_Low;
 | 
				
			||||||
 | 
					    SHA1ProcessMessageBlock(ctx);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								crypto/sha1.o
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								crypto/sha1.o
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										566
									
								
								ssl/asn1.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										566
									
								
								ssl/asn1.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,566 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Some primitive asn methods for extraction ASN.1 data.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <time.h>
 | 
				
			||||||
 | 
					#include "os_port.h"
 | 
				
			||||||
 | 
					#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] = 
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const uint8_t sig_sha1WithRSAEncrypt[SIG_IIS6_OID_SIZE] =
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    0x2b, 0x0e, 0x03, 0x02, 0x1d
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const uint8_t sig_subject_alt_name[SIG_SUBJECT_ALT_NAME_SIZE] =
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    0x55, 0x1d, 0x11
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* CN, O, OU */
 | 
				
			||||||
 | 
					static const uint8_t g_dn_types[] = { 3, 10, 11 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int get_asn1_length(const uint8_t *buf, int *offset)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int len, i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!(buf[*offset] & 0x80)) /* short form */
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        len = buf[(*offset)++];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else  /* long form */
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        int length_bytes = buf[(*offset)++]&0x7f;
 | 
				
			||||||
 | 
					        len = 0;
 | 
				
			||||||
 | 
					        for (i = 0; i < length_bytes; i++)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            len <<= 8;
 | 
				
			||||||
 | 
					            len += buf[(*offset)++];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return len;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Skip the ASN1.1 object type and its length. Get ready to read the object's
 | 
				
			||||||
 | 
					 * data.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int asn1_next_obj(const uint8_t *buf, int *offset, int obj_type)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (buf[*offset] != obj_type)
 | 
				
			||||||
 | 
					        return X509_NOT_OK;
 | 
				
			||||||
 | 
					    (*offset)++;
 | 
				
			||||||
 | 
					    return get_asn1_length(buf, offset);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Skip over an ASN.1 object type completely. Get ready to read the next
 | 
				
			||||||
 | 
					 * object.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int asn1_skip_obj(const uint8_t *buf, int *offset, int obj_type)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (buf[*offset] != obj_type)
 | 
				
			||||||
 | 
					        return X509_NOT_OK;
 | 
				
			||||||
 | 
					    (*offset)++;
 | 
				
			||||||
 | 
					    len = get_asn1_length(buf, offset);
 | 
				
			||||||
 | 
					    *offset += len;
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Read an integer value for ASN.1 data
 | 
				
			||||||
 | 
					 * Note: This function allocates memory which must be freed by the user.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int asn1_get_int(const uint8_t *buf, int *offset, uint8_t **object)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ((len = asn1_next_obj(buf, offset, ASN1_INTEGER)) < 0)
 | 
				
			||||||
 | 
					        goto end_int_array;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (len > 1 && buf[*offset] == 0x00)    /* ignore the negative byte */
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        len--;
 | 
				
			||||||
 | 
					        (*offset)++;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    *object = (uint8_t *)malloc(len);
 | 
				
			||||||
 | 
					    memcpy(*object, &buf[*offset], len);
 | 
				
			||||||
 | 
					    *offset += len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					end_int_array:
 | 
				
			||||||
 | 
					    return len;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Get all the RSA private key specifics from an ASN.1 encoded file 
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int asn1_get_private_key(const uint8_t *buf, int len, RSA_CTX **rsa_ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int offset = 7;
 | 
				
			||||||
 | 
					    uint8_t *modulus = NULL, *priv_exp = NULL, *pub_exp = NULL;
 | 
				
			||||||
 | 
					    int mod_len, priv_len, pub_len;
 | 
				
			||||||
 | 
					#ifdef CONFIG_BIGINT_CRT
 | 
				
			||||||
 | 
					    uint8_t *p = NULL, *q = NULL, *dP = NULL, *dQ = NULL, *qInv = NULL;
 | 
				
			||||||
 | 
					    int p_len, q_len, dP_len, dQ_len, qInv_len;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* not in der format */
 | 
				
			||||||
 | 
					    if (buf[0] != ASN1_SEQUENCE) /* basic sanity check */
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_FULL_MODE
 | 
				
			||||||
 | 
					        printf("Error: This is not a valid ASN.1 file\n");
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        return X509_INVALID_PRIV_KEY;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Use the private key to mix up the RNG if possible. */
 | 
				
			||||||
 | 
					    RNG_custom_init(buf, len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    mod_len = asn1_get_int(buf, &offset, &modulus);
 | 
				
			||||||
 | 
					    pub_len = asn1_get_int(buf, &offset, &pub_exp);
 | 
				
			||||||
 | 
					    priv_len = asn1_get_int(buf, &offset, &priv_exp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (mod_len <= 0 || pub_len <= 0 || priv_len <= 0)
 | 
				
			||||||
 | 
					        return X509_INVALID_PRIV_KEY;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_BIGINT_CRT
 | 
				
			||||||
 | 
					    p_len = asn1_get_int(buf, &offset, &p);
 | 
				
			||||||
 | 
					    q_len = asn1_get_int(buf, &offset, &q);
 | 
				
			||||||
 | 
					    dP_len = asn1_get_int(buf, &offset, &dP);
 | 
				
			||||||
 | 
					    dQ_len = asn1_get_int(buf, &offset, &dQ);
 | 
				
			||||||
 | 
					    qInv_len = asn1_get_int(buf, &offset, &qInv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (p_len <= 0 || q_len <= 0 || dP_len <= 0 || dQ_len <= 0 || qInv_len <= 0)
 | 
				
			||||||
 | 
					        return X509_INVALID_PRIV_KEY;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    RSA_priv_key_new(rsa_ctx, 
 | 
				
			||||||
 | 
					            modulus, mod_len, pub_exp, pub_len, priv_exp, priv_len,
 | 
				
			||||||
 | 
					            p, p_len, q, p_len, dP, dP_len, dQ, dQ_len, qInv, qInv_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    free(p);
 | 
				
			||||||
 | 
					    free(q);
 | 
				
			||||||
 | 
					    free(dP);
 | 
				
			||||||
 | 
					    free(dQ);
 | 
				
			||||||
 | 
					    free(qInv);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					    RSA_priv_key_new(rsa_ctx, 
 | 
				
			||||||
 | 
					            modulus, mod_len, pub_exp, pub_len, priv_exp, priv_len);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    free(modulus);
 | 
				
			||||||
 | 
					    free(priv_exp);
 | 
				
			||||||
 | 
					    free(pub_exp);
 | 
				
			||||||
 | 
					    return X509_OK;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Get the time of a certificate. Ignore hours/minutes/seconds.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int asn1_get_utc_time(const uint8_t *buf, int *offset, time_t *t)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int ret = X509_NOT_OK, len, t_offset;
 | 
				
			||||||
 | 
					    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 */
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					end_utc_time:
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Get the version type of a certificate (which we don't actually care about)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int asn1_version(const uint8_t *cert, int *offset, X509_CTX *x509_ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int ret = X509_NOT_OK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    (*offset) += 2;        /* get past explicit tag */
 | 
				
			||||||
 | 
					    if (asn1_skip_obj(cert, offset, ASN1_INTEGER))
 | 
				
			||||||
 | 
					        goto end_version;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ret = X509_OK;
 | 
				
			||||||
 | 
					end_version:
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Retrieve the notbefore and notafter certificate times.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int asn1_validity(const uint8_t *cert, int *offset, X509_CTX *x509_ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return (asn1_next_obj(cert, offset, ASN1_SEQUENCE) < 0 ||
 | 
				
			||||||
 | 
					              asn1_get_utc_time(cert, offset, &x509_ctx->not_before) ||
 | 
				
			||||||
 | 
					              asn1_get_utc_time(cert, offset, &x509_ctx->not_after));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Get the components of a distinguished name 
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int asn1_get_oid_x520(const uint8_t *buf, int *offset)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int dn_type = 0;
 | 
				
			||||||
 | 
					    int len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ((len = asn1_next_obj(buf, offset, ASN1_OID)) < 0)
 | 
				
			||||||
 | 
					        goto end_oid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* expect a sequence of 2.5.4.[x] where x is a one of distinguished name 
 | 
				
			||||||
 | 
					       components we are interested in. */
 | 
				
			||||||
 | 
					    if (len == 3 && buf[(*offset)++] == 0x55 && buf[(*offset)++] == 0x04)
 | 
				
			||||||
 | 
					        dn_type = buf[(*offset)++];
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        *offset += len;     /* skip over it */
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					end_oid:
 | 
				
			||||||
 | 
					    return dn_type;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Obtain an ASN.1 printable string type.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int asn1_get_printable_str(const uint8_t *buf, int *offset, char **str)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int len = X509_NOT_OK;
 | 
				
			||||||
 | 
					    int asn1_type = buf[*offset];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* some certs have this awful crud in them for some reason */
 | 
				
			||||||
 | 
					    if (asn1_type != ASN1_PRINTABLE_STR &&  
 | 
				
			||||||
 | 
					            asn1_type != ASN1_PRINTABLE_STR2 &&  
 | 
				
			||||||
 | 
					            asn1_type != ASN1_TELETEX_STR &&  
 | 
				
			||||||
 | 
					            asn1_type != ASN1_IA5_STR &&  
 | 
				
			||||||
 | 
					            asn1_type != ASN1_UNICODE_STR)
 | 
				
			||||||
 | 
					        goto end_pnt_str;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    (*offset)++;
 | 
				
			||||||
 | 
					    len = get_asn1_length(buf, offset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (asn1_type == ASN1_UNICODE_STR)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        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];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        (*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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					end_pnt_str:
 | 
				
			||||||
 | 
					    return len;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Get the subject name (or the issuer) of a certificate.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int asn1_name(const uint8_t *cert, int *offset, char *dn[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int ret = X509_NOT_OK;
 | 
				
			||||||
 | 
					    int dn_type;
 | 
				
			||||||
 | 
					    char *tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (asn1_next_obj(cert, offset, ASN1_SEQUENCE) < 0)
 | 
				
			||||||
 | 
					        goto end_name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while (asn1_next_obj(cert, offset, ASN1_SET) >= 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        int i, found = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (asn1_next_obj(cert, offset, ASN1_SEQUENCE) < 0 ||
 | 
				
			||||||
 | 
					               (dn_type = asn1_get_oid_x520(cert, offset)) < 0)
 | 
				
			||||||
 | 
					            goto end_name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        tmp = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (asn1_get_printable_str(cert, offset, &tmp) < 0)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            free(tmp);
 | 
				
			||||||
 | 
					            goto end_name;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* find the distinguished named type */
 | 
				
			||||||
 | 
					        for (i = 0; i < X509_NUM_DN_TYPES; i++)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (dn_type == g_dn_types[i])
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (dn[i] == NULL)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    dn[i] = tmp;
 | 
				
			||||||
 | 
					                    found = 1;
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (found == 0) /* not found so get rid of it */
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            free(tmp);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ret = X509_OK;
 | 
				
			||||||
 | 
					end_name:
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Read the modulus and public exponent of a certificate.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int asn1_public_key(const uint8_t *cert, int *offset, X509_CTX *x509_ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int ret = X509_NOT_OK, mod_len, pub_len;
 | 
				
			||||||
 | 
					    uint8_t *modulus = NULL, *pub_exp = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (asn1_next_obj(cert, offset, ASN1_SEQUENCE) < 0 ||
 | 
				
			||||||
 | 
					            asn1_skip_obj(cert, offset, ASN1_SEQUENCE) ||
 | 
				
			||||||
 | 
					            asn1_next_obj(cert, offset, ASN1_BIT_STRING) < 0)
 | 
				
			||||||
 | 
					        goto end_pub_key;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    (*offset)++;        /* ignore the padding bit field */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (asn1_next_obj(cert, offset, ASN1_SEQUENCE) < 0)
 | 
				
			||||||
 | 
					        goto end_pub_key;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    mod_len = asn1_get_int(cert, offset, &modulus);
 | 
				
			||||||
 | 
					    pub_len = asn1_get_int(cert, offset, &pub_exp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    RSA_pub_key_new(&x509_ctx->rsa_ctx, modulus, mod_len, pub_exp, pub_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    free(modulus);
 | 
				
			||||||
 | 
					    free(pub_exp);
 | 
				
			||||||
 | 
					    ret = X509_OK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					end_pub_key:
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_CERT_VERIFICATION
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Read the signature of the certificate.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int asn1_signature(const uint8_t *cert, int *offset, X509_CTX *x509_ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int ret = X509_NOT_OK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (cert[(*offset)++] != ASN1_BIT_STRING)
 | 
				
			||||||
 | 
					        goto end_sig;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    x509_ctx->sig_len = get_asn1_length(cert, offset)-1;
 | 
				
			||||||
 | 
					    (*offset)++;            /* ignore bit string padding bits */
 | 
				
			||||||
 | 
					    x509_ctx->signature = (uint8_t *)malloc(x509_ctx->sig_len);
 | 
				
			||||||
 | 
					    memcpy(x509_ctx->signature, &cert[*offset], x509_ctx->sig_len);
 | 
				
			||||||
 | 
					    *offset += x509_ctx->sig_len;
 | 
				
			||||||
 | 
					    ret = X509_OK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					end_sig:
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Compare 2 distinguished name components for equality 
 | 
				
			||||||
 | 
					 * @return 0 if a match
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int asn1_compare_dn_comp(const char *dn1, const char *dn2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (dn1 == NULL && dn2 == NULL)
 | 
				
			||||||
 | 
					        ret = 0;
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        ret = (dn1 && dn2) ? strcmp(dn1, dn2) : 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Clean up all of the CA certificates.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void remove_ca_certs(CA_CERT_CTX *ca_cert_ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int i = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (ca_cert_ctx == NULL)
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while (i < CONFIG_X509_MAX_CA_CERTS && ca_cert_ctx->cert[i])
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        x509_free(ca_cert_ctx->cert[i]);
 | 
				
			||||||
 | 
					        ca_cert_ctx->cert[i++] = NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    free(ca_cert_ctx);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Compare 2 distinguished names for equality 
 | 
				
			||||||
 | 
					 * @return 0 if a match
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int asn1_compare_dn(char * const dn1[], char * const dn2[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0; i < X509_NUM_DN_TYPES; i++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (asn1_compare_dn_comp(dn1[i], dn2[i]))
 | 
				
			||||||
 | 
					            return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;       /* all good */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int asn1_find_oid(const uint8_t* cert, int* offset, 
 | 
				
			||||||
 | 
					                    const uint8_t* oid, int oid_length)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int seqlen;
 | 
				
			||||||
 | 
					    if ((seqlen = asn1_next_obj(cert, offset, ASN1_SEQUENCE))> 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        int end = *offset + seqlen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        while (*offset < end)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            int type = cert[(*offset)++];
 | 
				
			||||||
 | 
					            int length = get_asn1_length(cert, offset);
 | 
				
			||||||
 | 
					            int noffset = *offset + length;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (type == ASN1_SEQUENCE)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                type = cert[(*offset)++];
 | 
				
			||||||
 | 
					                length = get_asn1_length(cert, offset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (type == ASN1_OID && length == oid_length && 
 | 
				
			||||||
 | 
					                              memcmp(cert + *offset, oid, oid_length) == 0)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    *offset += oid_length;
 | 
				
			||||||
 | 
					                    return 1;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            *offset = noffset;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return offset;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* CONFIG_SSL_CERT_VERIFICATION */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Read the signature type of the certificate. We only support RSA-MD5 and
 | 
				
			||||||
 | 
					 * RSA-SHA1 signature types.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int asn1_signature_type(const uint8_t *cert, 
 | 
				
			||||||
 | 
					                                int *offset, X509_CTX *x509_ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int ret = X509_NOT_OK, len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (cert[(*offset)++] != ASN1_OID)
 | 
				
			||||||
 | 
					        goto end_check_sig;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    len = get_asn1_length(cert, offset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (len == 5 && memcmp(sig_sha1WithRSAEncrypt, &cert[*offset], 
 | 
				
			||||||
 | 
					                                    SIG_IIS6_OID_SIZE) == 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        x509_ctx->sig_type = SIG_TYPE_SHA1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (memcmp(sig_oid_prefix, &cert[*offset], SIG_OID_PREFIX_SIZE))
 | 
				
			||||||
 | 
					            goto end_check_sig;     /* unrecognised cert type */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        x509_ctx->sig_type = cert[*offset + SIG_OID_PREFIX_SIZE];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    *offset += len;
 | 
				
			||||||
 | 
					    asn1_skip_obj(cert, offset, ASN1_NULL); /* if it's there */
 | 
				
			||||||
 | 
					    ret = X509_OK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					end_check_sig:
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								ssl/asn1.o
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								ssl/asn1.o
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										43
									
								
								ssl/cert.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								ssl/cert.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
				
			|||||||
 | 
					unsigned char default_certificate[] = {
 | 
				
			||||||
 | 
					  0x30, 0x82, 0x01, 0xd7, 0x30, 0x82, 0x01, 0x40, 0x02, 0x09, 0x00, 0xab,
 | 
				
			||||||
 | 
					  0x08, 0x18, 0xa7, 0x03, 0x07, 0x27, 0xfd, 0x30, 0x0d, 0x06, 0x09, 0x2a,
 | 
				
			||||||
 | 
					  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x34,
 | 
				
			||||||
 | 
					  0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x29, 0x61,
 | 
				
			||||||
 | 
					  0x78, 0x54, 0x4c, 0x53, 0x20, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74,
 | 
				
			||||||
 | 
					  0x20, 0x44, 0x6f, 0x64, 0x67, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
 | 
				
			||||||
 | 
					  0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
 | 
				
			||||||
 | 
					  0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x31, 0x32,
 | 
				
			||||||
 | 
					  0x32, 0x36, 0x32, 0x32, 0x33, 0x33, 0x33, 0x39, 0x5a, 0x17, 0x0d, 0x32,
 | 
				
			||||||
 | 
					  0x34, 0x30, 0x39, 0x30, 0x33, 0x32, 0x32, 0x33, 0x33, 0x33, 0x39, 0x5a,
 | 
				
			||||||
 | 
					  0x30, 0x2c, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
 | 
				
			||||||
 | 
					  0x0d, 0x61, 0x78, 0x54, 0x4c, 0x53, 0x20, 0x50, 0x72, 0x6f, 0x6a, 0x65,
 | 
				
			||||||
 | 
					  0x63, 0x74, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
 | 
				
			||||||
 | 
					  0x09, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x30, 0x81,
 | 
				
			||||||
 | 
					  0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
 | 
				
			||||||
 | 
					  0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02,
 | 
				
			||||||
 | 
					  0x81, 0x81, 0x00, 0xcd, 0xfd, 0x89, 0x48, 0xbe, 0x36, 0xb9, 0x95, 0x76,
 | 
				
			||||||
 | 
					  0xd4, 0x13, 0x30, 0x0e, 0xbf, 0xb2, 0xed, 0x67, 0x0a, 0xc0, 0x16, 0x3f,
 | 
				
			||||||
 | 
					  0x51, 0x09, 0x9d, 0x29, 0x2f, 0xb2, 0x6d, 0x3f, 0x3e, 0x6c, 0x2f, 0x90,
 | 
				
			||||||
 | 
					  0x80, 0xa1, 0x71, 0xdf, 0xbe, 0x38, 0xc5, 0xcb, 0xa9, 0x9a, 0x40, 0x14,
 | 
				
			||||||
 | 
					  0x90, 0x0a, 0xf9, 0xb7, 0x07, 0x0b, 0xe1, 0xda, 0xe7, 0x09, 0xbf, 0x0d,
 | 
				
			||||||
 | 
					  0x57, 0x41, 0x86, 0x60, 0xa1, 0xc1, 0x27, 0x91, 0x5b, 0x0a, 0x98, 0x46,
 | 
				
			||||||
 | 
					  0x1b, 0xf6, 0xa2, 0x84, 0xf8, 0x65, 0xc7, 0xce, 0x2d, 0x96, 0x17, 0xaa,
 | 
				
			||||||
 | 
					  0x91, 0xf8, 0x61, 0x04, 0x50, 0x70, 0xeb, 0xb4, 0x43, 0xb7, 0xdc, 0x9a,
 | 
				
			||||||
 | 
					  0xcc, 0x31, 0x01, 0x14, 0xd4, 0xcd, 0xcc, 0xc2, 0x37, 0x6d, 0x69, 0x82,
 | 
				
			||||||
 | 
					  0xd6, 0xc6, 0xc4, 0xbe, 0xf2, 0x34, 0xa5, 0xc9, 0xa6, 0x19, 0x53, 0x32,
 | 
				
			||||||
 | 
					  0x7a, 0x86, 0x0e, 0x91, 0x82, 0x0f, 0xa1, 0x42, 0x54, 0xaa, 0x01, 0x02,
 | 
				
			||||||
 | 
					  0x03, 0x01, 0x00, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
 | 
				
			||||||
 | 
					  0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x40,
 | 
				
			||||||
 | 
					  0xb4, 0x94, 0x9a, 0xa8, 0x89, 0x72, 0x1d, 0x07, 0xe5, 0xb3, 0x6b, 0x88,
 | 
				
			||||||
 | 
					  0x21, 0xc2, 0x38, 0x36, 0x9e, 0x7a, 0x8c, 0x49, 0x48, 0x68, 0x0c, 0x06,
 | 
				
			||||||
 | 
					  0xe8, 0xdb, 0x1f, 0x4e, 0x05, 0xe6, 0x31, 0xe3, 0xfd, 0xe6, 0x0d, 0x6b,
 | 
				
			||||||
 | 
					  0xd8, 0x13, 0x17, 0xe0, 0x2d, 0x0d, 0xb8, 0x7e, 0xcb, 0x20, 0x6c, 0xa8,
 | 
				
			||||||
 | 
					  0x73, 0xa7, 0xfd, 0xe3, 0xa7, 0xfa, 0xf3, 0x02, 0x60, 0x78, 0x1f, 0x13,
 | 
				
			||||||
 | 
					  0x40, 0x45, 0xee, 0x75, 0xf5, 0x10, 0xfd, 0x8f, 0x68, 0x74, 0xd4, 0xac,
 | 
				
			||||||
 | 
					  0xae, 0x04, 0x09, 0x55, 0x2c, 0xdb, 0xd8, 0x07, 0x07, 0x65, 0x69, 0x27,
 | 
				
			||||||
 | 
					  0x6e, 0xbf, 0x5e, 0x61, 0x40, 0x56, 0x8b, 0xd7, 0x33, 0x3b, 0xff, 0x6e,
 | 
				
			||||||
 | 
					  0x53, 0x7e, 0x9d, 0x3f, 0xc0, 0x40, 0x3a, 0xab, 0xa0, 0x50, 0x4e, 0x80,
 | 
				
			||||||
 | 
					  0x47, 0x46, 0x0d, 0x1e, 0xdb, 0x4c, 0xf1, 0x1b, 0x5d, 0x3c, 0x2a, 0x54,
 | 
				
			||||||
 | 
					  0xa7, 0x4d, 0xfa, 0x7b, 0x72, 0x66, 0xc5
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					unsigned int default_certificate_len = 475;
 | 
				
			||||||
							
								
								
									
										127
									
								
								ssl/config.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								ssl/config.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,127 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Automatically generated header file: don't edit
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define HAVE_DOT_CONFIG 1
 | 
				
			||||||
 | 
					#undef CONFIG_PLATFORM_LINUX
 | 
				
			||||||
 | 
					#define CONFIG_PLATFORM_CYGWIN 1
 | 
				
			||||||
 | 
					#undef CONFIG_PLATFORM_WIN32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * General Configuration
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define PREFIX "/usr/local"
 | 
				
			||||||
 | 
					#define CONFIG_DEBUG 1
 | 
				
			||||||
 | 
					#undef CONFIG_STRIP_UNWANTED_SECTIONS
 | 
				
			||||||
 | 
					#undef CONFIG_VISUAL_STUDIO_7_0
 | 
				
			||||||
 | 
					#undef CONFIG_VISUAL_STUDIO_8_0
 | 
				
			||||||
 | 
					#undef CONFIG_VISUAL_STUDIO_10_0
 | 
				
			||||||
 | 
					#define CONFIG_VISUAL_STUDIO_7_0_BASE ""
 | 
				
			||||||
 | 
					#define CONFIG_VISUAL_STUDIO_8_0_BASE ""
 | 
				
			||||||
 | 
					#define CONFIG_VISUAL_STUDIO_10_0_BASE ""
 | 
				
			||||||
 | 
					#define CONFIG_EXTRA_CFLAGS_OPTIONS ""
 | 
				
			||||||
 | 
					#define CONFIG_EXTRA_LDFLAGS_OPTIONS ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * SSL Library
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#undef CONFIG_SSL_SERVER_ONLY
 | 
				
			||||||
 | 
					#undef CONFIG_SSL_CERT_VERIFICATION
 | 
				
			||||||
 | 
					#undef CONFIG_SSL_ENABLE_CLIENT
 | 
				
			||||||
 | 
					#define CONFIG_SSL_FULL_MODE 1
 | 
				
			||||||
 | 
					#undef CONFIG_SSL_SKELETON_MODE
 | 
				
			||||||
 | 
					#undef CONFIG_SSL_PROT_LOW
 | 
				
			||||||
 | 
					#define CONFIG_SSL_PROT_MEDIUM 1
 | 
				
			||||||
 | 
					#undef CONFIG_SSL_PROT_HIGH
 | 
				
			||||||
 | 
					#define CONFIG_SSL_USE_DEFAULT_KEY
 | 
				
			||||||
 | 
					#define CONFIG_SSL_PRIVATE_KEY_LOCATION ""
 | 
				
			||||||
 | 
					#define CONFIG_SSL_PRIVATE_KEY_PASSWORD ""
 | 
				
			||||||
 | 
					#define CONFIG_SSL_X509_CERT_LOCATION ""
 | 
				
			||||||
 | 
					#undef CONFIG_SSL_GENERATE_X509_CERT
 | 
				
			||||||
 | 
					#define CONFIG_SSL_X509_COMMON_NAME ""
 | 
				
			||||||
 | 
					#define CONFIG_SSL_X509_ORGANIZATION_NAME ""
 | 
				
			||||||
 | 
					#define CONFIG_SSL_X509_ORGANIZATION_UNIT_NAME ""
 | 
				
			||||||
 | 
					#undef CONFIG_SSL_ENABLE_V23_HANDSHAKE
 | 
				
			||||||
 | 
					#define CONFIG_SSL_HAS_PEM 1
 | 
				
			||||||
 | 
					#undef CONFIG_SSL_USE_PKCS12
 | 
				
			||||||
 | 
					#define CONFIG_SSL_EXPIRY_TIME 24
 | 
				
			||||||
 | 
					#define CONFIG_X509_MAX_CA_CERTS 150
 | 
				
			||||||
 | 
					#define CONFIG_SSL_MAX_CERTS 3
 | 
				
			||||||
 | 
					#undef CONFIG_SSL_CTX_MUTEXING
 | 
				
			||||||
 | 
					//#define CONFIG_USE_DEV_URANDOM 1
 | 
				
			||||||
 | 
					#undef CONFIG_WIN32_USE_CRYPTO_LIB
 | 
				
			||||||
 | 
					#undef CONFIG_OPENSSL_COMPATIBLE
 | 
				
			||||||
 | 
					#undef CONFIG_PERFORMANCE_TESTING
 | 
				
			||||||
 | 
					#define CONFIG_SSL_TEST 1
 | 
				
			||||||
 | 
					#undef CONFIG_AXTLSWRAP
 | 
				
			||||||
 | 
					#define CONFIG_AXHTTPD 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Axhttpd Configuration
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#undef CONFIG_HTTP_STATIC_BUILD
 | 
				
			||||||
 | 
					#define CONFIG_HTTP_PORT 80
 | 
				
			||||||
 | 
					#define CONFIG_HTTP_HTTPS_PORT 443
 | 
				
			||||||
 | 
					#define CONFIG_HTTP_SESSION_CACHE_SIZE 5
 | 
				
			||||||
 | 
					#define CONFIG_HTTP_WEBROOT "../www"
 | 
				
			||||||
 | 
					#define CONFIG_HTTP_TIMEOUT 300
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * CGI
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#undef CONFIG_HTTP_HAS_CGI 
 | 
				
			||||||
 | 
					#define CONFIG_HTTP_CGI_EXTENSIONS ".lua,.lp,.php"
 | 
				
			||||||
 | 
					#define CONFIG_HTTP_ENABLE_LUA 1
 | 
				
			||||||
 | 
					#define CONFIG_HTTP_LUA_PREFIX "/usr"
 | 
				
			||||||
 | 
					#undef CONFIG_HTTP_BUILD_LUA
 | 
				
			||||||
 | 
					#define CONFIG_HTTP_CGI_LAUNCHER "/usr/bin/cgi"
 | 
				
			||||||
 | 
					#define CONFIG_HTTP_DIRECTORIES 1
 | 
				
			||||||
 | 
					#define CONFIG_HTTP_HAS_AUTHORIZATION 1
 | 
				
			||||||
 | 
					#undef CONFIG_HTTP_HAS_IPV6
 | 
				
			||||||
 | 
					#undef CONFIG_HTTP_ENABLE_DIFFERENT_USER
 | 
				
			||||||
 | 
					#define CONFIG_HTTP_USER ""
 | 
				
			||||||
 | 
					#define CONFIG_HTTP_VERBOSE 0
 | 
				
			||||||
 | 
					#undef CONFIG_HTTP_IS_DAEMON
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Language Bindings
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#undef CONFIG_BINDINGS
 | 
				
			||||||
 | 
					#undef CONFIG_CSHARP_BINDINGS
 | 
				
			||||||
 | 
					#undef CONFIG_VBNET_BINDINGS
 | 
				
			||||||
 | 
					#define CONFIG_DOT_NET_FRAMEWORK_BASE ""
 | 
				
			||||||
 | 
					#undef CONFIG_JAVA_BINDINGS
 | 
				
			||||||
 | 
					#define CONFIG_JAVA_HOME ""
 | 
				
			||||||
 | 
					#undef CONFIG_PERL_BINDINGS
 | 
				
			||||||
 | 
					#define CONFIG_PERL_CORE ""
 | 
				
			||||||
 | 
					#define CONFIG_PERL_LIB ""
 | 
				
			||||||
 | 
					#undef CONFIG_LUA_BINDINGS
 | 
				
			||||||
 | 
					#define CONFIG_LUA_CORE ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Samples
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define CONFIG_SAMPLES 1
 | 
				
			||||||
 | 
					#define CONFIG_C_SAMPLES 1
 | 
				
			||||||
 | 
					#undef CONFIG_CSHARP_SAMPLES
 | 
				
			||||||
 | 
					#undef CONFIG_VBNET_SAMPLES
 | 
				
			||||||
 | 
					#undef CONFIG_JAVA_SAMPLES
 | 
				
			||||||
 | 
					#undef CONFIG_PERL_SAMPLES
 | 
				
			||||||
 | 
					#undef CONFIG_LUA_SAMPLES
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * BigInt Options
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#undef CONFIG_BIGINT_CLASSICAL
 | 
				
			||||||
 | 
					#undef CONFIG_BIGINT_MONTGOMERY
 | 
				
			||||||
 | 
					#define CONFIG_BIGINT_BARRETT 1
 | 
				
			||||||
 | 
					#define CONFIG_BIGINT_CRT 1
 | 
				
			||||||
 | 
					#undef CONFIG_BIGINT_KARATSUBA
 | 
				
			||||||
 | 
					#define MUL_KARATSUBA_THRESH 
 | 
				
			||||||
 | 
					#define SQU_KARATSUBA_THRESH 
 | 
				
			||||||
 | 
					#define CONFIG_BIGINT_SLIDING_WINDOW 1
 | 
				
			||||||
 | 
					#define CONFIG_BIGINT_SQUARE 1
 | 
				
			||||||
 | 
					#define CONFIG_BIGINT_CHECK_ON 1
 | 
				
			||||||
 | 
					#define CONFIG_INTEGER_32BIT 1
 | 
				
			||||||
 | 
					#undef CONFIG_INTEGER_16BIT
 | 
				
			||||||
 | 
					#undef CONFIG_INTEGER_8BIT
 | 
				
			||||||
							
								
								
									
										172
									
								
								ssl/crypto_misc.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										172
									
								
								ssl/crypto_misc.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,172 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @file crypto_misc.h
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef HEADER_CRYPTO_MISC_H
 | 
				
			||||||
 | 
					#define HEADER_CRYPTO_MISC_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					extern "C" {
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "crypto.h"
 | 
				
			||||||
 | 
					#include "bigint.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**************************************************************************
 | 
				
			||||||
 | 
					 * X509 declarations 
 | 
				
			||||||
 | 
					 **************************************************************************/
 | 
				
			||||||
 | 
					#define X509_OK                             0
 | 
				
			||||||
 | 
					#define X509_NOT_OK                         -1
 | 
				
			||||||
 | 
					#define X509_VFY_ERROR_NO_TRUSTED_CERT      -2
 | 
				
			||||||
 | 
					#define X509_VFY_ERROR_BAD_SIGNATURE        -3      
 | 
				
			||||||
 | 
					#define X509_VFY_ERROR_NOT_YET_VALID        -4
 | 
				
			||||||
 | 
					#define X509_VFY_ERROR_EXPIRED              -5
 | 
				
			||||||
 | 
					#define X509_VFY_ERROR_SELF_SIGNED          -6
 | 
				
			||||||
 | 
					#define X509_VFY_ERROR_INVALID_CHAIN        -7
 | 
				
			||||||
 | 
					#define X509_VFY_ERROR_UNSUPPORTED_DIGEST   -8
 | 
				
			||||||
 | 
					#define X509_INVALID_PRIV_KEY               -9
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * The Distinguished Name
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define X509_NUM_DN_TYPES                   3
 | 
				
			||||||
 | 
					#define X509_COMMON_NAME                    0
 | 
				
			||||||
 | 
					#define X509_ORGANIZATION                   1
 | 
				
			||||||
 | 
					#define X509_ORGANIZATIONAL_UNIT            2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct _x509_ctx
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    char *ca_cert_dn[X509_NUM_DN_TYPES];
 | 
				
			||||||
 | 
					    char *cert_dn[X509_NUM_DN_TYPES];
 | 
				
			||||||
 | 
					    char **subject_alt_dnsnames;
 | 
				
			||||||
 | 
					    time_t not_before;
 | 
				
			||||||
 | 
					    time_t not_after;
 | 
				
			||||||
 | 
					    uint8_t *signature;
 | 
				
			||||||
 | 
					    uint16_t sig_len;
 | 
				
			||||||
 | 
					    uint8_t sig_type;
 | 
				
			||||||
 | 
					    RSA_CTX *rsa_ctx;
 | 
				
			||||||
 | 
					    bigint *digest;
 | 
				
			||||||
 | 
					    struct _x509_ctx *next;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct _x509_ctx X509_CTX;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_CERT_VERIFICATION
 | 
				
			||||||
 | 
					typedef struct 
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    X509_CTX *cert[CONFIG_X509_MAX_CA_CERTS];
 | 
				
			||||||
 | 
					} CA_CERT_CTX;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int x509_new(const uint8_t *cert, int *len, X509_CTX **ctx);
 | 
				
			||||||
 | 
					void x509_free(X509_CTX *x509_ctx);
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_CERT_VERIFICATION
 | 
				
			||||||
 | 
					int x509_verify(const CA_CERT_CTX *ca_cert_ctx, const X509_CTX *cert);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_FULL_MODE
 | 
				
			||||||
 | 
					void x509_print(const X509_CTX *cert, CA_CERT_CTX *ca_cert_ctx);
 | 
				
			||||||
 | 
					const char * x509_display_error(int error);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**************************************************************************
 | 
				
			||||||
 | 
					 * ASN1 declarations 
 | 
				
			||||||
 | 
					 **************************************************************************/
 | 
				
			||||||
 | 
					#define ASN1_INTEGER            0x02
 | 
				
			||||||
 | 
					#define ASN1_BIT_STRING         0x03
 | 
				
			||||||
 | 
					#define ASN1_OCTET_STRING       0x04
 | 
				
			||||||
 | 
					#define ASN1_NULL               0x05
 | 
				
			||||||
 | 
					#define ASN1_PRINTABLE_STR2     0x0C
 | 
				
			||||||
 | 
					#define ASN1_OID                0x06
 | 
				
			||||||
 | 
					#define ASN1_PRINTABLE_STR2     0x0C
 | 
				
			||||||
 | 
					#define ASN1_PRINTABLE_STR      0x13
 | 
				
			||||||
 | 
					#define ASN1_TELETEX_STR        0x14
 | 
				
			||||||
 | 
					#define ASN1_IA5_STR            0x16
 | 
				
			||||||
 | 
					#define ASN1_UTC_TIME           0x17
 | 
				
			||||||
 | 
					#define ASN1_UNICODE_STR        0x1e
 | 
				
			||||||
 | 
					#define ASN1_SEQUENCE           0x30
 | 
				
			||||||
 | 
					#define ASN1_CONTEXT_DNSNAME	0x82
 | 
				
			||||||
 | 
					#define ASN1_SET                0x31
 | 
				
			||||||
 | 
					#define ASN1_V3_DATA			0xa3
 | 
				
			||||||
 | 
					#define ASN1_IMPLICIT_TAG       0x80
 | 
				
			||||||
 | 
					#define ASN1_CONTEXT_DNSNAME	0x82
 | 
				
			||||||
 | 
					#define ASN1_EXPLICIT_TAG       0xa0
 | 
				
			||||||
 | 
					#define ASN1_V3_DATA			0xa3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SIG_TYPE_MD2            0x02
 | 
				
			||||||
 | 
					#define SIG_TYPE_MD5            0x04
 | 
				
			||||||
 | 
					#define SIG_TYPE_SHA1           0x05
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int 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);
 | 
				
			||||||
 | 
					int asn1_get_int(const uint8_t *buf, int *offset, uint8_t **object);
 | 
				
			||||||
 | 
					int asn1_version(const uint8_t *cert, int *offset, X509_CTX *x509_ctx);
 | 
				
			||||||
 | 
					int asn1_validity(const uint8_t *cert, int *offset, X509_CTX *x509_ctx);
 | 
				
			||||||
 | 
					int asn1_name(const uint8_t *cert, int *offset, char *dn[]);
 | 
				
			||||||
 | 
					int asn1_public_key(const uint8_t *cert, int *offset, X509_CTX *x509_ctx);
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_CERT_VERIFICATION
 | 
				
			||||||
 | 
					int asn1_signature(const uint8_t *cert, int *offset, X509_CTX *x509_ctx);
 | 
				
			||||||
 | 
					int asn1_find_subjectaltname(const uint8_t* cert, int offset);
 | 
				
			||||||
 | 
					int asn1_compare_dn(char * const dn1[], char * const dn2[]);
 | 
				
			||||||
 | 
					#endif /* CONFIG_SSL_CERT_VERIFICATION */
 | 
				
			||||||
 | 
					int asn1_signature_type(const uint8_t *cert, 
 | 
				
			||||||
 | 
					                                int *offset, X509_CTX *x509_ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**************************************************************************
 | 
				
			||||||
 | 
					 * MISC declarations 
 | 
				
			||||||
 | 
					 **************************************************************************/
 | 
				
			||||||
 | 
					#define SALT_SIZE               8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern const char * const unsupported_str;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef void (*crypt_func)(void *, const uint8_t *, uint8_t *, int);
 | 
				
			||||||
 | 
					typedef void (*hmac_func)(const uint8_t *msg, int length, const uint8_t *key, 
 | 
				
			||||||
 | 
					        int key_len, uint8_t *digest);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int get_file(const char *filename, uint8_t **buf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(CONFIG_SSL_FULL_MODE) || defined(WIN32) || defined(CONFIG_DEBUG)
 | 
				
			||||||
 | 
					EXP_FUNC void STDCALL print_blob(const char *format, const uint8_t *data, int size, ...);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					    #define print_blob(...)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EXP_FUNC int STDCALL base64_decode(const char *in,  int len,
 | 
				
			||||||
 | 
					                    uint8_t *out, int *outlen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif 
 | 
				
			||||||
							
								
								
									
										364
									
								
								ssl/gen_cert.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										364
									
								
								ssl/gen_cert.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,364 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_GENERATE_X509_CERT
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include "os_port.h"
 | 
				
			||||||
 | 
					#include "ssl.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Generate a basic X.509 certificate
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint8_t set_gen_length(int len, uint8_t *buf, int *offset)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (len < 0x80) /* short form */
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        buf[(*offset)++] = len;
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else /* long form */
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        int i, length_bytes = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (len & 0x00FF0000)
 | 
				
			||||||
 | 
					            length_bytes = 3;
 | 
				
			||||||
 | 
					        else if (len & 0x0000FF00)
 | 
				
			||||||
 | 
					            length_bytes = 2;
 | 
				
			||||||
 | 
					        else if (len & 0x000000FF)
 | 
				
			||||||
 | 
					            length_bytes = 1;
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					        buf[(*offset)++] = 0x80 + length_bytes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (i = length_bytes-1; i >= 0; i--)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            buf[*offset+i] = len & 0xFF;
 | 
				
			||||||
 | 
					            len >>= 8;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        *offset += length_bytes;
 | 
				
			||||||
 | 
					        return length_bytes+1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int pre_adjust_with_size(uint8_t type,
 | 
				
			||||||
 | 
					        int *seq_offset, uint8_t *buf, int *offset)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    buf[(*offset)++] = type;
 | 
				
			||||||
 | 
					    *seq_offset = *offset;
 | 
				
			||||||
 | 
					    *offset += 4;   /* fill in later */
 | 
				
			||||||
 | 
					    return *offset;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void adjust_with_size(int seq_size, int seq_start, 
 | 
				
			||||||
 | 
					                uint8_t *buf, int *offset)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint8_t seq_byte_size; 
 | 
				
			||||||
 | 
					    int orig_seq_size = seq_size;
 | 
				
			||||||
 | 
					    int orig_seq_start = seq_start;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    seq_size = *offset-seq_size;
 | 
				
			||||||
 | 
					    seq_byte_size = set_gen_length(seq_size, buf, &seq_start);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (seq_byte_size != 4)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        memmove(&buf[orig_seq_start+seq_byte_size], 
 | 
				
			||||||
 | 
					                &buf[orig_seq_size], seq_size);
 | 
				
			||||||
 | 
					        *offset -= 4-seq_byte_size;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void gen_serial_number(uint8_t *buf, int *offset)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    static const uint8_t ser_oid[] = { ASN1_INTEGER, 1, 0x7F };
 | 
				
			||||||
 | 
					    memcpy(&buf[*offset], ser_oid , sizeof(ser_oid));
 | 
				
			||||||
 | 
					    *offset += sizeof(ser_oid);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void gen_signature_alg(uint8_t *buf, int *offset)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /* OBJECT IDENTIFIER sha1withRSAEncryption (1 2 840 113549 1 1 5) */
 | 
				
			||||||
 | 
					    static const uint8_t sig_oid[] = 
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ASN1_SEQUENCE, 0x0d, ASN1_OID, 0x09, 
 | 
				
			||||||
 | 
					        0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
 | 
				
			||||||
 | 
					        ASN1_NULL, 0x00
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memcpy(&buf[*offset], sig_oid, sizeof(sig_oid));
 | 
				
			||||||
 | 
					    *offset += sizeof(sig_oid);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int gen_dn(const char *name, uint8_t dn_type, 
 | 
				
			||||||
 | 
					                        uint8_t *buf, int *offset)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int ret = X509_OK;
 | 
				
			||||||
 | 
					    int name_size = strlen(name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (name_size > 0x70)    /* just too big */
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ret = X509_NOT_OK;
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    buf[(*offset)++] = ASN1_SET;
 | 
				
			||||||
 | 
					    set_gen_length(9+name_size, buf, offset);
 | 
				
			||||||
 | 
					    buf[(*offset)++] = ASN1_SEQUENCE;
 | 
				
			||||||
 | 
					    set_gen_length(7+name_size, buf, offset);
 | 
				
			||||||
 | 
					    buf[(*offset)++] = ASN1_OID;
 | 
				
			||||||
 | 
					    buf[(*offset)++] = 3;
 | 
				
			||||||
 | 
					    buf[(*offset)++] = 0x55;
 | 
				
			||||||
 | 
					    buf[(*offset)++] = 0x04;
 | 
				
			||||||
 | 
					    buf[(*offset)++] = dn_type;
 | 
				
			||||||
 | 
					    buf[(*offset)++] = ASN1_PRINTABLE_STR;
 | 
				
			||||||
 | 
					    buf[(*offset)++] = name_size;
 | 
				
			||||||
 | 
					    strcpy(&buf[*offset], name);
 | 
				
			||||||
 | 
					    *offset += name_size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error:
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int gen_issuer(const char * dn[], uint8_t *buf, int *offset)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int ret = X509_OK;
 | 
				
			||||||
 | 
					    int seq_offset;
 | 
				
			||||||
 | 
					    int seq_size = pre_adjust_with_size(
 | 
				
			||||||
 | 
					                            ASN1_SEQUENCE, &seq_offset, buf, offset);
 | 
				
			||||||
 | 
					    char fqdn[128]; 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* we need the common name, so if not configured, work out the fully
 | 
				
			||||||
 | 
					     * qualified domain name */
 | 
				
			||||||
 | 
					    if (dn[X509_COMMON_NAME] == NULL || strlen(dn[X509_COMMON_NAME]) == 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        int fqdn_len;
 | 
				
			||||||
 | 
					        gethostname(fqdn, sizeof(fqdn));
 | 
				
			||||||
 | 
					        fqdn_len = strlen(fqdn);
 | 
				
			||||||
 | 
					        fqdn[fqdn_len++] = '.';
 | 
				
			||||||
 | 
					        getdomainname(&fqdn[fqdn_len], sizeof(fqdn)-fqdn_len);
 | 
				
			||||||
 | 
					        fqdn_len = strlen(fqdn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (fqdn[fqdn_len-1] == '.')    /* ensure '.' is not last char */
 | 
				
			||||||
 | 
					            fqdn[fqdn_len-1] = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        dn[X509_COMMON_NAME] = fqdn;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ((ret = gen_dn(dn[X509_COMMON_NAME], 3, buf, offset)))
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (dn[X509_ORGANIZATION] != NULL && strlen(dn[X509_ORGANIZATION]) > 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ((ret = gen_dn(dn[X509_ORGANIZATION], 10, buf, offset)))
 | 
				
			||||||
 | 
					            goto error;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (dn[X509_ORGANIZATIONAL_UNIT] != NULL &&
 | 
				
			||||||
 | 
					                                strlen(dn[X509_ORGANIZATIONAL_UNIT]) > 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ((ret = gen_dn(dn[X509_ORGANIZATIONAL_UNIT], 11, buf, offset)))
 | 
				
			||||||
 | 
					            goto error;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    adjust_with_size(seq_size, seq_offset, buf, offset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error:
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void gen_utc_time(uint8_t *buf, int *offset)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    static const uint8_t time_seq[] = 
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ASN1_SEQUENCE, 30, 
 | 
				
			||||||
 | 
					        ASN1_UTC_TIME, 13, 
 | 
				
			||||||
 | 
					        '0', '7', '0', '1', '0', '1', '0', '0', '0', '0', '0', '0', 'Z', 
 | 
				
			||||||
 | 
					        ASN1_UTC_TIME, 13,  /* make it good for 30 or so years */
 | 
				
			||||||
 | 
					        '3', '8', '0', '1', '0', '1', '0', '0', '0', '0', '0', '0', 'Z'
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* fixed time */
 | 
				
			||||||
 | 
					    memcpy(&buf[*offset], time_seq, sizeof(time_seq));
 | 
				
			||||||
 | 
					    *offset += sizeof(time_seq);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void gen_pub_key2(const RSA_CTX *rsa_ctx, uint8_t *buf, int *offset)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    static const uint8_t pub_key_seq[] = 
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ASN1_INTEGER, 0x03, 0x01, 0x00, 0x01 /* INTEGER 65537 */
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int seq_offset;
 | 
				
			||||||
 | 
					    int pub_key_size = rsa_ctx->num_octets;
 | 
				
			||||||
 | 
					    uint8_t *block = (uint8_t *)alloca(pub_key_size);
 | 
				
			||||||
 | 
					    int seq_size = pre_adjust_with_size(
 | 
				
			||||||
 | 
					                            ASN1_SEQUENCE, &seq_offset, buf, offset);
 | 
				
			||||||
 | 
					    buf[(*offset)++] = ASN1_INTEGER;
 | 
				
			||||||
 | 
					    bi_export(rsa_ctx->bi_ctx, rsa_ctx->m, block, pub_key_size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (*block & 0x80)  /* make integer positive */
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        set_gen_length(pub_key_size+1, buf, offset);
 | 
				
			||||||
 | 
					        buf[(*offset)++] = 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        set_gen_length(pub_key_size, buf, offset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memcpy(&buf[*offset], block, pub_key_size);
 | 
				
			||||||
 | 
					    *offset += pub_key_size;
 | 
				
			||||||
 | 
					    memcpy(&buf[*offset], pub_key_seq, sizeof(pub_key_seq));
 | 
				
			||||||
 | 
					    *offset += sizeof(pub_key_seq);
 | 
				
			||||||
 | 
					    adjust_with_size(seq_size, seq_offset, buf, offset);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void gen_pub_key1(const RSA_CTX *rsa_ctx, uint8_t *buf, int *offset)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int seq_offset;
 | 
				
			||||||
 | 
					    int seq_size = pre_adjust_with_size(
 | 
				
			||||||
 | 
					                            ASN1_BIT_STRING, &seq_offset, buf, offset);
 | 
				
			||||||
 | 
					    buf[(*offset)++] = 0;   /* bit string is multiple of 8 */
 | 
				
			||||||
 | 
					    gen_pub_key2(rsa_ctx, buf, offset);
 | 
				
			||||||
 | 
					    adjust_with_size(seq_size, seq_offset, buf, offset);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void gen_pub_key(const RSA_CTX *rsa_ctx, uint8_t *buf, int *offset)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /*  OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 1 1) */
 | 
				
			||||||
 | 
					    static const uint8_t rsa_enc_oid[] =
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ASN1_SEQUENCE, 0x0d, ASN1_OID, 0x09,
 | 
				
			||||||
 | 
					        0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
 | 
				
			||||||
 | 
					        ASN1_NULL, 0x00
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int seq_offset;
 | 
				
			||||||
 | 
					    int seq_size = pre_adjust_with_size(
 | 
				
			||||||
 | 
					                            ASN1_SEQUENCE, &seq_offset, buf, offset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memcpy(&buf[*offset], rsa_enc_oid, sizeof(rsa_enc_oid));
 | 
				
			||||||
 | 
					    *offset += sizeof(rsa_enc_oid);
 | 
				
			||||||
 | 
					    gen_pub_key1(rsa_ctx, buf, offset);
 | 
				
			||||||
 | 
					    adjust_with_size(seq_size, seq_offset, buf, offset);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void gen_signature(const RSA_CTX *rsa_ctx, const uint8_t *sha_dgst, 
 | 
				
			||||||
 | 
					                        uint8_t *buf, int *offset)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    static const uint8_t asn1_sig[] = 
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ASN1_SEQUENCE,  0x21, ASN1_SEQUENCE, 0x09, ASN1_OID, 0x05, 
 | 
				
			||||||
 | 
					        0x2b, 0x0e, 0x03, 0x02, 0x1a, /* sha1 (1 3 14 3 2 26) */
 | 
				
			||||||
 | 
					        ASN1_NULL, 0x00, ASN1_OCTET_STRING, 0x14 
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint8_t *enc_block = (uint8_t *)alloca(rsa_ctx->num_octets);
 | 
				
			||||||
 | 
					    uint8_t *block = (uint8_t *)alloca(sizeof(asn1_sig) + SHA1_SIZE);
 | 
				
			||||||
 | 
					    int sig_size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* add the digest as an embedded asn.1 sequence */
 | 
				
			||||||
 | 
					    memcpy(block, asn1_sig, sizeof(asn1_sig));
 | 
				
			||||||
 | 
					    memcpy(&block[sizeof(asn1_sig)], sha_dgst, SHA1_SIZE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sig_size = RSA_encrypt(rsa_ctx, block, 
 | 
				
			||||||
 | 
					                            sizeof(asn1_sig) + SHA1_SIZE, enc_block, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    buf[(*offset)++] = ASN1_BIT_STRING;
 | 
				
			||||||
 | 
					    set_gen_length(sig_size+1, buf, offset);
 | 
				
			||||||
 | 
					    buf[(*offset)++] = 0;   /* bit string is multiple of 8 */
 | 
				
			||||||
 | 
					    memcpy(&buf[*offset], enc_block, sig_size);
 | 
				
			||||||
 | 
					    *offset += sig_size;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int gen_tbs_cert(const char * dn[],
 | 
				
			||||||
 | 
					                    const RSA_CTX *rsa_ctx, uint8_t *buf, int *offset,
 | 
				
			||||||
 | 
					                    uint8_t *sha_dgst)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int ret = X509_OK;
 | 
				
			||||||
 | 
					    SHA1_CTX sha_ctx;
 | 
				
			||||||
 | 
					    int seq_offset;
 | 
				
			||||||
 | 
					    int begin_tbs = *offset;
 | 
				
			||||||
 | 
					    int seq_size = pre_adjust_with_size(
 | 
				
			||||||
 | 
					                        ASN1_SEQUENCE, &seq_offset, buf, offset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    gen_serial_number(buf, offset);
 | 
				
			||||||
 | 
					    gen_signature_alg(buf, offset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* CA certicate issuer */
 | 
				
			||||||
 | 
					    if ((ret = gen_issuer(dn, buf, offset)))
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    gen_utc_time(buf, offset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* certificate issuer */
 | 
				
			||||||
 | 
					    if ((ret = gen_issuer(dn, buf, offset)))
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    gen_pub_key(rsa_ctx, buf, offset);
 | 
				
			||||||
 | 
					    adjust_with_size(seq_size, seq_offset, buf, offset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    SHA1_Init(&sha_ctx);
 | 
				
			||||||
 | 
					    SHA1_Update(&sha_ctx, &buf[begin_tbs], *offset-begin_tbs);
 | 
				
			||||||
 | 
					    SHA1_Final(sha_dgst, &sha_ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error:
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Create a new certificate.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EXP_FUNC int STDCALL ssl_x509_create(SSL_CTX *ssl_ctx, uint32_t options, const char * dn[], uint8_t **cert_data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int ret = X509_OK, offset = 0, seq_offset;
 | 
				
			||||||
 | 
					    /* allocate enough space to load a new certificate */
 | 
				
			||||||
 | 
					    uint8_t *buf = (uint8_t *)alloca(ssl_ctx->rsa_ctx->num_octets*2 + 512);
 | 
				
			||||||
 | 
					    uint8_t sha_dgst[SHA1_SIZE];
 | 
				
			||||||
 | 
					    int seq_size = pre_adjust_with_size(ASN1_SEQUENCE, 
 | 
				
			||||||
 | 
					                                    &seq_offset, buf, &offset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ((ret = gen_tbs_cert(dn, ssl_ctx->rsa_ctx, buf, &offset, sha_dgst)) < 0)
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    gen_signature_alg(buf, &offset);
 | 
				
			||||||
 | 
					    gen_signature(ssl_ctx->rsa_ctx, sha_dgst, buf, &offset);
 | 
				
			||||||
 | 
					    adjust_with_size(seq_size, seq_offset, buf, &offset);
 | 
				
			||||||
 | 
					    *cert_data = (uint8_t *)malloc(offset); /* create the exact memory for it */
 | 
				
			||||||
 | 
					    memcpy(*cert_data, buf, offset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error:
 | 
				
			||||||
 | 
					    return ret < 0 ? ret : offset;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								ssl/gen_cert.o
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								ssl/gen_cert.o
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										483
									
								
								ssl/loader.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										483
									
								
								ssl/loader.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,483 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Load certificates/keys into memory. These can be in many different formats.
 | 
				
			||||||
 | 
					 * PEM support and other formats can be processed here.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The PEM private keys may be optionally encrypted with AES128 or AES256. 
 | 
				
			||||||
 | 
					 * The encrypted PEM keys were generated with something like:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * openssl genrsa -aes128 -passout pass:abcd -out axTLS.key_aes128.pem 512
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include "os_port.h"
 | 
				
			||||||
 | 
					#include "ssl.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int do_obj(SSL_CTX *ssl_ctx, int obj_type, 
 | 
				
			||||||
 | 
					                    SSLObjLoader *ssl_obj, const char *password);
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_HAS_PEM
 | 
				
			||||||
 | 
					static int ssl_obj_PEM_load(SSL_CTX *ssl_ctx, int obj_type, 
 | 
				
			||||||
 | 
					                        SSLObjLoader *ssl_obj, const char *password);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Load a file into memory that is in binary DER (or ascii PEM) format.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EXP_FUNC int STDCALL ssl_obj_load(SSL_CTX *ssl_ctx, int obj_type, 
 | 
				
			||||||
 | 
					                            const char *filename, const char *password)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#ifndef CONFIG_SSL_SKELETON_MODE
 | 
				
			||||||
 | 
					    static const char * const begin = "-----BEGIN";
 | 
				
			||||||
 | 
					    int ret = SSL_OK;
 | 
				
			||||||
 | 
					    SSLObjLoader *ssl_obj = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (filename == NULL)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ret = SSL_ERROR_INVALID_KEY;
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ssl_obj = (SSLObjLoader *)calloc(1, sizeof(SSLObjLoader));
 | 
				
			||||||
 | 
					    ssl_obj->len = get_file(filename, &ssl_obj->buf); 
 | 
				
			||||||
 | 
					    if (ssl_obj->len <= 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ret = SSL_ERROR_INVALID_KEY;
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* is the file a PEM file? */
 | 
				
			||||||
 | 
					    if (strstr((char *)ssl_obj->buf, begin) != NULL)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_HAS_PEM
 | 
				
			||||||
 | 
					        ret = ssl_obj_PEM_load(ssl_ctx, obj_type, ssl_obj, password);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					        printf(unsupported_str);
 | 
				
			||||||
 | 
					        ret = SSL_ERROR_NOT_SUPPORTED;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        ret = do_obj(ssl_ctx, obj_type, ssl_obj, password);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error:
 | 
				
			||||||
 | 
					    ssl_obj_free(ssl_obj);
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					    printf(unsupported_str);
 | 
				
			||||||
 | 
					    return SSL_ERROR_NOT_SUPPORTED;
 | 
				
			||||||
 | 
					#endif /* CONFIG_SSL_SKELETON_MODE */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Transfer binary data into the object loader.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EXP_FUNC int STDCALL ssl_obj_memory_load(SSL_CTX *ssl_ctx, int mem_type, 
 | 
				
			||||||
 | 
					        const uint8_t *data, int len, const char *password)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int ret;
 | 
				
			||||||
 | 
					    SSLObjLoader *ssl_obj;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ssl_obj = (SSLObjLoader *)calloc(1, sizeof(SSLObjLoader));
 | 
				
			||||||
 | 
					    ssl_obj->buf = (uint8_t *)malloc(len);
 | 
				
			||||||
 | 
					    memcpy(ssl_obj->buf, data, len);
 | 
				
			||||||
 | 
					    ssl_obj->len = len;
 | 
				
			||||||
 | 
					    ret = do_obj(ssl_ctx, mem_type, ssl_obj, password);
 | 
				
			||||||
 | 
					    ssl_obj_free(ssl_obj);
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Actually work out what we are doing 
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int do_obj(SSL_CTX *ssl_ctx, int obj_type, 
 | 
				
			||||||
 | 
					                    SSLObjLoader *ssl_obj, const char *password)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int ret = SSL_OK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    switch (obj_type)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        case SSL_OBJ_RSA_KEY:
 | 
				
			||||||
 | 
					            ret = add_private_key(ssl_ctx, ssl_obj);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case SSL_OBJ_X509_CERT:
 | 
				
			||||||
 | 
					            ret = add_cert(ssl_ctx, ssl_obj->buf, ssl_obj->len);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_CERT_VERIFICATION
 | 
				
			||||||
 | 
					        case SSL_OBJ_X509_CACERT:
 | 
				
			||||||
 | 
					            add_cert_auth(ssl_ctx, ssl_obj->buf, ssl_obj->len);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_USE_PKCS12
 | 
				
			||||||
 | 
					        case SSL_OBJ_PKCS8:
 | 
				
			||||||
 | 
					            ret = pkcs8_decode(ssl_ctx, ssl_obj, password);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case SSL_OBJ_PKCS12:
 | 
				
			||||||
 | 
					            ret = pkcs12_decode(ssl_ctx, ssl_obj, password);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        default:
 | 
				
			||||||
 | 
					            printf(unsupported_str);
 | 
				
			||||||
 | 
					            ret = SSL_ERROR_NOT_SUPPORTED;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Clean up our mess.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void ssl_obj_free(SSLObjLoader *ssl_obj)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (ssl_obj)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        free(ssl_obj->buf);
 | 
				
			||||||
 | 
					        free(ssl_obj);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Support for PEM encoded keys/certificates.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_HAS_PEM
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define NUM_PEM_TYPES               4
 | 
				
			||||||
 | 
					#define IV_SIZE                     16
 | 
				
			||||||
 | 
					#define IS_RSA_PRIVATE_KEY          0
 | 
				
			||||||
 | 
					#define IS_ENCRYPTED_PRIVATE_KEY    1
 | 
				
			||||||
 | 
					#define IS_PRIVATE_KEY              2
 | 
				
			||||||
 | 
					#define IS_CERTIFICATE              3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char * const begins[NUM_PEM_TYPES] =
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    "-----BEGIN RSA PRIVATE KEY-----",
 | 
				
			||||||
 | 
					    "-----BEGIN ENCRYPTED PRIVATE KEY-----",
 | 
				
			||||||
 | 
					    "-----BEGIN PRIVATE KEY-----",
 | 
				
			||||||
 | 
					    "-----BEGIN CERTIFICATE-----",
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char * const ends[NUM_PEM_TYPES] =
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    "-----END RSA PRIVATE KEY-----",
 | 
				
			||||||
 | 
					    "-----END ENCRYPTED PRIVATE KEY-----",
 | 
				
			||||||
 | 
					    "-----END PRIVATE KEY-----",
 | 
				
			||||||
 | 
					    "-----END CERTIFICATE-----",
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char * const aes_str[2] =
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    "DEK-Info: AES-128-CBC,",
 | 
				
			||||||
 | 
					    "DEK-Info: AES-256-CBC," 
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Take a base64 blob of data and decrypt it (using AES) into its 
 | 
				
			||||||
 | 
					 * proper ASN.1 form.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int pem_decrypt(const char *where, const char *end,
 | 
				
			||||||
 | 
					                        const char *password, SSLObjLoader *ssl_obj)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int ret = -1;
 | 
				
			||||||
 | 
					    int is_aes_256 = 0;
 | 
				
			||||||
 | 
					    char *start = NULL;
 | 
				
			||||||
 | 
					    uint8_t iv[IV_SIZE];
 | 
				
			||||||
 | 
					    int i, pem_size;
 | 
				
			||||||
 | 
					    MD5_CTX md5_ctx;
 | 
				
			||||||
 | 
					    AES_CTX aes_ctx;
 | 
				
			||||||
 | 
					    uint8_t key[32];        /* AES256 size */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (password == NULL || strlen(password) == 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_FULL_MODE
 | 
				
			||||||
 | 
					        printf("Error: Need a password for this PEM file\n"); TTY_FLUSH();
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ((start = strstr((const char *)where, aes_str[0])))         /* AES128? */
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        start += strlen(aes_str[0]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if ((start = strstr((const char *)where, aes_str[1])))    /* AES256? */
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        is_aes_256 = 1;
 | 
				
			||||||
 | 
					        start += strlen(aes_str[1]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else 
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_FULL_MODE
 | 
				
			||||||
 | 
					        printf("Error: Unsupported password cipher\n"); TTY_FLUSH();
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* convert from hex to binary - assumes uppercase hex */
 | 
				
			||||||
 | 
					    for (i = 0; i < IV_SIZE; i++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        char c = *start++ - '0';
 | 
				
			||||||
 | 
					        iv[i] = (c > 9 ? c + '0' - 'A' + 10 : c) << 4;
 | 
				
			||||||
 | 
					        c = *start++ - '0';
 | 
				
			||||||
 | 
					        iv[i] += (c > 9 ? c + '0' - 'A' + 10 : c);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while (*start == '\r' || *start == '\n')
 | 
				
			||||||
 | 
					        start++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* turn base64 into binary */
 | 
				
			||||||
 | 
					    pem_size = (int)(end-start);
 | 
				
			||||||
 | 
					    if (base64_decode(start, pem_size, ssl_obj->buf, &ssl_obj->len) != 0)
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* work out the key */
 | 
				
			||||||
 | 
					    MD5_Init(&md5_ctx);
 | 
				
			||||||
 | 
					    MD5_Update(&md5_ctx, (const uint8_t *)password, strlen(password));
 | 
				
			||||||
 | 
					    MD5_Update(&md5_ctx, iv, SALT_SIZE);
 | 
				
			||||||
 | 
					    MD5_Final(key, &md5_ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (is_aes_256)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        MD5_Init(&md5_ctx);
 | 
				
			||||||
 | 
					        MD5_Update(&md5_ctx, key, MD5_SIZE);
 | 
				
			||||||
 | 
					        MD5_Update(&md5_ctx, (const uint8_t *)password, strlen(password));
 | 
				
			||||||
 | 
					        MD5_Update(&md5_ctx, iv, SALT_SIZE);
 | 
				
			||||||
 | 
					        MD5_Final(&key[MD5_SIZE], &md5_ctx);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* decrypt using the key/iv */
 | 
				
			||||||
 | 
					    AES_set_key(&aes_ctx, key, iv, is_aes_256 ? AES_MODE_256 : AES_MODE_128);
 | 
				
			||||||
 | 
					    AES_convert_key(&aes_ctx);
 | 
				
			||||||
 | 
					    AES_cbc_decrypt(&aes_ctx, ssl_obj->buf, ssl_obj->buf, ssl_obj->len);
 | 
				
			||||||
 | 
					    ret = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error:
 | 
				
			||||||
 | 
					    return ret; 
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Take a base64 blob of data and turn it into its proper ASN.1 form.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int new_pem_obj(SSL_CTX *ssl_ctx, int is_cacert, char *where, 
 | 
				
			||||||
 | 
					                    int remain, const char *password)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int ret = SSL_ERROR_BAD_CERTIFICATE;
 | 
				
			||||||
 | 
					    SSLObjLoader *ssl_obj = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while (remain > 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        int i, pem_size, obj_type;
 | 
				
			||||||
 | 
					        char *start = NULL, *end = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (i = 0; i < NUM_PEM_TYPES; i++)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if ((start = strstr(where, begins[i])) &&
 | 
				
			||||||
 | 
					                    (end = strstr(where, ends[i])))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                remain -= (int)(end-where);
 | 
				
			||||||
 | 
					                start += strlen(begins[i]);
 | 
				
			||||||
 | 
					                pem_size = (int)(end-start);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                ssl_obj = (SSLObjLoader *)calloc(1, sizeof(SSLObjLoader));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                /* 4/3 bigger than what we need but so what */
 | 
				
			||||||
 | 
					                ssl_obj->buf = (uint8_t *)calloc(1, pem_size);
 | 
				
			||||||
 | 
					                ssl_obj->len = pem_size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (i == IS_RSA_PRIVATE_KEY && 
 | 
				
			||||||
 | 
					                            strstr(start, "Proc-Type:") && 
 | 
				
			||||||
 | 
					                            strstr(start, "4,ENCRYPTED"))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    /* check for encrypted PEM file */
 | 
				
			||||||
 | 
					                    if (pem_decrypt(start, end, password, ssl_obj) < 0)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        ret = SSL_ERROR_BAD_CERTIFICATE;
 | 
				
			||||||
 | 
					                        goto error;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                else 
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    ssl_obj->len = pem_size;
 | 
				
			||||||
 | 
					                    if (base64_decode(start, pem_size, 
 | 
				
			||||||
 | 
					                                ssl_obj->buf, &ssl_obj->len) != 0)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        ret = SSL_ERROR_BAD_CERTIFICATE;
 | 
				
			||||||
 | 
					                        goto error;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                switch (i)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    case IS_RSA_PRIVATE_KEY:
 | 
				
			||||||
 | 
					                        obj_type = SSL_OBJ_RSA_KEY;
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    case IS_ENCRYPTED_PRIVATE_KEY:
 | 
				
			||||||
 | 
					                    case IS_PRIVATE_KEY:
 | 
				
			||||||
 | 
					                        obj_type = SSL_OBJ_PKCS8;
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    case IS_CERTIFICATE:
 | 
				
			||||||
 | 
					                        obj_type = is_cacert ?
 | 
				
			||||||
 | 
					                                        SSL_OBJ_X509_CACERT : SSL_OBJ_X509_CERT;
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    default:
 | 
				
			||||||
 | 
					                        ret = SSL_ERROR_BAD_CERTIFICATE;
 | 
				
			||||||
 | 
					                        goto error;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                /* In a format we can now understand - so process it */
 | 
				
			||||||
 | 
					                if ((ret = do_obj(ssl_ctx, obj_type, ssl_obj, password)))
 | 
				
			||||||
 | 
					                    goto error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                end += strlen(ends[i]);
 | 
				
			||||||
 | 
					                remain -= strlen(ends[i]);
 | 
				
			||||||
 | 
					                while (remain > 0 && (*end == '\r' || *end == '\n'))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    end++;
 | 
				
			||||||
 | 
					                    remain--;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                where = end;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ssl_obj_free(ssl_obj);
 | 
				
			||||||
 | 
					        ssl_obj = NULL;
 | 
				
			||||||
 | 
					        if (start == NULL)
 | 
				
			||||||
 | 
					           break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					error:
 | 
				
			||||||
 | 
					    ssl_obj_free(ssl_obj);
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Load a file into memory that is in ASCII PEM format.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int ssl_obj_PEM_load(SSL_CTX *ssl_ctx, int obj_type, 
 | 
				
			||||||
 | 
					                        SSLObjLoader *ssl_obj, const char *password)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    char *start;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* add a null terminator */
 | 
				
			||||||
 | 
					    ssl_obj->len++;
 | 
				
			||||||
 | 
					    ssl_obj->buf = (uint8_t *)realloc(ssl_obj->buf, ssl_obj->len);
 | 
				
			||||||
 | 
					    ssl_obj->buf[ssl_obj->len-1] = 0;
 | 
				
			||||||
 | 
					    start = (char *)ssl_obj->buf;
 | 
				
			||||||
 | 
					    return new_pem_obj(ssl_ctx, obj_type == SSL_OBJ_X509_CACERT,
 | 
				
			||||||
 | 
					                                start, ssl_obj->len, password);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif /* CONFIG_SSL_HAS_PEM */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Load the key/certificates in memory depending on compile-time and user
 | 
				
			||||||
 | 
					 * options. 
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int load_key_certs(SSL_CTX *ssl_ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int ret = SSL_OK;
 | 
				
			||||||
 | 
					    uint32_t options = ssl_ctx->options;
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_GENERATE_X509_CERT 
 | 
				
			||||||
 | 
					    uint8_t *cert_data = NULL;
 | 
				
			||||||
 | 
					    int cert_size;
 | 
				
			||||||
 | 
					    static const char *dn[] = 
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        CONFIG_SSL_X509_COMMON_NAME,
 | 
				
			||||||
 | 
					        CONFIG_SSL_X509_ORGANIZATION_NAME,
 | 
				
			||||||
 | 
					        CONFIG_SSL_X509_ORGANIZATION_UNIT_NAME
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* do the private key first */
 | 
				
			||||||
 | 
					    if (strlen(CONFIG_SSL_PRIVATE_KEY_LOCATION) > 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ((ret = ssl_obj_load(ssl_ctx, SSL_OBJ_RSA_KEY, 
 | 
				
			||||||
 | 
					                                CONFIG_SSL_PRIVATE_KEY_LOCATION,
 | 
				
			||||||
 | 
					                                CONFIG_SSL_PRIVATE_KEY_PASSWORD)) < 0)
 | 
				
			||||||
 | 
					            goto error;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (!(options & SSL_NO_DEFAULT_KEY))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					#if defined(CONFIG_SSL_USE_DEFAULT_KEY) || defined(CONFIG_SSL_SKELETON_MODE)
 | 
				
			||||||
 | 
					        static const    /* saves a few more bytes */
 | 
				
			||||||
 | 
					#include "private_key.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ssl_obj_memory_load(ssl_ctx, SSL_OBJ_RSA_KEY, default_private_key,
 | 
				
			||||||
 | 
					                default_private_key_len, NULL); 
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* now load the certificate */
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_GENERATE_X509_CERT 
 | 
				
			||||||
 | 
					    if ((cert_size = ssl_x509_create(ssl_ctx, 0, dn, &cert_data)) < 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ret = cert_size;
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ssl_obj_memory_load(ssl_ctx, SSL_OBJ_X509_CERT, cert_data, cert_size, NULL);
 | 
				
			||||||
 | 
					    free(cert_data);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					    if (strlen(CONFIG_SSL_X509_CERT_LOCATION))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ((ret = ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CERT, 
 | 
				
			||||||
 | 
					                                CONFIG_SSL_X509_CERT_LOCATION, NULL)) < 0)
 | 
				
			||||||
 | 
					            goto error;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (!(options & SSL_NO_DEFAULT_KEY))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					#if defined(CONFIG_SSL_USE_DEFAULT_KEY) || defined(CONFIG_SSL_SKELETON_MODE)
 | 
				
			||||||
 | 
					        static const    /* saves a few bytes and RAM */
 | 
				
			||||||
 | 
					#include "cert.h"
 | 
				
			||||||
 | 
					        ssl_obj_memory_load(ssl_ctx, SSL_OBJ_X509_CERT, 
 | 
				
			||||||
 | 
					                    default_certificate, default_certificate_len, NULL);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error:
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_FULL_MODE
 | 
				
			||||||
 | 
					    if (ret)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        printf("Error: Certificate or key not loaded\n"); TTY_FLUSH();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								ssl/loader.o
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								ssl/loader.o
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										323
									
								
								ssl/openssl.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										323
									
								
								ssl/openssl.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,323 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Enable a subset of openssl compatible functions. We don't aim to be 100%
 | 
				
			||||||
 | 
					 * compatible - just to be able to do basic ports etc.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Only really tested on mini_httpd, so I'm not too sure how extensive this
 | 
				
			||||||
 | 
					 * port is.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_OPENSSL_COMPATIBLE
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <stdarg.h>
 | 
				
			||||||
 | 
					#include "os_port.h"
 | 
				
			||||||
 | 
					#include "ssl.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define OPENSSL_CTX_ATTR  ((OPENSSL_CTX *)ssl_ctx->bonus_attr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static char *key_password = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void *SSLv23_server_method(void) { return NULL; }
 | 
				
			||||||
 | 
					void *SSLv3_server_method(void) { return NULL; }
 | 
				
			||||||
 | 
					void *TLSv1_server_method(void) { return NULL; }
 | 
				
			||||||
 | 
					void *SSLv23_client_method(void) { return NULL; }
 | 
				
			||||||
 | 
					void *SSLv3_client_method(void) { return NULL; }
 | 
				
			||||||
 | 
					void *TLSv1_client_method(void) { return NULL; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef void * (*ssl_func_type_t)(void);
 | 
				
			||||||
 | 
					typedef void * (*bio_func_type_t)(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ssl_func_type_t ssl_func_type;
 | 
				
			||||||
 | 
					} OPENSSL_CTX;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SSL_CTX * SSL_CTX_new(ssl_func_type_t meth)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    SSL_CTX *ssl_ctx = ssl_ctx_new(0, 5);
 | 
				
			||||||
 | 
					    ssl_ctx->bonus_attr = malloc(sizeof(OPENSSL_CTX));
 | 
				
			||||||
 | 
					    OPENSSL_CTX_ATTR->ssl_func_type = meth;
 | 
				
			||||||
 | 
					    return ssl_ctx;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SSL_CTX_free(SSL_CTX * ssl_ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    free(ssl_ctx->bonus_attr);
 | 
				
			||||||
 | 
					    ssl_ctx_free(ssl_ctx);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SSL * SSL_new(SSL_CTX *ssl_ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    SSL *ssl;
 | 
				
			||||||
 | 
					    ssl_func_type_t ssl_func_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ssl = ssl_new(ssl_ctx, -1);        /* fd is set later */
 | 
				
			||||||
 | 
					    ssl_func_type = OPENSSL_CTX_ATTR->ssl_func_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_ENABLE_CLIENT
 | 
				
			||||||
 | 
					    if (ssl_func_type == SSLv23_client_method ||
 | 
				
			||||||
 | 
					        ssl_func_type == SSLv3_client_method ||
 | 
				
			||||||
 | 
					        ssl_func_type == TLSv1_client_method)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        SET_SSL_FLAG(SSL_IS_CLIENT);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ssl->next_state = HS_CLIENT_HELLO;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return ssl;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int SSL_set_fd(SSL *s, int fd)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    s->client_fd = fd;
 | 
				
			||||||
 | 
					    return 1;   /* always succeeds */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int SSL_accept(SSL *ssl)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    while (ssl_read(ssl, NULL) == SSL_OK)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (ssl->next_state == HS_CLIENT_HELLO)
 | 
				
			||||||
 | 
					            return 1;   /* we're done */
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_ENABLE_CLIENT
 | 
				
			||||||
 | 
					int SSL_connect(SSL *ssl)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return do_client_connect(ssl) == SSL_OK ? 1 : -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SSL_free(SSL *ssl)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ssl_free(ssl);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int SSL_read(SSL *ssl, void *buf, int num)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint8_t *read_buf;
 | 
				
			||||||
 | 
					    int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while ((ret = ssl_read(ssl, &read_buf)) == SSL_OK);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (ret > SSL_OK)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        memcpy(buf, read_buf, ret > num ? num : ret);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int SSL_write(SSL *ssl, const void *buf, int num)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return ssl_write(ssl, buf, num);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int SSL_CTX_use_certificate_file(SSL_CTX *ssl_ctx, const char *file, int type)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return (ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CERT, file, NULL) == SSL_OK);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int SSL_CTX_use_PrivateKey_file(SSL_CTX *ssl_ctx, const char *file, int type)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return (ssl_obj_load(ssl_ctx, SSL_OBJ_RSA_KEY, file, key_password) == SSL_OK);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int SSL_CTX_use_certificate_ASN1(SSL_CTX *ssl_ctx, int len, const uint8_t *d)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return (ssl_obj_memory_load(ssl_ctx, 
 | 
				
			||||||
 | 
					                        SSL_OBJ_X509_CERT, d, len, NULL) == SSL_OK);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const unsigned char *sid_ctx,
 | 
				
			||||||
 | 
					                                            unsigned int sid_ctx_len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int SSL_CTX_use_certificate_chain_file(SSL_CTX *ssl_ctx, const char *file)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return (ssl_obj_load(ssl_ctx, 
 | 
				
			||||||
 | 
					                        SSL_OBJ_X509_CERT, file, NULL) == SSL_OK);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int SSL_shutdown(SSL *ssl)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*** get/set session ***/
 | 
				
			||||||
 | 
					SSL_SESSION *SSL_get1_session(SSL *ssl)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return (SSL_SESSION *)ssl_get_session_id(ssl); /* note: wrong cast */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int SSL_set_session(SSL *ssl, SSL_SESSION *session)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    memcpy(ssl->session_id, (uint8_t *)session, SSL_SESSION_ID_SIZE);
 | 
				
			||||||
 | 
					    return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SSL_SESSION_free(SSL_SESSION *session) { }
 | 
				
			||||||
 | 
					/*** end get/set session ***/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SSL_CTX_set_verify(SSL_CTX *ctx, int mode,
 | 
				
			||||||
 | 
					                                 int (*verify_callback)(int, void *)) { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SSL_CTX_set_verify_depth(SSL_CTX *ctx,int depth) { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile,
 | 
				
			||||||
 | 
					                                           const char *CApath)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void *SSL_load_client_CA_file(const char *file)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return (void *)file;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SSL_CTX_set_client_CA_list(SSL_CTX *ssl_ctx, void *file) 
 | 
				
			||||||
 | 
					{ 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CERT, (const char *)file, NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SSLv23_method(void) { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, void *cb) { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u) 
 | 
				
			||||||
 | 
					{ 
 | 
				
			||||||
 | 
					    key_password = (char *)u;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int SSL_peek(SSL *ssl, void *buf, int num)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    memcpy(buf, ssl->bm_data, num);
 | 
				
			||||||
 | 
					    return num;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SSL_set_bio(SSL *ssl, void *rbio, void *wbio) { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					long SSL_get_verify_result(const SSL *ssl)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return ssl_handshake_status(ssl);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int SSL_state(SSL *ssl)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return 0x03; // ok state
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** end of could do better list */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void *SSL_get_peer_certificate(const SSL *ssl)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return &ssl->ssl_ctx->certs[0];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int SSL_clear(SSL *ssl)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int SSL_CTX_check_private_key(const SSL_CTX *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int SSL_CTX_set_cipher_list(SSL *s, const char *str)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int SSL_get_error(const SSL *ssl, int ret)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ssl_display_error(ret);
 | 
				
			||||||
 | 
					    return 0;   /* TODO: return proper return code */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SSL_CTX_set_options(SSL_CTX *ssl_ctx, int option) {}
 | 
				
			||||||
 | 
					int SSL_library_init(void ) { return 1; }
 | 
				
			||||||
 | 
					void SSL_load_error_strings(void ) {}
 | 
				
			||||||
 | 
					void ERR_print_errors_fp(FILE *fp) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef CONFIG_SSL_SKELETON_MODE
 | 
				
			||||||
 | 
					long SSL_CTX_get_timeout(const SSL_CTX *ssl_ctx) { 
 | 
				
			||||||
 | 
					                            return CONFIG_SSL_EXPIRY_TIME*3600; }
 | 
				
			||||||
 | 
					long SSL_CTX_set_timeout(SSL_CTX *ssl_ctx, long t) { 
 | 
				
			||||||
 | 
					                            return SSL_CTX_get_timeout(ssl_ctx); }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					void BIO_printf(FILE *f, const char *format, ...)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    va_list(ap);
 | 
				
			||||||
 | 
					    va_start(ap, format);
 | 
				
			||||||
 | 
					    vfprintf(f, format, ap);
 | 
				
			||||||
 | 
					    va_end(ap);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void* BIO_s_null(void) { return NULL; }
 | 
				
			||||||
 | 
					FILE *BIO_new(bio_func_type_t func)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (func == BIO_s_null)
 | 
				
			||||||
 | 
					        return fopen("/dev/null", "r");
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FILE *BIO_new_fp(FILE *stream, int close_flag) { return stream; }
 | 
				
			||||||
 | 
					int BIO_free(FILE *a) { if (a != stdout && a != stderr) fclose(a); return 1; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								ssl/openssl.o
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								ssl/openssl.o
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										8
									
								
								ssl/os_int.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								ssl/os_int.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					#ifndef OS_INT_H
 | 
				
			||||||
 | 
					#define OS_INT_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stddef.h>
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					#include <stdbool.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif //OS_INT_H
 | 
				
			||||||
							
								
								
									
										158
									
								
								ssl/os_port.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								ssl/os_port.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,158 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @file os_port.c
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * OS specific functions.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#include <time.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					#include <stdarg.h>
 | 
				
			||||||
 | 
					#include "os_port.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef WIN32
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * gettimeofday() not in Win32 
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EXP_FUNC void STDCALL gettimeofday(struct timeval* t, void* timezone)
 | 
				
			||||||
 | 
					{       
 | 
				
			||||||
 | 
					#if defined(_WIN32_WCE)
 | 
				
			||||||
 | 
					    t->tv_sec = time(NULL);
 | 
				
			||||||
 | 
					    t->tv_usec = 0;                         /* 1sec precision only */ 
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					    struct _timeb timebuffer;
 | 
				
			||||||
 | 
					    _ftime(&timebuffer);
 | 
				
			||||||
 | 
					    t->tv_sec = (long)timebuffer.time;
 | 
				
			||||||
 | 
					    t->tv_usec = 1000 * timebuffer.millitm; /* 1ms precision */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * strcasecmp() not in Win32
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EXP_FUNC int STDCALL strcasecmp(const char *s1, const char *s2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    while (tolower(*s1) == tolower(*s2++))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (*s1++ == '\0')
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return 0;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return *(unsigned char *)s1 - *(unsigned char *)(s2 - 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EXP_FUNC int STDCALL getdomainname(char *buf, int buf_size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    HKEY hKey;
 | 
				
			||||||
 | 
					    unsigned long datatype;
 | 
				
			||||||
 | 
					    unsigned long bufferlength = buf_size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
 | 
				
			||||||
 | 
					            TEXT("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters"),
 | 
				
			||||||
 | 
					                        0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS)
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    RegQueryValueEx(hKey, "Domain", NULL, &datatype, buf, &bufferlength);
 | 
				
			||||||
 | 
					    RegCloseKey(hKey);
 | 
				
			||||||
 | 
					    return 0; 
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#undef malloc
 | 
				
			||||||
 | 
					#undef realloc
 | 
				
			||||||
 | 
					#undef calloc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char * out_of_mem_str = "out of memory";
 | 
				
			||||||
 | 
					static const char * file_open_str = "Could not open file \"%s\"";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 
 | 
				
			||||||
 | 
					 * Some functions that call display some error trace and then call abort().
 | 
				
			||||||
 | 
					 * This just makes life much easier on embedded systems, since we're 
 | 
				
			||||||
 | 
					 * suffering major trauma...
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EXP_FUNC void * STDCALL ax_malloc(size_t s)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    void *x;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ((x = malloc(s)) == NULL)
 | 
				
			||||||
 | 
					        exit_now(out_of_mem_str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return x;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EXP_FUNC void * STDCALL ax_realloc(void *y, size_t s)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    void *x;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ((x = realloc(y, s)) == NULL)
 | 
				
			||||||
 | 
					        exit_now(out_of_mem_str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return x;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EXP_FUNC void * STDCALL ax_calloc(size_t n, size_t s)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    void *x;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ((x = calloc(n, s)) == NULL)
 | 
				
			||||||
 | 
					        exit_now(out_of_mem_str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return x;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EXP_FUNC int STDCALL ax_open(const char *pathname, int flags)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int x;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ((x = open(pathname, flags)) < 0)
 | 
				
			||||||
 | 
					        exit_now(file_open_str, pathname);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return x;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * This is a call which will deliberately exit an application, but will
 | 
				
			||||||
 | 
					 * display some information before dying.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void exit_now(const char *format, ...)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    va_list argp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    va_start(argp, format);
 | 
				
			||||||
 | 
					    vfprintf(stderr, format, argp);
 | 
				
			||||||
 | 
					    va_end(argp);
 | 
				
			||||||
 | 
					    abort();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										199
									
								
								ssl/os_port.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										199
									
								
								ssl/os_port.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,199 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @file os_port.h
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Some stuff to minimise the differences between windows and linux/unix
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef HEADER_OS_PORT_H
 | 
				
			||||||
 | 
					#define HEADER_OS_PORT_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					extern "C" {
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "os_int.h"
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef WIN32
 | 
				
			||||||
 | 
					#define STDCALL                 __stdcall
 | 
				
			||||||
 | 
					#define EXP_FUNC                __declspec(dllexport)
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define STDCALL
 | 
				
			||||||
 | 
					#define EXP_FUNC
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(_WIN32_WCE)
 | 
				
			||||||
 | 
					#undef WIN32
 | 
				
			||||||
 | 
					#define WIN32
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(ESP8266)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#elif defined(WIN32)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Windows CE stuff */
 | 
				
			||||||
 | 
					#if defined(_WIN32_WCE)
 | 
				
			||||||
 | 
					#include <basetsd.h>
 | 
				
			||||||
 | 
					#define abort()                 exit(1)
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#include <io.h>
 | 
				
			||||||
 | 
					#include <process.h>
 | 
				
			||||||
 | 
					#include <sys/timeb.h>
 | 
				
			||||||
 | 
					#include <fcntl.h>
 | 
				
			||||||
 | 
					#endif      /* _WIN32_WCE */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <winsock.h>
 | 
				
			||||||
 | 
					#include <direct.h>
 | 
				
			||||||
 | 
					#undef getpid
 | 
				
			||||||
 | 
					#undef open
 | 
				
			||||||
 | 
					#undef close
 | 
				
			||||||
 | 
					#undef sleep
 | 
				
			||||||
 | 
					#undef gettimeofday
 | 
				
			||||||
 | 
					#undef dup2
 | 
				
			||||||
 | 
					#undef unlink
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SOCKET_READ(A,B,C)      recv(A,B,C,0)
 | 
				
			||||||
 | 
					#define SOCKET_WRITE(A,B,C)     send(A,B,C,0)
 | 
				
			||||||
 | 
					#define SOCKET_CLOSE(A)         closesocket(A)
 | 
				
			||||||
 | 
					#define srandom(A)              srand(A)
 | 
				
			||||||
 | 
					#define random()                rand()
 | 
				
			||||||
 | 
					#define getpid()                _getpid()
 | 
				
			||||||
 | 
					#define snprintf                _snprintf
 | 
				
			||||||
 | 
					#define open(A,B)               _open(A,B)
 | 
				
			||||||
 | 
					#define dup2(A,B)               _dup2(A,B)
 | 
				
			||||||
 | 
					#define unlink(A)               _unlink(A)
 | 
				
			||||||
 | 
					#define close(A)                _close(A)
 | 
				
			||||||
 | 
					#define read(A,B,C)             _read(A,B,C)
 | 
				
			||||||
 | 
					#define write(A,B,C)            _write(A,B,C)
 | 
				
			||||||
 | 
					#define sleep(A)                Sleep(A*1000)
 | 
				
			||||||
 | 
					#define usleep(A)               Sleep(A/1000)
 | 
				
			||||||
 | 
					#define strdup(A)               _strdup(A)
 | 
				
			||||||
 | 
					#define chroot(A)               _chdir(A)
 | 
				
			||||||
 | 
					#define chdir(A)                _chdir(A)
 | 
				
			||||||
 | 
					#define alloca(A)               _alloca(A)
 | 
				
			||||||
 | 
					#ifndef lseek
 | 
				
			||||||
 | 
					#define lseek(A,B,C)            _lseek(A,B,C)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* This fix gets around a problem where a win32 application on a cygwin xterm
 | 
				
			||||||
 | 
					   doesn't display regular output (until a certain buffer limit) - but it works
 | 
				
			||||||
 | 
					   fine under a normal DOS window. This is a hack to get around the issue - 
 | 
				
			||||||
 | 
					   see http://www.khngai.com/emacs/tty.php  */
 | 
				
			||||||
 | 
					#define TTY_FLUSH()             if (!_isatty(_fileno(stdout))) fflush(stdout);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * automatically build some library dependencies.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#pragma comment(lib, "WS2_32.lib")
 | 
				
			||||||
 | 
					#pragma comment(lib, "AdvAPI32.lib")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef int socklen_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EXP_FUNC void STDCALL gettimeofday(struct timeval* t,void* timezone);
 | 
				
			||||||
 | 
					EXP_FUNC int STDCALL strcasecmp(const char *s1, const char *s2);
 | 
				
			||||||
 | 
					EXP_FUNC int STDCALL getdomainname(char *buf, int buf_size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#else   /* Not Win32 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					#include <pwd.h>
 | 
				
			||||||
 | 
					#include <netdb.h>
 | 
				
			||||||
 | 
					#include <dirent.h>
 | 
				
			||||||
 | 
					#include <fcntl.h>
 | 
				
			||||||
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					#include <sys/stat.h>
 | 
				
			||||||
 | 
					#include <sys/time.h>
 | 
				
			||||||
 | 
					#include <sys/socket.h>
 | 
				
			||||||
 | 
					#include <sys/wait.h>
 | 
				
			||||||
 | 
					#include <netinet/in.h>
 | 
				
			||||||
 | 
					#include <arpa/inet.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#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()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif  /* Not Win32 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* some functions to mutate the way these work */
 | 
				
			||||||
 | 
					#define malloc(A)       ax_malloc(A)
 | 
				
			||||||
 | 
					#ifndef realloc
 | 
				
			||||||
 | 
					#define realloc(A,B)    ax_realloc(A,B)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#define calloc(A,B)     ax_calloc(A,B)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EXP_FUNC void * STDCALL ax_malloc(size_t s);
 | 
				
			||||||
 | 
					EXP_FUNC void * STDCALL ax_realloc(void *y, size_t s);
 | 
				
			||||||
 | 
					EXP_FUNC void * STDCALL ax_calloc(size_t n, size_t s);
 | 
				
			||||||
 | 
					EXP_FUNC int STDCALL ax_open(const char *pathname, int flags); 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_PLATFORM_LINUX
 | 
				
			||||||
 | 
					void exit_now(const char *format, ...) __attribute((noreturn));
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					void exit_now(const char *format, ...);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Mutexing definitions */
 | 
				
			||||||
 | 
					#if defined(CONFIG_SSL_CTX_MUTEXING)
 | 
				
			||||||
 | 
					#if defined(WIN32)
 | 
				
			||||||
 | 
					#define SSL_CTX_MUTEX_TYPE          HANDLE
 | 
				
			||||||
 | 
					#define SSL_CTX_MUTEX_INIT(A)       A=CreateMutex(0, FALSE, 0)
 | 
				
			||||||
 | 
					#define SSL_CTX_MUTEX_DESTROY(A)    CloseHandle(A)
 | 
				
			||||||
 | 
					#define SSL_CTX_LOCK(A)             WaitForSingleObject(A, INFINITE)
 | 
				
			||||||
 | 
					#define SSL_CTX_UNLOCK(A)           ReleaseMutex(A)
 | 
				
			||||||
 | 
					#else 
 | 
				
			||||||
 | 
					#include <pthread.h>
 | 
				
			||||||
 | 
					#define SSL_CTX_MUTEX_TYPE          pthread_mutex_t
 | 
				
			||||||
 | 
					#define SSL_CTX_MUTEX_INIT(A)       pthread_mutex_init(&A, NULL)
 | 
				
			||||||
 | 
					#define SSL_CTX_MUTEX_DESTROY(A)    pthread_mutex_destroy(&A)
 | 
				
			||||||
 | 
					#define SSL_CTX_LOCK(A)             pthread_mutex_lock(&A)
 | 
				
			||||||
 | 
					#define SSL_CTX_UNLOCK(A)           pthread_mutex_unlock(&A)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#else   /* no mutexing */
 | 
				
			||||||
 | 
					#define SSL_CTX_MUTEX_INIT(A)
 | 
				
			||||||
 | 
					#define SSL_CTX_MUTEX_DESTROY(A)
 | 
				
			||||||
 | 
					#define SSL_CTX_LOCK(A)
 | 
				
			||||||
 | 
					#define SSL_CTX_UNLOCK(A)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif 
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								ssl/os_port.o
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								ssl/os_port.o
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										483
									
								
								ssl/p12.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										483
									
								
								ssl/p12.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,483 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Process PKCS#8/PKCS#12 keys.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The decoding of a PKCS#12 key is fairly specific - this code was tested on a
 | 
				
			||||||
 | 
					 * key generated with:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * openssl pkcs12 -export -in axTLS.x509_1024.pem -inkey axTLS.key_1024.pem
 | 
				
			||||||
 | 
					 * -keypbe PBE-SHA1-RC4-128 -certpbe PBE-SHA1-RC4-128 
 | 
				
			||||||
 | 
					 * -name "p12_withoutCA" -out axTLS.withoutCA.p12 -password pass:abcd
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * or with a certificate chain:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * openssl pkcs12 -export -in axTLS.x509_1024.pem -inkey axTLS.key_1024.pem
 | 
				
			||||||
 | 
					 * -certfile axTLS.ca_x509.pem -keypbe PBE-SHA1-RC4-128 -certpbe
 | 
				
			||||||
 | 
					 * PBE-SHA1-RC4-128 -name "p12_withCA" -out axTLS.withCA.p12 -password pass:abcd
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Note that the PBE has to be specified with PBE-SHA1-RC4-128. The
 | 
				
			||||||
 | 
					 * private/public keys/certs have to use RSA encryption. Both the integrity
 | 
				
			||||||
 | 
					 * and privacy passwords are the same.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The PKCS#8 files were generated with something like:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * PEM format:
 | 
				
			||||||
 | 
					 * openssl pkcs8 -in axTLS.key_512.pem -passout pass:abcd -topk8 -v1
 | 
				
			||||||
 | 
					 * PBE-SHA1-RC4-128 -out axTLS.encrypted_pem.p8
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * DER format:
 | 
				
			||||||
 | 
					 * openssl pkcs8 -in axTLS.key_512.pem -passout pass:abcd -topk8 -outform DER
 | 
				
			||||||
 | 
					 * -v1 PBE-SHA1-RC4-128 -out axTLS.encrypted.p8
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include "os_port.h"
 | 
				
			||||||
 | 
					#include "ssl.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* all commented out if not used */
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_USE_PKCS12
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define BLOCK_SIZE          64
 | 
				
			||||||
 | 
					#define PKCS12_KEY_ID       1
 | 
				
			||||||
 | 
					#define PKCS12_IV_ID        2
 | 
				
			||||||
 | 
					#define PKCS12_MAC_ID       3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static char *make_uni_pass(const char *password, int *uni_pass_len);
 | 
				
			||||||
 | 
					static int p8_decrypt(const char *uni_pass, int uni_pass_len, 
 | 
				
			||||||
 | 
					                        const uint8_t *salt, int iter, 
 | 
				
			||||||
 | 
					                        uint8_t *priv_key, int priv_key_len, int id);
 | 
				
			||||||
 | 
					static int p8_add_key(SSL_CTX *ssl_ctx, uint8_t *priv_key);
 | 
				
			||||||
 | 
					static int get_pbe_params(uint8_t *buf, int *offset, 
 | 
				
			||||||
 | 
					        const uint8_t **salt, int *iterations);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Take a raw pkcs8 block and then decrypt it and turn it into a normal key.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int pkcs8_decode(SSL_CTX *ssl_ctx, SSLObjLoader *ssl_obj, const char *password)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint8_t *buf = ssl_obj->buf;
 | 
				
			||||||
 | 
					    int len, offset = 0;
 | 
				
			||||||
 | 
					    int iterations;
 | 
				
			||||||
 | 
					    int ret = SSL_NOT_OK;
 | 
				
			||||||
 | 
					    uint8_t *version = NULL;
 | 
				
			||||||
 | 
					    const uint8_t *salt;
 | 
				
			||||||
 | 
					    uint8_t *priv_key;
 | 
				
			||||||
 | 
					    int uni_pass_len;
 | 
				
			||||||
 | 
					    char *uni_pass = make_uni_pass(password, &uni_pass_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_FULL_MODE
 | 
				
			||||||
 | 
					        printf("Error: Invalid p8 ASN.1 file\n");
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* unencrypted key? */
 | 
				
			||||||
 | 
					    if (asn1_get_int(buf, &offset, &version) > 0 && *version == 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ret = p8_add_key(ssl_ctx, buf);
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (get_pbe_params(buf, &offset, &salt, &iterations) < 0)
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ((len = asn1_next_obj(buf, &offset, ASN1_OCTET_STRING)) < 0)
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    priv_key = &buf[offset];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    p8_decrypt(uni_pass, uni_pass_len, salt, 
 | 
				
			||||||
 | 
					                        iterations, priv_key, len, PKCS12_KEY_ID);
 | 
				
			||||||
 | 
					    ret = p8_add_key(ssl_ctx, priv_key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error:
 | 
				
			||||||
 | 
					    free(version);
 | 
				
			||||||
 | 
					    free(uni_pass);
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Take the unencrypted pkcs8 and turn it into a private key 
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int p8_add_key(SSL_CTX *ssl_ctx, uint8_t *priv_key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint8_t *buf = priv_key;
 | 
				
			||||||
 | 
					    int len, offset = 0;
 | 
				
			||||||
 | 
					    int ret = SSL_NOT_OK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Skip the preamble and go straight to the private key.
 | 
				
			||||||
 | 
					       We only support rsaEncryption (1.2.840.113549.1.1.1)  */
 | 
				
			||||||
 | 
					    if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
 | 
				
			||||||
 | 
					            asn1_skip_obj(buf, &offset, ASN1_INTEGER) < 0 ||
 | 
				
			||||||
 | 
					            asn1_skip_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
 | 
				
			||||||
 | 
					            (len = asn1_next_obj(buf, &offset, ASN1_OCTET_STRING)) < 0)
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ret = asn1_get_private_key(&buf[offset], len, &ssl_ctx->rsa_ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error:
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Create the unicode password 
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static char *make_uni_pass(const char *password, int *uni_pass_len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int pass_len = 0, i;
 | 
				
			||||||
 | 
					    char *uni_pass;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (password == NULL)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        password = "";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uni_pass = (char *)malloc((strlen(password)+1)*2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* modify the password into a unicode version */
 | 
				
			||||||
 | 
					    for (i = 0; i < (int)strlen(password); i++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        uni_pass[pass_len++] = 0;
 | 
				
			||||||
 | 
					        uni_pass[pass_len++] = password[i];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uni_pass[pass_len++] = 0;       /* null terminate */
 | 
				
			||||||
 | 
					    uni_pass[pass_len++] = 0;
 | 
				
			||||||
 | 
					    *uni_pass_len = pass_len;
 | 
				
			||||||
 | 
					    return uni_pass;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Decrypt a pkcs8 block.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int p8_decrypt(const char *uni_pass, int uni_pass_len,
 | 
				
			||||||
 | 
					                        const uint8_t *salt, int iter, 
 | 
				
			||||||
 | 
					                        uint8_t *priv_key, int priv_key_len, int id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint8_t p[BLOCK_SIZE*2];
 | 
				
			||||||
 | 
					    uint8_t d[BLOCK_SIZE];
 | 
				
			||||||
 | 
					    uint8_t Ai[SHA1_SIZE];
 | 
				
			||||||
 | 
					    SHA1_CTX sha_ctx;
 | 
				
			||||||
 | 
					    RC4_CTX rc4_ctx;
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0; i < BLOCK_SIZE; i++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        p[i] = salt[i % SALT_SIZE];
 | 
				
			||||||
 | 
					        p[BLOCK_SIZE+i] = uni_pass[i % uni_pass_len];
 | 
				
			||||||
 | 
					        d[i] = id;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* get the key - no IV since we are using RC4 */
 | 
				
			||||||
 | 
					    SHA1_Init(&sha_ctx);
 | 
				
			||||||
 | 
					    SHA1_Update(&sha_ctx, d, sizeof(d));
 | 
				
			||||||
 | 
					    SHA1_Update(&sha_ctx, p, sizeof(p));
 | 
				
			||||||
 | 
					    SHA1_Final(Ai, &sha_ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 1; i < iter; i++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        SHA1_Init(&sha_ctx);
 | 
				
			||||||
 | 
					        SHA1_Update(&sha_ctx, Ai, SHA1_SIZE);
 | 
				
			||||||
 | 
					        SHA1_Final(Ai, &sha_ctx);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* do the decryption */
 | 
				
			||||||
 | 
					    if (id == PKCS12_KEY_ID)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        RC4_setup(&rc4_ctx, Ai, 16);
 | 
				
			||||||
 | 
					        RC4_crypt(&rc4_ctx, priv_key, priv_key, priv_key_len);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else  /* MAC */
 | 
				
			||||||
 | 
					        memcpy(priv_key, Ai, SHA1_SIZE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Take a raw pkcs12 block and the decrypt it and turn it into a certificate(s)
 | 
				
			||||||
 | 
					 * and keys.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int pkcs12_decode(SSL_CTX *ssl_ctx, SSLObjLoader *ssl_obj, const char *password)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint8_t *buf = ssl_obj->buf;
 | 
				
			||||||
 | 
					    int len, iterations, auth_safes_start, 
 | 
				
			||||||
 | 
					              auth_safes_end, auth_safes_len, key_offset, offset = 0;
 | 
				
			||||||
 | 
					    int all_certs = 0;
 | 
				
			||||||
 | 
					    uint8_t *version = NULL, *auth_safes = NULL, *cert, *orig_mac;
 | 
				
			||||||
 | 
					    uint8_t key[SHA1_SIZE];
 | 
				
			||||||
 | 
					    uint8_t mac[SHA1_SIZE];
 | 
				
			||||||
 | 
					    const uint8_t *salt;
 | 
				
			||||||
 | 
					    int uni_pass_len, ret = SSL_OK;
 | 
				
			||||||
 | 
					    char *uni_pass = make_uni_pass(password, &uni_pass_len);
 | 
				
			||||||
 | 
					    static const uint8_t pkcs_data[] = /* pkc7 data */
 | 
				
			||||||
 | 
					        { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01 };
 | 
				
			||||||
 | 
					    static const uint8_t pkcs_encrypted[] = /* pkc7 encrypted */
 | 
				
			||||||
 | 
					        { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x06 };
 | 
				
			||||||
 | 
					    static const uint8_t pkcs8_key_bag[] = /* 1.2.840.113549.1.12.10.1.2 */
 | 
				
			||||||
 | 
					        { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01, 0x02 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_FULL_MODE
 | 
				
			||||||
 | 
					        printf("Error: Invalid p12 ASN.1 file\n");
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (asn1_get_int(buf, &offset, &version) < 0 || *version != 3)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ret = SSL_ERROR_INVALID_VERSION;
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* remove all the boring pcks7 bits */
 | 
				
			||||||
 | 
					    if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 || 
 | 
				
			||||||
 | 
					                (len = asn1_next_obj(buf, &offset, ASN1_OID)) < 0 ||
 | 
				
			||||||
 | 
					                len != sizeof(pkcs_data) || 
 | 
				
			||||||
 | 
					                memcmp(&buf[offset], pkcs_data, sizeof(pkcs_data)))
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    offset += len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (asn1_next_obj(buf, &offset, ASN1_EXPLICIT_TAG) < 0 ||
 | 
				
			||||||
 | 
					            asn1_next_obj(buf, &offset, ASN1_OCTET_STRING) < 0)
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* work out the MAC start/end points (done on AuthSafes) */
 | 
				
			||||||
 | 
					    auth_safes_start = offset;
 | 
				
			||||||
 | 
					    auth_safes_end = offset;
 | 
				
			||||||
 | 
					    if (asn1_skip_obj(buf, &auth_safes_end, ASN1_SEQUENCE) < 0)
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    auth_safes_len = auth_safes_end - auth_safes_start;
 | 
				
			||||||
 | 
					    auth_safes = malloc(auth_safes_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memcpy(auth_safes, &buf[auth_safes_start], auth_safes_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
 | 
				
			||||||
 | 
					            asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
 | 
				
			||||||
 | 
					            (len = asn1_next_obj(buf, &offset, ASN1_OID)) < 0 ||
 | 
				
			||||||
 | 
					            (len != sizeof(pkcs_encrypted) || 
 | 
				
			||||||
 | 
					            memcmp(&buf[offset], pkcs_encrypted, sizeof(pkcs_encrypted))))
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    offset += len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (asn1_next_obj(buf, &offset, ASN1_EXPLICIT_TAG) < 0 ||
 | 
				
			||||||
 | 
					            asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
 | 
				
			||||||
 | 
					            asn1_skip_obj(buf, &offset, ASN1_INTEGER) < 0 ||
 | 
				
			||||||
 | 
					            asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
 | 
				
			||||||
 | 
					            (len = asn1_next_obj(buf, &offset, ASN1_OID)) < 0 ||
 | 
				
			||||||
 | 
					            len != sizeof(pkcs_data) || 
 | 
				
			||||||
 | 
					            memcmp(&buf[offset], pkcs_data, sizeof(pkcs_data)))
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    offset += len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* work out the salt for the certificate */
 | 
				
			||||||
 | 
					    if (get_pbe_params(buf, &offset, &salt, &iterations) < 0 ||
 | 
				
			||||||
 | 
					            (len = asn1_next_obj(buf, &offset, ASN1_IMPLICIT_TAG)) < 0)
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* decrypt the certificate */
 | 
				
			||||||
 | 
					    cert = &buf[offset];
 | 
				
			||||||
 | 
					    if ((ret = p8_decrypt(uni_pass, uni_pass_len, salt, iterations, cert, 
 | 
				
			||||||
 | 
					                            len, PKCS12_KEY_ID)) < 0)
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    offset += len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* load the certificate */
 | 
				
			||||||
 | 
					    key_offset = 0;
 | 
				
			||||||
 | 
					    all_certs = asn1_next_obj(cert, &key_offset, ASN1_SEQUENCE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* keep going until all certs are loaded */
 | 
				
			||||||
 | 
					    while (key_offset < all_certs)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        int cert_offset = key_offset;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (asn1_skip_obj(cert, &cert_offset, ASN1_SEQUENCE) < 0 ||
 | 
				
			||||||
 | 
					                asn1_next_obj(cert, &key_offset, ASN1_SEQUENCE) < 0 ||
 | 
				
			||||||
 | 
					                asn1_skip_obj(cert, &key_offset, ASN1_OID) < 0 ||
 | 
				
			||||||
 | 
					                asn1_next_obj(cert, &key_offset, ASN1_EXPLICIT_TAG) < 0 ||
 | 
				
			||||||
 | 
					                asn1_next_obj(cert, &key_offset, ASN1_SEQUENCE) < 0 ||
 | 
				
			||||||
 | 
					                asn1_skip_obj(cert, &key_offset, ASN1_OID) < 0 ||
 | 
				
			||||||
 | 
					                asn1_next_obj(cert, &key_offset, ASN1_EXPLICIT_TAG) < 0 ||
 | 
				
			||||||
 | 
					                (len = asn1_next_obj(cert, &key_offset, ASN1_OCTET_STRING)) < 0)
 | 
				
			||||||
 | 
					            goto error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ((ret = add_cert(ssl_ctx, &cert[key_offset], len)) < 0)
 | 
				
			||||||
 | 
					            goto error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        key_offset = cert_offset;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
 | 
				
			||||||
 | 
					            (len = asn1_next_obj(buf, &offset, ASN1_OID)) < 0 ||
 | 
				
			||||||
 | 
					            len != sizeof(pkcs_data) || 
 | 
				
			||||||
 | 
					            memcmp(&buf[offset], pkcs_data, sizeof(pkcs_data)))
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    offset += len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (asn1_next_obj(buf, &offset, ASN1_EXPLICIT_TAG) < 0 ||
 | 
				
			||||||
 | 
					            asn1_next_obj(buf, &offset, ASN1_OCTET_STRING) < 0 ||
 | 
				
			||||||
 | 
					            asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
 | 
				
			||||||
 | 
					            asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
 | 
				
			||||||
 | 
					            (len = asn1_next_obj(buf, &offset, ASN1_OID)) < 0 ||
 | 
				
			||||||
 | 
					            (len != sizeof(pkcs8_key_bag)) || 
 | 
				
			||||||
 | 
					            memcmp(&buf[offset], pkcs8_key_bag, sizeof(pkcs8_key_bag)))
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    offset += len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* work out the salt for the private key */
 | 
				
			||||||
 | 
					    if (asn1_next_obj(buf, &offset, ASN1_EXPLICIT_TAG) < 0 ||
 | 
				
			||||||
 | 
					            asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
 | 
				
			||||||
 | 
					            get_pbe_params(buf, &offset, &salt, &iterations) < 0 ||
 | 
				
			||||||
 | 
					            (len = asn1_next_obj(buf, &offset, ASN1_OCTET_STRING)) < 0)
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* decrypt the private key */
 | 
				
			||||||
 | 
					    cert = &buf[offset];
 | 
				
			||||||
 | 
					    if ((ret = p8_decrypt(uni_pass, uni_pass_len, salt, iterations, cert, 
 | 
				
			||||||
 | 
					                            len, PKCS12_KEY_ID)) < 0)
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    offset += len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* load the private key */
 | 
				
			||||||
 | 
					    if ((ret = p8_add_key(ssl_ctx, cert)) < 0)
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* miss out on friendly name, local key id etc */
 | 
				
			||||||
 | 
					    if (asn1_skip_obj(buf, &offset, ASN1_SET) < 0)
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* work out the MAC */
 | 
				
			||||||
 | 
					    if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
 | 
				
			||||||
 | 
					            asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
 | 
				
			||||||
 | 
					            asn1_skip_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
 | 
				
			||||||
 | 
					            (len = asn1_next_obj(buf, &offset, ASN1_OCTET_STRING)) < 0 ||
 | 
				
			||||||
 | 
					            len != SHA1_SIZE)
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    orig_mac = &buf[offset];
 | 
				
			||||||
 | 
					    offset += len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* get the salt */
 | 
				
			||||||
 | 
					    if ((len = asn1_next_obj(buf, &offset, ASN1_OCTET_STRING)) < 0 || len != 8)
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    salt = &buf[offset];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* work out what the mac should be */
 | 
				
			||||||
 | 
					    if ((ret = p8_decrypt(uni_pass, uni_pass_len, salt, iterations, 
 | 
				
			||||||
 | 
					                            key, SHA1_SIZE, PKCS12_MAC_ID)) < 0)
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    hmac_sha1(auth_safes, auth_safes_len, key, SHA1_SIZE, mac);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (memcmp(mac, orig_mac, SHA1_SIZE))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ret = SSL_ERROR_INVALID_HMAC;                  
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error:
 | 
				
			||||||
 | 
					    free(version);
 | 
				
			||||||
 | 
					    free(uni_pass);
 | 
				
			||||||
 | 
					    free(auth_safes);
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Retrieve the salt/iteration details from a PBE block.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int get_pbe_params(uint8_t *buf, int *offset, 
 | 
				
			||||||
 | 
					        const uint8_t **salt, int *iterations)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    static const uint8_t pbeSH1RC4[] = /* pbeWithSHAAnd128BitRC4  */
 | 
				
			||||||
 | 
					            { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x01 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int i, len;
 | 
				
			||||||
 | 
					    uint8_t *iter = NULL;
 | 
				
			||||||
 | 
					    int error_code = SSL_ERROR_NOT_SUPPORTED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Get the PBE type */
 | 
				
			||||||
 | 
					    if (asn1_next_obj(buf, offset, ASN1_SEQUENCE) < 0 ||
 | 
				
			||||||
 | 
					            (len = asn1_next_obj(buf, offset, ASN1_OID)) < 0)
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* we expect pbeWithSHAAnd128BitRC4 (1.2.840.113549.1.12.1.1) 
 | 
				
			||||||
 | 
					       which is the only algorithm we support */
 | 
				
			||||||
 | 
					    if (len != sizeof(pbeSH1RC4) || 
 | 
				
			||||||
 | 
					                    memcmp(&buf[*offset], pbeSH1RC4, sizeof(pbeSH1RC4)))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_FULL_MODE
 | 
				
			||||||
 | 
					        printf("Error: pkcs8/pkcs12 must use \"PBE-SHA1-RC4-128\"\n");
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    *offset += len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (asn1_next_obj(buf, offset, ASN1_SEQUENCE) < 0 ||
 | 
				
			||||||
 | 
					            (len = asn1_next_obj(buf, offset, ASN1_OCTET_STRING)) < 0 || 
 | 
				
			||||||
 | 
					            len != 8)
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    *salt = &buf[*offset];
 | 
				
			||||||
 | 
					    *offset += len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ((len = asn1_get_int(buf, offset, &iter)) < 0)
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    *iterations = 0;
 | 
				
			||||||
 | 
					    for (i = 0; i < len; i++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        (*iterations) <<= 8;
 | 
				
			||||||
 | 
					        (*iterations) += iter[i];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    free(iter);
 | 
				
			||||||
 | 
					    error_code = SSL_OK;       /* got here - we are ok */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error:
 | 
				
			||||||
 | 
					    return error_code;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										54
									
								
								ssl/private_key.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								ssl/private_key.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,54 @@
 | 
				
			|||||||
 | 
					unsigned char default_private_key[] = {
 | 
				
			||||||
 | 
					  0x30, 0x82, 0x02, 0x5d, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xcd,
 | 
				
			||||||
 | 
					  0xfd, 0x89, 0x48, 0xbe, 0x36, 0xb9, 0x95, 0x76, 0xd4, 0x13, 0x30, 0x0e,
 | 
				
			||||||
 | 
					  0xbf, 0xb2, 0xed, 0x67, 0x0a, 0xc0, 0x16, 0x3f, 0x51, 0x09, 0x9d, 0x29,
 | 
				
			||||||
 | 
					  0x2f, 0xb2, 0x6d, 0x3f, 0x3e, 0x6c, 0x2f, 0x90, 0x80, 0xa1, 0x71, 0xdf,
 | 
				
			||||||
 | 
					  0xbe, 0x38, 0xc5, 0xcb, 0xa9, 0x9a, 0x40, 0x14, 0x90, 0x0a, 0xf9, 0xb7,
 | 
				
			||||||
 | 
					  0x07, 0x0b, 0xe1, 0xda, 0xe7, 0x09, 0xbf, 0x0d, 0x57, 0x41, 0x86, 0x60,
 | 
				
			||||||
 | 
					  0xa1, 0xc1, 0x27, 0x91, 0x5b, 0x0a, 0x98, 0x46, 0x1b, 0xf6, 0xa2, 0x84,
 | 
				
			||||||
 | 
					  0xf8, 0x65, 0xc7, 0xce, 0x2d, 0x96, 0x17, 0xaa, 0x91, 0xf8, 0x61, 0x04,
 | 
				
			||||||
 | 
					  0x50, 0x70, 0xeb, 0xb4, 0x43, 0xb7, 0xdc, 0x9a, 0xcc, 0x31, 0x01, 0x14,
 | 
				
			||||||
 | 
					  0xd4, 0xcd, 0xcc, 0xc2, 0x37, 0x6d, 0x69, 0x82, 0xd6, 0xc6, 0xc4, 0xbe,
 | 
				
			||||||
 | 
					  0xf2, 0x34, 0xa5, 0xc9, 0xa6, 0x19, 0x53, 0x32, 0x7a, 0x86, 0x0e, 0x91,
 | 
				
			||||||
 | 
					  0x82, 0x0f, 0xa1, 0x42, 0x54, 0xaa, 0x01, 0x02, 0x03, 0x01, 0x00, 0x01,
 | 
				
			||||||
 | 
					  0x02, 0x81, 0x81, 0x00, 0x95, 0xaa, 0x6e, 0x11, 0xf5, 0x6a, 0x8b, 0xa2,
 | 
				
			||||||
 | 
					  0xc6, 0x48, 0xc6, 0x7c, 0x37, 0x6b, 0x1f, 0x55, 0x10, 0x76, 0x26, 0x24,
 | 
				
			||||||
 | 
					  0xc3, 0xf2, 0x5c, 0x5a, 0xdd, 0x2e, 0xf3, 0xa4, 0x1e, 0xbc, 0x7b, 0x1c,
 | 
				
			||||||
 | 
					  0x80, 0x10, 0x85, 0xbc, 0xd8, 0x45, 0x3c, 0xb8, 0xb2, 0x06, 0x53, 0xb5,
 | 
				
			||||||
 | 
					  0xd5, 0x7a, 0xe7, 0x0e, 0x92, 0xe6, 0x42, 0xc2, 0xe2, 0x2a, 0xd5, 0xd1,
 | 
				
			||||||
 | 
					  0x03, 0x9f, 0x6f, 0x53, 0x74, 0x68, 0x72, 0x8e, 0xbf, 0x03, 0xbb, 0xab,
 | 
				
			||||||
 | 
					  0xbd, 0xa1, 0xf9, 0x81, 0x7d, 0x12, 0xd4, 0x9d, 0xb6, 0xae, 0x4c, 0xad,
 | 
				
			||||||
 | 
					  0xca, 0xa8, 0xc9, 0x80, 0x8d, 0x0d, 0xd5, 0xd0, 0xa1, 0xbf, 0xec, 0x60,
 | 
				
			||||||
 | 
					  0x48, 0x49, 0xed, 0x97, 0x0f, 0x5e, 0xed, 0xfc, 0x39, 0x15, 0x96, 0x9e,
 | 
				
			||||||
 | 
					  0x5d, 0xe2, 0xb4, 0x5d, 0x2e, 0x04, 0xdc, 0x08, 0xa2, 0x65, 0x29, 0x2d,
 | 
				
			||||||
 | 
					  0x37, 0xfb, 0x62, 0x90, 0x1b, 0x7b, 0xe5, 0x3a, 0x58, 0x05, 0x55, 0xc1,
 | 
				
			||||||
 | 
					  0x02, 0x41, 0x00, 0xfc, 0x69, 0x28, 0xc9, 0xa8, 0xc4, 0x5c, 0xe3, 0xd0,
 | 
				
			||||||
 | 
					  0x5e, 0xaa, 0xda, 0xde, 0x87, 0x74, 0xdb, 0xcb, 0x40, 0x78, 0x8e, 0x1d,
 | 
				
			||||||
 | 
					  0x12, 0x96, 0x16, 0x61, 0x3f, 0xb3, 0x3e, 0xa3, 0x0d, 0xdc, 0x49, 0xa5,
 | 
				
			||||||
 | 
					  0x25, 0x87, 0xc5, 0x97, 0x85, 0x9d, 0xbb, 0xb4, 0xf0, 0x44, 0xfd, 0x6c,
 | 
				
			||||||
 | 
					  0xe8, 0xd2, 0x8c, 0xec, 0x33, 0x81, 0x46, 0x1e, 0x10, 0x12, 0x33, 0x16,
 | 
				
			||||||
 | 
					  0x95, 0x00, 0x4f, 0x75, 0xb4, 0xe5, 0x79, 0x02, 0x41, 0x00, 0xd0, 0xeb,
 | 
				
			||||||
 | 
					  0x65, 0x07, 0x10, 0x3b, 0xd9, 0x03, 0xeb, 0xdc, 0x6f, 0x4b, 0x8f, 0xc3,
 | 
				
			||||||
 | 
					  0x87, 0xce, 0x76, 0xd6, 0xc5, 0x14, 0x21, 0x4e, 0xe7, 0x4f, 0x1b, 0xe8,
 | 
				
			||||||
 | 
					  0x05, 0xf8, 0x84, 0x1a, 0xe0, 0xc5, 0xd6, 0xe3, 0x08, 0xb3, 0x54, 0x57,
 | 
				
			||||||
 | 
					  0x02, 0x1f, 0xd4, 0xd9, 0xfb, 0xff, 0x40, 0xb1, 0x56, 0x1c, 0x60, 0xf7,
 | 
				
			||||||
 | 
					  0xac, 0x91, 0xf3, 0xd3, 0xc6, 0x7f, 0x84, 0xfd, 0x84, 0x9d, 0xea, 0x26,
 | 
				
			||||||
 | 
					  0xee, 0xc9, 0x02, 0x41, 0x00, 0xa6, 0xcf, 0x1c, 0x6c, 0x81, 0x03, 0x1c,
 | 
				
			||||||
 | 
					  0x5c, 0x56, 0x05, 0x6a, 0x26, 0x70, 0xef, 0xd6, 0x13, 0xb7, 0x74, 0x28,
 | 
				
			||||||
 | 
					  0xf7, 0xca, 0x50, 0xd1, 0x2d, 0x83, 0x21, 0x64, 0xe4, 0xdd, 0x3f, 0x38,
 | 
				
			||||||
 | 
					  0xb8, 0xd6, 0xd2, 0x41, 0xb3, 0x1c, 0x9a, 0xea, 0x0d, 0xf5, 0xda, 0xdf,
 | 
				
			||||||
 | 
					  0xcd, 0x17, 0x9f, 0x9a, 0x1e, 0x15, 0xaf, 0x48, 0x1c, 0xbd, 0x9b, 0x63,
 | 
				
			||||||
 | 
					  0x5b, 0xad, 0xed, 0xd4, 0xa1, 0xae, 0xa9, 0x59, 0x09, 0x02, 0x40, 0x4e,
 | 
				
			||||||
 | 
					  0x08, 0xce, 0xa8, 0x8f, 0xc0, 0xba, 0xf3, 0x83, 0x02, 0xc8, 0x33, 0x62,
 | 
				
			||||||
 | 
					  0x14, 0x77, 0xc2, 0x7f, 0x93, 0x02, 0xf3, 0xdc, 0xe9, 0x1a, 0xee, 0xea,
 | 
				
			||||||
 | 
					  0x8e, 0x84, 0xc4, 0x69, 0x9b, 0x9c, 0x7f, 0x69, 0x1f, 0x4e, 0x1d, 0xa5,
 | 
				
			||||||
 | 
					  0x90, 0x06, 0x44, 0x1b, 0x7d, 0xfc, 0x69, 0x40, 0x21, 0xbc, 0xf7, 0x46,
 | 
				
			||||||
 | 
					  0xa4, 0xdc, 0x39, 0x7b, 0xe8, 0x8b, 0x49, 0x10, 0x44, 0x9d, 0x67, 0x5a,
 | 
				
			||||||
 | 
					  0x91, 0x86, 0x39, 0x02, 0x40, 0x41, 0x2c, 0x4e, 0xfe, 0xd9, 0x90, 0x89,
 | 
				
			||||||
 | 
					  0x00, 0x5c, 0x94, 0x0a, 0x4a, 0x7e, 0x1b, 0x1a, 0x80, 0x06, 0x01, 0x37,
 | 
				
			||||||
 | 
					  0xda, 0x50, 0x61, 0x9d, 0x9c, 0xfe, 0x25, 0x7f, 0xd8, 0xd4, 0xc4, 0x9e,
 | 
				
			||||||
 | 
					  0x81, 0xf2, 0x0c, 0x1e, 0x38, 0x21, 0x1e, 0x90, 0x3f, 0xd4, 0xba, 0x6c,
 | 
				
			||||||
 | 
					  0x53, 0xcb, 0xf0, 0x77, 0x79, 0x9b, 0xf1, 0xfa, 0x3f, 0x81, 0xdc, 0xf3,
 | 
				
			||||||
 | 
					  0x21, 0x02, 0x6d, 0xb7, 0x95, 0xc3, 0x2e, 0xce, 0xd5
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					unsigned int default_private_key_len = 609;
 | 
				
			||||||
							
								
								
									
										499
									
								
								ssl/ssl.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										499
									
								
								ssl/ssl.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,499 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @mainpage axTLS API
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @image html axolotl.jpg
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The axTLS library has features such as:
 | 
				
			||||||
 | 
					 * - The TLSv1 SSL client/server protocol
 | 
				
			||||||
 | 
					 * - No requirement to use any openssl libraries.
 | 
				
			||||||
 | 
					 * - A choice between AES block (128/256 bit) and RC4 (128 bit) stream ciphers.
 | 
				
			||||||
 | 
					 * - RSA encryption/decryption with variable sized keys (up to 4096 bits).
 | 
				
			||||||
 | 
					 * - Certificate chaining and peer authentication.
 | 
				
			||||||
 | 
					 * - Session resumption, session renegotiation.
 | 
				
			||||||
 | 
					 * - ASN.1, X.509, PKCS#8, PKCS#12 keys/certificates with DER/PEM encoding.
 | 
				
			||||||
 | 
					 * - Highly configurable compile time options.
 | 
				
			||||||
 | 
					 * - Portable across many platforms (written in ANSI C), and has language
 | 
				
			||||||
 | 
					 * bindings in C, C#, VB.NET, Java, Perl and Lua.
 | 
				
			||||||
 | 
					 * - Partial openssl API compatibility (via a wrapper).
 | 
				
			||||||
 | 
					 * - A very small footprint (around 50-60kB for the library in 'server-only' 
 | 
				
			||||||
 | 
					 *   mode).
 | 
				
			||||||
 | 
					 * - No dependencies on sockets - can use serial connections for example.
 | 
				
			||||||
 | 
					 * - A very simple API - ~ 20 functions/methods.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * A list of these functions/methods are described below.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  @ref c_api 
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  @ref bigint_api 
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  @ref csharp_api 
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  @ref java_api 
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#ifndef HEADER_SSL_H
 | 
				
			||||||
 | 
					#define HEADER_SSL_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					extern "C" {
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <time.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* need to predefine before ssl_lib.h gets to it */
 | 
				
			||||||
 | 
					#define SSL_SESSION_ID_SIZE                     32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tls1.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* The optional parameters that can be given to the client/server SSL engine */
 | 
				
			||||||
 | 
					#define SSL_CLIENT_AUTHENTICATION               0x00010000
 | 
				
			||||||
 | 
					#define SSL_SERVER_VERIFY_LATER                 0x00020000
 | 
				
			||||||
 | 
					#define SSL_NO_DEFAULT_KEY                      0x00040000
 | 
				
			||||||
 | 
					#define SSL_DISPLAY_STATES                      0x00080000
 | 
				
			||||||
 | 
					#define SSL_DISPLAY_BYTES                       0x00100000
 | 
				
			||||||
 | 
					#define SSL_DISPLAY_CERTS                       0x00200000
 | 
				
			||||||
 | 
					#define SSL_DISPLAY_RSA                         0x00400000
 | 
				
			||||||
 | 
					#define SSL_CONNECT_IN_PARTS                    0x00800000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* errors that can be generated */
 | 
				
			||||||
 | 
					#define SSL_OK                                  0
 | 
				
			||||||
 | 
					#define SSL_NOT_OK                              -1
 | 
				
			||||||
 | 
					#define SSL_ERROR_DEAD                          -2
 | 
				
			||||||
 | 
					#define SSL_CLOSE_NOTIFY                        -3
 | 
				
			||||||
 | 
					#define SSL_ERROR_CONN_LOST                     -256
 | 
				
			||||||
 | 
					#define SSL_ERROR_SOCK_SETUP_FAILURE            -258
 | 
				
			||||||
 | 
					#define SSL_ERROR_INVALID_HANDSHAKE             -260
 | 
				
			||||||
 | 
					#define SSL_ERROR_INVALID_PROT_MSG              -261
 | 
				
			||||||
 | 
					#define SSL_ERROR_INVALID_HMAC                  -262
 | 
				
			||||||
 | 
					#define SSL_ERROR_INVALID_VERSION               -263
 | 
				
			||||||
 | 
					#define SSL_ERROR_INVALID_SESSION               -265
 | 
				
			||||||
 | 
					#define SSL_ERROR_NO_CIPHER                     -266
 | 
				
			||||||
 | 
					#define SSL_ERROR_BAD_CERTIFICATE               -268
 | 
				
			||||||
 | 
					#define SSL_ERROR_INVALID_KEY                   -269
 | 
				
			||||||
 | 
					#define SSL_ERROR_FINISHED_INVALID              -271
 | 
				
			||||||
 | 
					#define SSL_ERROR_NO_CERT_DEFINED               -272
 | 
				
			||||||
 | 
					#define SSL_ERROR_NO_CLIENT_RENOG               -273
 | 
				
			||||||
 | 
					#define SSL_ERROR_NOT_SUPPORTED                 -274
 | 
				
			||||||
 | 
					#define SSL_X509_OFFSET                         -512
 | 
				
			||||||
 | 
					#define SSL_X509_ERROR(A)                       (SSL_X509_OFFSET+A)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* alert types that are recognized */
 | 
				
			||||||
 | 
					#define SSL_ALERT_TYPE_WARNING                  1
 | 
				
			||||||
 | 
					#define SLL_ALERT_TYPE_FATAL                    2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* these are all the alerts that are recognized */
 | 
				
			||||||
 | 
					#define SSL_ALERT_CLOSE_NOTIFY                  0
 | 
				
			||||||
 | 
					#define SSL_ALERT_UNEXPECTED_MESSAGE            10
 | 
				
			||||||
 | 
					#define SSL_ALERT_BAD_RECORD_MAC                20
 | 
				
			||||||
 | 
					#define SSL_ALERT_HANDSHAKE_FAILURE             40
 | 
				
			||||||
 | 
					#define SSL_ALERT_BAD_CERTIFICATE               42
 | 
				
			||||||
 | 
					#define SSL_ALERT_ILLEGAL_PARAMETER             47
 | 
				
			||||||
 | 
					#define SSL_ALERT_DECODE_ERROR                  50
 | 
				
			||||||
 | 
					#define SSL_ALERT_DECRYPT_ERROR                 51
 | 
				
			||||||
 | 
					#define SSL_ALERT_INVALID_VERSION               70
 | 
				
			||||||
 | 
					#define SSL_ALERT_NO_RENEGOTIATION              100
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* The ciphers that are supported */
 | 
				
			||||||
 | 
					#define SSL_AES128_SHA                          0x2f
 | 
				
			||||||
 | 
					#define SSL_AES256_SHA                          0x35
 | 
				
			||||||
 | 
					#define SSL_RC4_128_SHA                         0x05
 | 
				
			||||||
 | 
					#define SSL_RC4_128_MD5                         0x04
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* build mode ids' */
 | 
				
			||||||
 | 
					#define SSL_BUILD_SKELETON_MODE                 0x01
 | 
				
			||||||
 | 
					#define SSL_BUILD_SERVER_ONLY                   0x02
 | 
				
			||||||
 | 
					#define SSL_BUILD_ENABLE_VERIFICATION           0x03
 | 
				
			||||||
 | 
					#define SSL_BUILD_ENABLE_CLIENT                 0x04
 | 
				
			||||||
 | 
					#define SSL_BUILD_FULL_MODE                     0x05
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* offsets to retrieve configuration information */
 | 
				
			||||||
 | 
					#define SSL_BUILD_MODE                          0
 | 
				
			||||||
 | 
					#define SSL_MAX_CERT_CFG_OFFSET                 1
 | 
				
			||||||
 | 
					#define SSL_MAX_CA_CERT_CFG_OFFSET              2
 | 
				
			||||||
 | 
					#define SSL_HAS_PEM                             3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* default session sizes */
 | 
				
			||||||
 | 
					#define SSL_DEFAULT_SVR_SESS                    5
 | 
				
			||||||
 | 
					#define SSL_DEFAULT_CLNT_SESS                   1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* X.509/X.520 distinguished name types */
 | 
				
			||||||
 | 
					#define SSL_X509_CERT_COMMON_NAME               0
 | 
				
			||||||
 | 
					#define SSL_X509_CERT_ORGANIZATION              1
 | 
				
			||||||
 | 
					#define SSL_X509_CERT_ORGANIZATIONAL_NAME       2
 | 
				
			||||||
 | 
					#define SSL_X509_CA_CERT_COMMON_NAME            3
 | 
				
			||||||
 | 
					#define SSL_X509_CA_CERT_ORGANIZATION           4
 | 
				
			||||||
 | 
					#define SSL_X509_CA_CERT_ORGANIZATIONAL_NAME    5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* SSL object loader types */
 | 
				
			||||||
 | 
					#define SSL_OBJ_X509_CERT                       1
 | 
				
			||||||
 | 
					#define SSL_OBJ_X509_CACERT                     2
 | 
				
			||||||
 | 
					#define SSL_OBJ_RSA_KEY                         3
 | 
				
			||||||
 | 
					#define SSL_OBJ_PKCS8                           4
 | 
				
			||||||
 | 
					#define SSL_OBJ_PKCS12                          5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @defgroup c_api Standard C API
 | 
				
			||||||
 | 
					 * @brief The standard interface in C.
 | 
				
			||||||
 | 
					 * @{
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Establish a new client/server context.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This function is called before any client/server SSL connections are made. 
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Each new connection will use the this context's private key and 
 | 
				
			||||||
 | 
					 * certificate chain. If a different certificate chain is required, then a 
 | 
				
			||||||
 | 
					 * different context needs to be be used.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * There are two threading models supported - a single thread with one
 | 
				
			||||||
 | 
					 * SSL_CTX can support any number of SSL connections - and multiple threads can 
 | 
				
			||||||
 | 
					 * support one SSL_CTX object each (the default). But if a single SSL_CTX 
 | 
				
			||||||
 | 
					 * object uses many SSL objects in individual threads, then the 
 | 
				
			||||||
 | 
					 * CONFIG_SSL_CTX_MUTEXING option needs to be configured.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param options [in]  Any particular options. At present the options
 | 
				
			||||||
 | 
					 * supported are:
 | 
				
			||||||
 | 
					 * - SSL_SERVER_VERIFY_LATER (client only): Don't stop a handshake if the server
 | 
				
			||||||
 | 
					 * authentication fails. The certificate can be authenticated later with a
 | 
				
			||||||
 | 
					 * call to ssl_verify_cert().
 | 
				
			||||||
 | 
					 * - SSL_CLIENT_AUTHENTICATION (server only): Enforce client authentication
 | 
				
			||||||
 | 
					 * i.e. each handshake will include a "certificate request" message from the
 | 
				
			||||||
 | 
					 * server. Only available if verification has been enabled.
 | 
				
			||||||
 | 
					 * - SSL_DISPLAY_BYTES (full mode build only): Display the byte sequences
 | 
				
			||||||
 | 
					 * during the handshake.
 | 
				
			||||||
 | 
					 * - SSL_DISPLAY_STATES (full mode build only): Display the state changes
 | 
				
			||||||
 | 
					 * during the handshake.
 | 
				
			||||||
 | 
					 * - SSL_DISPLAY_CERTS (full mode build only): Display the certificates that
 | 
				
			||||||
 | 
					 * are passed during a handshake.
 | 
				
			||||||
 | 
					 * - SSL_DISPLAY_RSA (full mode build only): Display the RSA key details that
 | 
				
			||||||
 | 
					 * are passed during a handshake.
 | 
				
			||||||
 | 
					 * - SSL_CONNECT_IN_PARTS (client only): To use a non-blocking version of 
 | 
				
			||||||
 | 
					 * ssl_client_new().
 | 
				
			||||||
 | 
					 * @param num_sessions [in] The number of sessions to be used for session
 | 
				
			||||||
 | 
					 * caching. If this value is 0, then there is no session caching. This option
 | 
				
			||||||
 | 
					 * is not used in skeleton mode.
 | 
				
			||||||
 | 
					 * @return A client/server context.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EXP_FUNC SSL_CTX * STDCALL ssl_ctx_new(uint32_t options, int num_sessions);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Remove a client/server context.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Frees any used resources used by this context. Each connection will be 
 | 
				
			||||||
 | 
					 * sent a "Close Notify" alert (if possible).
 | 
				
			||||||
 | 
					 * @param ssl_ctx [in] The client/server context.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EXP_FUNC void STDCALL ssl_ctx_free(SSL_CTX *ssl_ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief (server only) Establish a new SSL connection to an SSL client.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * It is up to the application to establish the logical connection (whether it
 | 
				
			||||||
 | 
					 * is  a socket, serial connection etc).
 | 
				
			||||||
 | 
					 * @param ssl_ctx [in] The server context.
 | 
				
			||||||
 | 
					 * @param client_fd [in] The client's file descriptor. 
 | 
				
			||||||
 | 
					 * @return An SSL object reference.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EXP_FUNC SSL * STDCALL ssl_server_new(SSL_CTX *ssl_ctx, int client_fd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief (client only) Establish a new SSL connection to an SSL server.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * It is up to the application to establish the initial logical connection 
 | 
				
			||||||
 | 
					 * (whether it is  a socket, serial connection etc).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This is a normally a blocking call - it will finish when the handshake is 
 | 
				
			||||||
 | 
					 * complete (or has failed). To use in non-blocking mode, set 
 | 
				
			||||||
 | 
					 * SSL_CONNECT_IN_PARTS in ssl_ctx_new().
 | 
				
			||||||
 | 
					 * @param ssl_ctx [in] The client context.
 | 
				
			||||||
 | 
					 * @param client_fd [in] The client's file descriptor.
 | 
				
			||||||
 | 
					 * @param session_id [in] A 32 byte session id for session resumption. This 
 | 
				
			||||||
 | 
					 * can be null if no session resumption is being used or required. This option
 | 
				
			||||||
 | 
					 * is not used in skeleton mode.
 | 
				
			||||||
 | 
					 * @param sess_id_size The size of the session id (max 32)
 | 
				
			||||||
 | 
					 * @return An SSL object reference. Use ssl_handshake_status() to check 
 | 
				
			||||||
 | 
					 * if a handshake succeeded.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EXP_FUNC SSL * STDCALL ssl_client_new(SSL_CTX *ssl_ctx, int client_fd, const uint8_t *session_id, uint8_t sess_id_size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Free any used resources on this connection. 
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 * A "Close Notify" message is sent on this connection (if possible). It is up 
 | 
				
			||||||
 | 
					 * to the application to close the socket or file descriptor.
 | 
				
			||||||
 | 
					 * @param ssl [in] The ssl object reference.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EXP_FUNC void STDCALL ssl_free(SSL *ssl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Read the SSL data stream.
 | 
				
			||||||
 | 
					 * If the socket is non-blocking and data is blocked then SSO_OK will be
 | 
				
			||||||
 | 
					 * returned.
 | 
				
			||||||
 | 
					 * @param ssl [in] An SSL object reference.
 | 
				
			||||||
 | 
					 * @param in_data [out] If the read was successful, a pointer to the read
 | 
				
			||||||
 | 
					 * buffer will be here. Do NOT ever free this memory as this buffer is used in
 | 
				
			||||||
 | 
					 * sucessive calls. If the call was unsuccessful, this value will be null.
 | 
				
			||||||
 | 
					 * @return The number of decrypted bytes:
 | 
				
			||||||
 | 
					 * - if > 0, then the handshaking is complete and we are returning the number 
 | 
				
			||||||
 | 
					 *   of decrypted bytes. 
 | 
				
			||||||
 | 
					 * - SSL_OK if the handshaking stage is successful (but not yet complete).  
 | 
				
			||||||
 | 
					 * - < 0 if an error.
 | 
				
			||||||
 | 
					 * @see ssl.h for the error code list.
 | 
				
			||||||
 | 
					 * @note Use in_data before doing any successive ssl calls.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EXP_FUNC int STDCALL ssl_read(SSL *ssl, uint8_t **in_data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Write to the SSL data stream. 
 | 
				
			||||||
 | 
					 * if the socket is non-blocking and data is blocked then a check is made
 | 
				
			||||||
 | 
					 * to ensure that all data is sent (i.e. blocked mode is forced).
 | 
				
			||||||
 | 
					 * @param ssl [in] An SSL obect reference.
 | 
				
			||||||
 | 
					 * @param out_data [in] The data to be written
 | 
				
			||||||
 | 
					 * @param out_len [in] The number of bytes to be written.
 | 
				
			||||||
 | 
					 * @return The number of bytes sent, or if < 0 if an error.
 | 
				
			||||||
 | 
					 * @see ssl.h for the error code list.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EXP_FUNC int STDCALL ssl_write(SSL *ssl, const uint8_t *out_data, int out_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Find an ssl object based on a file descriptor.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Goes through the list of SSL objects maintained in a client/server context
 | 
				
			||||||
 | 
					 * to look for a file descriptor match.
 | 
				
			||||||
 | 
					 * @param ssl_ctx [in] The client/server context.
 | 
				
			||||||
 | 
					 * @param client_fd [in]  The file descriptor.
 | 
				
			||||||
 | 
					 * @return A reference to the SSL object. Returns null if the object could not 
 | 
				
			||||||
 | 
					 * be found.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EXP_FUNC SSL * STDCALL ssl_find(SSL_CTX *ssl_ctx, int client_fd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the session id for a handshake. 
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This will be a 32 byte sequence and is available after the first
 | 
				
			||||||
 | 
					 * handshaking messages are sent.
 | 
				
			||||||
 | 
					 * @param ssl [in] An SSL object reference.
 | 
				
			||||||
 | 
					 * @return The session id as a 32 byte sequence.
 | 
				
			||||||
 | 
					 * @note A SSLv23 handshake may have only 16 valid bytes.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EXP_FUNC const uint8_t * STDCALL ssl_get_session_id(const SSL *ssl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the session id size for a handshake. 
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This will normally be 32 but could be 0 (no session id) or something else.
 | 
				
			||||||
 | 
					 * @param ssl [in] An SSL object reference.
 | 
				
			||||||
 | 
					 * @return The size of the session id.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EXP_FUNC uint8_t STDCALL ssl_get_session_id_size(const SSL *ssl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Return the cipher id (in the SSL form).
 | 
				
			||||||
 | 
					 * @param ssl [in] An SSL object reference.
 | 
				
			||||||
 | 
					 * @return The cipher id. This will be one of the following:
 | 
				
			||||||
 | 
					 * - SSL_AES128_SHA (0x2f)
 | 
				
			||||||
 | 
					 * - SSL_AES256_SHA (0x35)
 | 
				
			||||||
 | 
					 * - SSL_RC4_128_SHA (0x05)
 | 
				
			||||||
 | 
					 * - SSL_RC4_128_MD5 (0x04)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EXP_FUNC uint8_t STDCALL ssl_get_cipher_id(const SSL *ssl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Return the status of the handshake.
 | 
				
			||||||
 | 
					 * @param ssl [in] An SSL object reference.
 | 
				
			||||||
 | 
					 * @return SSL_OK if the handshake is complete and ok. 
 | 
				
			||||||
 | 
					 * @see ssl.h for the error code list.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EXP_FUNC int STDCALL ssl_handshake_status(const SSL *ssl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Retrieve various parameters about the axTLS engine.
 | 
				
			||||||
 | 
					 * @param offset [in] The configuration offset. It will be one of the following:
 | 
				
			||||||
 | 
					 * - SSL_BUILD_MODE The build mode. This will be one of the following:
 | 
				
			||||||
 | 
					 *   - SSL_BUILD_SERVER_ONLY            (basic server mode)
 | 
				
			||||||
 | 
					 *   - SSL_BUILD_ENABLE_VERIFICATION    (server can do client authentication)
 | 
				
			||||||
 | 
					 *   - SSL_BUILD_ENABLE_CLIENT          (client/server capabilties)
 | 
				
			||||||
 | 
					 *   - SSL_BUILD_FULL_MODE              (client/server with diagnostics)
 | 
				
			||||||
 | 
					 *   - SSL_BUILD_SKELETON_MODE          (skeleton mode)
 | 
				
			||||||
 | 
					 * - SSL_MAX_CERT_CFG_OFFSET The maximum number of certificates allowed.
 | 
				
			||||||
 | 
					 * - SSL_MAX_CA_CERT_CFG_OFFSET The maximum number of CA certificates allowed.
 | 
				
			||||||
 | 
					 * - SSL_HAS_PEM                        1 if supported
 | 
				
			||||||
 | 
					 * @return The value of the requested parameter.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EXP_FUNC int STDCALL ssl_get_config(int offset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Display why the handshake failed.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This call is only useful in a 'full mode' build. The output is to stdout.
 | 
				
			||||||
 | 
					 * @param error_code [in] An error code.
 | 
				
			||||||
 | 
					 * @see ssl.h for the error code list.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EXP_FUNC void STDCALL ssl_display_error(int error_code);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Authenticate a received certificate.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This call is usually made by a client after a handshake is complete and the
 | 
				
			||||||
 | 
					 * context is in SSL_SERVER_VERIFY_LATER mode.
 | 
				
			||||||
 | 
					 * @param ssl [in] An SSL object reference.
 | 
				
			||||||
 | 
					 * @return SSL_OK if the certificate is verified.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EXP_FUNC int STDCALL ssl_verify_cert(const SSL *ssl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Retrieve an X.509 distinguished name component.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * When a handshake is complete and a certificate has been exchanged, then the
 | 
				
			||||||
 | 
					 * details of the remote certificate can be retrieved.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This will usually be used by a client to check that the server's common 
 | 
				
			||||||
 | 
					 * name matches the URL.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param ssl [in] An SSL object reference.
 | 
				
			||||||
 | 
					 * @param component [in] one of:
 | 
				
			||||||
 | 
					 * - SSL_X509_CERT_COMMON_NAME
 | 
				
			||||||
 | 
					 * - SSL_X509_CERT_ORGANIZATION
 | 
				
			||||||
 | 
					 * - SSL_X509_CERT_ORGANIZATIONAL_NAME
 | 
				
			||||||
 | 
					 * - SSL_X509_CA_CERT_COMMON_NAME
 | 
				
			||||||
 | 
					 * - SSL_X509_CA_CERT_ORGANIZATION
 | 
				
			||||||
 | 
					 * - SSL_X509_CA_CERT_ORGANIZATIONAL_NAME
 | 
				
			||||||
 | 
					 * @return The appropriate string (or null if not defined)
 | 
				
			||||||
 | 
					 * @note Verification build mode must be enabled.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EXP_FUNC const char * STDCALL ssl_get_cert_dn(const SSL *ssl, int component);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Retrieve a Subject Alternative DNSName
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * When a handshake is complete and a certificate has been exchanged, then the
 | 
				
			||||||
 | 
					 * details of the remote certificate can be retrieved.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This will usually be used by a client to check that the server's DNS  
 | 
				
			||||||
 | 
					 * name matches the URL.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param ssl [in] An SSL object reference.
 | 
				
			||||||
 | 
					 * @param dnsindex [in] The index of the DNS name to retrieve.
 | 
				
			||||||
 | 
					 * @return The appropriate string (or null if not defined)
 | 
				
			||||||
 | 
					 * @note Verification build mode must be enabled.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EXP_FUNC const char * STDCALL ssl_get_cert_subject_alt_dnsname(const SSL *ssl, int dnsindex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Force the client to perform its handshake again.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * For a client this involves sending another "client hello" message.
 | 
				
			||||||
 | 
					 * For the server is means sending a "hello request" message.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This is a blocking call on the client (until the handshake completes).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param ssl [in] An SSL object reference.
 | 
				
			||||||
 | 
					 * @return SSL_OK if renegotiation instantiation was ok
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EXP_FUNC int STDCALL ssl_renegotiate(SSL *ssl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Process a file that is in binary DER or ASCII PEM format.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * These are temporary objects that are used to load private keys,
 | 
				
			||||||
 | 
					 * certificates etc into memory.
 | 
				
			||||||
 | 
					 * @param ssl_ctx [in] The client/server context.
 | 
				
			||||||
 | 
					 * @param obj_type [in] The format of the file. Can be one of:
 | 
				
			||||||
 | 
					 * - SSL_OBJ_X509_CERT (no password required)
 | 
				
			||||||
 | 
					 * - SSL_OBJ_X509_CACERT (no password required)
 | 
				
			||||||
 | 
					 * - SSL_OBJ_RSA_KEY (AES128/AES256 PEM encryption supported)
 | 
				
			||||||
 | 
					 * - SSL_OBJ_PKCS8 (RC4-128 encrypted data supported)
 | 
				
			||||||
 | 
					 * - SSL_OBJ_PKCS12 (RC4-128 encrypted data supported)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * PEM files are automatically detected (if supported). The object type is
 | 
				
			||||||
 | 
					 * also detected, and so is not relevant for these types of files.
 | 
				
			||||||
 | 
					 * @param filename [in] The location of a file in DER/PEM format.
 | 
				
			||||||
 | 
					 * @param password [in] The password used. Can be null if not required.
 | 
				
			||||||
 | 
					 * @return SSL_OK if all ok
 | 
				
			||||||
 | 
					 * @note Not available in skeleton build mode.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EXP_FUNC int STDCALL ssl_obj_load(SSL_CTX *ssl_ctx, int obj_type, const char *filename, const char *password);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Process binary data.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * These are temporary objects that are used to load private keys,
 | 
				
			||||||
 | 
					 * certificates etc into memory.
 | 
				
			||||||
 | 
					 * @param ssl_ctx [in] The client/server context.
 | 
				
			||||||
 | 
					 * @param obj_type [in] The format of the memory data.
 | 
				
			||||||
 | 
					 * @param data [in] The binary data to be loaded.
 | 
				
			||||||
 | 
					 * @param len [in] The amount of data to be loaded.
 | 
				
			||||||
 | 
					 * @param password [in] The password used. Can be null if not required.
 | 
				
			||||||
 | 
					 * @return SSL_OK if all ok
 | 
				
			||||||
 | 
					 * @see ssl_obj_load for more details on obj_type.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EXP_FUNC int STDCALL ssl_obj_memory_load(SSL_CTX *ssl_ctx, int obj_type, const uint8_t *data, int len, const char *password);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_GENERATE_X509_CERT
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Create an X.509 certificate. 
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This certificate is a self-signed v1 cert with a fixed start/stop validity 
 | 
				
			||||||
 | 
					 * times. It is signed with an internal private key in ssl_ctx.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param ssl_ctx [in] The client/server context.
 | 
				
			||||||
 | 
					 * @param options [in] Not used yet.
 | 
				
			||||||
 | 
					 * @param dn [in] An array of distinguished name strings. The array is defined
 | 
				
			||||||
 | 
					 * by:
 | 
				
			||||||
 | 
					 * - SSL_X509_CERT_COMMON_NAME (0)
 | 
				
			||||||
 | 
					 *      - If SSL_X509_CERT_COMMON_NAME is empty or not defined, then the 
 | 
				
			||||||
 | 
					 *        hostname will be used.
 | 
				
			||||||
 | 
					 * - SSL_X509_CERT_ORGANIZATION (1)
 | 
				
			||||||
 | 
					 *      - If SSL_X509_CERT_ORGANIZATION is empty or not defined, then $USERNAME 
 | 
				
			||||||
 | 
					 *        will be used.
 | 
				
			||||||
 | 
					 * - SSL_X509_CERT_ORGANIZATIONAL_NAME (2)
 | 
				
			||||||
 | 
					 *      - SSL_X509_CERT_ORGANIZATIONAL_NAME is optional.
 | 
				
			||||||
 | 
					 * @param cert_data [out] The certificate as a sequence of bytes.
 | 
				
			||||||
 | 
					 * @return < 0 if an error, or the size of the certificate in bytes.
 | 
				
			||||||
 | 
					 * @note cert_data must be freed when there is no more need for it.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EXP_FUNC int STDCALL ssl_x509_create(SSL_CTX *ssl_ctx, uint32_t options, const char * dn[], uint8_t **cert_data);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Return the axTLS library version as a string.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EXP_FUNC const char * STDCALL ssl_version(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** @} */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										2191
									
								
								ssl/tls1.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2191
									
								
								ssl/tls1.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										297
									
								
								ssl/tls1.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										297
									
								
								ssl/tls1.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,297 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @file tls1.h
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @brief The definitions for the TLS library.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#ifndef HEADER_SSL_LIB_H
 | 
				
			||||||
 | 
					#define HEADER_SSL_LIB_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					extern "C" {
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "version.h"
 | 
				
			||||||
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					#include "os_int.h"
 | 
				
			||||||
 | 
					#include "crypto.h"
 | 
				
			||||||
 | 
					#include "crypto_misc.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SSL_PROTOCOL_MIN_VERSION    0x31   /* TLS v1.0 */
 | 
				
			||||||
 | 
					#define SSL_PROTOCOL_MINOR_VERSION  0x02   /* TLS v1.1 */
 | 
				
			||||||
 | 
					#define SSL_PROTOCOL_VERSION_MAX    0x32   /* TLS v1.1 */
 | 
				
			||||||
 | 
					#define SSL_PROTOCOL_VERSION1_1     0x32   /* TLS v1.1 */
 | 
				
			||||||
 | 
					#define SSL_RANDOM_SIZE             32
 | 
				
			||||||
 | 
					#define SSL_SECRET_SIZE             48
 | 
				
			||||||
 | 
					#define SSL_FINISHED_HASH_SIZE      12
 | 
				
			||||||
 | 
					#define SSL_RECORD_SIZE             5
 | 
				
			||||||
 | 
					#define SSL_SERVER_READ             0
 | 
				
			||||||
 | 
					#define SSL_SERVER_WRITE            1
 | 
				
			||||||
 | 
					#define SSL_CLIENT_READ             2
 | 
				
			||||||
 | 
					#define SSL_CLIENT_WRITE            3
 | 
				
			||||||
 | 
					#define SSL_HS_HDR_SIZE             4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* the flags we use while establishing a connection */
 | 
				
			||||||
 | 
					#define SSL_NEED_RECORD             0x0001
 | 
				
			||||||
 | 
					#define SSL_TX_ENCRYPTED            0x0002 
 | 
				
			||||||
 | 
					#define SSL_RX_ENCRYPTED            0x0004
 | 
				
			||||||
 | 
					#define SSL_SESSION_RESUME          0x0008
 | 
				
			||||||
 | 
					#define SSL_IS_CLIENT               0x0010
 | 
				
			||||||
 | 
					#define SSL_HAS_CERT_REQ            0x0020
 | 
				
			||||||
 | 
					#define SSL_SENT_CLOSE_NOTIFY       0x0040
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* some macros to muck around with flag bits */
 | 
				
			||||||
 | 
					#define SET_SSL_FLAG(A)             (ssl->flag |= A)
 | 
				
			||||||
 | 
					#define CLR_SSL_FLAG(A)             (ssl->flag &= ~A)
 | 
				
			||||||
 | 
					#define IS_SET_SSL_FLAG(A)          (ssl->flag & A)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MAX_KEY_BYTE_SIZE           512     /* for a 4096 bit key */
 | 
				
			||||||
 | 
					#define RT_MAX_PLAIN_LENGTH         16384
 | 
				
			||||||
 | 
					#define RT_EXTRA                    1024
 | 
				
			||||||
 | 
					#define BM_RECORD_OFFSET            5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_SKELETON_MODE
 | 
				
			||||||
 | 
					#define NUM_PROTOCOLS               1
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define NUM_PROTOCOLS               4
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define PARANOIA_CHECK(A, B)        if (A < B) { \
 | 
				
			||||||
 | 
					    ret = SSL_ERROR_INVALID_HANDSHAKE; goto error; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* protocol types */
 | 
				
			||||||
 | 
					enum
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    PT_CHANGE_CIPHER_SPEC = 20,
 | 
				
			||||||
 | 
					    PT_ALERT_PROTOCOL,
 | 
				
			||||||
 | 
					    PT_HANDSHAKE_PROTOCOL,
 | 
				
			||||||
 | 
					    PT_APP_PROTOCOL_DATA
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* handshaking types */
 | 
				
			||||||
 | 
					enum
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    HS_HELLO_REQUEST,
 | 
				
			||||||
 | 
					    HS_CLIENT_HELLO,
 | 
				
			||||||
 | 
					    HS_SERVER_HELLO,
 | 
				
			||||||
 | 
					    HS_CERTIFICATE = 11,
 | 
				
			||||||
 | 
					    HS_SERVER_KEY_XCHG,
 | 
				
			||||||
 | 
					    HS_CERT_REQ,
 | 
				
			||||||
 | 
					    HS_SERVER_HELLO_DONE,
 | 
				
			||||||
 | 
					    HS_CERT_VERIFY,
 | 
				
			||||||
 | 
					    HS_CLIENT_KEY_XCHG,
 | 
				
			||||||
 | 
					    HS_FINISHED = 20
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct 
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint8_t cipher;
 | 
				
			||||||
 | 
					    uint8_t key_size;
 | 
				
			||||||
 | 
					    uint8_t iv_size;
 | 
				
			||||||
 | 
					    uint8_t key_block_size;
 | 
				
			||||||
 | 
					    uint8_t padding_size;
 | 
				
			||||||
 | 
					    uint8_t digest_size;
 | 
				
			||||||
 | 
					    hmac_func hmac;
 | 
				
			||||||
 | 
					    crypt_func encrypt;
 | 
				
			||||||
 | 
					    crypt_func decrypt;
 | 
				
			||||||
 | 
					} cipher_info_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct _SSLObjLoader 
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint8_t *buf;
 | 
				
			||||||
 | 
					    int len;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct _SSLObjLoader SSLObjLoader;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct 
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    time_t conn_time;
 | 
				
			||||||
 | 
					    uint8_t session_id[SSL_SESSION_ID_SIZE];
 | 
				
			||||||
 | 
					    uint8_t master_secret[SSL_SECRET_SIZE];
 | 
				
			||||||
 | 
					} SSL_SESSION;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint8_t *buf;
 | 
				
			||||||
 | 
					    int size;
 | 
				
			||||||
 | 
					} SSL_CERT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    MD5_CTX md5_ctx;
 | 
				
			||||||
 | 
					    SHA1_CTX sha1_ctx;
 | 
				
			||||||
 | 
					    uint8_t final_finish_mac[SSL_FINISHED_HASH_SIZE];
 | 
				
			||||||
 | 
					    uint8_t *key_block;
 | 
				
			||||||
 | 
					    uint8_t master_secret[SSL_SECRET_SIZE];
 | 
				
			||||||
 | 
					    uint8_t client_random[SSL_RANDOM_SIZE]; /* client's random sequence */
 | 
				
			||||||
 | 
					    uint8_t server_random[SSL_RANDOM_SIZE]; /* server's random sequence */
 | 
				
			||||||
 | 
					    uint16_t bm_proc_index;
 | 
				
			||||||
 | 
					} DISPOSABLE_CTX;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct _SSL
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint32_t flag;
 | 
				
			||||||
 | 
					    uint16_t need_bytes;
 | 
				
			||||||
 | 
					    uint16_t got_bytes;
 | 
				
			||||||
 | 
					    uint8_t record_type;
 | 
				
			||||||
 | 
					    uint8_t cipher;
 | 
				
			||||||
 | 
					    uint8_t sess_id_size;
 | 
				
			||||||
 | 
					    uint8_t version;
 | 
				
			||||||
 | 
					    uint8_t client_version;
 | 
				
			||||||
 | 
					    int16_t next_state;
 | 
				
			||||||
 | 
					    int16_t hs_status;
 | 
				
			||||||
 | 
					    DISPOSABLE_CTX *dc;         /* temporary data which we'll get rid of soon */
 | 
				
			||||||
 | 
					    int client_fd;
 | 
				
			||||||
 | 
					    const cipher_info_t *cipher_info;
 | 
				
			||||||
 | 
					    void *encrypt_ctx;
 | 
				
			||||||
 | 
					    void *decrypt_ctx;
 | 
				
			||||||
 | 
					    uint8_t bm_all_data[RT_MAX_PLAIN_LENGTH+RT_EXTRA];
 | 
				
			||||||
 | 
					    uint8_t *bm_data;
 | 
				
			||||||
 | 
					    uint16_t bm_index;
 | 
				
			||||||
 | 
					    uint16_t bm_read_index;
 | 
				
			||||||
 | 
					    struct _SSL *next;                  /* doubly linked list */
 | 
				
			||||||
 | 
					    struct _SSL *prev;
 | 
				
			||||||
 | 
					    struct _SSL_CTX *ssl_ctx;           /* back reference to a clnt/svr ctx */
 | 
				
			||||||
 | 
					#ifndef CONFIG_SSL_SKELETON_MODE
 | 
				
			||||||
 | 
					    uint16_t session_index;
 | 
				
			||||||
 | 
					    SSL_SESSION *session;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_CERT_VERIFICATION
 | 
				
			||||||
 | 
					    X509_CTX *x509_ctx;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint8_t session_id[SSL_SESSION_ID_SIZE]; 
 | 
				
			||||||
 | 
					    uint8_t client_mac[SHA1_SIZE];  /* for HMAC verification */
 | 
				
			||||||
 | 
					    uint8_t server_mac[SHA1_SIZE];  /* for HMAC verification */
 | 
				
			||||||
 | 
					    uint8_t read_sequence[8];       /* 64 bit sequence number */
 | 
				
			||||||
 | 
					    uint8_t write_sequence[8];      /* 64 bit sequence number */
 | 
				
			||||||
 | 
					    uint8_t hmac_header[SSL_RECORD_SIZE];    /* rx hmac */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct _SSL SSL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct _SSL_CTX
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint32_t options;
 | 
				
			||||||
 | 
					    uint8_t chain_length;
 | 
				
			||||||
 | 
					    RSA_CTX *rsa_ctx;
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_CERT_VERIFICATION
 | 
				
			||||||
 | 
					    CA_CERT_CTX *ca_cert_ctx;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    SSL *head;
 | 
				
			||||||
 | 
					    SSL *tail;
 | 
				
			||||||
 | 
					    SSL_CERT certs[CONFIG_SSL_MAX_CERTS];
 | 
				
			||||||
 | 
					#ifndef CONFIG_SSL_SKELETON_MODE
 | 
				
			||||||
 | 
					    uint16_t num_sessions;
 | 
				
			||||||
 | 
					    SSL_SESSION **ssl_sessions;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_CTX_MUTEXING
 | 
				
			||||||
 | 
					    SSL_CTX_MUTEX_TYPE mutex;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#ifdef CONFIG_OPENSSL_COMPATIBLE
 | 
				
			||||||
 | 
					    void *bonus_attr;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct _SSL_CTX SSL_CTX;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* backwards compatibility */
 | 
				
			||||||
 | 
					typedef struct _SSL_CTX SSLCTX;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern const uint8_t ssl_prot_prefs[NUM_PROTOCOLS];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SSL *ssl_new(SSL_CTX *ssl_ctx, int client_fd);
 | 
				
			||||||
 | 
					void disposable_new(SSL *ssl);
 | 
				
			||||||
 | 
					void disposable_free(SSL *ssl);
 | 
				
			||||||
 | 
					int send_packet(SSL *ssl, uint8_t protocol, 
 | 
				
			||||||
 | 
					        const uint8_t *in, int length);
 | 
				
			||||||
 | 
					int do_svr_handshake(SSL *ssl, int handshake_type, uint8_t *buf, int hs_len);
 | 
				
			||||||
 | 
					int do_clnt_handshake(SSL *ssl, int handshake_type, uint8_t *buf, int hs_len);
 | 
				
			||||||
 | 
					int process_finished(SSL *ssl, uint8_t *buf, int hs_len);
 | 
				
			||||||
 | 
					int process_sslv23_client_hello(SSL *ssl);
 | 
				
			||||||
 | 
					int send_alert(SSL *ssl, int error_code);
 | 
				
			||||||
 | 
					int send_finished(SSL *ssl);
 | 
				
			||||||
 | 
					int send_certificate(SSL *ssl);
 | 
				
			||||||
 | 
					int basic_read(SSL *ssl, uint8_t **in_data);
 | 
				
			||||||
 | 
					int send_change_cipher_spec(SSL *ssl);
 | 
				
			||||||
 | 
					void finished_digest(SSL *ssl, const char *label, uint8_t *digest);
 | 
				
			||||||
 | 
					void generate_master_secret(SSL *ssl, const uint8_t *premaster_secret);
 | 
				
			||||||
 | 
					void add_packet(SSL *ssl, const uint8_t *pkt, int len);
 | 
				
			||||||
 | 
					int add_cert(SSL_CTX *ssl_ctx, const uint8_t *buf, int len);
 | 
				
			||||||
 | 
					int add_private_key(SSL_CTX *ssl_ctx, SSLObjLoader *ssl_obj);
 | 
				
			||||||
 | 
					void ssl_obj_free(SSLObjLoader *ssl_obj);
 | 
				
			||||||
 | 
					int pkcs8_decode(SSL_CTX *ssl_ctx, SSLObjLoader *ssl_obj, const char *password);
 | 
				
			||||||
 | 
					int pkcs12_decode(SSL_CTX *ssl_ctx, SSLObjLoader *ssl_obj, const char *password);
 | 
				
			||||||
 | 
					int load_key_certs(SSL_CTX *ssl_ctx);
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_CERT_VERIFICATION
 | 
				
			||||||
 | 
					int add_cert_auth(SSL_CTX *ssl_ctx, const uint8_t *buf, int len);
 | 
				
			||||||
 | 
					void remove_ca_certs(CA_CERT_CTX *ca_cert_ctx);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_ENABLE_CLIENT
 | 
				
			||||||
 | 
					int do_client_connect(SSL *ssl);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_FULL_MODE
 | 
				
			||||||
 | 
					void DISPLAY_STATE(SSL *ssl, int is_send, uint8_t state, int not_ok);
 | 
				
			||||||
 | 
					void DISPLAY_BYTES(SSL *ssl, const char *format, 
 | 
				
			||||||
 | 
					        const uint8_t *data, int size, ...);
 | 
				
			||||||
 | 
					void DISPLAY_CERT(SSL *ssl, const X509_CTX *x509_ctx);
 | 
				
			||||||
 | 
					void DISPLAY_RSA(SSL *ssl,  const RSA_CTX *rsa_ctx);
 | 
				
			||||||
 | 
					void DISPLAY_ALERT(SSL *ssl, int alert);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define DISPLAY_STATE(A,B,C,D)
 | 
				
			||||||
 | 
					#define DISPLAY_CERT(A,B)
 | 
				
			||||||
 | 
					#define DISPLAY_RSA(A,B)
 | 
				
			||||||
 | 
					#define DISPLAY_ALERT(A, B)
 | 
				
			||||||
 | 
					#ifdef WIN32
 | 
				
			||||||
 | 
					void DISPLAY_BYTES(SSL *ssl, const char *format,/* win32 has no variadic macros */
 | 
				
			||||||
 | 
					        const uint8_t *data, int size, ...);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define DISPLAY_BYTES(A,B,C,D,...)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_CERT_VERIFICATION
 | 
				
			||||||
 | 
					int process_certificate(SSL *ssl, X509_CTX **x509_ctx);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SSL_SESSION *ssl_session_update(int max_sessions, 
 | 
				
			||||||
 | 
					        SSL_SESSION *ssl_sessions[], SSL *ssl,
 | 
				
			||||||
 | 
					        const uint8_t *session_id);
 | 
				
			||||||
 | 
					void kill_ssl_session(SSL_SESSION **ssl_sessions, SSL *ssl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif 
 | 
				
			||||||
							
								
								
									
										395
									
								
								ssl/tls1_clnt.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										395
									
								
								ssl/tls1_clnt.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,395 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <time.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include "os_port.h"
 | 
				
			||||||
 | 
					#include "ssl.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_ENABLE_CLIENT        /* all commented out if no client */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int send_client_hello(SSL *ssl);
 | 
				
			||||||
 | 
					static int process_server_hello(SSL *ssl);
 | 
				
			||||||
 | 
					static int process_server_hello_done(SSL *ssl);
 | 
				
			||||||
 | 
					static int send_client_key_xchg(SSL *ssl);
 | 
				
			||||||
 | 
					static int process_cert_req(SSL *ssl);
 | 
				
			||||||
 | 
					static int send_cert_verify(SSL *ssl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Establish a new SSL connection to an SSL server.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EXP_FUNC SSL * STDCALL ssl_client_new(SSL_CTX *ssl_ctx, int client_fd, const
 | 
				
			||||||
 | 
					        uint8_t *session_id, uint8_t sess_id_size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    SSL *ssl = ssl_new(ssl_ctx, client_fd);
 | 
				
			||||||
 | 
					    ssl->version = SSL_PROTOCOL_VERSION_MAX; /* try top version first */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (session_id && ssl_ctx->num_sessions)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (sess_id_size > SSL_SESSION_ID_SIZE) /* validity check */
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            ssl_free(ssl);
 | 
				
			||||||
 | 
					            return NULL;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        memcpy(ssl->session_id, session_id, sess_id_size);
 | 
				
			||||||
 | 
					        ssl->sess_id_size = sess_id_size;
 | 
				
			||||||
 | 
					        SET_SSL_FLAG(SSL_SESSION_RESUME);   /* just flag for later */
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    SET_SSL_FLAG(SSL_IS_CLIENT);
 | 
				
			||||||
 | 
					    do_client_connect(ssl);
 | 
				
			||||||
 | 
					    return ssl;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Process the handshake record.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int do_clnt_handshake(SSL *ssl, int handshake_type, uint8_t *buf, int hs_len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* To get here the state must be valid */
 | 
				
			||||||
 | 
					    switch (handshake_type)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        case HS_SERVER_HELLO:
 | 
				
			||||||
 | 
					            ret = process_server_hello(ssl);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case HS_CERTIFICATE:
 | 
				
			||||||
 | 
					            ret = process_certificate(ssl, &ssl->x509_ctx);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case HS_SERVER_HELLO_DONE:
 | 
				
			||||||
 | 
					            if ((ret = process_server_hello_done(ssl)) == SSL_OK)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (IS_SET_SSL_FLAG(SSL_HAS_CERT_REQ))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    if ((ret = send_certificate(ssl)) == SSL_OK &&
 | 
				
			||||||
 | 
					                        (ret = send_client_key_xchg(ssl)) == SSL_OK)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        send_cert_verify(ssl);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    ret = send_client_key_xchg(ssl);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (ret == SSL_OK && 
 | 
				
			||||||
 | 
					                     (ret = send_change_cipher_spec(ssl)) == SSL_OK)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    ret = send_finished(ssl);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case HS_CERT_REQ:
 | 
				
			||||||
 | 
					            ret = process_cert_req(ssl);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case HS_FINISHED:
 | 
				
			||||||
 | 
					            ret = process_finished(ssl, buf, hs_len);
 | 
				
			||||||
 | 
					            disposable_free(ssl);   /* free up some memory */
 | 
				
			||||||
 | 
					            /* note: client renegotiation is not allowed after this */
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case HS_HELLO_REQUEST:
 | 
				
			||||||
 | 
					            disposable_new(ssl);
 | 
				
			||||||
 | 
					            ret = do_client_connect(ssl);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        default:
 | 
				
			||||||
 | 
					            ret = SSL_ERROR_INVALID_HANDSHAKE;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Do the handshaking from the beginning.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int do_client_connect(SSL *ssl)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int ret = SSL_OK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    send_client_hello(ssl);                 /* send the client hello */
 | 
				
			||||||
 | 
					    ssl->bm_read_index = 0;
 | 
				
			||||||
 | 
					    ssl->next_state = HS_SERVER_HELLO;
 | 
				
			||||||
 | 
					    ssl->hs_status = SSL_NOT_OK;            /* not connected */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* sit in a loop until it all looks good */
 | 
				
			||||||
 | 
					    if (!IS_SET_SSL_FLAG(SSL_CONNECT_IN_PARTS))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        while (ssl->hs_status != SSL_OK)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            ret = ssl_read(ssl, NULL);
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            if (ret < SSL_OK)
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ssl->hs_status = ret;            /* connected? */    
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Send the initial client hello.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int send_client_hello(SSL *ssl)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint8_t *buf = ssl->bm_data;
 | 
				
			||||||
 | 
					    time_t tm = time(NULL);
 | 
				
			||||||
 | 
					    uint8_t *tm_ptr = &buf[6]; /* time will go here */
 | 
				
			||||||
 | 
					    int i, offset;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    buf[0] = HS_CLIENT_HELLO;
 | 
				
			||||||
 | 
					    buf[1] = 0;
 | 
				
			||||||
 | 
					    buf[2] = 0;
 | 
				
			||||||
 | 
					    /* byte 3 is calculated later */
 | 
				
			||||||
 | 
					    buf[4] = 0x03;
 | 
				
			||||||
 | 
					    buf[5] = ssl->version & 0x0f;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* client random value - spec says that 1st 4 bytes are big endian time */
 | 
				
			||||||
 | 
					    *tm_ptr++ = (uint8_t)(((long)tm & 0xff000000) >> 24);
 | 
				
			||||||
 | 
					    *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]);
 | 
				
			||||||
 | 
					    memcpy(ssl->dc->client_random, &buf[6], SSL_RANDOM_SIZE);
 | 
				
			||||||
 | 
					    offset = 6 + SSL_RANDOM_SIZE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* give session resumption a go */
 | 
				
			||||||
 | 
					    if (IS_SET_SSL_FLAG(SSL_SESSION_RESUME))    /* set initially by user */
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        buf[offset++] = ssl->sess_id_size;
 | 
				
			||||||
 | 
					        memcpy(&buf[offset], ssl->session_id, ssl->sess_id_size);
 | 
				
			||||||
 | 
					        offset += ssl->sess_id_size;
 | 
				
			||||||
 | 
					        CLR_SSL_FLAG(SSL_SESSION_RESUME);       /* clear so we can set later */
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /* no session id - because no session resumption just yet */
 | 
				
			||||||
 | 
					        buf[offset++] = 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    buf[offset++] = 0;              /* number of ciphers */
 | 
				
			||||||
 | 
					    buf[offset++] = NUM_PROTOCOLS*2;/* number of ciphers */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* put all our supported protocols in our request */
 | 
				
			||||||
 | 
					    for (i = 0; i < NUM_PROTOCOLS; i++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        buf[offset++] = 0;          /* cipher we are using */
 | 
				
			||||||
 | 
					        buf[offset++] = ssl_prot_prefs[i];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    buf[offset++] = 1;              /* no compression */
 | 
				
			||||||
 | 
					    buf[offset++] = 0;
 | 
				
			||||||
 | 
					    buf[3] = offset - 4;            /* handshake size */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, offset);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Process the server hello.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int process_server_hello(SSL *ssl)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint8_t *buf = ssl->bm_data;
 | 
				
			||||||
 | 
					    int pkt_size = ssl->bm_index;
 | 
				
			||||||
 | 
					    int num_sessions = ssl->ssl_ctx->num_sessions;
 | 
				
			||||||
 | 
					    uint8_t sess_id_size;
 | 
				
			||||||
 | 
					    int offset, ret = SSL_OK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* check that we are talking to a TLSv1 server */
 | 
				
			||||||
 | 
					    uint8_t version = (buf[4] << 4) + buf[5];
 | 
				
			||||||
 | 
					    if (version > SSL_PROTOCOL_VERSION_MAX)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        version = SSL_PROTOCOL_VERSION_MAX;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (ssl->version < SSL_PROTOCOL_MIN_VERSION)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ret = SSL_ERROR_INVALID_VERSION;
 | 
				
			||||||
 | 
					        ssl_display_error(ret);
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ssl->version = version;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* get the server random value */
 | 
				
			||||||
 | 
					    memcpy(ssl->dc->server_random, &buf[6], SSL_RANDOM_SIZE);
 | 
				
			||||||
 | 
					    offset = 6 + SSL_RANDOM_SIZE; /* skip of session id size */
 | 
				
			||||||
 | 
					    sess_id_size = buf[offset++];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (sess_id_size > SSL_SESSION_ID_SIZE)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ret = SSL_ERROR_INVALID_SESSION;
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (num_sessions)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ssl->session = ssl_session_update(num_sessions,
 | 
				
			||||||
 | 
					                ssl->ssl_ctx->ssl_sessions, ssl, &buf[offset]);
 | 
				
			||||||
 | 
					        memcpy(ssl->session->session_id, &buf[offset], sess_id_size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* pad the rest with 0's */
 | 
				
			||||||
 | 
					        if (sess_id_size < SSL_SESSION_ID_SIZE)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            memset(&ssl->session->session_id[sess_id_size], 0,
 | 
				
			||||||
 | 
					                SSL_SESSION_ID_SIZE-sess_id_size);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memcpy(ssl->session_id, &buf[offset], sess_id_size);
 | 
				
			||||||
 | 
					    ssl->sess_id_size = sess_id_size;
 | 
				
			||||||
 | 
					    offset += sess_id_size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* get the real cipher we are using */
 | 
				
			||||||
 | 
					    ssl->cipher = buf[++offset];
 | 
				
			||||||
 | 
					    ssl->next_state = IS_SET_SSL_FLAG(SSL_SESSION_RESUME) ? 
 | 
				
			||||||
 | 
					                                        HS_FINISHED : HS_CERTIFICATE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    offset++;   // skip the compr
 | 
				
			||||||
 | 
					    PARANOIA_CHECK(pkt_size, offset);
 | 
				
			||||||
 | 
					    ssl->dc->bm_proc_index = offset+1; 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error:
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Process the server hello done message.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int process_server_hello_done(SSL *ssl)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ssl->next_state = HS_FINISHED;
 | 
				
			||||||
 | 
					    return SSL_OK;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Send a client key exchange message.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int send_client_key_xchg(SSL *ssl)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint8_t *buf = ssl->bm_data;
 | 
				
			||||||
 | 
					    uint8_t premaster_secret[SSL_SECRET_SIZE];
 | 
				
			||||||
 | 
					    int enc_secret_size = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    buf[0] = HS_CLIENT_KEY_XCHG;
 | 
				
			||||||
 | 
					    buf[1] = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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]);
 | 
				
			||||||
 | 
					    DISPLAY_RSA(ssl, ssl->x509_ctx->rsa_ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* rsa_ctx->bi_ctx is not thread-safe */
 | 
				
			||||||
 | 
					    SSL_CTX_LOCK(ssl->ssl_ctx->mutex);
 | 
				
			||||||
 | 
					    enc_secret_size = RSA_encrypt(ssl->x509_ctx->rsa_ctx, premaster_secret,
 | 
				
			||||||
 | 
					            SSL_SECRET_SIZE, &buf[6], 0);
 | 
				
			||||||
 | 
					    SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    buf[2] = (enc_secret_size + 2) >> 8;
 | 
				
			||||||
 | 
					    buf[3] = (enc_secret_size + 2) & 0xff;
 | 
				
			||||||
 | 
					    buf[4] = enc_secret_size >> 8;
 | 
				
			||||||
 | 
					    buf[5] = enc_secret_size & 0xff;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    generate_master_secret(ssl, premaster_secret);
 | 
				
			||||||
 | 
					    return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, enc_secret_size+6);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Process the certificate request.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int process_cert_req(SSL *ssl)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint8_t *buf = &ssl->bm_data[ssl->dc->bm_proc_index];
 | 
				
			||||||
 | 
					    int ret = SSL_OK;
 | 
				
			||||||
 | 
					    int offset = (buf[2] << 4) + buf[3];
 | 
				
			||||||
 | 
					    int pkt_size = ssl->bm_index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* don't do any processing - we will send back an RSA certificate anyway */
 | 
				
			||||||
 | 
					    ssl->next_state = HS_SERVER_HELLO_DONE;
 | 
				
			||||||
 | 
					    SET_SSL_FLAG(SSL_HAS_CERT_REQ);
 | 
				
			||||||
 | 
					    ssl->dc->bm_proc_index += offset;
 | 
				
			||||||
 | 
					    PARANOIA_CHECK(pkt_size, offset);
 | 
				
			||||||
 | 
					error:
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Send a certificate verify message.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int send_cert_verify(SSL *ssl)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint8_t *buf = ssl->bm_data;
 | 
				
			||||||
 | 
					    uint8_t dgst[MD5_SIZE+SHA1_SIZE];
 | 
				
			||||||
 | 
					    RSA_CTX *rsa_ctx = ssl->ssl_ctx->rsa_ctx;
 | 
				
			||||||
 | 
					    int n = 0, ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    DISPLAY_RSA(ssl, rsa_ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    buf[0] = HS_CERT_VERIFY;
 | 
				
			||||||
 | 
					    buf[1] = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    finished_digest(ssl, NULL, dgst);   /* calculate the digest */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* rsa_ctx->bi_ctx is not thread-safe */
 | 
				
			||||||
 | 
					    if (rsa_ctx)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        SSL_CTX_LOCK(ssl->ssl_ctx->mutex);
 | 
				
			||||||
 | 
					        n = RSA_encrypt(rsa_ctx, dgst, sizeof(dgst), &buf[6], 1);
 | 
				
			||||||
 | 
					        SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (n == 0)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            ret = SSL_ERROR_INVALID_KEY;
 | 
				
			||||||
 | 
					            goto error;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    buf[4] = n >> 8;        /* add the RSA size (not officially documented) */
 | 
				
			||||||
 | 
					    buf[5] = n & 0xff;
 | 
				
			||||||
 | 
					    n += 2;
 | 
				
			||||||
 | 
					    buf[2] = n >> 8;
 | 
				
			||||||
 | 
					    buf[3] = n & 0xff;
 | 
				
			||||||
 | 
					    ret = send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, n+4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error:
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif      /* CONFIG_SSL_ENABLE_CLIENT */
 | 
				
			||||||
							
								
								
									
										478
									
								
								ssl/tls1_svr.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										478
									
								
								ssl/tls1_svr.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,478 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include "os_port.h"
 | 
				
			||||||
 | 
					#include "ssl.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const uint8_t g_hello_done[] = { HS_SERVER_HELLO_DONE, 0, 0, 0 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int process_client_hello(SSL *ssl);
 | 
				
			||||||
 | 
					static int send_server_hello_sequence(SSL *ssl);
 | 
				
			||||||
 | 
					static int send_server_hello(SSL *ssl);
 | 
				
			||||||
 | 
					static int send_server_hello_done(SSL *ssl);
 | 
				
			||||||
 | 
					static int process_client_key_xchg(SSL *ssl);
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_CERT_VERIFICATION
 | 
				
			||||||
 | 
					static int send_certificate_request(SSL *ssl);
 | 
				
			||||||
 | 
					static int process_cert_verify(SSL *ssl);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Establish a new SSL connection to an SSL client.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EXP_FUNC SSL * STDCALL ssl_server_new(SSL_CTX *ssl_ctx, int client_fd)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    SSL *ssl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ssl = ssl_new(ssl_ctx, client_fd);
 | 
				
			||||||
 | 
					    ssl->next_state = HS_CLIENT_HELLO;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_FULL_MODE
 | 
				
			||||||
 | 
					    if (ssl_ctx->chain_length == 0)
 | 
				
			||||||
 | 
					        printf("Warning - no server certificate defined\n"); TTY_FLUSH();
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return ssl;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Process the handshake record.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int do_svr_handshake(SSL *ssl, int handshake_type, uint8_t *buf, int hs_len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int ret = SSL_OK;
 | 
				
			||||||
 | 
					    ssl->hs_status = SSL_NOT_OK;            /* not connected */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* To get here the state must be valid */
 | 
				
			||||||
 | 
					    switch (handshake_type)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        case HS_CLIENT_HELLO:
 | 
				
			||||||
 | 
					            if ((ret = process_client_hello(ssl)) == SSL_OK)
 | 
				
			||||||
 | 
					                ret = send_server_hello_sequence(ssl);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_CERT_VERIFICATION
 | 
				
			||||||
 | 
					        case HS_CERTIFICATE:/* the client sends its cert */
 | 
				
			||||||
 | 
					            ret = process_certificate(ssl, &ssl->x509_ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (ret == SSL_OK)    /* verify the cert */
 | 
				
			||||||
 | 
					            { 
 | 
				
			||||||
 | 
					                int cert_res;
 | 
				
			||||||
 | 
					                cert_res = x509_verify(
 | 
				
			||||||
 | 
					                        ssl->ssl_ctx->ca_cert_ctx, ssl->x509_ctx);
 | 
				
			||||||
 | 
					                ret = (cert_res == 0) ? SSL_OK : SSL_X509_ERROR(cert_res);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case HS_CERT_VERIFY:    
 | 
				
			||||||
 | 
					            ret = process_cert_verify(ssl);
 | 
				
			||||||
 | 
					            add_packet(ssl, buf, hs_len);   /* needs to be done after */
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        case HS_CLIENT_KEY_XCHG:
 | 
				
			||||||
 | 
					            ret = process_client_key_xchg(ssl);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case HS_FINISHED:
 | 
				
			||||||
 | 
					            ret = process_finished(ssl, buf, hs_len);
 | 
				
			||||||
 | 
					            disposable_free(ssl);   /* free up some memory */
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 
 | 
				
			||||||
 | 
					 * Process a client hello message.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					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;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    uint8_t version = (buf[4] << 4) + buf[5];
 | 
				
			||||||
 | 
					    ssl->version = ssl->client_version = version;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (version > SSL_PROTOCOL_VERSION_MAX)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /* use client's version instead */
 | 
				
			||||||
 | 
					        ssl->version = SSL_PROTOCOL_VERSION_MAX; 
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (version < SSL_PROTOCOL_MIN_VERSION)  /* old version supported? */
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ret = SSL_ERROR_INVALID_VERSION;
 | 
				
			||||||
 | 
					        ssl_display_error(ret);
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memcpy(ssl->dc->client_random, &buf[6], SSL_RANDOM_SIZE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* process the session id */
 | 
				
			||||||
 | 
					    id_len = buf[offset++];
 | 
				
			||||||
 | 
					    if (id_len > SSL_SESSION_ID_SIZE)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return SSL_ERROR_INVALID_SESSION;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef CONFIG_SSL_SKELETON_MODE
 | 
				
			||||||
 | 
					    ssl->session = ssl_session_update(ssl->ssl_ctx->num_sessions,
 | 
				
			||||||
 | 
					            ssl->ssl_ctx->ssl_sessions, ssl, id_len ? &buf[offset] : NULL);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    offset += id_len;
 | 
				
			||||||
 | 
					    cs_len = (buf[offset]<<8) + buf[offset+1];
 | 
				
			||||||
 | 
					    offset += 3;        /* add 1 due to all cipher suites being 8 bit */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    PARANOIA_CHECK(pkt_size, offset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* work out what cipher suite we are going to use - client defines 
 | 
				
			||||||
 | 
					       the preference */
 | 
				
			||||||
 | 
					    for (i = 0; i < cs_len; i += 2)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        for (j = 0; j < NUM_PROTOCOLS; j++)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (ssl_prot_prefs[j] == buf[offset+i])   /* got a match? */
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                ssl->cipher = ssl_prot_prefs[j];
 | 
				
			||||||
 | 
					                goto do_state;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* ouch! protocol is not supported */
 | 
				
			||||||
 | 
					    ret = SSL_ERROR_NO_CIPHER;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					do_state:
 | 
				
			||||||
 | 
					error:
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_ENABLE_V23_HANDSHAKE
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Some browsers use a hybrid SSLv2 "client hello" 
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int process_sslv23_client_hello(SSL *ssl)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint8_t *buf = ssl->bm_data;
 | 
				
			||||||
 | 
					    int bytes_needed = ((buf[0] & 0x7f) << 8) + buf[1];
 | 
				
			||||||
 | 
					    int ret = SSL_OK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* we have already read 3 extra bytes so far */
 | 
				
			||||||
 | 
					    int read_len = SOCKET_READ(ssl->client_fd, buf, bytes_needed-3);
 | 
				
			||||||
 | 
					    int cs_len = buf[1];
 | 
				
			||||||
 | 
					    int id_len = buf[3];
 | 
				
			||||||
 | 
					    int ch_len = buf[5];
 | 
				
			||||||
 | 
					    int i, j, offset = 8;   /* start at first cipher */
 | 
				
			||||||
 | 
					    int random_offset = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return SSL_ERROR_CONN_LOST;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* now work out what cipher suite we are going to use */
 | 
				
			||||||
 | 
					    for (j = 0; j < NUM_PROTOCOLS; j++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        for (i = 0; i < cs_len; i += 3)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (ssl_prot_prefs[j] == buf[offset+i])
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                ssl->cipher = ssl_prot_prefs[j];
 | 
				
			||||||
 | 
					                goto server_hello;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* ouch! protocol is not supported */
 | 
				
			||||||
 | 
					    ret = SSL_ERROR_NO_CIPHER;
 | 
				
			||||||
 | 
					    goto error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					server_hello:
 | 
				
			||||||
 | 
					    /* get the session id */
 | 
				
			||||||
 | 
					    offset += cs_len - 2;   /* we've gone 2 bytes past the end */
 | 
				
			||||||
 | 
					#ifndef CONFIG_SSL_SKELETON_MODE
 | 
				
			||||||
 | 
					    ssl->session = ssl_session_update(ssl->ssl_ctx->num_sessions,
 | 
				
			||||||
 | 
					            ssl->ssl_ctx->ssl_sessions, ssl, id_len ? &buf[offset] : NULL);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* get the client random data */
 | 
				
			||||||
 | 
					    offset += id_len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* random can be anywhere between 16 and 32 bytes long - so it is padded
 | 
				
			||||||
 | 
					     * with 0's to the left */
 | 
				
			||||||
 | 
					    if (ch_len == 0x10)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        random_offset += 0x10;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memcpy(&ssl->dc->client_random[random_offset], &buf[offset], ch_len);
 | 
				
			||||||
 | 
					    ret = send_server_hello_sequence(ssl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error:
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Send the entire server hello sequence
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int send_server_hello_sequence(SSL *ssl)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ((ret = send_server_hello(ssl)) == SSL_OK)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					#ifndef CONFIG_SSL_SKELETON_MODE
 | 
				
			||||||
 | 
					        /* resume handshake? */
 | 
				
			||||||
 | 
					        if (IS_SET_SSL_FLAG(SSL_SESSION_RESUME))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if ((ret = send_change_cipher_spec(ssl)) == SSL_OK)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                ret = send_finished(ssl);
 | 
				
			||||||
 | 
					                ssl->next_state = HS_FINISHED;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else 
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        if ((ret = send_certificate(ssl)) == SSL_OK)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_CERT_VERIFICATION
 | 
				
			||||||
 | 
					            /* ask the client for its certificate */
 | 
				
			||||||
 | 
					            if (IS_SET_SSL_FLAG(SSL_CLIENT_AUTHENTICATION))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if ((ret = send_certificate_request(ssl)) == SSL_OK)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    ret = send_server_hello_done(ssl);
 | 
				
			||||||
 | 
					                    ssl->next_state = HS_CERTIFICATE;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                ret = send_server_hello_done(ssl);
 | 
				
			||||||
 | 
					                ssl->next_state = HS_CLIENT_KEY_XCHG;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Send a server hello message.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int send_server_hello(SSL *ssl)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint8_t *buf = ssl->bm_data;
 | 
				
			||||||
 | 
					    int offset = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    buf[0] = HS_SERVER_HELLO;
 | 
				
			||||||
 | 
					    buf[1] = 0;
 | 
				
			||||||
 | 
					    buf[2] = 0;
 | 
				
			||||||
 | 
					    /* byte 3 is calculated later */
 | 
				
			||||||
 | 
					    buf[4] = 0x03;
 | 
				
			||||||
 | 
					    buf[5] = ssl->version & 0x0f;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* server random value */
 | 
				
			||||||
 | 
					    get_random(SSL_RANDOM_SIZE, &buf[6]);
 | 
				
			||||||
 | 
					    memcpy(ssl->dc->server_random, &buf[6], SSL_RANDOM_SIZE);
 | 
				
			||||||
 | 
					    offset = 6 + SSL_RANDOM_SIZE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef CONFIG_SSL_SKELETON_MODE
 | 
				
			||||||
 | 
					    if (IS_SET_SSL_FLAG(SSL_SESSION_RESUME))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /* retrieve id from session cache */
 | 
				
			||||||
 | 
					        buf[offset++] = SSL_SESSION_ID_SIZE;
 | 
				
			||||||
 | 
					        memcpy(&buf[offset], ssl->session->session_id, SSL_SESSION_ID_SIZE);
 | 
				
			||||||
 | 
					        memcpy(ssl->session_id, ssl->session->session_id, SSL_SESSION_ID_SIZE);
 | 
				
			||||||
 | 
					        ssl->sess_id_size = SSL_SESSION_ID_SIZE;
 | 
				
			||||||
 | 
					        offset += SSL_SESSION_ID_SIZE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else    /* generate our own session id */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					#ifndef CONFIG_SSL_SKELETON_MODE
 | 
				
			||||||
 | 
					        buf[offset++] = SSL_SESSION_ID_SIZE;
 | 
				
			||||||
 | 
					        get_random(SSL_SESSION_ID_SIZE, &buf[offset]);
 | 
				
			||||||
 | 
					        memcpy(ssl->session_id, &buf[offset], SSL_SESSION_ID_SIZE);
 | 
				
			||||||
 | 
					        ssl->sess_id_size = SSL_SESSION_ID_SIZE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* store id in session cache */
 | 
				
			||||||
 | 
					        if (ssl->ssl_ctx->num_sessions)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            memcpy(ssl->session->session_id, 
 | 
				
			||||||
 | 
					                    ssl->session_id, SSL_SESSION_ID_SIZE);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        offset += SSL_SESSION_ID_SIZE;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					        buf[offset++] = 0;  /* don't bother with session id in skelton mode */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    buf[offset++] = 0;      /* cipher we are using */
 | 
				
			||||||
 | 
					    buf[offset++] = ssl->cipher;
 | 
				
			||||||
 | 
					    buf[offset++] = 0;      /* no compression */
 | 
				
			||||||
 | 
					    buf[3] = offset - 4;    /* handshake size */
 | 
				
			||||||
 | 
					    return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, offset);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Send the server hello done message.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int send_server_hello_done(SSL *ssl)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, 
 | 
				
			||||||
 | 
					                            g_hello_done, sizeof(g_hello_done));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Pull apart a client key exchange message. Decrypt the pre-master key (using
 | 
				
			||||||
 | 
					 * our RSA private key) and then work out the master key. Initialise the
 | 
				
			||||||
 | 
					 * ciphers.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int process_client_key_xchg(SSL *ssl)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint8_t *buf = &ssl->bm_data[ssl->dc->bm_proc_index];
 | 
				
			||||||
 | 
					    int pkt_size = ssl->bm_index;
 | 
				
			||||||
 | 
					    int premaster_size, secret_length = (buf[2] << 8) + buf[3];
 | 
				
			||||||
 | 
					    uint8_t premaster_secret[MAX_KEY_BYTE_SIZE];
 | 
				
			||||||
 | 
					    RSA_CTX *rsa_ctx = ssl->ssl_ctx->rsa_ctx;
 | 
				
			||||||
 | 
					    int offset = 4;
 | 
				
			||||||
 | 
					    int ret = SSL_OK;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (rsa_ctx == NULL)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ret = SSL_ERROR_NO_CERT_DEFINED;
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* is there an extra size field? */
 | 
				
			||||||
 | 
					    if ((secret_length - 2) == rsa_ctx->num_octets)
 | 
				
			||||||
 | 
					        offset += 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    PARANOIA_CHECK(pkt_size, rsa_ctx->num_octets+offset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* 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);
 | 
				
			||||||
 | 
					    SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (premaster_size != SSL_SECRET_SIZE || 
 | 
				
			||||||
 | 
					            premaster_secret[0] != 0x03 ||  /* must be the same as client
 | 
				
			||||||
 | 
					                                               offered version */
 | 
				
			||||||
 | 
					                premaster_secret[1] != (ssl->client_version & 0x0f))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /* guard against a Bleichenbacher attack */
 | 
				
			||||||
 | 
					        get_random(SSL_SECRET_SIZE, premaster_secret);
 | 
				
			||||||
 | 
					        /* and continue - will die eventually when checking the mac */
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if 0
 | 
				
			||||||
 | 
					    print_blob("pre-master", premaster_secret, SSL_SECRET_SIZE);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    generate_master_secret(ssl, premaster_secret);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_CERT_VERIFICATION
 | 
				
			||||||
 | 
					    ssl->next_state = IS_SET_SSL_FLAG(SSL_CLIENT_AUTHENTICATION) ?  
 | 
				
			||||||
 | 
					                                            HS_CERT_VERIFY : HS_FINISHED;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					    ssl->next_state = HS_FINISHED; 
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ssl->dc->bm_proc_index += rsa_ctx->num_octets+offset;
 | 
				
			||||||
 | 
					error:
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_CERT_VERIFICATION
 | 
				
			||||||
 | 
					static const uint8_t g_cert_request[] = { HS_CERT_REQ, 0, 0, 4, 1, 0, 0, 0 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Send the certificate request message.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int send_certificate_request(SSL *ssl)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, 
 | 
				
			||||||
 | 
					            g_cert_request, sizeof(g_cert_request));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Ensure the client has the private key by first decrypting the packet and
 | 
				
			||||||
 | 
					 * then checking the packet digests.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int process_cert_verify(SSL *ssl)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint8_t *buf = &ssl->bm_data[ssl->dc->bm_proc_index];
 | 
				
			||||||
 | 
					    int pkt_size = ssl->bm_index;
 | 
				
			||||||
 | 
					    uint8_t dgst_buf[MAX_KEY_BYTE_SIZE];
 | 
				
			||||||
 | 
					    uint8_t dgst[MD5_SIZE+SHA1_SIZE];
 | 
				
			||||||
 | 
					    X509_CTX *x509_ctx = ssl->x509_ctx;
 | 
				
			||||||
 | 
					    int ret = SSL_OK;
 | 
				
			||||||
 | 
					    int n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    PARANOIA_CHECK(pkt_size, x509_ctx->rsa_ctx->num_octets+6);
 | 
				
			||||||
 | 
					    DISPLAY_RSA(ssl, x509_ctx->rsa_ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* 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);
 | 
				
			||||||
 | 
					    SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (n != SHA1_SIZE + MD5_SIZE)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ret = SSL_ERROR_INVALID_KEY;
 | 
				
			||||||
 | 
					        goto end_cert_vfy;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    finished_digest(ssl, NULL, dgst);       /* calculate the digest */
 | 
				
			||||||
 | 
					    if (memcmp(dgst_buf, dgst, MD5_SIZE + SHA1_SIZE))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ret = SSL_ERROR_INVALID_KEY;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					end_cert_vfy:
 | 
				
			||||||
 | 
					    ssl->next_state = HS_FINISHED;
 | 
				
			||||||
 | 
					error:
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										1
									
								
								ssl/version.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								ssl/version.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					#define AXTLS_VERSION    "1.4.9"
 | 
				
			||||||
							
								
								
									
										559
									
								
								ssl/x509.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										559
									
								
								ssl/x509.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,559 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @file x509.c
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * Certificate processing.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <time.h>
 | 
				
			||||||
 | 
					#include "os_port.h"
 | 
				
			||||||
 | 
					#include "crypto_misc.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_CERT_VERIFICATION
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Retrieve the signature from a certificate.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static const uint8_t *get_signature(const uint8_t *asn1_sig, int *len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int offset = 0;
 | 
				
			||||||
 | 
					    const uint8_t *ptr = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (asn1_next_obj(asn1_sig, &offset, ASN1_SEQUENCE) < 0 || 
 | 
				
			||||||
 | 
					            asn1_skip_obj(asn1_sig, &offset, ASN1_SEQUENCE))
 | 
				
			||||||
 | 
					        goto end_get_sig;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (asn1_sig[offset++] != ASN1_OCTET_STRING)
 | 
				
			||||||
 | 
					        goto end_get_sig;
 | 
				
			||||||
 | 
					    *len = get_asn1_length(asn1_sig, &offset);
 | 
				
			||||||
 | 
					    ptr = &asn1_sig[offset];          /* all ok */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					end_get_sig:
 | 
				
			||||||
 | 
					    return ptr;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Construct a new x509 object.
 | 
				
			||||||
 | 
					 * @return 0 if ok. < 0 if there was a problem.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int x509_new(const uint8_t *cert, int *len, X509_CTX **ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int begin_tbs, end_tbs;
 | 
				
			||||||
 | 
					    int ret = X509_NOT_OK, offset = 0, cert_size = 0;
 | 
				
			||||||
 | 
					    X509_CTX *x509_ctx;
 | 
				
			||||||
 | 
					    BI_CTX *bi_ctx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    *ctx = (X509_CTX *)calloc(1, sizeof(X509_CTX));
 | 
				
			||||||
 | 
					    x509_ctx = *ctx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* get the certificate size */
 | 
				
			||||||
 | 
					    asn1_skip_obj(cert, &cert_size, ASN1_SEQUENCE); 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (asn1_next_obj(cert, &offset, ASN1_SEQUENCE) < 0)
 | 
				
			||||||
 | 
					        goto end_cert;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    begin_tbs = offset;         /* start of the tbs */
 | 
				
			||||||
 | 
					    end_tbs = begin_tbs;        /* work out the end of the tbs */
 | 
				
			||||||
 | 
					    asn1_skip_obj(cert, &end_tbs, ASN1_SEQUENCE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (asn1_next_obj(cert, &offset, ASN1_SEQUENCE) < 0)
 | 
				
			||||||
 | 
					        goto end_cert;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (cert[offset] == ASN1_EXPLICIT_TAG)   /* optional version */
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (asn1_version(cert, &offset, x509_ctx))
 | 
				
			||||||
 | 
					            goto end_cert;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (asn1_skip_obj(cert, &offset, ASN1_INTEGER) || /* serial number */ 
 | 
				
			||||||
 | 
					            asn1_next_obj(cert, &offset, ASN1_SEQUENCE) < 0)
 | 
				
			||||||
 | 
					        goto end_cert;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* make sure the signature is ok */
 | 
				
			||||||
 | 
					    if (asn1_signature_type(cert, &offset, x509_ctx))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ret = X509_VFY_ERROR_UNSUPPORTED_DIGEST;
 | 
				
			||||||
 | 
					        goto end_cert;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (asn1_name(cert, &offset, x509_ctx->ca_cert_dn) || 
 | 
				
			||||||
 | 
					            asn1_validity(cert, &offset, x509_ctx) ||
 | 
				
			||||||
 | 
					            asn1_name(cert, &offset, x509_ctx->cert_dn) ||
 | 
				
			||||||
 | 
					            asn1_public_key(cert, &offset, x509_ctx))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        goto end_cert;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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) */
 | 
				
			||||||
 | 
					    if (x509_ctx->sig_type == 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);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    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);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (cert[offset] == ASN1_V3_DATA)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        int suboffset;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ++offset;
 | 
				
			||||||
 | 
					        get_asn1_length(cert, &offset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ((suboffset = asn1_find_subjectaltname(cert, offset)) > 0)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (asn1_next_obj(cert, &suboffset, ASN1_OCTET_STRING) > 0)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                int altlen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if ((altlen = asn1_next_obj(cert, 
 | 
				
			||||||
 | 
					                                            &suboffset, ASN1_SEQUENCE)) > 0)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    int endalt = suboffset + altlen;
 | 
				
			||||||
 | 
					                    int totalnames = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    while (suboffset < endalt)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        int type = cert[suboffset++];
 | 
				
			||||||
 | 
					                        int dnslen = get_asn1_length(cert, &suboffset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        if (type == ASN1_CONTEXT_DNSNAME)
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            x509_ctx->subject_alt_dnsnames = (char**)
 | 
				
			||||||
 | 
					                                    realloc(x509_ctx->subject_alt_dnsnames, 
 | 
				
			||||||
 | 
					                                       (totalnames + 2) * sizeof(char*));
 | 
				
			||||||
 | 
					                            x509_ctx->subject_alt_dnsnames[totalnames] = 
 | 
				
			||||||
 | 
					                                    (char*)malloc(dnslen + 1);
 | 
				
			||||||
 | 
					                            x509_ctx->subject_alt_dnsnames[totalnames+1] = NULL;
 | 
				
			||||||
 | 
					                            memcpy(x509_ctx->subject_alt_dnsnames[totalnames], 
 | 
				
			||||||
 | 
					                                    cert + suboffset, dnslen);
 | 
				
			||||||
 | 
					                            x509_ctx->subject_alt_dnsnames[
 | 
				
			||||||
 | 
					                                    totalnames][dnslen] = 0;
 | 
				
			||||||
 | 
					                            ++totalnames;
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        suboffset += dnslen;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    offset = end_tbs;   /* skip the rest of v3 data */
 | 
				
			||||||
 | 
					    if (asn1_skip_obj(cert, &offset, ASN1_SEQUENCE) || 
 | 
				
			||||||
 | 
					            asn1_signature(cert, &offset, x509_ctx))
 | 
				
			||||||
 | 
					        goto end_cert;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    ret = X509_OK;
 | 
				
			||||||
 | 
					end_cert:
 | 
				
			||||||
 | 
					    if (len)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        *len = cert_size;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (ret)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_FULL_MODE
 | 
				
			||||||
 | 
					        printf("Error: Invalid X509 ASN.1 file (%s)\n",
 | 
				
			||||||
 | 
					                        x509_display_error(ret));
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        x509_free(x509_ctx);
 | 
				
			||||||
 | 
					        *ctx = NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Free an X.509 object's resources.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void x509_free(X509_CTX *x509_ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    X509_CTX *next;
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (x509_ctx == NULL)       /* if already null, then don't bother */
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0; i < X509_NUM_DN_TYPES; i++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        free(x509_ctx->ca_cert_dn[i]);
 | 
				
			||||||
 | 
					        free(x509_ctx->cert_dn[i]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    free(x509_ctx->signature);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_CERT_VERIFICATION 
 | 
				
			||||||
 | 
					    if (x509_ctx->digest)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        bi_free(x509_ctx->rsa_ctx->bi_ctx, x509_ctx->digest);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (x509_ctx->subject_alt_dnsnames)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        for (i = 0; x509_ctx->subject_alt_dnsnames[i]; ++i)
 | 
				
			||||||
 | 
					            free(x509_ctx->subject_alt_dnsnames[i]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        free(x509_ctx->subject_alt_dnsnames);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    RSA_free(x509_ctx->rsa_ctx);
 | 
				
			||||||
 | 
					    next = x509_ctx->next;
 | 
				
			||||||
 | 
					    free(x509_ctx);
 | 
				
			||||||
 | 
					    x509_free(next);        /* clear the chain */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_SSL_CERT_VERIFICATION
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Take a signature and decrypt it.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static bigint *sig_verify(BI_CTX *ctx, const uint8_t *sig, int sig_len,
 | 
				
			||||||
 | 
					        bigint *modulus, bigint *pub_exp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int i, size;
 | 
				
			||||||
 | 
					    bigint *decrypted_bi, *dat_bi;
 | 
				
			||||||
 | 
					    bigint *bir = NULL;
 | 
				
			||||||
 | 
					    uint8_t *block = (uint8_t *)alloca(sig_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* decrypt */
 | 
				
			||||||
 | 
					    dat_bi = bi_import(ctx, sig, sig_len);
 | 
				
			||||||
 | 
					    ctx->mod_offset = BIGINT_M_OFFSET;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* convert to a normal block */
 | 
				
			||||||
 | 
					    decrypted_bi = bi_mod_power2(ctx, dat_bi, modulus, pub_exp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bi_export(ctx, decrypted_bi, block, sig_len);
 | 
				
			||||||
 | 
					    ctx->mod_offset = BIGINT_M_OFFSET;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    i = 10; /* start at the first possible non-padded byte */
 | 
				
			||||||
 | 
					    while (block[i++] && i < sig_len);
 | 
				
			||||||
 | 
					    size = sig_len - i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* get only the bit we want */
 | 
				
			||||||
 | 
					    if (size > 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        int len;
 | 
				
			||||||
 | 
					        const uint8_t *sig_ptr = get_signature(&block[i], &len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (sig_ptr)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            bir = bi_import(ctx, sig_ptr, len);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* save a few bytes of memory */
 | 
				
			||||||
 | 
					    bi_clear_cache(ctx);
 | 
				
			||||||
 | 
					    return bir;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Do some basic checks on the certificate chain.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Certificate verification consists of a number of checks:
 | 
				
			||||||
 | 
					 * - The date of the certificate is after the start date.
 | 
				
			||||||
 | 
					 * - The date of the certificate is before the finish date.
 | 
				
			||||||
 | 
					 * - A root certificate exists in the certificate store.
 | 
				
			||||||
 | 
					 * - That the certificate(s) are not self-signed.
 | 
				
			||||||
 | 
					 * - The certificate chain is valid.
 | 
				
			||||||
 | 
					 * - The signature of the certificate is valid.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int x509_verify(const CA_CERT_CTX *ca_cert_ctx, const X509_CTX *cert) 
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int ret = X509_OK, i = 0;
 | 
				
			||||||
 | 
					    bigint *cert_sig;
 | 
				
			||||||
 | 
					    X509_CTX *next_cert = NULL;
 | 
				
			||||||
 | 
					    BI_CTX *ctx = NULL;
 | 
				
			||||||
 | 
					    bigint *mod = NULL, *expn = NULL;
 | 
				
			||||||
 | 
					    int match_ca_cert = 0;
 | 
				
			||||||
 | 
					    struct timeval tv;
 | 
				
			||||||
 | 
					    uint8_t is_self_signed = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (cert == NULL)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ret = X509_VFY_ERROR_NO_TRUSTED_CERT;       
 | 
				
			||||||
 | 
					        goto end_verify;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* a self-signed certificate that is not in the CA store - use this 
 | 
				
			||||||
 | 
					       to check the signature */
 | 
				
			||||||
 | 
					    if (asn1_compare_dn(cert->ca_cert_dn, cert->cert_dn) == 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        is_self_signed = 1;
 | 
				
			||||||
 | 
					        ctx = cert->rsa_ctx->bi_ctx;
 | 
				
			||||||
 | 
					        mod = cert->rsa_ctx->m;
 | 
				
			||||||
 | 
					        expn = cert->rsa_ctx->e;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    gettimeofday(&tv, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* check the not before date */
 | 
				
			||||||
 | 
					    if (tv.tv_sec < cert->not_before)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ret = X509_VFY_ERROR_NOT_YET_VALID;
 | 
				
			||||||
 | 
					        goto end_verify;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* check the not after date */
 | 
				
			||||||
 | 
					    if (tv.tv_sec > cert->not_after)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ret = X509_VFY_ERROR_EXPIRED;
 | 
				
			||||||
 | 
					        goto end_verify;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    next_cert = cert->next;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* last cert in the chain - look for a trusted cert */
 | 
				
			||||||
 | 
					    if (next_cert == NULL)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					       if (ca_cert_ctx != NULL) 
 | 
				
			||||||
 | 
					       {
 | 
				
			||||||
 | 
					            /* go thu the CA store */
 | 
				
			||||||
 | 
					            while (i < CONFIG_X509_MAX_CA_CERTS && ca_cert_ctx->cert[i])
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (asn1_compare_dn(cert->ca_cert_dn,
 | 
				
			||||||
 | 
					                                            ca_cert_ctx->cert[i]->cert_dn) == 0)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    /* use this CA certificate for signature verification */
 | 
				
			||||||
 | 
					                    match_ca_cert = 1;
 | 
				
			||||||
 | 
					                    ctx = ca_cert_ctx->cert[i]->rsa_ctx->bi_ctx;
 | 
				
			||||||
 | 
					                    mod = ca_cert_ctx->cert[i]->rsa_ctx->m;
 | 
				
			||||||
 | 
					                    expn = ca_cert_ctx->cert[i]->rsa_ctx->e;
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                i++;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* couldn't find a trusted cert (& let self-signed errors 
 | 
				
			||||||
 | 
					           be returned) */
 | 
				
			||||||
 | 
					        if (!match_ca_cert && !is_self_signed)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            ret = X509_VFY_ERROR_NO_TRUSTED_CERT;       
 | 
				
			||||||
 | 
					            goto end_verify;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (asn1_compare_dn(cert->ca_cert_dn, next_cert->cert_dn) != 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /* check the chain */
 | 
				
			||||||
 | 
					        ret = X509_VFY_ERROR_INVALID_CHAIN;
 | 
				
			||||||
 | 
					        goto end_verify;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else /* use the next certificate in the chain for signature verify */
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ctx = next_cert->rsa_ctx->bi_ctx;
 | 
				
			||||||
 | 
					        mod = next_cert->rsa_ctx->m;
 | 
				
			||||||
 | 
					        expn = next_cert->rsa_ctx->e;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* cert is self signed */
 | 
				
			||||||
 | 
					    if (!match_ca_cert && is_self_signed)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ret = X509_VFY_ERROR_SELF_SIGNED;
 | 
				
			||||||
 | 
					        goto end_verify;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* check the signature */
 | 
				
			||||||
 | 
					    cert_sig = sig_verify(ctx, cert->signature, cert->sig_len, 
 | 
				
			||||||
 | 
					                        bi_clone(ctx, mod), bi_clone(ctx, expn));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (cert_sig && cert->digest)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (bi_compare(cert_sig, cert->digest) != 0)
 | 
				
			||||||
 | 
					            ret = X509_VFY_ERROR_BAD_SIGNATURE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        bi_free(ctx, cert_sig);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ret = X509_VFY_ERROR_BAD_SIGNATURE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (ret)
 | 
				
			||||||
 | 
					        goto end_verify;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* go down the certificate chain using recursion. */
 | 
				
			||||||
 | 
					    if (next_cert != NULL)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ret = x509_verify(ca_cert_ctx, next_cert);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					end_verify:
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined (CONFIG_SSL_FULL_MODE)
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Used for diagnostics.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static const char *not_part_of_cert = "<Not Part Of Certificate>";
 | 
				
			||||||
 | 
					void x509_print(const X509_CTX *cert, CA_CERT_CTX *ca_cert_ctx) 
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (cert == NULL)
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    printf("=== CERTIFICATE ISSUED TO ===\n");
 | 
				
			||||||
 | 
					    printf("Common Name (CN):\t\t");
 | 
				
			||||||
 | 
					    printf("%s\n", cert->cert_dn[X509_COMMON_NAME] ?
 | 
				
			||||||
 | 
					                    cert->cert_dn[X509_COMMON_NAME] : not_part_of_cert);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    printf("Organization (O):\t\t");
 | 
				
			||||||
 | 
					    printf("%s\n", cert->cert_dn[X509_ORGANIZATION] ?
 | 
				
			||||||
 | 
					        cert->cert_dn[X509_ORGANIZATION] : not_part_of_cert);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    printf("Organizational Unit (OU):\t");
 | 
				
			||||||
 | 
					    printf("%s\n", cert->cert_dn[X509_ORGANIZATIONAL_UNIT] ?
 | 
				
			||||||
 | 
					        cert->cert_dn[X509_ORGANIZATIONAL_UNIT] : not_part_of_cert);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    printf("=== CERTIFICATE ISSUED BY ===\n");
 | 
				
			||||||
 | 
					    printf("Common Name (CN):\t\t");
 | 
				
			||||||
 | 
					    printf("%s\n", cert->ca_cert_dn[X509_COMMON_NAME] ?
 | 
				
			||||||
 | 
					                    cert->ca_cert_dn[X509_COMMON_NAME] : not_part_of_cert);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    printf("Organization (O):\t\t");
 | 
				
			||||||
 | 
					    printf("%s\n", cert->ca_cert_dn[X509_ORGANIZATION] ?
 | 
				
			||||||
 | 
					        cert->ca_cert_dn[X509_ORGANIZATION] : not_part_of_cert);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    printf("Organizational Unit (OU):\t");
 | 
				
			||||||
 | 
					    printf("%s\n", cert->ca_cert_dn[X509_ORGANIZATIONAL_UNIT] ?
 | 
				
			||||||
 | 
					        cert->ca_cert_dn[X509_ORGANIZATIONAL_UNIT] : not_part_of_cert);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    printf("Not Before:\t\t\t%s", ctime(&cert->not_before));
 | 
				
			||||||
 | 
					    printf("Not After:\t\t\t%s", ctime(&cert->not_after));
 | 
				
			||||||
 | 
					    printf("RSA bitsize:\t\t\t%d\n", cert->rsa_ctx->num_octets*8);
 | 
				
			||||||
 | 
					    printf("Sig Type:\t\t\t");
 | 
				
			||||||
 | 
					    switch (cert->sig_type)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        case SIG_TYPE_MD5:
 | 
				
			||||||
 | 
					            printf("MD5\n");
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case SIG_TYPE_SHA1:
 | 
				
			||||||
 | 
					            printf("SHA1\n");
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case SIG_TYPE_MD2:
 | 
				
			||||||
 | 
					            printf("MD2\n");
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        default:
 | 
				
			||||||
 | 
					            printf("Unrecognized: %d\n", cert->sig_type);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (ca_cert_ctx)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        printf("Verify:\t\t\t\t%s\n",
 | 
				
			||||||
 | 
					                x509_display_error(x509_verify(ca_cert_ctx, cert)));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if 0
 | 
				
			||||||
 | 
					    print_blob("Signature", cert->signature, cert->sig_len);
 | 
				
			||||||
 | 
					    bi_print("Modulus", cert->rsa_ctx->m);
 | 
				
			||||||
 | 
					    bi_print("Pub Exp", cert->rsa_ctx->e);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (ca_cert_ctx)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        x509_print(cert->next, ca_cert_ctx);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    TTY_FLUSH();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const char * x509_display_error(int error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    switch (error)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        case X509_OK:
 | 
				
			||||||
 | 
					            return "Certificate verify successful";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case X509_NOT_OK:
 | 
				
			||||||
 | 
					            return "X509 not ok";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case X509_VFY_ERROR_NO_TRUSTED_CERT:
 | 
				
			||||||
 | 
					            return "No trusted cert is available";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case X509_VFY_ERROR_BAD_SIGNATURE:
 | 
				
			||||||
 | 
					            return "Bad signature";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case X509_VFY_ERROR_NOT_YET_VALID:
 | 
				
			||||||
 | 
					            return "Cert is not yet valid";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case X509_VFY_ERROR_EXPIRED:
 | 
				
			||||||
 | 
					            return "Cert has expired";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case X509_VFY_ERROR_SELF_SIGNED:
 | 
				
			||||||
 | 
					            return "Cert is self-signed";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case X509_VFY_ERROR_INVALID_CHAIN:
 | 
				
			||||||
 | 
					            return "Chain is invalid (check order of certs)";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case X509_VFY_ERROR_UNSUPPORTED_DIGEST:
 | 
				
			||||||
 | 
					            return "Unsupported digest";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case X509_INVALID_PRIV_KEY:
 | 
				
			||||||
 | 
					            return "Invalid private key";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        default:
 | 
				
			||||||
 | 
					            return "Unknown";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif      /* CONFIG_SSL_FULL_MODE */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Reference in New Issue
	
	Block a user