mirror of
https://github.com/esp8266/Arduino.git
synced 2025-06-12 01:53:07 +03:00
new trunk
git-svn-id: svn://svn.code.sf.net/p/axtls/code/trunk@78 9a5d90b5-6617-0410-8a86-bb477d3ed2e3
This commit is contained in:
132
ssl/BigIntConfig.in
Normal file
132
ssl/BigIntConfig.in
Normal file
@ -0,0 +1,132 @@
|
||||
#
|
||||
# For a description of the syntax of this configuration file,
|
||||
# see scripts/config/Kconfig-language.txt
|
||||
#
|
||||
|
||||
menu "BigInt Options"
|
||||
depends on !CONFIG_SSL_SKELETON_MODE
|
||||
|
||||
choice
|
||||
prompt "Reduction Algorithm"
|
||||
default CONFIG_BIGINT_BARRETT
|
||||
|
||||
config CONFIG_BIGINT_CLASSICAL
|
||||
bool "Classical"
|
||||
help
|
||||
Classical uses standard division. It has no limitations and is
|
||||
theoretically the slowest due to the divisions used. For this particular
|
||||
implementation it is surprisingly quite fast.
|
||||
|
||||
config CONFIG_BIGINT_MONTGOMERY
|
||||
bool "Montgomery"
|
||||
help
|
||||
Montgomery uses simple addition and multiplication to achieve its
|
||||
performance. In this implementation it is slower than classical,
|
||||
and it has the limitation that 0 <= x, y < m, and so is not used
|
||||
when CRT is active.
|
||||
|
||||
This option will not be normally selected.
|
||||
|
||||
config CONFIG_BIGINT_BARRETT
|
||||
bool "Barrett"
|
||||
help
|
||||
Barrett performs expensive precomputation before reduction and partial
|
||||
multiplies for computational speed. It can't be used with some of the
|
||||
calculations when CRT is used, and so defaults to classical when this
|
||||
occurs.
|
||||
|
||||
It is about 40% faster than Classical/Montgomery with the expense of
|
||||
about 2kB, and so this option is normally selected.
|
||||
|
||||
endchoice
|
||||
|
||||
config CONFIG_BIGINT_CRT
|
||||
bool "Chinese Remainder Theorem (CRT)"
|
||||
default y
|
||||
help
|
||||
Allow the Chinese Remainder Theorem (CRT) to be used.
|
||||
|
||||
Uses a number of extra coefficients from the private key to improve the
|
||||
performance of a decryption. This feature is one of the most
|
||||
significant performance improvements (it reduces a decryption time by
|
||||
over 3 times).
|
||||
|
||||
This option should be selected.
|
||||
|
||||
config CONFIG_BIGINT_KARATSUBA
|
||||
bool "Karatsuba Multiplication"
|
||||
default n
|
||||
help
|
||||
Allow Karasuba multiplication to be used.
|
||||
|
||||
Uses 3 multiplications (plus a number of additions/subtractions)
|
||||
instead of 4. Multiplications are O(N^2) but addition/subtraction
|
||||
is O(N) hence for large numbers is beneficial. For this project, the
|
||||
effect was only useful for 4096 bit keys. As these aren't likely to
|
||||
be used, the feature is disabled by default.
|
||||
|
||||
It costs about 2kB to enable it.
|
||||
|
||||
config MUL_KARATSUBA_THRESH
|
||||
int "Karatsuba Multiplication Theshold"
|
||||
default 20
|
||||
depends on CONFIG_BIGINT_KARATSUBA
|
||||
help
|
||||
The minimum number of components needed before Karasuba muliplication
|
||||
is used.
|
||||
|
||||
This is very dependent on the speed/implementation of bi_add()/
|
||||
bi_subtract(). There is a bit of trial and error here and will be
|
||||
at a different point for different architectures.
|
||||
|
||||
config SQU_KARATSUBA_THRESH
|
||||
int "Karatsuba Square Threshold"
|
||||
default 40
|
||||
depends on CONFIG_BIGINT_KARATSUBA && CONFIG_BIGINT_SQUARE
|
||||
help
|
||||
The minimum number of components needed before Karatsuba squaring
|
||||
is used.
|
||||
|
||||
This is very dependent on the speed/implementation of bi_add()/
|
||||
bi_subtract(). There is a bit of trial and error here and will be
|
||||
at a different point for different architectures.
|
||||
|
||||
config CONFIG_BIGINT_SLIDING_WINDOW
|
||||
bool "Sliding Window Exponentiation"
|
||||
default y
|
||||
help
|
||||
Allow Sliding-Window Exponentiation to be used.
|
||||
|
||||
Potentially processes more than 1 bit at a time when doing
|
||||
exponentiation. The sliding-window technique reduces the number of
|
||||
precomputations compared to other precomputed techniques.
|
||||
|
||||
It results in a considerable performance improvement with it enabled
|
||||
(it halves the decryption time) and so should be selected.
|
||||
|
||||
config CONFIG_BIGINT_SQUARE
|
||||
bool "Square Algorithm"
|
||||
default y
|
||||
help
|
||||
Allow squaring to be used instead of a multiplication.
|
||||
|
||||
Squaring is theoretically 50% faster than a standard multiply
|
||||
(but is actually about 25% faster).
|
||||
|
||||
It gives a 20% speed improvement and so should be selected.
|
||||
|
||||
config CONFIG_BIGINT_CHECK_ON
|
||||
bool "BigInt Integrity Checking"
|
||||
default n if !CONFIG_DEBUG
|
||||
default y if CONFIG_DEBUG
|
||||
help
|
||||
This is used when developing bigint algorithms. It performs a sanity
|
||||
check on all operations at the expense of speed.
|
||||
|
||||
This option is only selected when developing and should normally be
|
||||
turned off.
|
||||
|
||||
endmenu
|
||||
|
||||
|
||||
|
274
ssl/Config.in
Normal file
274
ssl/Config.in
Normal file
@ -0,0 +1,274 @@
|
||||
#
|
||||
# For a description of the syntax of this configuration file,
|
||||
# see scripts/config/Kconfig-language.txt
|
||||
#
|
||||
|
||||
menu "SSL Library"
|
||||
|
||||
choice
|
||||
prompt "Mode"
|
||||
default CONFIG_SSL_FULL_MODE
|
||||
|
||||
config CONFIG_SSL_SERVER_ONLY
|
||||
bool "Server only - no verification"
|
||||
help
|
||||
Enable server functionality (no client functionality).
|
||||
This mode still supports sessions and chaining (which can be turned
|
||||
off in configuration).
|
||||
|
||||
The axssl sample runs with the minimum of features.
|
||||
|
||||
This is the most space efficient of the modes with the library
|
||||
about 45kB in size. Use this mode if you are doing standard SSL server
|
||||
work.
|
||||
|
||||
config CONFIG_SSL_CERT_VERIFICATION
|
||||
bool "Server only - with verification"
|
||||
help
|
||||
Enable server functionality with client authentication (no client
|
||||
functionality).
|
||||
|
||||
The axssl sample runs with the "-verify" and "-CAfile" options.
|
||||
|
||||
This mode produces a library about 49kB in size. Use this mode if you
|
||||
have an SSL server which requires client authentication (which is
|
||||
uncommon in browser applications).
|
||||
|
||||
config CONFIG_SSL_ENABLE_CLIENT
|
||||
bool "Client/Server enabled"
|
||||
help
|
||||
Enable client/server functionality (including peer authentication).
|
||||
|
||||
The axssl sample runs with the "s_client" option enabled.
|
||||
|
||||
This mode produces a library about 51kB in size. Use this mode if you
|
||||
require axTLS to use SSL client functionality (the SSL server code
|
||||
is always enabled).
|
||||
|
||||
config CONFIG_SSL_FULL_MODE
|
||||
bool "Client/Server enabled with diagnostics"
|
||||
help
|
||||
Enable client/server functionality including diagnostics. Most of the
|
||||
extra size in this mode is due to the storage of various strings that
|
||||
are used.
|
||||
|
||||
The axssl sample has 3 more options, "-debug", "-state" and "-show-rsa"
|
||||
|
||||
This mode produces a library about 58kB in size. It is suggested that
|
||||
this mode is used only during development, or systems that have more
|
||||
generous memory limits.
|
||||
|
||||
It is the default to demonstrate the features of axTLS.
|
||||
|
||||
config CONFIG_SSL_SKELETON_MODE
|
||||
bool "Skeleton mode - the smallest server mode"
|
||||
help
|
||||
This is an experiment to build the smallest library at the expense of
|
||||
features and speed.
|
||||
|
||||
* Server mode only.
|
||||
* The AES cipher is disabled.
|
||||
* No session resumption.
|
||||
* No external keys/certificates are supported.
|
||||
* The bigint library has most of the performance features disabled.
|
||||
* Some other features/API calls may not work.
|
||||
|
||||
This mode produces a library about 37kB in size. The main
|
||||
disadvantage of this mode is speed - it will be much slower than the
|
||||
other build modes.
|
||||
|
||||
endchoice
|
||||
|
||||
choice
|
||||
prompt "Protocol Preference"
|
||||
depends on !CONFIG_SSL_SKELETON_MODE
|
||||
default CONFIG_SSL_PROT_MEDIUM
|
||||
|
||||
config CONFIG_SSL_PROT_LOW
|
||||
bool "Low"
|
||||
help
|
||||
Chooses the cipher in the order of RC4-SHA, AES128-SHA, AES256-SHA.
|
||||
|
||||
This will use the fastest cipher(s) but at the expense of security.
|
||||
|
||||
config CONFIG_SSL_PROT_MEDIUM
|
||||
bool "Medium"
|
||||
help
|
||||
Chooses the cipher in the order of AES128-SHA, AES256-SHA, RC4-SHA.
|
||||
|
||||
This mode is a balance between speed and security and is the default.
|
||||
|
||||
config CONFIG_SSL_PROT_HIGH
|
||||
bool "High"
|
||||
help
|
||||
Chooses the cipher in the order of AES256-SHA, AES128-SHA, RC4-SHA.
|
||||
|
||||
This will use the strongest cipher(s) at the cost of speed.
|
||||
|
||||
endchoice
|
||||
|
||||
config CONFIG_SSL_USE_DEFAULT_KEY
|
||||
bool "Enable default key"
|
||||
depends on !CONFIG_SSL_SKELETON_MODE
|
||||
default y
|
||||
help
|
||||
Some applications will not require the default private key/certificate
|
||||
that is built in. This is one way to save on a couple of kB's if an
|
||||
external private key/certificate is used.
|
||||
|
||||
The advantage of a built-in private key/certificate is that no file
|
||||
system is required for access.
|
||||
|
||||
However this private key/certificate can never be changed (without a
|
||||
code update).
|
||||
|
||||
This mode is enabled by default. Disable this mode if the
|
||||
built-in key/certificate is not used.
|
||||
|
||||
config CONFIG_SSL_ENABLE_V23_HANDSHAKE
|
||||
bool "Enable v23 Handshake"
|
||||
default y
|
||||
help
|
||||
Some browsers use the v23 handshake client hello message
|
||||
(an SSL2 format message which all SSL servers can understand).
|
||||
It may be used if SSL2 is enabled in the browser.
|
||||
|
||||
Since this feature takes a kB or so, this feature may be disabled - at
|
||||
the risk of making it incompatible with some browsers (IE6 is ok,
|
||||
Firefox 1.5 and below use it).
|
||||
|
||||
Disable if backwards compatibility is not an issue (i.e. the client is
|
||||
always using TLS1.0)
|
||||
|
||||
config CONFIG_SSL_HAS_PEM
|
||||
bool "Enable PEM"
|
||||
default n if !CONFIG_SSL_FULL_MODE
|
||||
default y if CONFIG_SSL_FULL_MODE
|
||||
depends on !CONFIG_SSL_SKELETON_MODE
|
||||
help
|
||||
Enable the use of PEM format for certificates and private keys.
|
||||
|
||||
PEM is not normally needed - PEM files can be converted into DER files
|
||||
quite easily. However they have the convenience of allowing multiple
|
||||
certificates/keys in the same file.
|
||||
|
||||
This feature will add a couple of kB to the library.
|
||||
|
||||
Disable if PEM is not used (which will be in most cases).
|
||||
|
||||
config CONFIG_SSL_USE_PKCS12
|
||||
bool "Use PKCS8/PKCS12"
|
||||
default n if !CONFIG_SSL_FULL_MODE
|
||||
default y if CONFIG_SSL_FULL_MODE
|
||||
depends on !CONFIG_SSL_SERVER_ONLY && !CONFIG_SSL_SKELETON_MODE
|
||||
help
|
||||
PKCS#12 certificates combine private keys and certificates together in
|
||||
one file.
|
||||
|
||||
PKCS#8 private keys are also suppported (as it is a subset of PKCS#12).
|
||||
|
||||
The decryption of these certificates uses RC4-128 (and these
|
||||
certificates must be encrypted using this cipher). The actual
|
||||
algorithm is "PBE-SHA1-RC4-128".
|
||||
|
||||
Disable if PKCS#12 is not used (which will be in most cases).
|
||||
|
||||
config CONFIG_SSL_EXPIRY_TIME
|
||||
int "Session expiry time (in hours)"
|
||||
depends on !CONFIG_SSL_SKELETON_MODE
|
||||
default 24
|
||||
help
|
||||
The time (in hours) before a session expires.
|
||||
|
||||
A longer time means that the expensive parts of a handshake don't
|
||||
need to be run when a client reconnects later.
|
||||
|
||||
The default is 1 day.
|
||||
|
||||
config CONFIG_X509_MAX_CA_CERTS
|
||||
int "Maximum number of certificate authorites"
|
||||
default 4
|
||||
depends on !CONFIG_SSL_SERVER_ONLY && !CONFIG_SSL_SKELETON_MODE
|
||||
help
|
||||
Determines the number of CA's allowed.
|
||||
|
||||
Increase this figure if more trusted sites are allowed. Each
|
||||
certificate adds about 300 bytes (when added).
|
||||
|
||||
The default is to allow four certification authorities.
|
||||
|
||||
config CONFIG_SSL_MAX_CERTS
|
||||
int "Maximum number of chained certificates"
|
||||
default 2
|
||||
help
|
||||
Determines the number of certificates used in a certificate
|
||||
chain. The chain length must be at least 1.
|
||||
|
||||
Increase this figure if more certificates are to be added to the
|
||||
chain. Each certificate adds about 300 bytes (when added).
|
||||
|
||||
The default is to allow one certificate + 1 certificate in the chain
|
||||
(which may be the certificate authority certificate).
|
||||
|
||||
config CONFIG_SSL_CTX_MUTEXING
|
||||
bool "Enable SSL_CTX mutexing"
|
||||
default n
|
||||
help
|
||||
Normally mutexing is not required - each SSL_CTX object can deal with
|
||||
many SSL objects (as long as each SSL_CTX object is using a single
|
||||
thread).
|
||||
|
||||
If the SSL_CTX object is not thread safe e.g. the case where a
|
||||
new thread is created for each SSL object, then mutexing is required.
|
||||
|
||||
Select y when a mutex on the SSL_CTX object is required.
|
||||
|
||||
config CONFIG_USE_DEV_URANDOM
|
||||
bool "Use /dev/urandom"
|
||||
default y
|
||||
depends on !CONFIG_PLATFORM_WIN32
|
||||
help
|
||||
Use /dev/urandom. Otherwise a custom RNG is used.
|
||||
|
||||
This will be the default on most Linux systems.
|
||||
|
||||
config CONFIG_WIN32_USE_CRYPTO_LIB
|
||||
bool "Use Win32 Crypto Library"
|
||||
default y if !CONFIG_VISUAL_STUDIO_6_0
|
||||
default n if CONFIG_VISUAL_STUDIO_6_0
|
||||
depends on CONFIG_PLATFORM_WIN32
|
||||
help
|
||||
Microsoft produce a Crypto API which requires the Platform SDK to be
|
||||
installed. It's used for the RNG.
|
||||
|
||||
This will be the default on most Win32 systems. If using Visual Studio
|
||||
6.0, then the SDK containing the crypto libraries must be used.
|
||||
|
||||
config CONFIG_OPENSSL_COMPATIBLE
|
||||
bool "Enable openssl API compatibility"
|
||||
default n
|
||||
help
|
||||
To ease the porting of openssl applications, a subset of the openssl
|
||||
API is wrapped around the axTLS API.
|
||||
|
||||
Note: not all the API is implemented, so parts may still break. And
|
||||
it's definitely not 100% compatible.
|
||||
|
||||
config CONFIG_PERFORMANCE_TESTING
|
||||
bool "Build the bigint performance test tool"
|
||||
default n
|
||||
help
|
||||
Used for performance testing of bigint.
|
||||
|
||||
This is a testing tool and is normally disabled.
|
||||
|
||||
config CONFIG_SSL_TEST
|
||||
bool "Build the SSL testing tool"
|
||||
default n
|
||||
depends on CONFIG_SSL_FULL_MODE
|
||||
help
|
||||
Used for sanity checking the SSL handshaking.
|
||||
|
||||
This is a testing tool and is normally disabled.
|
||||
|
||||
endmenu
|
101
ssl/Makefile
Normal file
101
ssl/Makefile
Normal file
@ -0,0 +1,101 @@
|
||||
#
|
||||
# Copyright(C) 2007 Cameron Rich
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
include ../config/.config
|
||||
include ../config/makefile.conf
|
||||
|
||||
all: libs
|
||||
ifdef CONFIG_PERFORMANCE_TESTING
|
||||
$(MAKE) -C test
|
||||
else
|
||||
ifdef CONFIG_SSL_TEST
|
||||
$(MAKE) -C test
|
||||
endif
|
||||
endif
|
||||
|
||||
ifndef CONFIG_PLATFORM_WIN32
|
||||
TARGET1=../$(STAGE)/libaxtls.a
|
||||
BASETARGET=libaxtls.so
|
||||
ifdef CONFIG_PLATFORM_CYGWIN
|
||||
TARGET2=../$(STAGE)/libaxtls.dll.a
|
||||
else
|
||||
TARGET2=../$(STAGE)/$(LIBMINOR)
|
||||
endif
|
||||
|
||||
# shared library major/minor numbers
|
||||
LIBMAJOR=$(BASETARGET).1
|
||||
LIBMINOR=$(BASETARGET).1.1
|
||||
else
|
||||
TARGET1=axtls.lib
|
||||
TARGET2=../$(STAGE)/axtls.dll
|
||||
STATIC_LIB=../$(STAGE)/axtls.static.lib
|
||||
endif
|
||||
|
||||
libs: $(TARGET1) $(TARGET2)
|
||||
|
||||
OBJ=\
|
||||
aes.o \
|
||||
asn1.o \
|
||||
bigint.o \
|
||||
crypto_misc.o \
|
||||
hmac.o \
|
||||
os_port.o \
|
||||
loader.o \
|
||||
md5.o \
|
||||
openssl.o \
|
||||
p12.o \
|
||||
rsa.o \
|
||||
rc4.o \
|
||||
sha1.o \
|
||||
tls1.o \
|
||||
tls1_svr.o \
|
||||
tls1_clnt.o
|
||||
|
||||
include ../config/makefile.post
|
||||
|
||||
ifndef CONFIG_PLATFORM_WIN32 # Linux/Unix/Cygwin
|
||||
|
||||
$(TARGET1) : $(OBJ)
|
||||
$(AR) -r $@ $(OBJ)
|
||||
|
||||
$(TARGET2) : $(OBJ)
|
||||
ifndef CONFIG_PLATFORM_CYGWIN
|
||||
$(LD) $(LDFLAGS) $(LDSHARED) -Wl,-soname,$(LIBMAJOR) -o ../$(STAGE)/$(LIBMINOR) $(OBJ)
|
||||
cd ../$(STAGE); ln -sf $(LIBMINOR) $(LIBMAJOR); ln -sf $(LIBMAJOR) $(BASETARGET); cd -
|
||||
else
|
||||
$(LD) $(LDFLAGS) $(LDSHARED) -o ../$(STAGE)/cygaxtls.dll \
|
||||
-Wl,--out-implib=../$(STAGE)/libaxtls.dll.a \
|
||||
-Wl,--export-all-symbols \
|
||||
-Wl,--enable-auto-import $(OBJ)
|
||||
endif
|
||||
|
||||
else # Win32
|
||||
|
||||
$(TARGET1) : $(OBJ)
|
||||
$(AR) /out:$@ $(OBJ)
|
||||
|
||||
$(TARGET2) : $(OBJ)
|
||||
cp $(TARGET1) $(STATIC_LIB)
|
||||
$(LD) $(LDFLAGS) $(LDSHARED) /out:$@ $(OBJ)
|
||||
|
||||
endif
|
||||
|
||||
clean::
|
||||
$(MAKE) -C test clean
|
||||
-@rm -f ../$(STAGE)/* *.a *.lib
|
||||
|
444
ssl/aes.c
Normal file
444
ssl/aes.c
Normal file
@ -0,0 +1,444 @@
|
||||
/*
|
||||
* Copyright(C) 2006 Cameron Rich
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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 "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 = (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
|
864
ssl/asn1.c
Normal file
864
ssl/asn1.c
Normal file
@ -0,0 +1,864 @@
|
||||
/*
|
||||
* Copyright(C) 2006 Cameron Rich
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file asn1.c
|
||||
*
|
||||
* Some primitive asn methods for extraction rsa modulus information. It also
|
||||
* is used for retrieving information from X.509 certificates.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include "crypto.h"
|
||||
|
||||
#define SIG_OID_PREFIX_SIZE 8
|
||||
|
||||
#define SIG_TYPE_MD2 0x02
|
||||
#define SIG_TYPE_MD5 0x04
|
||||
#define SIG_TYPE_SHA1 0x05
|
||||
|
||||
/* 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
|
||||
};
|
||||
|
||||
/* CN, O, OU */
|
||||
static const uint8_t g_dn_types[] = { 3, 10, 11 };
|
||||
|
||||
static 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;
|
||||
|
||||
*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, *priv_exp, *pub_exp;
|
||||
int mod_len, priv_len, pub_len;
|
||||
#ifdef CONFIG_BIGINT_CRT
|
||||
uint8_t *p, *q, *dP, *dQ, *qInv;
|
||||
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;
|
||||
}
|
||||
|
||||
/* initialise the RNG */
|
||||
RNG_initialize(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)
|
||||
*/
|
||||
static 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.
|
||||
*/
|
||||
static 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;
|
||||
|
||||
/* some certs have this awful crud in them for some reason */
|
||||
if (buf[*offset] != ASN1_PRINTABLE_STR &&
|
||||
buf[*offset] != ASN1_TELETEX_STR && buf[*offset] != ASN1_IA5_STR)
|
||||
goto end_pnt_str;
|
||||
|
||||
(*offset)++;
|
||||
len = get_asn1_length(buf, offset);
|
||||
*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.
|
||||
*/
|
||||
static int asn1_name(const uint8_t *cert, int *offset, char *dn[])
|
||||
{
|
||||
int ret = X509_NOT_OK;
|
||||
int dn_type;
|
||||
char *tmp = NULL;
|
||||
|
||||
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;
|
||||
|
||||
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.
|
||||
*/
|
||||
static 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, *pub_exp;
|
||||
|
||||
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)++;
|
||||
|
||||
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.
|
||||
*/
|
||||
static 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);
|
||||
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 = 1;
|
||||
|
||||
if ((dn1 && dn2 == NULL) || (dn1 == NULL && dn2)) goto err_no_match;
|
||||
|
||||
ret = (dn1 && dn2) ? strcmp(dn1, dn2) : 0;
|
||||
|
||||
err_no_match:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up all of the CA certificates.
|
||||
*/
|
||||
void remove_ca_certs(CA_CERT_CTX *ca_cert_ctx)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
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
|
||||
*/
|
||||
static 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 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the signature from a certificate.
|
||||
*/
|
||||
const uint8_t *x509_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
|
||||
|
||||
/**
|
||||
* Read the signature type of the certificate. We only support RSA-MD5 and
|
||||
* RSA-SHA1 signature types.
|
||||
*/
|
||||
static 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 (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;
|
||||
if (asn1_skip_obj(cert, offset, ASN1_NULL))
|
||||
goto end_check_sig;
|
||||
ret = X509_OK;
|
||||
|
||||
end_check_sig:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 (either SHA1 or MD5) */
|
||||
if (x509_ctx->sig_type == SIG_TYPE_MD5)
|
||||
{
|
||||
MD5_CTX md5_ctx;
|
||||
uint8_t md5_dgst[MD5_SIZE];
|
||||
MD5Init(&md5_ctx);
|
||||
MD5Update(&md5_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
|
||||
MD5Final(&md5_ctx, md5_dgst);
|
||||
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];
|
||||
SHA1Init(&sha_ctx);
|
||||
SHA1Update(&sha_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
|
||||
SHA1Final(&sha_ctx, sha_dgst);
|
||||
x509_ctx->digest = bi_import(bi_ctx, sha_dgst, SHA1_SIZE);
|
||||
}
|
||||
|
||||
offset = end_tbs; /* skip the v3 data */
|
||||
if (asn1_skip_obj(cert, &offset, ASN1_SEQUENCE) ||
|
||||
asn1_signature(cert, &offset, x509_ctx))
|
||||
goto end_cert;
|
||||
#endif
|
||||
|
||||
if (len)
|
||||
{
|
||||
*len = cert_size;
|
||||
}
|
||||
|
||||
ret = X509_OK;
|
||||
end_cert:
|
||||
|
||||
#ifdef CONFIG_SSL_FULL_MODE
|
||||
if (ret)
|
||||
{
|
||||
printf("Error: Invalid X509 ASN.1 file\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
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);
|
||||
}
|
||||
#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
|
||||
/**
|
||||
* Do some basic checks on the certificate chain.
|
||||
*
|
||||
* Certificate verification consists of a number of checks:
|
||||
* - A root certificate exists in the certificate store.
|
||||
* - The date of the certificate is after the start date.
|
||||
* - The date of the certificate is before the finish date.
|
||||
* - The certificate chain is valid.
|
||||
* - That the certificate(s) are not self-signed.
|
||||
* - 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;
|
||||
bigint *mod, *expn;
|
||||
struct timeval tv;
|
||||
int match_ca_cert = 0;
|
||||
|
||||
if (cert == NULL || ca_cert_ctx == NULL)
|
||||
{
|
||||
ret = X509_VFY_ERROR_NO_TRUSTED_CERT;
|
||||
goto end_verify;
|
||||
}
|
||||
|
||||
/* last cert in the chain - look for a trusted cert */
|
||||
if (cert->next == NULL)
|
||||
{
|
||||
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)
|
||||
{
|
||||
match_ca_cert = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
if (i < CONFIG_X509_MAX_CA_CERTS && ca_cert_ctx->cert[i])
|
||||
{
|
||||
next_cert = ca_cert_ctx->cert[i];
|
||||
}
|
||||
else /* trusted cert not found */
|
||||
{
|
||||
ret = X509_VFY_ERROR_NO_TRUSTED_CERT;
|
||||
goto end_verify;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
next_cert = cert->next;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* check the chain integrity */
|
||||
if (asn1_compare_dn(cert->ca_cert_dn, next_cert->cert_dn))
|
||||
{
|
||||
ret = X509_VFY_ERROR_INVALID_CHAIN;
|
||||
goto end_verify;
|
||||
}
|
||||
|
||||
/* check for self-signing */
|
||||
if (!match_ca_cert && asn1_compare_dn(cert->ca_cert_dn, cert->cert_dn) == 0)
|
||||
{
|
||||
ret = X509_VFY_ERROR_SELF_SIGNED;
|
||||
goto end_verify;
|
||||
}
|
||||
|
||||
/* check the signature */
|
||||
ctx = cert->rsa_ctx->bi_ctx;
|
||||
mod = next_cert->rsa_ctx->m;
|
||||
expn = next_cert->rsa_ctx->e;
|
||||
cert_sig = RSA_sign_verify(ctx, cert->signature, cert->sig_len,
|
||||
bi_clone(ctx, mod), bi_clone(ctx, expn));
|
||||
|
||||
if (cert_sig)
|
||||
{
|
||||
ret = cert->digest ? /* check the signature */
|
||||
bi_compare(cert_sig, cert->digest) :
|
||||
X509_VFY_ERROR_UNSUPPORTED_DIGEST;
|
||||
bi_free(ctx, cert_sig);
|
||||
|
||||
if (ret)
|
||||
goto end_verify;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = X509_VFY_ERROR_BAD_SIGNATURE;
|
||||
goto end_verify;
|
||||
}
|
||||
|
||||
/* go down the certificate chain using recursion. */
|
||||
if (ret == 0 && cert->next)
|
||||
{
|
||||
ret = x509_verify(ca_cert_ctx, next_cert);
|
||||
}
|
||||
|
||||
end_verify:
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (CONFIG_SSL_FULL_MODE)
|
||||
/**
|
||||
* Used for diagnostics.
|
||||
*/
|
||||
void x509_print(CA_CERT_CTX *ca_cert_ctx, const X509_CTX *cert)
|
||||
{
|
||||
if (cert == NULL)
|
||||
return;
|
||||
|
||||
printf("---------------- CERT DEBUG ----------------\n");
|
||||
printf("* CA Cert Distinguished Name\n");
|
||||
if (cert->ca_cert_dn[X509_COMMON_NAME])
|
||||
{
|
||||
printf("Common Name (CN):\t%s\n", cert->ca_cert_dn[X509_COMMON_NAME]);
|
||||
}
|
||||
|
||||
if (cert->ca_cert_dn[X509_ORGANIZATION])
|
||||
{
|
||||
printf("Organization (O):\t%s\n", cert->ca_cert_dn[X509_ORGANIZATION]);
|
||||
}
|
||||
|
||||
if (cert->ca_cert_dn[X509_ORGANIZATIONAL_TYPE])
|
||||
{
|
||||
printf("Organizational Unit (OU): %s\n",
|
||||
cert->ca_cert_dn[X509_ORGANIZATIONAL_TYPE]);
|
||||
}
|
||||
|
||||
printf("* Cert Distinguished Name\n");
|
||||
if (cert->cert_dn[X509_COMMON_NAME])
|
||||
{
|
||||
printf("Common Name (CN):\t%s\n", cert->cert_dn[X509_COMMON_NAME]);
|
||||
}
|
||||
|
||||
if (cert->cert_dn[X509_ORGANIZATION])
|
||||
{
|
||||
printf("Organization (O):\t%s\n", cert->cert_dn[X509_ORGANIZATION]);
|
||||
}
|
||||
|
||||
if (cert->cert_dn[X509_ORGANIZATIONAL_TYPE])
|
||||
{
|
||||
printf("Organizational Unit (OU): %s\n",
|
||||
cert->cert_dn[X509_ORGANIZATIONAL_TYPE]);
|
||||
}
|
||||
|
||||
printf("Not Before:\t\t%s", ctime(&cert->not_before));
|
||||
printf("Not After:\t\t%s", ctime(&cert->not_after));
|
||||
printf("RSA bitsize:\t\t%d\n", cert->rsa_ctx->num_octets*8);
|
||||
printf("Sig Type:\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;
|
||||
}
|
||||
|
||||
printf("Verify:\t\t\t");
|
||||
|
||||
if (ca_cert_ctx)
|
||||
{
|
||||
x509_display_error(x509_verify(ca_cert_ctx, cert));
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
#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(ca_cert_ctx, cert->next);
|
||||
}
|
||||
}
|
||||
|
||||
void x509_display_error(int error)
|
||||
{
|
||||
switch (error)
|
||||
{
|
||||
case X509_NOT_OK:
|
||||
printf("X509 not ok");
|
||||
break;
|
||||
|
||||
case X509_VFY_ERROR_NO_TRUSTED_CERT:
|
||||
printf("No trusted cert is available");
|
||||
break;
|
||||
|
||||
case X509_VFY_ERROR_BAD_SIGNATURE:
|
||||
printf("Bad signature");
|
||||
break;
|
||||
|
||||
case X509_VFY_ERROR_NOT_YET_VALID:
|
||||
printf("Cert is not yet valid");
|
||||
break;
|
||||
|
||||
case X509_VFY_ERROR_EXPIRED:
|
||||
printf("Cert has expired");
|
||||
break;
|
||||
|
||||
case X509_VFY_ERROR_SELF_SIGNED:
|
||||
printf("Cert is self-signed");
|
||||
break;
|
||||
|
||||
case X509_VFY_ERROR_INVALID_CHAIN:
|
||||
printf("Chain is invalid (check order of certs)");
|
||||
break;
|
||||
|
||||
case X509_VFY_ERROR_UNSUPPORTED_DIGEST:
|
||||
printf("Unsupported digest");
|
||||
break;
|
||||
|
||||
case X509_INVALID_PRIV_KEY:
|
||||
printf("Invalid private key");
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_SSL_FULL_MODE */
|
||||
|
1506
ssl/bigint.c
Normal file
1506
ssl/bigint.c
Normal file
File diff suppressed because it is too large
Load Diff
93
ssl/bigint.h
Normal file
93
ssl/bigint.h
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright(C) 2006 Cameron Rich
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef BIGINT_HEADER
|
||||
#define BIGINT_HEADER
|
||||
|
||||
#include "config.h"
|
||||
|
||||
/* 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
|
||||
|
||||
#include "os_port.h"
|
||||
#include "bigint_impl.h"
|
||||
|
||||
#ifndef CONFIG_BIGINT_CHECK_ON
|
||||
#define check(A) /**< disappears in normal production mode */
|
||||
#endif
|
||||
BI_CTX *bi_initialize(void);
|
||||
void bi_terminate(BI_CTX *ctx);
|
||||
void bi_permanent(bigint *bi);
|
||||
void bi_depermanent(bigint *bi);
|
||||
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
|
||||
|
||||
#endif
|
105
ssl/bigint_impl.h
Normal file
105
ssl/bigint_impl.h
Normal file
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright(C) 2006 Cameron Rich
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#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 */
|
||||
#ifdef WIN32
|
||||
#define COMP_RADIX 4294967296i64
|
||||
#define COMP_BIG_MSB 0x8000000000000000i64
|
||||
#else
|
||||
#define COMP_RADIX 4294967296ULL /**< Max component + 1 */
|
||||
#define COMP_BIG_MSB 0x8000000000000000ULL /**< (Max dbl comp + 1)/ 2 */
|
||||
#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. */
|
||||
|
||||
/**
|
||||
* @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. */
|
||||
|
||||
#define V1 v->comps[v->size-1] /**< v1 for division */
|
||||
#define V2 v->comps[v->size-2] /**< v2 for division */
|
||||
#define U(j) tmp_u->comps[tmp_u->size-j-1] /**< uj for division */
|
||||
#define Q(j) quotient->comps[quotient->size-j-1] /**< qj for division */
|
||||
|
||||
#endif
|
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, 0xf1,
|
||||
0xc3, 0x87, 0xc0, 0xd4, 0xf4, 0x57, 0xc3, 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, 0x30, 0x36, 0x30, 0x36,
|
||||
0x30, 0x37, 0x31, 0x31, 0x34, 0x34, 0x33, 0x32, 0x5a, 0x17, 0x0d, 0x33,
|
||||
0x33, 0x31, 0x30, 0x32, 0x33, 0x31, 0x31, 0x34, 0x34, 0x33, 0x32, 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, 0xd8, 0xe0, 0xbf, 0x15, 0xde, 0xea, 0xaf, 0xe8, 0xd5,
|
||||
0xfd, 0x0b, 0xa8, 0xa8, 0xb3, 0xd7, 0x46, 0x5d, 0xa7, 0x26, 0x6c, 0x0c,
|
||||
0xb5, 0xd9, 0xbc, 0xc6, 0xf8, 0xc0, 0x78, 0xd0, 0xf6, 0x56, 0x65, 0xf8,
|
||||
0x29, 0x48, 0x0e, 0x7b, 0x0b, 0xa6, 0x25, 0x7e, 0xe8, 0x7b, 0x79, 0x6f,
|
||||
0x38, 0xe5, 0xb5, 0xb7, 0xf4, 0xe0, 0x9c, 0x91, 0x60, 0xf4, 0x06, 0xf3,
|
||||
0x40, 0x1e, 0xf9, 0x91, 0x19, 0xa9, 0x2f, 0x47, 0x43, 0xb5, 0x9b, 0x1e,
|
||||
0xdc, 0xf6, 0xaa, 0x1c, 0x49, 0x79, 0x21, 0x28, 0xcb, 0xaa, 0x49, 0x73,
|
||||
0xd9, 0x09, 0x05, 0x4c, 0x02, 0xf2, 0x4c, 0x4d, 0x6c, 0x1c, 0x80, 0xa7,
|
||||
0x14, 0x91, 0x44, 0xfc, 0x12, 0xb3, 0xe1, 0xe7, 0xe3, 0x4f, 0x44, 0xba,
|
||||
0x8c, 0xc3, 0x74, 0x39, 0xe8, 0x4c, 0xd0, 0xd4, 0x4c, 0x24, 0x61, 0xb4,
|
||||
0x40, 0x95, 0x8c, 0xc0, 0x0a, 0xb7, 0x02, 0x39, 0x31, 0x85, 0x93, 0x02,
|
||||
0x03, 0x01, 0x00, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
|
||||
0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x0b,
|
||||
0x47, 0x24, 0x52, 0x7d, 0xb6, 0x63, 0x78, 0xbc, 0x80, 0xdd, 0x87, 0x6c,
|
||||
0x90, 0x4c, 0x33, 0xc3, 0x5c, 0xa7, 0x97, 0x09, 0x1c, 0x09, 0x4f, 0x9b,
|
||||
0x6e, 0xb3, 0x5a, 0x3e, 0x46, 0x92, 0x1a, 0xc7, 0x87, 0x15, 0x59, 0xe1,
|
||||
0x88, 0x5c, 0xce, 0x6a, 0xe2, 0x96, 0xaa, 0x32, 0xec, 0xc2, 0xed, 0x78,
|
||||
0x8b, 0xe0, 0x90, 0x66, 0x93, 0x14, 0xc3, 0x98, 0xab, 0x33, 0x35, 0xd3,
|
||||
0x7d, 0x5d, 0x51, 0x0a, 0x9c, 0xb9, 0x10, 0x58, 0x47, 0x7a, 0x98, 0x95,
|
||||
0x64, 0xff, 0x4c, 0x5d, 0x82, 0x19, 0xf9, 0xea, 0x0f, 0x5e, 0x9a, 0xcb,
|
||||
0x32, 0x27, 0x64, 0xca, 0x6f, 0x58, 0x8a, 0xd0, 0xc0, 0x36, 0xf4, 0xb9,
|
||||
0x63, 0x34, 0xa5, 0xda, 0x36, 0x50, 0x36, 0x49, 0xd2, 0xb7, 0x3a, 0x21,
|
||||
0x33, 0x5b, 0x3e, 0xd6, 0x5f, 0x0c, 0x99, 0x83, 0xb7, 0xb2, 0xf7, 0x8b,
|
||||
0x44, 0xc4, 0x5e, 0x73, 0x41, 0xa9, 0x02
|
||||
};
|
||||
unsigned int default_certificate_len = 475;
|
285
ssl/crypto.h
Normal file
285
ssl/crypto.h
Normal file
@ -0,0 +1,285 @@
|
||||
/*
|
||||
* Copyright(C) 2006 Cameron Rich
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file crypto.h
|
||||
*/
|
||||
|
||||
#ifndef HEADER_CRYPTO_H
|
||||
#define HEADER_CRYPTO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "bigint.h"
|
||||
|
||||
/**************************************************************************
|
||||
* 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
|
||||
{
|
||||
int 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 SHA1Init(SHA1_CTX *);
|
||||
void SHA1Update(SHA1_CTX *, const uint8_t * msg, int len);
|
||||
void SHA1Final(SHA1_CTX *, uint8_t *digest);
|
||||
|
||||
/**************************************************************************
|
||||
* MD5 declarations
|
||||
**************************************************************************/
|
||||
|
||||
/* MD5 context. */
|
||||
|
||||
#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 MD5Init(MD5_CTX *);
|
||||
EXP_FUNC void STDCALL MD5Update(MD5_CTX *, const uint8_t *msg, int len);
|
||||
EXP_FUNC void STDCALL MD5Final(MD5_CTX *, uint8_t *digest);
|
||||
|
||||
/**************************************************************************
|
||||
* 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);
|
||||
|
||||
/**************************************************************************
|
||||
* RNG declarations
|
||||
**************************************************************************/
|
||||
EXP_FUNC void STDCALL RNG_initialize(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);
|
||||
|
||||
/**************************************************************************
|
||||
* 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);
|
||||
#ifdef CONFIG_SSL_CERT_VERIFICATION
|
||||
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
|
||||
|
||||
/**************************************************************************
|
||||
* ASN1 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_TYPE 2
|
||||
|
||||
#define ASN1_INTEGER 0x02
|
||||
#define ASN1_BIT_STRING 0x03
|
||||
#define ASN1_OCTET_STRING 0x04
|
||||
#define ASN1_NULL 0x05
|
||||
#define ASN1_OID 0x06
|
||||
#define ASN1_PRINTABLE_STR 0x13
|
||||
#define ASN1_TELETEX_STR 0x14
|
||||
#define ASN1_IA5_STR 0x16
|
||||
#define ASN1_UTC_TIME 0x17
|
||||
#define ASN1_SEQUENCE 0x30
|
||||
#define ASN1_SET 0x31
|
||||
#define ASN1_IMPLICIT_TAG 0x80
|
||||
#define ASN1_EXPLICIT_TAG 0xa0
|
||||
|
||||
#define SALT_SIZE 8
|
||||
|
||||
struct _x509_ctx
|
||||
{
|
||||
char *ca_cert_dn[X509_NUM_DN_TYPES];
|
||||
char *cert_dn[X509_NUM_DN_TYPES];
|
||||
#if defined(_WIN32_WCE)
|
||||
long not_before;
|
||||
long not_after;
|
||||
#else
|
||||
time_t not_before;
|
||||
time_t not_after;
|
||||
#endif
|
||||
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 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 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);
|
||||
const uint8_t *x509_get_signature(const uint8_t *asn1_signature, int *len);
|
||||
#endif
|
||||
#ifdef CONFIG_SSL_FULL_MODE
|
||||
void x509_print(CA_CERT_CTX *ca_cert_ctx, const X509_CTX *cert);
|
||||
void x509_display_error(int error);
|
||||
#endif
|
||||
|
||||
/**************************************************************************
|
||||
* MISC declarations
|
||||
**************************************************************************/
|
||||
|
||||
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
|
345
ssl/crypto_misc.c
Normal file
345
ssl/crypto_misc.c
Normal file
@ -0,0 +1,345 @@
|
||||
/*
|
||||
* Copyright(C) 2006 Cameron Rich
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* Some misc. routines to help things out
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include "crypto.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))
|
||||
static uint64_t rng_num;
|
||||
#endif
|
||||
|
||||
static int rng_ref_count;
|
||||
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(const uint8_t *seed_buf, int size)
|
||||
{
|
||||
if (rng_ref_count == 0)
|
||||
{
|
||||
#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
|
||||
/* help seed with the user's private key - this is a number that
|
||||
should be hard to find, due to the fact that it relies on knowing
|
||||
the private key */
|
||||
int i;
|
||||
|
||||
for (i = 0; i < size/(int)sizeof(uint64_t); i++)
|
||||
rng_num ^= *((uint64_t *)&seed_buf[i*sizeof(uint64_t)]);
|
||||
|
||||
srand((long)seed_buf); /* use the stack ptr as another rnd seed */
|
||||
#endif
|
||||
}
|
||||
|
||||
rng_ref_count++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Terminate the RNG engine.
|
||||
*/
|
||||
EXP_FUNC void STDCALL RNG_terminate(void)
|
||||
{
|
||||
if (--rng_ref_count == 0)
|
||||
{
|
||||
#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;
|
||||
uint64_t big_num1, big_num2;
|
||||
|
||||
gettimeofday(&tv, NULL); /* yes I know we shouldn't do this */
|
||||
|
||||
/* all numbers by themselves are pretty simple, but combined should
|
||||
* be a challenge */
|
||||
big_num1 = (uint64_t)tv.tv_sec*(tv.tv_usec+1);
|
||||
big_num2 = (uint64_t)rand()*big_num1;
|
||||
big_num1 ^= rng_num;
|
||||
|
||||
memcpy(rand_data, &big_num1, sizeof(uint64_t));
|
||||
if (num_rand_bytes > sizeof(uint64_t))
|
||||
memcpy(&rand_data[8], &big_num2, sizeof(uint64_t));
|
||||
|
||||
if (num_rand_bytes > 16)
|
||||
{
|
||||
/* clear rest of data */
|
||||
memset(&rand_data[16], 0, num_rand_bytes-16);
|
||||
}
|
||||
|
||||
RC4_setup(&rng_ctx, rand_data, 16); /* use as a key */
|
||||
RC4_crypt(&rng_ctx, rand_data, rand_data, num_rand_bytes);
|
||||
|
||||
/* use last 8 bytes for next time */
|
||||
memcpy(&rng_num, &rand_data[num_rand_bytes-8], sizeof(uint64_t));
|
||||
#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;
|
||||
}
|
||||
}
|
||||
|
||||
if (y != 0)
|
||||
goto error;
|
||||
|
||||
if (outlen)
|
||||
*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
|
||||
|
88
ssl/hmac.c
Normal file
88
ssl/hmac.c
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright(C) 2006 Cameron Rich
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* HMAC implementation - This code was originally taken from RFC2104
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "crypto.h"
|
||||
|
||||
/**
|
||||
* Perform HMAC-MD5
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
MD5Init(&context);
|
||||
MD5Update(&context, k_ipad, 64);
|
||||
MD5Update(&context, msg, length);
|
||||
MD5Final(&context, digest);
|
||||
MD5Init(&context);
|
||||
MD5Update(&context, k_opad, 64);
|
||||
MD5Update(&context, digest, MD5_SIZE);
|
||||
MD5Final(&context, digest);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform HMAC-SHA1
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
SHA1Init(&context);
|
||||
SHA1Update(&context, k_ipad, 64);
|
||||
SHA1Update(&context, msg, length);
|
||||
SHA1Final(&context, digest);
|
||||
SHA1Init(&context);
|
||||
SHA1Update(&context, k_opad, 64);
|
||||
SHA1Update(&context, digest, SHA1_SIZE);
|
||||
SHA1Final(&context, digest);
|
||||
}
|
375
ssl/loader.c
Normal file
375
ssl/loader.c
Normal file
@ -0,0 +1,375 @@
|
||||
/*
|
||||
* Copyright(C) 2006 Cameron Rich
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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 "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, 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 (strncmp((char *)ssl_obj->buf, begin, strlen(begin)) == 0)
|
||||
{
|
||||
#ifdef CONFIG_SSL_HAS_PEM
|
||||
ret = ssl_obj_PEM_load(ssl_ctx, 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:
|
||||
ret = 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 3
|
||||
#define IV_SIZE 16
|
||||
#define IS_RSA_PRIVATE_KEY 0
|
||||
#define IS_ENCRYPTED_PRIVATE_KEY 1
|
||||
#define IS_CERTIFICATE 2
|
||||
|
||||
static const char * const begins[NUM_PEM_TYPES] =
|
||||
{
|
||||
"-----BEGIN RSA PRIVATE KEY-----",
|
||||
"-----BEGIN ENCRYPTED PRIVATE KEY-----",
|
||||
"-----BEGIN CERTIFICATE-----",
|
||||
};
|
||||
|
||||
static const char * const ends[NUM_PEM_TYPES] =
|
||||
{
|
||||
"-----END RSA PRIVATE KEY-----",
|
||||
"-----END ENCRYPTED 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)
|
||||
{
|
||||
#ifdef CONFIG_SSL_FULL_MODE
|
||||
printf("Error: need a password for this PEM file\n");
|
||||
#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");
|
||||
#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 */
|
||||
MD5Init(&md5_ctx);
|
||||
MD5Update(&md5_ctx, (const uint8_t *)password, strlen(password));
|
||||
MD5Update(&md5_ctx, iv, SALT_SIZE);
|
||||
MD5Final(&md5_ctx, key);
|
||||
|
||||
if (is_aes_256)
|
||||
{
|
||||
MD5Init(&md5_ctx);
|
||||
MD5Update(&md5_ctx, key, MD5_SIZE);
|
||||
MD5Update(&md5_ctx, (const uint8_t *)password, strlen(password));
|
||||
MD5Update(&md5_ctx, iv, SALT_SIZE);
|
||||
MD5Final(&md5_ctx, &key[MD5_SIZE]);
|
||||
}
|
||||
|
||||
/* 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, char *where,
|
||||
int remain, const char *password)
|
||||
{
|
||||
int ret = SSL_OK;
|
||||
SSLObjLoader *ssl_obj = NULL;
|
||||
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-start);
|
||||
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);
|
||||
|
||||
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)
|
||||
goto error;
|
||||
}
|
||||
else if (base64_decode(start, pem_size,
|
||||
ssl_obj->buf, &ssl_obj->len) != 0)
|
||||
goto error;
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case IS_RSA_PRIVATE_KEY:
|
||||
obj_type = SSL_OBJ_RSA_KEY;
|
||||
break;
|
||||
|
||||
case IS_ENCRYPTED_PRIVATE_KEY:
|
||||
obj_type = SSL_OBJ_PKCS8;
|
||||
break;
|
||||
|
||||
case IS_CERTIFICATE:
|
||||
obj_type = SSL_OBJ_X509_CERT;
|
||||
break;
|
||||
|
||||
default:
|
||||
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--;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == NUM_PEM_TYPES)
|
||||
goto error;
|
||||
|
||||
/* more PEM stuff to process? */
|
||||
if (remain)
|
||||
ret = new_pem_obj(ssl_ctx, end, remain, password);
|
||||
|
||||
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, 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, start, ssl_obj->len, password);
|
||||
}
|
||||
#endif /* CONFIG_SSL_HAS_PEM */
|
281
ssl/md5.c
Normal file
281
ssl/md5.c
Normal file
@ -0,0 +1,281 @@
|
||||
/*
|
||||
* Copyright(C) 2006 Cameron Rich
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* This file implements the MD5 algorithm as defined in RFC1321
|
||||
*/
|
||||
|
||||
#include <string.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 MD5Init(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 MD5Update(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 MD5Final(MD5_CTX *ctx, uint8_t *digest)
|
||||
{
|
||||
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);
|
||||
MD5Update(ctx, PADDING, padLen);
|
||||
|
||||
/* Append length (before padding) */
|
||||
MD5Update(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);
|
||||
}
|
209
ssl/openssl.c
Normal file
209
ssl/openssl.c
Normal file
@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Copyright(C) 2007 Cameron Rich
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Lesser License
|
||||
* along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 "ssl.h"
|
||||
|
||||
#define OPENSSL_CTX_ATTR ((OPENSSL_CTX *)ssl_ctx->bonus_attr)
|
||||
|
||||
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, NULL) == 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);
|
||||
}
|
||||
|
||||
#if 0
|
||||
const uint8_t *SSL_get_session(const SSL *ssl)
|
||||
{
|
||||
/* TODO: return SSL_SESSION type */
|
||||
return ssl_get_session_id(ssl);
|
||||
}
|
||||
#endif
|
||||
|
||||
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) {}
|
||||
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); }
|
||||
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
|
142
ssl/os_port.c
Normal file
142
ssl/os_port.c
Normal file
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright(C) 2006 Cameron Rich
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @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);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#undef malloc
|
||||
#undef realloc
|
||||
#undef calloc
|
||||
#undef open
|
||||
#undef fopen
|
||||
|
||||
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 FILE * STDCALL ax_fopen(const char *pathname, const char *type)
|
||||
{
|
||||
FILE *f;
|
||||
|
||||
if ((f = fopen(pathname, type)) == NULL)
|
||||
exit_now(file_open_str, pathname);
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
166
ssl/os_port.h
Normal file
166
ssl/os_port.h
Normal file
@ -0,0 +1,166 @@
|
||||
/*
|
||||
* Copyright(C) 2006 Cameron Rich
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @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 <stdio.h>
|
||||
|
||||
#if defined(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
|
||||
|
||||
#ifdef 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)
|
||||
#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")
|
||||
|
||||
#ifdef CONFIG_WIN32_USE_CRYPTO_LIB
|
||||
#pragma comment(lib, "AdvAPI32.lib")
|
||||
#endif
|
||||
|
||||
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;
|
||||
|
||||
EXP_FUNC void STDCALL gettimeofday(struct timeval* t,void* timezone);
|
||||
EXP_FUNC int STDCALL strcasecmp(const char *s1, const char *s2);
|
||||
|
||||
#else /* Not Win32 */
|
||||
|
||||
#ifdef CONFIG_PLATFORM_SOLARIS
|
||||
#include <inttypes.h>
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif /* Not Solaris */
|
||||
|
||||
#include <unistd.h>
|
||||
#include <pwd.h>
|
||||
#include <netdb.h>
|
||||
#include <dirent.h>
|
||||
#include <fcntl.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) close(A)
|
||||
#define TTY_FLUSH()
|
||||
|
||||
#endif /* Not Win32 */
|
||||
|
||||
/* some functions to mutate the way these work */
|
||||
#define malloc(A) ax_malloc(A)
|
||||
#define realloc(A,B) ax_realloc(A,B)
|
||||
#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 FILE * STDCALL ax_fopen(const char *name, const char *type);
|
||||
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
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
474
ssl/p12.c
Normal file
474
ssl/p12.c
Normal file
@ -0,0 +1,474 @@
|
||||
/*
|
||||
* Copyright(C) 2006 Cameron Rich
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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 "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 */
|
||||
SHA1Init(&sha_ctx);
|
||||
SHA1Update(&sha_ctx, d, sizeof(d));
|
||||
SHA1Update(&sha_ctx, p, sizeof(p));
|
||||
SHA1Final(&sha_ctx, Ai);
|
||||
|
||||
for (i = 1; i < iter; i++)
|
||||
{
|
||||
SHA1Init(&sha_ctx);
|
||||
SHA1Update(&sha_ctx, Ai, SHA1_SIZE);
|
||||
SHA1Final(&sha_ctx, Ai);
|
||||
}
|
||||
|
||||
/* 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 all_ok = 0, 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;
|
||||
int error_code = SSL_ERROR_NOT_SUPPORTED;
|
||||
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)
|
||||
{
|
||||
error_code = 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))
|
||||
{
|
||||
error_code = SSL_ERROR_INVALID_HMAC;
|
||||
goto error;
|
||||
}
|
||||
|
||||
all_ok = 1;
|
||||
|
||||
error:
|
||||
free(version);
|
||||
free(uni_pass);
|
||||
free(auth_safes);
|
||||
return all_ok ? SSL_OK : error_code;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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, 0xd8,
|
||||
0xe0, 0xbf, 0x15, 0xde, 0xea, 0xaf, 0xe8, 0xd5, 0xfd, 0x0b, 0xa8, 0xa8,
|
||||
0xb3, 0xd7, 0x46, 0x5d, 0xa7, 0x26, 0x6c, 0x0c, 0xb5, 0xd9, 0xbc, 0xc6,
|
||||
0xf8, 0xc0, 0x78, 0xd0, 0xf6, 0x56, 0x65, 0xf8, 0x29, 0x48, 0x0e, 0x7b,
|
||||
0x0b, 0xa6, 0x25, 0x7e, 0xe8, 0x7b, 0x79, 0x6f, 0x38, 0xe5, 0xb5, 0xb7,
|
||||
0xf4, 0xe0, 0x9c, 0x91, 0x60, 0xf4, 0x06, 0xf3, 0x40, 0x1e, 0xf9, 0x91,
|
||||
0x19, 0xa9, 0x2f, 0x47, 0x43, 0xb5, 0x9b, 0x1e, 0xdc, 0xf6, 0xaa, 0x1c,
|
||||
0x49, 0x79, 0x21, 0x28, 0xcb, 0xaa, 0x49, 0x73, 0xd9, 0x09, 0x05, 0x4c,
|
||||
0x02, 0xf2, 0x4c, 0x4d, 0x6c, 0x1c, 0x80, 0xa7, 0x14, 0x91, 0x44, 0xfc,
|
||||
0x12, 0xb3, 0xe1, 0xe7, 0xe3, 0x4f, 0x44, 0xba, 0x8c, 0xc3, 0x74, 0x39,
|
||||
0xe8, 0x4c, 0xd0, 0xd4, 0x4c, 0x24, 0x61, 0xb4, 0x40, 0x95, 0x8c, 0xc0,
|
||||
0x0a, 0xb7, 0x02, 0x39, 0x31, 0x85, 0x93, 0x02, 0x03, 0x01, 0x00, 0x01,
|
||||
0x02, 0x81, 0x81, 0x00, 0x94, 0x07, 0x72, 0xe5, 0xbe, 0xad, 0x79, 0x3b,
|
||||
0xf7, 0x33, 0x2c, 0x8e, 0x05, 0xf8, 0x1a, 0x6b, 0xd0, 0xe8, 0x91, 0xf5,
|
||||
0x16, 0x07, 0xd9, 0x82, 0x5c, 0x5c, 0xd5, 0x22, 0xa1, 0x9e, 0x42, 0x02,
|
||||
0x7f, 0x8b, 0xcd, 0xbe, 0xf4, 0x85, 0x52, 0xf6, 0x2c, 0xd5, 0x09, 0xd2,
|
||||
0x2c, 0xf4, 0x2c, 0xf6, 0x07, 0x85, 0x80, 0xf9, 0xdc, 0xd0, 0xcc, 0x3f,
|
||||
0x22, 0x31, 0x15, 0xf3, 0x49, 0xf2, 0xb5, 0xe2, 0x69, 0x99, 0x04, 0x04,
|
||||
0x49, 0x21, 0xdb, 0x9f, 0xa1, 0x54, 0x5a, 0xfa, 0xe4, 0xd9, 0xf9, 0x07,
|
||||
0x05, 0xff, 0x9a, 0x65, 0xa4, 0xeb, 0xf2, 0x47, 0xce, 0x56, 0xc7, 0x72,
|
||||
0x49, 0x48, 0x5c, 0xe8, 0x14, 0xd7, 0x8f, 0x25, 0xcc, 0x49, 0x29, 0x06,
|
||||
0x6a, 0x54, 0x7b, 0x17, 0xdc, 0x9e, 0xd4, 0x53, 0xf0, 0xf5, 0x9e, 0x85,
|
||||
0x25, 0xa1, 0xeb, 0x3d, 0xe9, 0x2f, 0xb9, 0x9c, 0xf6, 0xe1, 0x80, 0x81,
|
||||
0x02, 0x41, 0x00, 0xee, 0x02, 0x78, 0xc7, 0x78, 0x85, 0x04, 0x97, 0xcc,
|
||||
0x36, 0xbd, 0xd6, 0x11, 0xe2, 0xc7, 0x39, 0xd9, 0x34, 0x51, 0x72, 0x6f,
|
||||
0x8a, 0x0f, 0xcd, 0x88, 0x32, 0x33, 0x9b, 0xc7, 0xa7, 0x03, 0x77, 0xd9,
|
||||
0x82, 0x35, 0xb6, 0xdd, 0x1f, 0xc2, 0xc1, 0x13, 0x40, 0x83, 0x55, 0xeb,
|
||||
0x60, 0xeb, 0x81, 0x8e, 0x0c, 0x16, 0x62, 0xb4, 0xb4, 0x3c, 0xeb, 0x08,
|
||||
0x80, 0x9c, 0x79, 0xd3, 0x38, 0xca, 0xf1, 0x02, 0x41, 0x00, 0xe9, 0x45,
|
||||
0x5f, 0x2e, 0x16, 0xcc, 0x93, 0x50, 0x40, 0xb6, 0x79, 0xbc, 0x38, 0xe0,
|
||||
0x56, 0x68, 0x50, 0xd3, 0x2f, 0x73, 0x8c, 0x8c, 0x2a, 0x0e, 0x81, 0x4a,
|
||||
0x8a, 0xbb, 0xcc, 0xf0, 0x64, 0x34, 0x46, 0x9f, 0x07, 0x7d, 0x22, 0xb6,
|
||||
0xf9, 0x46, 0xac, 0x57, 0x23, 0x8c, 0x1e, 0xeb, 0xd3, 0x05, 0x4d, 0xa8,
|
||||
0x83, 0x6a, 0x67, 0xf6, 0xa6, 0xb1, 0xab, 0x8e, 0xc1, 0xef, 0xef, 0x7d,
|
||||
0xf0, 0xc3, 0x02, 0x40, 0x2f, 0xc6, 0x59, 0x3e, 0x18, 0xe8, 0x02, 0x73,
|
||||
0x01, 0xef, 0xdf, 0x0d, 0x30, 0x4b, 0xe8, 0x17, 0xa9, 0x8c, 0xc1, 0xe8,
|
||||
0x89, 0x91, 0x19, 0xf8, 0xf4, 0xa4, 0xb7, 0x0d, 0x46, 0xf7, 0x34, 0x50,
|
||||
0x03, 0x5e, 0x0a, 0xb0, 0x29, 0x14, 0xae, 0x00, 0x19, 0x80, 0x32, 0x9c,
|
||||
0xb5, 0x81, 0x9f, 0xe4, 0x42, 0x82, 0x14, 0xa0, 0x3d, 0x8b, 0x8c, 0x4a,
|
||||
0xd5, 0x4b, 0x13, 0x9d, 0xb4, 0x93, 0x4a, 0xd1, 0x02, 0x40, 0x64, 0x8c,
|
||||
0x83, 0x77, 0x61, 0x5a, 0x73, 0x11, 0x3f, 0xa3, 0xa8, 0x1b, 0x8a, 0xc4,
|
||||
0xa0, 0x5a, 0x3c, 0xa4, 0x9b, 0x2a, 0x8a, 0x65, 0x8c, 0x67, 0x4e, 0x31,
|
||||
0xac, 0x55, 0x41, 0x04, 0x49, 0x9d, 0x02, 0xe7, 0xdf, 0x99, 0x7f, 0xd2,
|
||||
0x30, 0xe6, 0xd6, 0xb8, 0x84, 0xd9, 0x0c, 0x27, 0x08, 0x81, 0x9b, 0xb4,
|
||||
0xcc, 0x58, 0x9c, 0x51, 0x84, 0x0e, 0xc7, 0x6d, 0x34, 0x89, 0x50, 0xc9,
|
||||
0x0f, 0x73, 0x02, 0x41, 0x00, 0xda, 0xde, 0x5e, 0x1a, 0xac, 0x1d, 0x1d,
|
||||
0xd7, 0xb9, 0x65, 0x26, 0x00, 0xf5, 0xd4, 0xe4, 0x28, 0x84, 0x86, 0x2f,
|
||||
0x00, 0x9c, 0x41, 0x00, 0x52, 0xe1, 0x47, 0x91, 0xc0, 0x52, 0x05, 0x4e,
|
||||
0x0f, 0x2f, 0x0d, 0xca, 0x9b, 0x3d, 0x89, 0x41, 0xbf, 0xee, 0x9f, 0xa1,
|
||||
0xe6, 0x9d, 0xa4, 0xeb, 0x45, 0x7f, 0xe3, 0xcb, 0xa4, 0x6b, 0x0a, 0xe2,
|
||||
0x7e, 0xb0, 0x87, 0x5c, 0x40, 0xb1, 0x51, 0x11, 0x1d
|
||||
};
|
||||
unsigned int default_private_key_len = 609;
|
78
ssl/rc4.c
Normal file
78
ssl/rc4.c
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright(C) 2006 Cameron Rich
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* An implementation of the RC4/ARC4 algorithm.
|
||||
* Originally written by Christophe Devine.
|
||||
*/
|
||||
|
||||
#include <string.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, *m, a;
|
||||
|
||||
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).
|
||||
*/
|
||||
void RC4_crypt(RC4_CTX *ctx, const uint8_t *msg, uint8_t *out, int length)
|
||||
{
|
||||
int i, x, y, *m, a, b;
|
||||
out = (uint8_t *)msg;
|
||||
|
||||
x = ctx->x;
|
||||
y = ctx->y;
|
||||
m = ctx->m;
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
x = (uint8_t)(x + 1);
|
||||
a = m[x];
|
||||
y = (uint8_t)(y + a);
|
||||
m[x] = b = m[y];
|
||||
m[y] = a;
|
||||
out[i] ^= m[(uint8_t)(a + b)];
|
||||
}
|
||||
|
||||
ctx->x = x;
|
||||
ctx->y = y;
|
||||
}
|
330
ssl/rsa.c
Normal file
330
ssl/rsa.c
Normal file
@ -0,0 +1,330 @@
|
||||
/*
|
||||
* Copyright(C) 2006 Cameron Rich
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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 "crypto.h"
|
||||
|
||||
#ifdef CONFIG_BIGINT_CRT
|
||||
static bigint *bi_crt(const RSA_CTX *rsa, bigint *bi);
|
||||
#endif
|
||||
|
||||
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 = 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 & 0xFFF0);
|
||||
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)
|
||||
{
|
||||
int byte_size = ctx->num_octets;
|
||||
uint8_t *block;
|
||||
int i, size;
|
||||
bigint *decrypted_bi, *dat_bi;
|
||||
|
||||
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 */
|
||||
block = (uint8_t *)malloc(byte_size);
|
||||
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);
|
||||
|
||||
free(block);
|
||||
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_msg);
|
||||
#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_BIGINT_CRT
|
||||
/**
|
||||
* Use the Chinese Remainder Theorem to quickly perform RSA decrypts.
|
||||
* This should really be in bigint.c (and was at one stage), but needs
|
||||
* access to the RSA_CTX context...
|
||||
*/
|
||||
static bigint *bi_crt(const RSA_CTX *rsa, bigint *bi)
|
||||
{
|
||||
BI_CTX *ctx = rsa->bi_ctx;
|
||||
bigint *m1, *m2, *h;
|
||||
|
||||
/* Montgomery has a condition the 0 < x, y < m and these products violate
|
||||
* that condition. So disable Montgomery when using CRT */
|
||||
#if defined(CONFIG_BIGINT_MONTGOMERY)
|
||||
ctx->use_classical = 1;
|
||||
#endif
|
||||
ctx->mod_offset = BIGINT_P_OFFSET;
|
||||
m1 = bi_mod_power(ctx, bi_copy(bi), rsa->dP);
|
||||
|
||||
ctx->mod_offset = BIGINT_Q_OFFSET;
|
||||
m2 = bi_mod_power(ctx, bi, rsa->dQ);
|
||||
|
||||
h = bi_subtract(ctx, bi_add(ctx, m1, rsa->p), bi_copy(m2), NULL);
|
||||
h = bi_multiply(ctx, h, rsa->qInv);
|
||||
ctx->mod_offset = BIGINT_P_OFFSET;
|
||||
h = bi_residue(ctx, h);
|
||||
#if defined(CONFIG_BIGINT_MONTGOMERY)
|
||||
ctx->use_classical = 0; /* reset for any further operation */
|
||||
#endif
|
||||
return bi_add(ctx, m2, bi_multiply(ctx, rsa->q, h));
|
||||
}
|
||||
#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
|
||||
|
||||
#ifdef CONFIG_SSL_CERT_VERIFICATION
|
||||
/**
|
||||
* 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);
|
||||
return byte_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Take a signature and decrypt it.
|
||||
*/
|
||||
bigint *RSA_sign_verify(BI_CTX *ctx, const uint8_t *sig, int sig_len,
|
||||
bigint *modulus, bigint *pub_exp)
|
||||
{
|
||||
uint8_t *block;
|
||||
int i, size;
|
||||
bigint *decrypted_bi, *dat_bi;
|
||||
bigint *bir = NULL;
|
||||
|
||||
block = (uint8_t *)malloc(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 = x509_get_signature(&block[i], &len);
|
||||
|
||||
if (sig_ptr)
|
||||
{
|
||||
bir = bi_import(ctx, sig_ptr, len);
|
||||
}
|
||||
}
|
||||
|
||||
free(block);
|
||||
return bir;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_SSL_CERT_VERIFICATION */
|
236
ssl/sha1.c
Normal file
236
ssl/sha1.c
Normal file
@ -0,0 +1,236 @@
|
||||
/*
|
||||
* Copyright(C) 2006 Cameron Rich
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* SHA1 implementation - as defined in FIPS PUB 180-1 published April 17, 1995.
|
||||
* This code was originally taken from RFC3174
|
||||
*/
|
||||
|
||||
#include <string.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 SHA1Init(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 SHA1Update(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 SHA1Final(SHA1_CTX *ctx, uint8_t *digest)
|
||||
{
|
||||
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);
|
||||
}
|
429
ssl/ssl.h
Normal file
429
ssl/ssl.h
Normal file
@ -0,0 +1,429 @@
|
||||
/*
|
||||
* Copyright(C) 2006 Cameron Rich
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @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 and Perl.
|
||||
* - Partial openssl API compatibility (via a wrapper).
|
||||
* - A very small footprint for a HTTPS server (around 60-70kB 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>
|
||||
#include "crypto.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
|
||||
|
||||
/* errors that can be generated */
|
||||
#define SSL_OK 0
|
||||
#define SSL_NOT_OK -1
|
||||
#define SSL_ERROR_DEAD -2
|
||||
#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_NOT_SUPPORTED -274
|
||||
#define SSL_X509_OFFSET -512
|
||||
#define SSL_X509_ERROR(A) (SSL_X509_OFFSET+A)
|
||||
|
||||
/* 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
|
||||
|
||||
/* 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_NO_DEFAULT_KEY: Don't use the default key/certificate. The user will
|
||||
* load the key/certificate explicitly.
|
||||
* - 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.
|
||||
*
|
||||
* @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 blocking call - it will finish when the handshake is complete (or
|
||||
* has failed).
|
||||
* @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.
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* @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.
|
||||
* The socket must be in blocking mode.
|
||||
* @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.
|
||||
* The socket must be in blocking mode.
|
||||
* @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 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.
|
||||
*
|
||||
* A full handshake needs to occur for this call to work properly.
|
||||
*
|
||||
* @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 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);
|
||||
|
||||
/**
|
||||
* @brief Return the axTLS library version as a string.
|
||||
* @note New API function for v1.1
|
||||
*/
|
||||
EXP_FUNC const char * STDCALL ssl_version(void);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
65
ssl/test/Makefile
Normal file
65
ssl/test/Makefile
Normal file
@ -0,0 +1,65 @@
|
||||
#
|
||||
# Copyright(C) 2006 Cameron Rich
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
all:
|
||||
|
||||
include ../../config/.config
|
||||
include ../../config/makefile.conf
|
||||
|
||||
ifdef CONFIG_PERFORMANCE_TESTING
|
||||
all: performance
|
||||
endif
|
||||
|
||||
ifdef CONFIG_SSL_TEST
|
||||
all: ssltesting
|
||||
endif
|
||||
|
||||
ifndef CONFIG_PLATFORM_WIN32
|
||||
performance: ../../$(STAGE)/perf_bigint
|
||||
ssltesting: ../../$(STAGE)/ssltest
|
||||
LIBS=../../$(STAGE)
|
||||
CFLAGS += -I../../ssl -I../../config
|
||||
|
||||
../../$(STAGE)/perf_bigint: perf_bigint.o $(LIBS)/libaxtls.a
|
||||
$(CC) $(LDFLAGS) -o $@ $^ -L $(LIBS) -laxtls
|
||||
|
||||
../../$(STAGE)/ssltest: ssltest.o $(LIBS)/libaxtls.a
|
||||
$(CC) $(LDFLAGS) -o $@ $^ -lpthread -L $(LIBS) -laxtls
|
||||
else
|
||||
performance: ../../$(STAGE)/perf_bigint.exe
|
||||
ssltesting: ../../$(STAGE)/ssltest.exe
|
||||
CFLAGS += /I".." /I"../../config"
|
||||
|
||||
%.obj : %.c
|
||||
$(CC) $(CFLAGS) $<
|
||||
|
||||
OBJLIST=..\aes.obj ..\asn1.obj ..\bigint.obj ..\crypto_misc.obj ..\hmac.obj \
|
||||
..\md5.obj ..\loader.obj ..\p12.obj ..\os_port.obj ..\rc4.obj \
|
||||
..\rsa.obj ..\sha1.obj ..\tls1.obj ..\tls1_clnt.obj ..\tls1_svr.obj
|
||||
|
||||
../../$(STAGE)/perf_bigint.exe: perf_bigint.obj $(OBJLIST)
|
||||
$(LD) $(LDFLAGS) /out:$@ $^
|
||||
|
||||
../../$(STAGE)/ssltest.exe: ssltest.obj $(OBJLIST)
|
||||
$(LD) $(LDFLAGS) /out:$@ $^
|
||||
endif
|
||||
|
||||
clean::
|
||||
-@rm -f ../../$(STAGE)/perf_bigint* ../../$(STAGE)/ssltest*
|
||||
|
||||
include ../../config/makefile.post
|
15
ssl/test/axTLS.ca_key.pem
Normal file
15
ssl/test/axTLS.ca_key.pem
Normal file
@ -0,0 +1,15 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICWwIBAAKBgQCnZdk20fYWh8O6kDTt0AuJWyp0YIrb7W1UNNMPXI5wA4J59IVj
|
||||
Nmk5wocm9+Hqzbg7rORAN/mHPBhzLAjhnm1HODs36hW15DtbDkkH4wCM/Tsyv79m
|
||||
n0xq1V6peK3t9vi2D4p/IRjHkYR2jm+BeknopijhY0kHHfpGTHa2DnVirwIDAQAB
|
||||
AoGAd4Ia5SxYiBU9A0BYyT8yPUm8sYELIaAL4YYk+F6Xwhh/Whnb8MyzquzaGFP4
|
||||
Ee30jYYNHlvX5VheDDtvy8OTN5FgKNNdzvW15iA4Hxje04ZI7W87G7OIxm7aYRid
|
||||
sG4XqZBtsOdj33IRd9hgozywGJ2qRqS6nn2KxRv1w07RniECQQDZAlKxijdn+vQ7
|
||||
8/8mXzC+FwQtzeTUCuLrBJcos9I/591ABoxYkWcYLxpFqgCEVwb1qfPBJkL07JPt
|
||||
Fu6CTnBFAkEAxXmUBs47x5QM99qyBO5UwW0Ksrm/WD4guaaxzQShMt/HzgJl613z
|
||||
/x4FtxiQJHAr6r2K0t5xTJx89LVKuouYYwJAImue6DAvJ5wDfzrtXo28snn+HLHK
|
||||
uONdKL/apgcXszE4w74GJsoxWwGlniUf3d3b6b1iP2GtPyIDOJjpjduZLQJAE4jS
|
||||
VtYB3d1MZxxQLeKxqayyuTlcr0r+C79sqT5C//hZGIzuLhlOMLd0k0cvwxsBjSgQ
|
||||
2ok8pfp49fAVI1z5xwJAVmJgLc/mSti5A2q3c8HW8qvMJEDPWbpb7p8pg4ePtpa8
|
||||
EE3TO4O4J2H+k40C397km4yZXdkNQsiT1zVljJZpiw==
|
||||
-----END RSA PRIVATE KEY-----
|
BIN
ssl/test/axTLS.ca_x509.cer
Normal file
BIN
ssl/test/axTLS.ca_x509.cer
Normal file
Binary file not shown.
13
ssl/test/axTLS.ca_x509.pem
Normal file
13
ssl/test/axTLS.ca_x509.pem
Normal file
@ -0,0 +1,13 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIB3zCCAUgCCQCdbnM4pjqlWjANBgkqhkiG9w0BAQUFADA0MTIwMAYDVQQKEylh
|
||||
eFRMUyBQcm9qZWN0IERvZGd5IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0wNjA2
|
||||
MDcxMTQ0MzJaFw0zMzEwMjMxMTQ0MzJaMDQxMjAwBgNVBAoTKWF4VExTIFByb2pl
|
||||
Y3QgRG9kZ3kgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA
|
||||
A4GNADCBiQKBgQCnZdk20fYWh8O6kDTt0AuJWyp0YIrb7W1UNNMPXI5wA4J59IVj
|
||||
Nmk5wocm9+Hqzbg7rORAN/mHPBhzLAjhnm1HODs36hW15DtbDkkH4wCM/Tsyv79m
|
||||
n0xq1V6peK3t9vi2D4p/IRjHkYR2jm+BeknopijhY0kHHfpGTHa2DnVirwIDAQAB
|
||||
MA0GCSqGSIb3DQEBBQUAA4GBAB0LgNo0oCcwIie5plgwwFybQ8x95q6e3wndM/Mp
|
||||
3gjcAFbGuchpo3dfFlTcRI0KyERb3q1MVxPM4sff9nT7EdHVyK9s8/ITkP2dcTKc
|
||||
flbcTEfJVIeM8L2P5F41Hvn9GuGcMW8EmsC06gdbp1LLnqsdrXdMNBsAUBXfgPrU
|
||||
+UcZ
|
||||
-----END CERTIFICATE-----
|
BIN
ssl/test/axTLS.device_key
Normal file
BIN
ssl/test/axTLS.device_key
Normal file
Binary file not shown.
15
ssl/test/axTLS.device_key.pem
Normal file
15
ssl/test/axTLS.device_key.pem
Normal file
@ -0,0 +1,15 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXQIBAAKBgQDUIg4NEiu/diDAlbsWbTAhMKw4iBf2X5ohGJdTO6vhGQdEkhBR
|
||||
Bgzdl9+0LbVDJY8YStUghwnuztT+IpNCrUtXtRK8Cn3QP+buzSe2ZGPVoEJIbvV/
|
||||
QudK/WuUDyTNSRTtW4S3RO36KqtbT6xh1QGTXV3I8sp7qwmcysklqZW8GwIDAQAB
|
||||
AoGBAKBEDkuPw9+Ftp7pQIxj963LoQGgyEHJ3p9Mfd9TQLrydsw2cf9Uy9mKiWcN
|
||||
9VkCgkZ/Gt/VRgrW1pIduxXv6O+8S14An+2mTayy3Ga1N6MulD7OHQP9kqR4j8TT
|
||||
xaYPR/1skjhQ+Y0Uw4NEa3OkQp6lAUEp1aVX/mTfIZBguaUxAkEA/H543Ha6wbUV
|
||||
iB+pHaBgj1nzarmuEey6kqqs7X0zoZory1X6bdpJ6l0/4qICa6aq+pt/7ywJCNoI
|
||||
CPK3mL2zGQJBANcUHRBe7/HRWrJNIqB2WDA/gJshq4xOAiIBXWk1wpabvpkCnUjQ
|
||||
rip5CAL3hXDnCQswZxRN/v7B4IlSxkKiY1MCQQCsL0MUdRMejfLFBXI6defjWiAZ
|
||||
I86FAr6oziNnQP44sf4zh8pjp3zIihbK4lhsORhYFjrES29NzgG0uHBjhNnhAj97
|
||||
gBEwVVNyh8SMnb5EZbA+BDjU24CmECUpYZ9Bypzx3nyTX+zw4uMfgGAZVAhLzF5l
|
||||
DmYiQqcpoipMsDsoCBcCQQCxBYSicXIPG8G6ZuFbgXFcZR7llgq74mbhfGuVEGbP
|
||||
qS6ldhJb/IG9O3MFlRwdU44YyJ8QGpBKWF94OpIduF6w
|
||||
-----END RSA PRIVATE KEY-----
|
BIN
ssl/test/axTLS.encrypted.p8
Normal file
BIN
ssl/test/axTLS.encrypted.p8
Normal file
Binary file not shown.
11
ssl/test/axTLS.encrypted_pem.p8
Normal file
11
ssl/test/axTLS.encrypted_pem.p8
Normal file
@ -0,0 +1,11 @@
|
||||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
MIIBfTAcBgoqhkiG9w0BDAEBMA4ECN+YmhCv0ILdAgIIAASCAVu0QEfMkp0xUsNq
|
||||
0Ek4Nsa/uxcs8N/2P7Ae7qCakkvsdRvvPPH0y+wuj5NgrG6WpPeeEx9fI2oNNTfC
|
||||
pwncH0Xm99ofVrgMX6XC45LDZtzXNSZd4TdBP6xvlYXbuGegp5GPJ8emzscHCFhC
|
||||
JfPHemRAcB7DhiWukPosuSUr5R8OluEMJrQLHuQtlDAvMjLEI98lSchPxF8LKCk3
|
||||
SS2uCcmc+4WiR0nHG9BOaGi38+PytHAnbfo1mfVSQzLfgLicMAVGysfQ9QOgpQOO
|
||||
ygYfM/s7Duwbl0rshyXVJP+7BpYJnPtHvO4BTiizU7ZEr4WBiEnnANDrupSdsxeH
|
||||
+cxZo70YJVdoPdgMd2ke6EIkUhp7HughFg+okldlEtJA4muKeEzwAxZu0TqxOtZ8
|
||||
UYRS4Ygk+rN7Y0qTKSYwSkrFBwUDkpctYjRUOeAZ/mYMKWmMn1ejAb5Is7bjEIxl
|
||||
tw==
|
||||
-----END ENCRYPTED PRIVATE KEY-----
|
BIN
ssl/test/axTLS.key_1024
Normal file
BIN
ssl/test/axTLS.key_1024
Normal file
Binary file not shown.
15
ssl/test/axTLS.key_1024.pem
Normal file
15
ssl/test/axTLS.key_1024.pem
Normal file
@ -0,0 +1,15 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXQIBAAKBgQDY4L8V3uqv6NX9C6ios9dGXacmbAy12bzG+MB40PZWZfgpSA57
|
||||
C6Ylfuh7eW845bW39OCckWD0BvNAHvmRGakvR0O1mx7c9qocSXkhKMuqSXPZCQVM
|
||||
AvJMTWwcgKcUkUT8ErPh5+NPRLqMw3Q56EzQ1EwkYbRAlYzACrcCOTGFkwIDAQAB
|
||||
AoGBAJQHcuW+rXk79zMsjgX4GmvQ6JH1FgfZglxc1SKhnkICf4vNvvSFUvYs1QnS
|
||||
LPQs9geFgPnc0Mw/IjEV80nyteJpmQQESSHbn6FUWvrk2fkHBf+aZaTr8kfOVsdy
|
||||
SUhc6BTXjyXMSSkGalR7F9ye1FPw9Z6FJaHrPekvuZz24YCBAkEA7gJ4x3iFBJfM
|
||||
Nr3WEeLHOdk0UXJvig/NiDIzm8enA3fZgjW23R/CwRNAg1XrYOuBjgwWYrS0POsI
|
||||
gJx50zjK8QJBAOlFXy4WzJNQQLZ5vDjgVmhQ0y9zjIwqDoFKirvM8GQ0Rp8HfSK2
|
||||
+UasVyOMHuvTBU2og2pn9qaxq47B7+998MMCQC/GWT4Y6AJzAe/fDTBL6BepjMHo
|
||||
iZEZ+PSktw1G9zRQA14KsCkUrgAZgDKctYGf5EKCFKA9i4xK1UsTnbSTStECQGSM
|
||||
g3dhWnMRP6OoG4rEoFo8pJsqimWMZ04xrFVBBEmdAuffmX/SMObWuITZDCcIgZu0
|
||||
zFicUYQOx200iVDJD3MCQQDa3l4arB0d17llJgD11OQohIYvAJxBAFLhR5HAUgVO
|
||||
Dy8Nyps9iUG/7p+h5p2k60V/48ukawrifrCHXECxUREd
|
||||
-----END RSA PRIVATE KEY-----
|
BIN
ssl/test/axTLS.key_2048
Normal file
BIN
ssl/test/axTLS.key_2048
Normal file
Binary file not shown.
27
ssl/test/axTLS.key_2048.pem
Normal file
27
ssl/test/axTLS.key_2048.pem
Normal file
@ -0,0 +1,27 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEAwqC/2/rPcAZEs5/ejT3ZL8Q3Pfdna2WC44i6HYCnCnbOIcW+
|
||||
6Xub2IXGwRwQBFy+mRE9WjqJ8kuOEkSt6e+8wAhLdag7WXJ6cxoag110t5FEHSyd
|
||||
GfvFFyUNjMJhLd+EmaQTTpEv9MJPJj0Zdruh1EjyRxa4HJmiD9t7XmWyCfSmM0qM
|
||||
kgJ0J6s62rRMBX+l/NEEX2VzJugdZAU671RWYOncuxX/2jUYlvIqI1l3SP8acMU5
|
||||
BtfLsYMj08lNHOjgZCPRwkdjsl6U5EqIizKZygw1FNugVEDHnL2MAYXwqzX3pGr/
|
||||
72Biy+J4TSH6lt0stszS5m8BirMgYr2FFHslrQIDAQABAoIBAQDBTa0gzEupJOCp
|
||||
UvhUagBDO+vuBMJX3XuRh6PqV3QQpYz36BJEjXttIvkTpU6XNpIrLv8zlX6bAsW5
|
||||
iTL+bRiX1eU0l4FSxqutlFiO7oxVIdd37m6edvv6j9eUXR7t09k8S8TNPNBXlYHN
|
||||
JdQbpCIH2OehCYSVC1X1z/UI/ZJF5VSn7UsYgwReK102svfHtll85K0TgHMir9Rx
|
||||
Dlh0vYx3IJi2nDOTyJ4JekkyEAcYd3D6JUd0JujcN3Ev3EOsns5GXzN6KYvinmYf
|
||||
Z1bA/HEMNb9ZS9bdsoAvyeJAeGp8ejzuJVHGL0kATgrAamb58fPS+A8Guk5eN5KY
|
||||
5zvzNrJVAoGBAPVWvPrDOJX2ZI7poJ269xFteTWWIYA+r+YRRkhMBMcD08H5gs6e
|
||||
QMWU9w8qjgSmbNkx8skkhn/gV5R3CbVYYRR2osrZIoOayWAsJmY0bHFTIvooYhfp
|
||||
3lPVNIPzUpRObFksamtrsK+zpx5qOdigNhComXLsGWKfrN9Yvkb7YzIDAoGBAMsV
|
||||
4UVH9WH0IKV1vx3QtrGEb69SZMpbmM8ZsPvaPgq00In9udY4w5V2ZygfTiq0ChUY
|
||||
fYy6BeO6Gyp2DSABdz1AUH+0wcnNrHJghFtxtsq4Thu4MHU6ftc+JCGfSeWUapfh
|
||||
KiHS0TEguRFcYSHnM1IDEiU4aTHY59FRUWMI2hKPAoGAIVfviTk9GIyLMC0qaiV9
|
||||
7L1vKsxDs1VRvLf+UFcckxu/DO7nS0OQ1Amh5krHUHR5+K7kK1gue3S3EnN3O1FO
|
||||
qGRTTbRjD3XbBpoZgeyADIrbBxqz8kITuFsSrxhD0eoyqY/yyrSxJ8AH54dSY1Gq
|
||||
52qyqD7UWGYRLa229pi165cCgYAd7/rGWMY+i1toqMPkpEjaQFiqcq3y+q+7D+F8
|
||||
Lv7oWyFGxkVn4/RJCyxHyN2gA+xckcCoRx/pIx0wFDj5F945BEsZmE7c7dnW/o1k
|
||||
YY39sk+pXGygS2A5YKq43h9pnYhdHU81rzsxT86YVZLoCYoSM+uv2vH+7Ce4PpGN
|
||||
1Nc41wKBgDUrYyfDB1RzdB63FwPRax5uLjewnuMXyZhy70ZkiGh0XBuQt2aCLeCZ
|
||||
HpAyGcJryxdDFYA+UwJoSWjaW9ku0lp+GxX1F+cResrRHTi70w9czwGVaKmcG3kI
|
||||
fFjG7w8nkiw5J7IRH7SxmNbmAv8L0Iy6jvoWLFB+EdUGWllkjCmJ
|
||||
-----END RSA PRIVATE KEY-----
|
BIN
ssl/test/axTLS.key_4096
Normal file
BIN
ssl/test/axTLS.key_4096
Normal file
Binary file not shown.
51
ssl/test/axTLS.key_4096.pem
Normal file
51
ssl/test/axTLS.key_4096.pem
Normal file
@ -0,0 +1,51 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIJKQIBAAKCAgEA/Ce0mV0qytAwDPrjXRBlUh2gdKs2thDw3N18owXVrSUFq9Sw
|
||||
AaMNrmep9DR9MEALcdMm3GCEJ7sOOiEQcqTz25di36WJDe+jo1z5nD2XZsPIsp9+
|
||||
k51Vz+W3B4vsXJAgzV+XZbmv9L0598VEwkpeI3Uc9et8ZhGvDPoHZyBQG1KAj6h3
|
||||
AKZ1+NthrhajxlrndQZ5Du/R5DSUQOBcCHHdzZgihdfF97Yn/kp1mele1ElZMlqg
|
||||
BtpDi1TEQJ9XBtjCW0epFAm5THQ3gMx5DCcqB/cNYdZWqpZ0AuwATm61+46m4fFK
|
||||
g3YAYPOi/74aKFuIQBw/lc8W//SV1x8SL/hf2XIdvSa9QhroNN0d3Xu2EUQzXZxo
|
||||
PRMKzOqKfwlZW7ozT6hFBwPMh8yfhoPugq2TvqBjke1s3gmvwTgEcf+gY97qXiZC
|
||||
X5bh/ehmnZ7vIblYFUD2yMlsKaXGJYweh3WKJlQnh71wQUg2Mxa6ig8ijrEozNlw
|
||||
YfPCQFrNLqQfJOwdx90dy7hpUyUn1wo39p6wmC6n9ex4zeKbO4ndSp+/AJ+d5Qp8
|
||||
zoMzwneYV9LBQG8ry4uwzDkSWKb/WghsEbQ9O3sGIuI13SlT/B64v3bLb5AHagI8
|
||||
zS3kPsshjKhkcc2W9MKRBU2wIeCsNS052kaUq3rPMSBROrALmLk3en/Dq48CAwEA
|
||||
AQKCAgEArPMy7So5Cqjm/FAtGI0BYeRORReWTCSsgGEudsauu7a0ABq+qjDDVodl
|
||||
y8kgwLJ85xKUCf3tRy8G4BoDpQ688DYSrCFnMvbWP1urHV4ldWf+RX4eHHODAzil
|
||||
ZHi1ovt8dEEHn89P/8a2dtqIgdbuYNWYCpj9Vyjz7yujXjmMmGDrKx26meiS7CDV
|
||||
C8odhRSewuawq+0UArmJokIA/g3Tu4uIylKoR3JaVhGOPgYSc/rnQiFkt66HO47l
|
||||
mQlxcJHGJUOulb7hqK3hz+bvc8V9D7+FH0EbaqANbF+hCirniWZb0odku2x5cAZM
|
||||
G6uxV1MIzihR+Jf1R5PkHowCNoLegfM45tnuadP1+8Kezv1SsqkrkMEwfb0QN19C
|
||||
2+bmnwYXagUgg/A2q2Shg9h4/3cpwdrDzGHD8IttGlzLR8HnlHkcAK3qRNqy9h60
|
||||
JDEW/tOurUSZBXjU9ZyoZSukcK3+yUjCDWS92wMOBlUQGh4/HCOOizahe6lhn2nT
|
||||
+jkBvl38c+7GBKR0VyCisFi++FukMBbyU/hNNFByZxOj0b/+YVYI0qwM5oDzLhJH
|
||||
69/VhxMx0xVt9/kOOO3yhdGjKCZztPZZm5mg2OzzXmf4im+hPSg0/OrdXrVNk4v/
|
||||
w7ouUQHSa3+rAAu8BJFF2rTWA7rjecVEnk6c77I6dEVYXdCfz8kCggEBAP+IJLHo
|
||||
7Cs51qPcRKQc633phJa3pFGf6O8xN6pl8z1ZQX0voZyROKJLTytSH+zmPdmggUeg
|
||||
7CRoV8BKY49YiOxO2Kx8BPfftItS9yvA3O9ztcdzQa72nYusMWwvj0yFU8DbYfnx
|
||||
yYw59F/1pdPKFN83Sj4MJAOb4nAxBP1GiZvsPAgcTpf/197NLNHwUDdk/TXDtTLa
|
||||
lx4uTn/SJDQuvsCCLBKyx7FdN5NPRN2kIKUWZLd7HRu2EhcSlATwf4TUPZz7atKN
|
||||
2FD0svErpPOAspNPtnNj3RgeunGVqS2oi/XueuveNNCYLkcV8/UaZm85LBrPoEre
|
||||
23qK9/ZN0SD534sCggEBAPyd+nD71pScrM0TI4Lc3jMNUKeZj3sT5rlhlkWlARhQ
|
||||
WPEWYYg5vs3zDiRpG4Xy3n9ey+M6Tuw+/XpcJZxhrLYFOqparxXPP4qc+3EvtzpF
|
||||
OskLR/2/bVnESf6+pQspmwW6G4IJ9vOmIJeUj9zeU0txuxKkjhAmInCnMxJOlYRm
|
||||
xeLymuo5LZxrXmSXcX4cyZ0/4bF2L3IE5vH7ffdWXWYzW9wP7M4sFp+0iKjHuhC1
|
||||
gB6Qg0Mp0TVNUt0ZEelFLEJdA2lbbZ5yHhNXuhOxW/l3ASSe9tjTpy7yBSwBOpFG
|
||||
l7QGISfJVEFfjyn7yWBYj5LDGnitlP4TtN8zyy6cJI0CggEAPRwY8ncqq7e8Thmq
|
||||
TLkh1E3ZSJYIdQDSGwnhLx4MirpiwAZ5FtFgAugRueF9AxGY7wfEgxXIA3j0q2be
|
||||
4nQg4qqEhNNv+LuGGN+xfsQz0gwRB+7XYXlW+gUnGKFTGtCz0+ZjSvv44FEn0R8V
|
||||
Fk44qZ02YxpSLo7EG2KNt+h7lk9rl+D1JsKnpH/a3SYkeOrs50OzfMLr6urWGRlv
|
||||
UQ9wzOcUlTAuM4uAc/k8FelfaTuuwHZv4qWrM9tcjMXbKS/8wCMcS9hiSBINDUIL
|
||||
w7QegL5KetQCFveaTPmmqOWq+xiaSvgsF0qdnqBwZEh5ANZiZtMKmX0sbeT4Ie5A
|
||||
OiunuwKCAQBlSlrvDqu9rwzCtdfZUwJtaftbGIGlkhdDYdPFXSIRQ7ZGBPlai/zr
|
||||
y3dyNgrpLLb2T2ZlWC3pIGC2vVf/WlLMMVCSmgX2MsGBrOxNOBq57KRjlHhrUGRi
|
||||
SAh7cqnuzeHw6+y3uZMhow0Semks4KB5ccLW+NBVvVS14vThdE0TZ7oVA74GCKM3
|
||||
Qv34S5kgPh7BRKoUZBUmHL0VbgfWMvUEU7eTh3cmPBteMh9RvbPnmz8iAkP/nDbc
|
||||
roJ5UOITrL7QZUdG6XgMvik9DEH6P3Vnk8YLjwnfaw5wDm7wdBWtxqZxcru8nkeA
|
||||
ZvaamPDoBtqauExW8xL4xaISlUv1BnrJAoIBAQCiEZk93GeRzYJFCO1YafsGYueX
|
||||
Pffgd9wM2TpObgaEw8OIfEpGQKDiR35fb0uVzNyI5fVU5D5tP0b3LfvtQXV12ryQ
|
||||
sVTA5YJcb8mRuUGy/AkjL54kNiZthUnlGHQjY3lqSyI1r5WxRIZBBRn5+g1eSZVq
|
||||
CYCGjEryKm7vw8Qcvy1+H2crcZ0rRyLTcfFCr1ZXlyEZu48ScOtxcIDHc7j4J0LO
|
||||
Peq2z0tbBojGkxFLX94J7zpRkWMPX9VHorEavDv7ZJwtgoXn3Lom0xHhO+JQaxY9
|
||||
FtJ79Ps9+SquXAnkhna4bbkrqrPM3+MAAV/S7bd1T1/8d4YiRQyaMHGS4Yr8
|
||||
-----END RSA PRIVATE KEY-----
|
BIN
ssl/test/axTLS.key_512
Normal file
BIN
ssl/test/axTLS.key_512
Normal file
Binary file not shown.
9
ssl/test/axTLS.key_512.pem
Normal file
9
ssl/test/axTLS.key_512.pem
Normal file
@ -0,0 +1,9 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIBPQIBAAJBANE7MF+pAUI9hm1yvkBuUcFJf1d1oS025cE9DyAa0SNt+nTSPiOw
|
||||
cPygat7sQYiE/lQVa2HFFmK4k0HxTz3/Lr0CAwEAAQJBAJF5xO2ONajX3GK2+B8W
|
||||
VVO+BYNK71DfranJCX46BxXI/Ra7wOSY0UWZYHVsZGWJxx41os0UBTg5FRq4DwWW
|
||||
AQECIQDo69eo39iQqjwhpAQxatMh2CWYT7gokyu56V+5o2V3fQIhAOX2b+tQxDsB
|
||||
w0J9UDN6CdwI5XbzveoP5fHTPS9j4rhBAiEA3c+y6Zx6dZHYf8TdRV5QwDtB2iGY
|
||||
4/L7Qimvwm6Lc1UCIQDDXWrVsocTTjsReJ6zLOHFcjVnqklU2W7T1E8tvKE3QQIh
|
||||
AMRpCFM7MrS2axuc8/HzGkqW/3AlIBqdZbilj5zHd2R0
|
||||
-----END RSA PRIVATE KEY-----
|
12
ssl/test/axTLS.key_aes128.pem
Normal file
12
ssl/test/axTLS.key_aes128.pem
Normal file
@ -0,0 +1,12 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: AES-128-CBC,B3A0D2BCEF4DE916D0BBA30A6885251B
|
||||
|
||||
v8y74AGReaPLmDt6O8wir6hX1Ze8K4fVNkrLqfDMdW5E7jBXKO8riCMNmSjQ9fyh
|
||||
eTicej93+8krcIvSXKW18TdO+EWezQevgnLrAZQWaNPH2j4B+K5gm701uiiKFKVa
|
||||
1zngAOByePYlN6z4JLbiCyJRhxSo5zCaUYkKC2eGh8mlE64QmokPSCAj0wcCDzGh
|
||||
hdhBg1vm0GmaQwIDVn+8zMfahscXVMtBmyQf5YP4PQW2nqOt7aZHjBNdg9qnBpGw
|
||||
b6YuY7eZ4FgQvYcsNCi34NroJb9pkTrrF2F9Meb6+3So7jtMFG/YaJdCuXtf01g/
|
||||
Qm+XA5pJUtIUr/hLQjhkaOVUtXv/k0o/MR4k5CbAmboLt6YHf5V8+01vk0bvv5dI
|
||||
70pVdXMmx26xDZOGmjYzd93PWc+75jak3GN2fbWryQs=
|
||||
-----END RSA PRIVATE KEY-----
|
12
ssl/test/axTLS.key_aes256.pem
Normal file
12
ssl/test/axTLS.key_aes256.pem
Normal file
@ -0,0 +1,12 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: AES-256-CBC,F076229CDC2BCB3B8722E3865855B45C
|
||||
|
||||
WFV9QWzr4tNmD+1OeQ7BceQg5LVQHp20Jo1Ax29lq8JTPzeObhtaU2MUHlcPKHUS
|
||||
vK4FyQxJ25CyMubbnaZqCCz9pNbseFuJ1tob9UqRmXkZ8HV3snRjJRbcctD+V9x+
|
||||
Ymi1GreXoDQtMp0FtMiFjPvIYciBQnaRv2ChMAnGXNbZXCxWWA9E5S3a+yWzo+gd
|
||||
wEcowL+SUac1PEDGHokhKn7nctvI9cC4hE6JmKM1sD68/U3rRPXMGqmC7umqyT5P
|
||||
gjWBb1uu0iRjFC9eQUsaKPxey5Be710GFlyf/Ff/tep7RhkryIWEPvIzYCBf6rhk
|
||||
3pysFgTjfiUuBYUNumjXr/q5hgdtb75788XUDxKwAoUx+m8gi0nJg35CN2nmQ054
|
||||
VJxcZlNv0wqnJ+GTTZeN6fiAhTpVtHsqHQomRSfaBiw=
|
||||
-----END RSA PRIVATE KEY-----
|
BIN
ssl/test/axTLS.noname.p12
Normal file
BIN
ssl/test/axTLS.noname.p12
Normal file
Binary file not shown.
BIN
ssl/test/axTLS.unencrypted.p8
Normal file
BIN
ssl/test/axTLS.unencrypted.p8
Normal file
Binary file not shown.
10
ssl/test/axTLS.unencrypted_pem.p8
Normal file
10
ssl/test/axTLS.unencrypted_pem.p8
Normal file
@ -0,0 +1,10 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIBVwIBADANBgkqhkiG9w0BAQEFAASCAUEwggE9AgEAAkEA0TswX6kBQj2GbXK+
|
||||
QG5RwUl/V3WhLTblwT0PIBrRI236dNI+I7Bw/KBq3uxBiIT+VBVrYcUWYriTQfFP
|
||||
Pf8uvQIDAQABAkEAkXnE7Y41qNfcYrb4HxZVU74Fg0rvUN+tqckJfjoHFcj9FrvA
|
||||
5JjRRZlgdWxkZYnHHjWizRQFODkVGrgPBZYBAQIhAOjr16jf2JCqPCGkBDFq0yHY
|
||||
JZhPuCiTK7npX7mjZXd9AiEA5fZv61DEOwHDQn1QM3oJ3AjldvO96g/l8dM9L2Pi
|
||||
uEECIQDdz7LpnHp1kdh/xN1FXlDAO0HaIZjj8vtCKa/CbotzVQIhAMNdatWyhxNO
|
||||
OxF4nrMs4cVyNWeqSVTZbtPUTy28oTdBAiEAxGkIUzsytLZrG5zz8fMaSpb/cCUg
|
||||
Gp1luKWPnMd3ZHQ=
|
||||
-----END PRIVATE KEY-----
|
BIN
ssl/test/axTLS.withCA.p12
Normal file
BIN
ssl/test/axTLS.withCA.p12
Normal file
Binary file not shown.
BIN
ssl/test/axTLS.withoutCA.p12
Normal file
BIN
ssl/test/axTLS.withoutCA.p12
Normal file
Binary file not shown.
BIN
ssl/test/axTLS.x509_1024.cer
Normal file
BIN
ssl/test/axTLS.x509_1024.cer
Normal file
Binary file not shown.
12
ssl/test/axTLS.x509_1024.pem
Normal file
12
ssl/test/axTLS.x509_1024.pem
Normal file
@ -0,0 +1,12 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIB1zCCAUACCQDxw4fA1PRXwzANBgkqhkiG9w0BAQUFADA0MTIwMAYDVQQKEylh
|
||||
eFRMUyBQcm9qZWN0IERvZGd5IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0wNjA2
|
||||
MDcxMTQ0MzJaFw0zMzEwMjMxMTQ0MzJaMCwxFjAUBgNVBAoTDWF4VExTIFByb2pl
|
||||
Y3QxEjAQBgNVBAMTCTEyNy4wLjAuMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC
|
||||
gYEA2OC/Fd7qr+jV/QuoqLPXRl2nJmwMtdm8xvjAeND2VmX4KUgOewumJX7oe3lv
|
||||
OOW1t/TgnJFg9AbzQB75kRmpL0dDtZse3PaqHEl5ISjLqklz2QkFTALyTE1sHICn
|
||||
FJFE/BKz4efjT0S6jMN0OehM0NRMJGG0QJWMwAq3AjkxhZMCAwEAATANBgkqhkiG
|
||||
9w0BAQUFAAOBgQALRyRSfbZjeLyA3YdskEwzw1ynlwkcCU+bbrNaPkaSGseHFVnh
|
||||
iFzOauKWqjLswu14i+CQZpMUw5irMzXTfV1RCpy5EFhHepiVZP9MXYIZ+eoPXprL
|
||||
Midkym9YitDANvS5YzSl2jZQNknStzohM1s+1l8MmYO3sveLRMRec0GpAg==
|
||||
-----END CERTIFICATE-----
|
BIN
ssl/test/axTLS.x509_2048.cer
Normal file
BIN
ssl/test/axTLS.x509_2048.cer
Normal file
Binary file not shown.
15
ssl/test/axTLS.x509_2048.pem
Normal file
15
ssl/test/axTLS.x509_2048.pem
Normal file
@ -0,0 +1,15 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICWzCCAcQCCQDxw4fA1PRXxDANBgkqhkiG9w0BAQQFADA0MTIwMAYDVQQKEylh
|
||||
eFRMUyBQcm9qZWN0IERvZGd5IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0wNjA2
|
||||
MDcxMTQ0MzJaFw0zMzEwMjMxMTQ0MzJaMCwxFjAUBgNVBAoTDWF4VExTIFByb2pl
|
||||
Y3QxEjAQBgNVBAMTCTEyNy4wLjAuMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
|
||||
AQoCggEBAMKgv9v6z3AGRLOf3o092S/ENz33Z2tlguOIuh2Apwp2ziHFvul7m9iF
|
||||
xsEcEARcvpkRPVo6ifJLjhJErenvvMAIS3WoO1lyenMaGoNddLeRRB0snRn7xRcl
|
||||
DYzCYS3fhJmkE06RL/TCTyY9GXa7odRI8kcWuByZog/be15lsgn0pjNKjJICdCer
|
||||
Otq0TAV/pfzRBF9lcyboHWQFOu9UVmDp3LsV/9o1GJbyKiNZd0j/GnDFOQbXy7GD
|
||||
I9PJTRzo4GQj0cJHY7JelORKiIsymcoMNRTboFRAx5y9jAGF8Ks196Rq/+9gYsvi
|
||||
eE0h+pbdLLbM0uZvAYqzIGK9hRR7Ja0CAwEAATANBgkqhkiG9w0BAQQFAAOBgQA8
|
||||
L1Zz9K6M/PQCYWrfnTjbPKY2rTB1OvSV0Uwy5KKPQRS1+oK9dx4K0miX+1ZvI1bo
|
||||
f7/1aFXOsW3dpTwYUSjJvTMjSwNUPKiB/q/xwA1mzsbIZsbnhIITU95mOJ3xFhgc
|
||||
YFdJ4saL7pppTzfOxZ+h9jWbDwgJJAwx/q+O72uE5w==
|
||||
-----END CERTIFICATE-----
|
BIN
ssl/test/axTLS.x509_4096.cer
Normal file
BIN
ssl/test/axTLS.x509_4096.cer
Normal file
Binary file not shown.
20
ssl/test/axTLS.x509_4096.pem
Normal file
20
ssl/test/axTLS.x509_4096.pem
Normal file
@ -0,0 +1,20 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDWzCCAsQCCQDxw4fA1PRXxTANBgkqhkiG9w0BAQQFADA0MTIwMAYDVQQKEylh
|
||||
eFRMUyBQcm9qZWN0IERvZGd5IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0wNjA2
|
||||
MDcxMTQ0MzJaFw0zMzEwMjMxMTQ0MzJaMCwxFjAUBgNVBAoTDWF4VExTIFByb2pl
|
||||
Y3QxEjAQBgNVBAMTCTEyNy4wLjAuMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCC
|
||||
AgoCggIBAPwntJldKsrQMAz6410QZVIdoHSrNrYQ8NzdfKMF1a0lBavUsAGjDa5n
|
||||
qfQ0fTBAC3HTJtxghCe7DjohEHKk89uXYt+liQ3vo6Nc+Zw9l2bDyLKffpOdVc/l
|
||||
tweL7FyQIM1fl2W5r/S9OffFRMJKXiN1HPXrfGYRrwz6B2cgUBtSgI+odwCmdfjb
|
||||
Ya4Wo8Za53UGeQ7v0eQ0lEDgXAhx3c2YIoXXxfe2J/5KdZnpXtRJWTJaoAbaQ4tU
|
||||
xECfVwbYwltHqRQJuUx0N4DMeQwnKgf3DWHWVqqWdALsAE5utfuOpuHxSoN2AGDz
|
||||
ov++GihbiEAcP5XPFv/0ldcfEi/4X9lyHb0mvUIa6DTdHd17thFEM12caD0TCszq
|
||||
in8JWVu6M0+oRQcDzIfMn4aD7oKtk76gY5HtbN4Jr8E4BHH/oGPe6l4mQl+W4f3o
|
||||
Zp2e7yG5WBVA9sjJbCmlxiWMHod1iiZUJ4e9cEFINjMWuooPIo6xKMzZcGHzwkBa
|
||||
zS6kHyTsHcfdHcu4aVMlJ9cKN/aesJgup/XseM3imzuJ3UqfvwCfneUKfM6DM8J3
|
||||
mFfSwUBvK8uLsMw5Elim/1oIbBG0PTt7BiLiNd0pU/weuL92y2+QB2oCPM0t5D7L
|
||||
IYyoZHHNlvTCkQVNsCHgrDUtOdpGlKt6zzEgUTqwC5i5N3p/w6uPAgMBAAEwDQYJ
|
||||
KoZIhvcNAQEEBQADgYEAcrCtPXmZyPX01uNMh2X1VkgmUn/zLemierou7WD/h7xL
|
||||
dOl4eeKjFBqIiC19382m1DK4h1F8MceqaMgTueCJpLM7A2cwN3ta8/pGP2yEVhdp
|
||||
h10PkdRPF/AU8JmxnFaADsc6+6xWbbrdNv5xcvP1bJKWWW+30EhRF9PxjXiETXc=
|
||||
-----END CERTIFICATE-----
|
BIN
ssl/test/axTLS.x509_512.cer
Normal file
BIN
ssl/test/axTLS.x509_512.cer
Normal file
Binary file not shown.
11
ssl/test/axTLS.x509_512.pem
Normal file
11
ssl/test/axTLS.x509_512.pem
Normal file
@ -0,0 +1,11 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBkjCB/AIJAPHDh8DU9FfCMA0GCSqGSIb3DQEBBQUAMDQxMjAwBgNVBAoTKWF4
|
||||
VExTIFByb2plY3QgRG9kZ3kgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTA2MDYw
|
||||
NzExNDQzMloXDTMzMTAyMzExNDQzMlowLDEWMBQGA1UEChMNYXhUTFMgUHJvamVj
|
||||
dDESMBAGA1UEAxMJMTI3LjAuMC4xMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANE7
|
||||
MF+pAUI9hm1yvkBuUcFJf1d1oS025cE9DyAa0SNt+nTSPiOwcPygat7sQYiE/lQV
|
||||
a2HFFmK4k0HxTz3/Lr0CAwEAATANBgkqhkiG9w0BAQUFAAOBgQAKRT6LwFr1xedJ
|
||||
b4qrvjB+EwV/0p4TNNXUS9S30rMSFvRar7VxvLP1lpYj9PR1JGSZMG/B6hR4yumF
|
||||
Rjwel9FPgNcWCW4DXAWqz3UQF7oZtJL6K+XJpQ0gwC+Nxc+RRGNLMlK7dLiqFh/V
|
||||
qZLej5Xy93M0JyZBiLV88P+c08gd7A==
|
||||
-----END CERTIFICATE-----
|
11
ssl/test/axTLS.x509_aes128.pem
Normal file
11
ssl/test/axTLS.x509_aes128.pem
Normal file
@ -0,0 +1,11 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBkjCB/AIJAPHDh8DU9FfHMA0GCSqGSIb3DQEBBQUAMDQxMjAwBgNVBAoTKWF4
|
||||
VExTIFByb2plY3QgRG9kZ3kgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTA2MDYw
|
||||
NzExNDQzMloXDTMzMTAyMzExNDQzMlowLDEWMBQGA1UEChMNYXhUTFMgUHJvamVj
|
||||
dDESMBAGA1UEAxMJMTI3LjAuMC4xMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMDo
|
||||
g6K2iXFftW+Qk+rrzkMGWrtfY6YSxPstPRrI7akluUEoyWGITXbK6L3QfERrf2eu
|
||||
CnWyciQiHVRoHC0EgZUCAwEAATANBgkqhkiG9w0BAQUFAAOBgQBT6YhR8x/bBteK
|
||||
lr8E0l4mATOnYlsmge+z/SFYs4bDBofqlwQCVJXNSBA4ZsEjgP9qIWTu/85QrVGq
|
||||
LrkewSM6Oeh95LGnE+uhJVtIX++O+Hsex3H1UL067dCG99XmDhqbEU9AI6YSZu2p
|
||||
cjoSowFELtOoG667+id9QObfV3EQoQ==
|
||||
-----END CERTIFICATE-----
|
11
ssl/test/axTLS.x509_aes256.pem
Normal file
11
ssl/test/axTLS.x509_aes256.pem
Normal file
@ -0,0 +1,11 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBkjCB/AIJAPHDh8DU9FfIMA0GCSqGSIb3DQEBBQUAMDQxMjAwBgNVBAoTKWF4
|
||||
VExTIFByb2plY3QgRG9kZ3kgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTA2MDYw
|
||||
NzExNDQzMloXDTMzMTAyMzExNDQzMlowLDEWMBQGA1UEChMNYXhUTFMgUHJvamVj
|
||||
dDESMBAGA1UEAxMJMTI3LjAuMC4xMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANAW
|
||||
9PdXa5u4gWi5VB5p/eQmOtteRq9/54JkiEs8cVNrTQgZsjjU1LGedE3JwBqZ1EIW
|
||||
HGPjcGg5dVxFjkn7RekCAwEAATANBgkqhkiG9w0BAQUFAAOBgQBmJMt0Crdd/BPn
|
||||
EdmzsVXou0zTizTC8wyUPMVpg/KzzP7fhZux/ZIrH9/RVcJd9y+B2/mXc3C+K99+
|
||||
TXQoYKsLGArfDPzmpy1wPrdEcB1A9gkWDl1Uq6xRyvrVm3gX8NTITRuGKL9njgWx
|
||||
2SrApIBtOOUOinYtfH3745cVVl5HOA==
|
||||
-----END CERTIFICATE-----
|
11
ssl/test/axTLS.x509_bad_after.pem
Normal file
11
ssl/test/axTLS.x509_bad_after.pem
Normal file
@ -0,0 +1,11 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBkjCB/AIJAPHDh8DU9FfKMA0GCSqGSIb3DQEBBQUAMDQxMjAwBgNVBAoTKWF4
|
||||
VExTIFByb2plY3QgRG9kZ3kgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTA2MDYw
|
||||
NzExNDQzMloXDTA1MDYwNzExNDQzMlowLDEWMBQGA1UEChMNYXhUTFMgUHJvamVj
|
||||
dDESMBAGA1UEAxMJMTI3LjAuMC4xMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANE7
|
||||
MF+pAUI9hm1yvkBuUcFJf1d1oS025cE9DyAa0SNt+nTSPiOwcPygat7sQYiE/lQV
|
||||
a2HFFmK4k0HxTz3/Lr0CAwEAATANBgkqhkiG9w0BAQUFAAOBgQCmPSs9EceViMZD
|
||||
ZTXDZpQWJFcXaeInrXWgYWyVgnHBY/eSuqNCxkV/ehv/Wc5pWBGnrX+4cSvQ+TpQ
|
||||
FdZegeOjvgipjtJb/0TJCcvgcdHTntEM0h7VXjfbsJXAHwJPFzWIKxV4jeFXnaaw
|
||||
W+YHrj9GQ8PnFmapPuh4h/y6LyHAcg==
|
||||
-----END CERTIFICATE-----
|
11
ssl/test/axTLS.x509_bad_before.pem
Normal file
11
ssl/test/axTLS.x509_bad_before.pem
Normal file
@ -0,0 +1,11 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBkjCB/AIJAPHDh8DU9FfJMA0GCSqGSIb3DQEBBQUAMDQxMjAwBgNVBAoTKWF4
|
||||
VExTIFByb2plY3QgRG9kZ3kgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTI0MTIz
|
||||
MTE0MDAwMFoXDTI1MTIzMTE0MDAwMFowLDEWMBQGA1UEChMNYXhUTFMgUHJvamVj
|
||||
dDESMBAGA1UEAxMJMTI3LjAuMC4xMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANE7
|
||||
MF+pAUI9hm1yvkBuUcFJf1d1oS025cE9DyAa0SNt+nTSPiOwcPygat7sQYiE/lQV
|
||||
a2HFFmK4k0HxTz3/Lr0CAwEAATANBgkqhkiG9w0BAQUFAAOBgQApbldYefE8A0ez
|
||||
SYvAuCtYxx/2KHwBRD/cR0q7widl9WGjVC/dsnbFo109vHEr3FP1HVYSI0aweiaK
|
||||
XZmpUyJ9DprbbWQqaLuDnqIH8X7kfiMuO7/LGQc812iDJI2Akxp9cIlPBFBD8GVx
|
||||
+0EphzSodDDlLD8bPqLaWTE+8Ydtjw==
|
||||
-----END CERTIFICATE-----
|
BIN
ssl/test/axTLS.x509_device.cer
Normal file
BIN
ssl/test/axTLS.x509_device.cer
Normal file
Binary file not shown.
24
ssl/test/axTLS.x509_device.pem
Normal file
24
ssl/test/axTLS.x509_device.pem
Normal file
@ -0,0 +1,24 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBjTCCATcCCQDxw4fA1PRXxjANBgkqhkiG9w0BAQUFADAsMRYwFAYDVQQKEw1h
|
||||
eFRMUyBQcm9qZWN0MRIwEAYDVQQDEwkxMjcuMC4wLjEwHhcNMDYwNjA3MTE0NDMy
|
||||
WhcNMzMxMDIzMTE0NDMyWjArMSkwJwYDVQQKEyBheFRMUyBQcm9qZWN0IERldmlj
|
||||
ZSBDZXJ0aWZpY2F0ZTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1CIODRIr
|
||||
v3YgwJW7Fm0wITCsOIgX9l+aIRiXUzur4RkHRJIQUQYM3ZfftC21QyWPGErVIIcJ
|
||||
7s7U/iKTQq1LV7USvAp90D/m7s0ntmRj1aBCSG71f0LnSv1rlA8kzUkU7VuEt0Tt
|
||||
+iqrW0+sYdUBk11dyPLKe6sJnMrJJamVvBsCAwEAATANBgkqhkiG9w0BAQUFAANB
|
||||
ABC3Uc6uImIpcLl1WYu8K8qkGnVT4K9JkdXHQFbhFZs37lvITrOHQ3j2oGXTbdAx
|
||||
JFJ3II9xXkm+nc7oLHqhXlc=
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIB3zCCAUgCCQCdbnM4pjqlWjANBgkqhkiG9w0BAQUFADA0MTIwMAYDVQQKEylh
|
||||
eFRMUyBQcm9qZWN0IERvZGd5IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0wNjA2
|
||||
MDcxMTQ0MzJaFw0zMzEwMjMxMTQ0MzJaMDQxMjAwBgNVBAoTKWF4VExTIFByb2pl
|
||||
Y3QgRG9kZ3kgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA
|
||||
A4GNADCBiQKBgQCnZdk20fYWh8O6kDTt0AuJWyp0YIrb7W1UNNMPXI5wA4J59IVj
|
||||
Nmk5wocm9+Hqzbg7rORAN/mHPBhzLAjhnm1HODs36hW15DtbDkkH4wCM/Tsyv79m
|
||||
n0xq1V6peK3t9vi2D4p/IRjHkYR2jm+BeknopijhY0kHHfpGTHa2DnVirwIDAQAB
|
||||
MA0GCSqGSIb3DQEBBQUAA4GBAB0LgNo0oCcwIie5plgwwFybQ8x95q6e3wndM/Mp
|
||||
3gjcAFbGuchpo3dfFlTcRI0KyERb3q1MVxPM4sff9nT7EdHVyK9s8/ITkP2dcTKc
|
||||
flbcTEfJVIeM8L2P5F41Hvn9GuGcMW8EmsC06gdbp1LLnqsdrXdMNBsAUBXfgPrU
|
||||
+UcZ
|
||||
-----END CERTIFICATE-----
|
BIN
ssl/test/deutsche_telecom.x509_ca
Normal file
BIN
ssl/test/deutsche_telecom.x509_ca
Normal file
Binary file not shown.
BIN
ssl/test/equifax.x509_ca
Normal file
BIN
ssl/test/equifax.x509_ca
Normal file
Binary file not shown.
2
ssl/test/killopenssl.sh
Executable file
2
ssl/test/killopenssl.sh
Executable file
@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
ps -ef|grep openssl | /usr/bin/awk '{print $2}' |xargs kill -9
|
162
ssl/test/make_certs.sh
Executable file
162
ssl/test/make_certs.sh
Executable file
@ -0,0 +1,162 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright(C) 2006 Cameron Rich
|
||||
#
|
||||
# This license is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This license is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this license; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
#
|
||||
# Generate the certificates and keys for testing.
|
||||
#
|
||||
|
||||
PROJECT_NAME="axTLS Project"
|
||||
|
||||
# Generate the openssl configuration files.
|
||||
cat > ca_cert.conf << EOF
|
||||
[ req ]
|
||||
distinguished_name = req_distinguished_name
|
||||
prompt = no
|
||||
|
||||
[ req_distinguished_name ]
|
||||
O = $PROJECT_NAME Dodgy Certificate Authority
|
||||
EOF
|
||||
|
||||
cat > certs.conf << EOF
|
||||
[ req ]
|
||||
distinguished_name = req_distinguished_name
|
||||
prompt = no
|
||||
|
||||
[ req_distinguished_name ]
|
||||
O = $PROJECT_NAME
|
||||
CN = 127.0.0.1
|
||||
EOF
|
||||
|
||||
cat > device_cert.conf << EOF
|
||||
[ req ]
|
||||
distinguished_name = req_distinguished_name
|
||||
prompt = no
|
||||
|
||||
[ req_distinguished_name ]
|
||||
O = $PROJECT_NAME Device Certificate
|
||||
EOF
|
||||
|
||||
# private key generation
|
||||
openssl genrsa -out axTLS.ca_key.pem 1024
|
||||
openssl genrsa -out axTLS.key_512.pem 512
|
||||
openssl genrsa -out axTLS.key_1024.pem 1024
|
||||
openssl genrsa -out axTLS.key_2048.pem 2048
|
||||
openssl genrsa -out axTLS.key_4096.pem 4096
|
||||
openssl genrsa -out axTLS.device_key.pem 1024
|
||||
openssl genrsa -aes128 -passout pass:abcd -out axTLS.key_aes128.pem 512
|
||||
openssl genrsa -aes256 -passout pass:abcd -out axTLS.key_aes256.pem 512
|
||||
|
||||
# convert private keys into DER format
|
||||
openssl rsa -in axTLS.key_512.pem -out axTLS.key_512 -outform DER
|
||||
openssl rsa -in axTLS.key_1024.pem -out axTLS.key_1024 -outform DER
|
||||
openssl rsa -in axTLS.key_2048.pem -out axTLS.key_2048 -outform DER
|
||||
openssl rsa -in axTLS.key_4096.pem -out axTLS.key_4096 -outform DER
|
||||
openssl rsa -in axTLS.device_key.pem -out axTLS.device_key -outform DER
|
||||
|
||||
# cert requests
|
||||
openssl req -out axTLS.ca_x509.req -key axTLS.ca_key.pem -new \
|
||||
-config ./ca_cert.conf
|
||||
openssl req -out axTLS.x509_512.req -key axTLS.key_512.pem -new \
|
||||
-config ./certs.conf
|
||||
openssl req -out axTLS.x509_1024.req -key axTLS.key_1024.pem -new \
|
||||
-config ./certs.conf
|
||||
openssl req -out axTLS.x509_2048.req -key axTLS.key_2048.pem -new \
|
||||
-config ./certs.conf
|
||||
openssl req -out axTLS.x509_4096.req -key axTLS.key_4096.pem -new \
|
||||
-config ./certs.conf
|
||||
openssl req -out axTLS.x509_device.req -key axTLS.device_key.pem -new \
|
||||
-config ./device_cert.conf
|
||||
openssl req -out axTLS.x509_aes128.req -key axTLS.key_aes128.pem \
|
||||
-new -config ./certs.conf -passin pass:abcd
|
||||
openssl req -out axTLS.x509_aes256.req -key axTLS.key_aes256.pem \
|
||||
-new -config ./certs.conf -passin pass:abcd
|
||||
|
||||
# generate the actual certs.
|
||||
openssl x509 -req -in axTLS.ca_x509.req -out axTLS.ca_x509.pem \
|
||||
-sha1 -days 10000 -signkey axTLS.ca_key.pem
|
||||
openssl x509 -req -in axTLS.x509_512.req -out axTLS.x509_512.pem \
|
||||
-sha1 -CAcreateserial -days 10000 \
|
||||
-CA axTLS.ca_x509.pem -CAkey axTLS.ca_key.pem
|
||||
openssl x509 -req -in axTLS.x509_1024.req -out axTLS.x509_1024.pem \
|
||||
-sha1 -CAcreateserial -days 10000 \
|
||||
-CA axTLS.ca_x509.pem -CAkey axTLS.ca_key.pem
|
||||
openssl x509 -req -in axTLS.x509_2048.req -out axTLS.x509_2048.pem \
|
||||
-md5 -CAcreateserial -days 10000 \
|
||||
-CA axTLS.ca_x509.pem -CAkey axTLS.ca_key.pem
|
||||
openssl x509 -req -in axTLS.x509_4096.req -out axTLS.x509_4096.pem \
|
||||
-md5 -CAcreateserial -days 10000 \
|
||||
-CA axTLS.ca_x509.pem -CAkey axTLS.ca_key.pem
|
||||
openssl x509 -req -in axTLS.x509_device.req -out axTLS.x509_device.pem \
|
||||
-sha1 -CAcreateserial -days 10000 \
|
||||
-CA axTLS.x509_512.pem -CAkey axTLS.key_512.pem
|
||||
openssl x509 -req -in axTLS.x509_aes128.req \
|
||||
-out axTLS.x509_aes128.pem \
|
||||
-sha1 -CAcreateserial -days 10000 \
|
||||
-CA axTLS.ca_x509.pem -CAkey axTLS.ca_key.pem
|
||||
openssl x509 -req -in axTLS.x509_aes256.req \
|
||||
-out axTLS.x509_aes256.pem \
|
||||
-sha1 -CAcreateserial -days 10000 \
|
||||
-CA axTLS.ca_x509.pem -CAkey axTLS.ca_key.pem
|
||||
|
||||
# note: must be root to do this
|
||||
DATE_NOW=`date`
|
||||
if date -s "Jan 1 2025"; then
|
||||
openssl x509 -req -in axTLS.x509_512.req -out axTLS.x509_bad_before.pem \
|
||||
-sha1 -CAcreateserial -days 365 \
|
||||
-CA axTLS.ca_x509.pem -CAkey axTLS.ca_key.pem
|
||||
date -s "$DATE_NOW"
|
||||
touch axTLS.x509_bad_before.pem
|
||||
fi
|
||||
openssl x509 -req -in axTLS.x509_512.req -out axTLS.x509_bad_after.pem \
|
||||
-sha1 -CAcreateserial -days -365 \
|
||||
-CA axTLS.ca_x509.pem -CAkey axTLS.ca_key.pem
|
||||
|
||||
# some cleanup
|
||||
rm axTLS*.req
|
||||
rm axTLS.srl
|
||||
rm *.conf
|
||||
|
||||
# need this for the client tests
|
||||
openssl x509 -in axTLS.ca_x509.pem -outform DER -out axTLS.ca_x509.cer
|
||||
openssl x509 -in axTLS.x509_512.pem -outform DER -out axTLS.x509_512.cer
|
||||
openssl x509 -in axTLS.x509_1024.pem -outform DER -out axTLS.x509_1024.cer
|
||||
openssl x509 -in axTLS.x509_2048.pem -outform DER -out axTLS.x509_2048.cer
|
||||
openssl x509 -in axTLS.x509_4096.pem -outform DER -out axTLS.x509_4096.cer
|
||||
openssl x509 -in axTLS.x509_device.pem -outform DER -out axTLS.x509_device.cer
|
||||
|
||||
# generate pkcs8 files (use RC4-128 for encryption)
|
||||
openssl pkcs8 -in axTLS.key_512.pem -passout pass:abcd -topk8 -v1 PBE-SHA1-RC4-128 -out axTLS.encrypted_pem.p8
|
||||
openssl pkcs8 -in axTLS.key_512.pem -passout pass:abcd -topk8 -outform DER -v1 PBE-SHA1-RC4-128 -out axTLS.encrypted.p8
|
||||
openssl pkcs8 -in axTLS.key_512.pem -nocrypt -topk8 -out axTLS.unencrypted_pem.p8
|
||||
openssl pkcs8 -in axTLS.key_512.pem -nocrypt -topk8 -outform DER -out axTLS.unencrypted.p8
|
||||
|
||||
# generate pkcs12 files (use RC4-128 for encryption)
|
||||
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_with_CA" -out axTLS.withCA.p12 -password pass:abcd
|
||||
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_without_CA" -out axTLS.withoutCA.p12 -password pass:abcd
|
||||
openssl pkcs12 -export -in axTLS.x509_1024.pem -inkey axTLS.key_1024.pem -keypbe PBE-SHA1-RC4-128 -certpbe PBE-SHA1-RC4-128 -out axTLS.noname.p12 -password pass:abcd
|
||||
|
||||
# PEM certificate chain
|
||||
cat axTLS.ca_x509.pem >> axTLS.x509_device.pem
|
||||
|
||||
# set default key/cert for use in the server
|
||||
xxd -i axTLS.x509_1024.cer | sed -e \
|
||||
"s/axTLS_x509_1024_cer/default_certificate/" > ../../ssl/cert.h
|
||||
xxd -i axTLS.key_1024 | sed -e \
|
||||
"s/axTLS_key_1024/default_private_key/" > ../../ssl/private_key.h
|
BIN
ssl/test/microsoft.x509_ca
Normal file
BIN
ssl/test/microsoft.x509_ca
Normal file
Binary file not shown.
24
ssl/test/microsoft.x509_ca.pem
Normal file
24
ssl/test/microsoft.x509_ca.pem
Normal file
@ -0,0 +1,24 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEEjCCAvqgAwIBAgIPAMEAizw8iBHRPvZj7N9AMA0GCSqGSIb3DQEBBAUAMHAx
|
||||
KzApBgNVBAsTIkNvcHlyaWdodCAoYykgMTk5NyBNaWNyb3NvZnQgQ29ycC4xHjAc
|
||||
BgNVBAsTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEhMB8GA1UEAxMYTWljcm9zb2Z0
|
||||
IFJvb3QgQXV0aG9yaXR5MB4XDTk3MDExMDA3MDAwMFoXDTIwMTIzMTA3MDAwMFow
|
||||
cDErMCkGA1UECxMiQ29weXJpZ2h0IChjKSAxOTk3IE1pY3Jvc29mdCBDb3JwLjEe
|
||||
MBwGA1UECxMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSEwHwYDVQQDExhNaWNyb3Nv
|
||||
ZnQgUm9vdCBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
|
||||
AQCpAr3BcOY78k4bKJ+XeF4w6qKpjSVf+P6VTKO3/p2iID58UaKboo9gMmvRQmR5
|
||||
7qx2yVTa8uuchhyPn4Rms8VremIj1h083g8BkuiWxL8tZpqaaCaZ0Dosvwy1WCbB
|
||||
RucKPjiWLKkoOajsSYNC44QPu5psVWGsgnyhYC13TOmZtGQ7mlAcMQgkFJ+p55Er
|
||||
GOY9mGMUYFgFZZ8dN1KH96fvlALGG9O/VUWziYC/OuxUlE6u/ad6bXROrxjMlgko
|
||||
IQBXkGBpN7tLEgc8Vv9b+6RmCgim0oFWV++2O14WgXcE2va+roCV/rDNf9anGnJc
|
||||
PMq88AijIjCzBoXJsyB3E4XfAgMBAAGjgagwgaUwgaIGA1UdAQSBmjCBl4AQW9Bw
|
||||
72lyniNRfhSyTY7/y6FyMHAxKzApBgNVBAsTIkNvcHlyaWdodCAoYykgMTk5NyBN
|
||||
aWNyb3NvZnQgQ29ycC4xHjAcBgNVBAsTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEh
|
||||
MB8GA1UEAxMYTWljcm9zb2Z0IFJvb3QgQXV0aG9yaXR5gg8AwQCLPDyIEdE+9mPs
|
||||
30AwDQYJKoZIhvcNAQEEBQADggEBAJXoC8CN85cYNe24ASTYdxHzXGAyn54Lyz4F
|
||||
kYiPyTrmIfLwV5MstaBHyGLv/NfMOztaqTZUaf4kbT/JzKreBXzdMY09nxBwarv+
|
||||
Ek8YacD80EPjEVogT+pie6+qGcgrNyUtvmWhEoolD2Oj91Qc+SHJ1hXzUqxuQzIH
|
||||
/YIX+OVnbA1R9r3xUse958Qw/CAxCYgdlSkaTdUdAqXxgOADtFv0sd3IV+5lScdS
|
||||
VLa0AygS/5DW8AiPfriXxas3LOR65Kh343agANBqP8HSNorgQRKoNWobats14dQc
|
||||
BOSoRQTIWjM4bk0cDWK3CqKM09VUP0bNHFWmcNsSOoeTdZ+n0qA=
|
||||
-----END CERTIFICATE-----
|
216
ssl/test/perf_bigint.c
Normal file
216
ssl/test/perf_bigint.c
Normal file
@ -0,0 +1,216 @@
|
||||
/*
|
||||
* Copyright(C) 2006 Cameron Rich
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This license is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this license; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* Some performance testing of bigint.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "ssl.h"
|
||||
|
||||
/**************************************************************************
|
||||
* BIGINT tests
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#ifdef CONFIG_SSL_CERT_VERIFICATION
|
||||
RSA_CTX *rsa_ctx;
|
||||
BI_CTX *ctx;
|
||||
bigint *bi_data, *bi_res;
|
||||
int diff, res = 1;
|
||||
struct timeval tv_old, tv_new;
|
||||
const char *plaintext;
|
||||
uint8_t compare[MAX_KEY_BYTE_SIZE];
|
||||
int i, max_biggie = 10; /* really crank performance */
|
||||
int len;
|
||||
uint8_t *buf;
|
||||
|
||||
/**
|
||||
* 512 bit key
|
||||
*/
|
||||
plaintext = /* 64 byte number */
|
||||
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^";
|
||||
|
||||
len = get_file("../ssl/test/axTLS.key_512", &buf);
|
||||
asn1_get_private_key(buf, len, &rsa_ctx);
|
||||
ctx = rsa_ctx->bi_ctx;
|
||||
bi_data = bi_import(ctx, (uint8_t *)plaintext, strlen(plaintext));
|
||||
bi_res = RSA_public(rsa_ctx, bi_data);
|
||||
bi_data = bi_res; /* reuse again */
|
||||
|
||||
gettimeofday(&tv_old, NULL);
|
||||
for (i = 0; i < max_biggie; i++)
|
||||
{
|
||||
bi_res = RSA_private(rsa_ctx, bi_copy(bi_data));
|
||||
if (i < max_biggie-1)
|
||||
{
|
||||
bi_free(ctx, bi_res);
|
||||
}
|
||||
}
|
||||
|
||||
gettimeofday(&tv_new, NULL);
|
||||
bi_free(ctx, bi_data);
|
||||
|
||||
diff = (tv_new.tv_sec-tv_old.tv_sec)*1000 +
|
||||
(tv_new.tv_usec-tv_old.tv_usec)/1000;
|
||||
printf("512 bit decrypt time: %dms\n", diff/max_biggie);
|
||||
TTY_FLUSH();
|
||||
bi_export(ctx, bi_res, compare, 64);
|
||||
RSA_free(rsa_ctx);
|
||||
free(buf);
|
||||
if (memcmp(plaintext, compare, 64) != 0)
|
||||
goto end;
|
||||
|
||||
/**
|
||||
* 1024 bit key
|
||||
*/
|
||||
plaintext = /* 128 byte number */
|
||||
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^"
|
||||
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^";
|
||||
|
||||
len = get_file("../ssl/test/axTLS.key_1024", &buf);
|
||||
asn1_get_private_key(buf, len, &rsa_ctx);
|
||||
ctx = rsa_ctx->bi_ctx;
|
||||
bi_data = bi_import(ctx, (uint8_t *)plaintext, strlen(plaintext));
|
||||
bi_res = RSA_public(rsa_ctx, bi_data);
|
||||
bi_data = bi_res; /* reuse again */
|
||||
|
||||
gettimeofday(&tv_old, NULL);
|
||||
for (i = 0; i < max_biggie; i++)
|
||||
{
|
||||
bi_res = RSA_private(rsa_ctx, bi_copy(bi_data));
|
||||
if (i < max_biggie-1)
|
||||
{
|
||||
bi_free(ctx, bi_res);
|
||||
}
|
||||
}
|
||||
|
||||
gettimeofday(&tv_new, NULL);
|
||||
bi_free(ctx, bi_data);
|
||||
|
||||
diff = (tv_new.tv_sec-tv_old.tv_sec)*1000 +
|
||||
(tv_new.tv_usec-tv_old.tv_usec)/1000;
|
||||
printf("1024 bit decrypt time: %dms\n", diff/max_biggie);
|
||||
TTY_FLUSH();
|
||||
bi_export(ctx, bi_res, compare, 128);
|
||||
RSA_free(rsa_ctx);
|
||||
free(buf);
|
||||
if (memcmp(plaintext, compare, 128) != 0)
|
||||
goto end;
|
||||
|
||||
/**
|
||||
* 2048 bit key
|
||||
*/
|
||||
plaintext = /* 256 byte number */
|
||||
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^"
|
||||
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^"
|
||||
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^"
|
||||
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^";
|
||||
|
||||
len = get_file("../ssl/test/axTLS.key_2048", &buf);
|
||||
asn1_get_private_key(buf, len, &rsa_ctx);
|
||||
ctx = rsa_ctx->bi_ctx;
|
||||
bi_data = bi_import(ctx, (uint8_t *)plaintext, strlen(plaintext));
|
||||
bi_res = RSA_public(rsa_ctx, bi_data);
|
||||
bi_data = bi_res; /* reuse again */
|
||||
|
||||
gettimeofday(&tv_old, NULL);
|
||||
for (i = 0; i < max_biggie; i++)
|
||||
{
|
||||
bi_res = RSA_private(rsa_ctx, bi_copy(bi_data));
|
||||
if (i < max_biggie-1)
|
||||
{
|
||||
bi_free(ctx, bi_res);
|
||||
}
|
||||
}
|
||||
gettimeofday(&tv_new, NULL);
|
||||
bi_free(ctx, bi_data);
|
||||
|
||||
diff = (tv_new.tv_sec-tv_old.tv_sec)*1000 +
|
||||
(tv_new.tv_usec-tv_old.tv_usec)/1000;
|
||||
printf("2048 bit decrypt time: %dms\n", diff/max_biggie);
|
||||
TTY_FLUSH();
|
||||
bi_export(ctx, bi_res, compare, 256);
|
||||
RSA_free(rsa_ctx);
|
||||
free(buf);
|
||||
if (memcmp(plaintext, compare, 256) != 0)
|
||||
goto end;
|
||||
|
||||
/**
|
||||
* 4096 bit key
|
||||
*/
|
||||
plaintext = /* 512 byte number */
|
||||
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^"
|
||||
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^"
|
||||
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^"
|
||||
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^"
|
||||
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^"
|
||||
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^"
|
||||
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^"
|
||||
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^";
|
||||
|
||||
len = get_file("../ssl/test/axTLS.key_4096", &buf);
|
||||
asn1_get_private_key(buf, len, &rsa_ctx);
|
||||
ctx = rsa_ctx->bi_ctx;
|
||||
bi_data = bi_import(ctx, (uint8_t *)plaintext, strlen(plaintext));
|
||||
gettimeofday(&tv_old, NULL);
|
||||
bi_res = RSA_public(rsa_ctx, bi_data);
|
||||
gettimeofday(&tv_new, NULL);
|
||||
diff = (tv_new.tv_sec-tv_old.tv_sec)*1000 +
|
||||
(tv_new.tv_usec-tv_old.tv_usec)/1000;
|
||||
printf("4096 bit encrypt time: %dms\n", diff);
|
||||
TTY_FLUSH();
|
||||
bi_data = bi_res; /* reuse again */
|
||||
|
||||
gettimeofday(&tv_old, NULL);
|
||||
for (i = 0; i < max_biggie; i++)
|
||||
{
|
||||
bi_res = RSA_private(rsa_ctx, bi_copy(bi_data));
|
||||
if (i < max_biggie-1)
|
||||
{
|
||||
bi_free(ctx, bi_res);
|
||||
}
|
||||
}
|
||||
|
||||
gettimeofday(&tv_new, NULL);
|
||||
bi_free(ctx, bi_data);
|
||||
|
||||
diff = (tv_new.tv_sec-tv_old.tv_sec)*1000 +
|
||||
(tv_new.tv_usec-tv_old.tv_usec)/1000;
|
||||
printf("4096 bit decrypt time: %dms\n", diff/max_biggie);
|
||||
TTY_FLUSH();
|
||||
bi_export(ctx, bi_res, compare, 512);
|
||||
RSA_free(rsa_ctx);
|
||||
free(buf);
|
||||
if (memcmp(plaintext, compare, 512) != 0)
|
||||
goto end;
|
||||
|
||||
/* done */
|
||||
printf("Bigint performance testing complete\n");
|
||||
res = 0;
|
||||
|
||||
end:
|
||||
return res;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
1813
ssl/test/ssltest.c
Normal file
1813
ssl/test/ssltest.c
Normal file
File diff suppressed because it is too large
Load Diff
136
ssl/test/test_axssl.sh
Executable file
136
ssl/test/test_axssl.sh
Executable file
@ -0,0 +1,136 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright(C) 2006 Cameron Rich
|
||||
#
|
||||
# This license is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This license is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this license; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
#
|
||||
# Test the various axssl bindings. To run it, got to the _install directory
|
||||
# and run this script from there.
|
||||
#
|
||||
|
||||
if grep "CONFIG_PLATFORM_WIN32=y" "../config/.config" > /dev/null; then
|
||||
JAVA_BIN="/cygdrive/c/Program Files/Java/jdk1.5.0_06/bin"
|
||||
PERL_BIN="/cygdrive/c/Perl/bin/perl"
|
||||
KILL_AXSSL="kill %1"
|
||||
KILL_CSHARP="kill %1"
|
||||
KILL_PERL="kill %1"
|
||||
KILL_JAVA="kill %1"
|
||||
else
|
||||
if grep "CONFIG_PLATFORM_CYGWIN=y" "../config/.config" > /dev/null; then
|
||||
# no .net or java on cygwin
|
||||
PERL_BIN=/usr/bin/perl
|
||||
KILL_AXSSL="killall axssl"
|
||||
KILL_PERL="killall /usr/bin/perl"
|
||||
else # Linux
|
||||
JAVA_BIN=/usr/lib/java/bin
|
||||
PERL_BIN=/usr/bin/perl
|
||||
KILL_AXSSL="killall axssl"
|
||||
KILL_CSHARP="killall mono"
|
||||
KILL_PERL="killall /usr/bin/perl"
|
||||
RUN_CSHARP="mono"
|
||||
KILL_JAVA="killall $JAVA_BIN/java"
|
||||
fi
|
||||
fi
|
||||
|
||||
BASE=..
|
||||
SERVER_ARGS="s_server -accept 15001 -verify -CAfile $BASE/ssl/test/axTLS.ca_x509.cer"
|
||||
CLIENT_ARGS="s_client -reconnect -connect localhost:15001 -verify -CAfile $BASE/ssl/test/axTLS.ca_x509.cer -key $BASE/ssl/test/axTLS.key_1024 -cert $BASE/ssl/test/axTLS.x509_1024.cer"
|
||||
|
||||
# check pem arguments
|
||||
SERVER_PEM_ARGS="s_server -accept 15001 -pass abcd -key $BASE/ssl/test/axTLS.key_aes128.pem -cert $BASE/ssl/test/axTLS.x509_aes128.pem"
|
||||
CLIENT_PEM_ARGS="s_client -connect localhost:15001 -CAfile $BASE/ssl/test/axTLS.ca_x509.pem -key $BASE/ssl/test/axTLS.key_1024.pem -cert $BASE/ssl/test/axTLS.x509_1024.pem"
|
||||
|
||||
export LD_LIBRARY_PATH=.:`perl -e 'use Config; print $Config{archlib};'`/CORE
|
||||
|
||||
if [ -x ./axssl ]; then
|
||||
echo "############################# C SAMPLE ###########################"
|
||||
./axssl $SERVER_ARGS &
|
||||
echo "C Test passed" | ./axssl $CLIENT_ARGS
|
||||
$KILL_AXSSL
|
||||
sleep 1
|
||||
|
||||
./axssl $SERVER_PEM_ARGS &
|
||||
echo "C Test passed" | ./axssl $CLIENT_PEM_ARGS
|
||||
$KILL_AXSSL
|
||||
sleep 2
|
||||
echo "### C tests complete"
|
||||
fi
|
||||
|
||||
if [ -f ./axtls.jar ]; then
|
||||
echo "########################## JAVA SAMPLE ###########################"
|
||||
"$JAVA_BIN/java" -jar ./axtls.jar $SERVER_ARGS &
|
||||
echo "Java Test passed" | "$JAVA_BIN/java" -jar ./axtls.jar $CLIENT_ARGS
|
||||
$KILL_JAVA
|
||||
sleep 1
|
||||
|
||||
"$JAVA_BIN/java" -jar ./axtls.jar $SERVER_PEM_ARGS &
|
||||
echo "Java Test passed" | "$JAVA_BIN/java" -jar ./axtls.jar $CLIENT_PEM_ARGS
|
||||
$KILL_JAVA
|
||||
sleep 1
|
||||
|
||||
echo "### Java tests complete"
|
||||
fi
|
||||
|
||||
if [ -x ./axssl.csharp.exe ]; then
|
||||
echo "############################ C# SAMPLE ###########################"
|
||||
$RUN_CSHARP ./axssl.csharp.exe $SERVER_ARGS &
|
||||
echo "C# Test passed" | $RUN_CSHARP ./axssl.csharp.exe $CLIENT_ARGS
|
||||
sleep 1
|
||||
$KILL_CSHARP
|
||||
sleep 1
|
||||
|
||||
$RUN_CSHARP ./axssl.csharp.exe $SERVER_PEM_ARGS &
|
||||
echo "C# Test passed" | $RUN_CSHARP ./axssl.csharp.exe $CLIENT_PEM_ARGS
|
||||
sleep 1
|
||||
$KILL_CSHARP
|
||||
sleep 1
|
||||
|
||||
echo "### C# tests complete"
|
||||
fi
|
||||
|
||||
if [ -x ./axssl.vbnet.exe ]; then
|
||||
echo "######################## VB.NET SAMPLE ###########################"
|
||||
./axssl.vbnet $SERVER_ARGS &
|
||||
sleep 1
|
||||
echo "VB.NET Test passed" | ./axssl.vbnet.exe $CLIENT_ARGS
|
||||
kill %1
|
||||
sleep 1
|
||||
|
||||
./axssl.vbnet $SERVER_PEM_ARGS &
|
||||
sleep 1
|
||||
echo "VB.NET Test passed" | ./axssl.vbnet.exe $CLIENT_PEM_ARGS
|
||||
kill %1
|
||||
sleep 1
|
||||
echo "### VB.NET tests complete"
|
||||
fi
|
||||
|
||||
if [ -f ./axssl.pl ]; then
|
||||
echo "########################## PERL SAMPLE ###########################"
|
||||
"$PERL_BIN" ./axssl.pl $SERVER_ARGS &
|
||||
echo "Perl Test passed" | "$PERL_BIN" ./axssl.pl $CLIENT_ARGS
|
||||
$KILL_PERL
|
||||
sleep 1
|
||||
|
||||
"$PERL_BIN" ./axssl.pl $SERVER_PEM_ARGS &
|
||||
echo "Perl Test passed" | "$PERL_BIN" ./axssl.pl $CLIENT_PEM_ARGS
|
||||
$KILL_PERL
|
||||
sleep 1
|
||||
echo "### Perl tests complete"
|
||||
fi
|
||||
|
||||
echo "########################## ALL TESTS COMPLETE ###########################"
|
BIN
ssl/test/thawte.x509_ca
Normal file
BIN
ssl/test/thawte.x509_ca
Normal file
Binary file not shown.
BIN
ssl/test/verisign.x509_ca
Normal file
BIN
ssl/test/verisign.x509_ca
Normal file
Binary file not shown.
16
ssl/test/verisign.x509_ca.pem
Normal file
16
ssl/test/verisign.x509_ca.pem
Normal file
@ -0,0 +1,16 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICmDCCAgECECCol67bggLewTagTia9h3MwDQYJKoZIhvcNAQECBQAwgYwxCzAJ
|
||||
BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEwMC4GA1UECxMnRm9y
|
||||
IFRlc3QgUHVycG9zZXMgT25seS4gIE5vIGFzc3VyYW5jZXMuMTIwMAYDVQQDEylW
|
||||
ZXJpU2lnbiBUcmlhbCBTZWN1cmUgU2VydmVyIFRlc3QgUm9vdCBDQTAeFw0wNTAy
|
||||
MDkwMDAwMDBaFw0yNTAyMDgyMzU5NTlaMIGMMQswCQYDVQQGEwJVUzEXMBUGA1UE
|
||||
ChMOVmVyaVNpZ24sIEluYy4xMDAuBgNVBAsTJ0ZvciBUZXN0IFB1cnBvc2VzIE9u
|
||||
bHkuICBObyBhc3N1cmFuY2VzLjEyMDAGA1UEAxMpVmVyaVNpZ24gVHJpYWwgU2Vj
|
||||
dXJlIFNlcnZlciBUZXN0IFJvb3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ
|
||||
AoGBAJ8h98U7klaZH5cEn6CSEKmGWVBsTwHIaMAAVqGqCUn7Q9C10sEOIHBznyLy
|
||||
eSDjMs5M1nC/iAA7KCASf/yHz0AdlU+1IRSijwHTF/2dYSoTTxP2GCmtL1Ga4i7+
|
||||
zDDo086V7+NiFAGJj+CYey47ue4Xa33o/4YOA9PGL87oqFe7AgMBAAEwDQYJKoZI
|
||||
hvcNAQECBQADgYEAOq447rP5EDqFEl3vhLhgTbnyaskNYwPvxk+0grnQyDA4sF/q
|
||||
gK8nFlnvLmAOF3DmfuqW6WSr4zqTYzpwmJlsn48Om/yWirL8GuWRftit2POxTfHS
|
||||
B8VmR+PZx2k24UgWUZyojDGxJtiHd3tjCdqFgTit4NK429cWOcZrh47xeOI=
|
||||
-----END CERTIFICATE-----
|
BIN
ssl/test/verisign.x509_my_cert
Normal file
BIN
ssl/test/verisign.x509_my_cert
Normal file
Binary file not shown.
25
ssl/test/verisign.x509_my_cert.pem
Normal file
25
ssl/test/verisign.x509_my_cert.pem
Normal file
@ -0,0 +1,25 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEQzCCA6ygAwIBAgIQR/dXCzC/x5Ta5RvL6hKEojANBgkqhkiG9w0BAQUFADCB
|
||||
jDELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTAwLgYDVQQL
|
||||
EydGb3IgVGVzdCBQdXJwb3NlcyBPbmx5LiAgTm8gYXNzdXJhbmNlcy4xMjAwBgNV
|
||||
BAMTKVZlcmlTaWduIFRyaWFsIFNlY3VyZSBTZXJ2ZXIgVGVzdCBSb290IENBMB4X
|
||||
DTA2MDExNjAwMDAwMFoXDTA2MDEzMDIzNTk1OVowgbkxCzAJBgNVBAYTAkFVMQww
|
||||
CgYDVQQIEwNRbGQxETAPBgNVBAcUCEJyaXNiYW5lMRkwFwYDVQQKFBBheG9sb1RM
|
||||
UyBQcm9qZWN0MRUwEwYDVQQLFAwxMDI0IGJpdCBrZXkxOjA4BgNVBAsUMVRlcm1z
|
||||
IG9mIHVzZSBhdCB3d3cudmVyaXNpZ24uY29tL2Nwcy90ZXN0Y2EgKGMpMDUxGzAZ
|
||||
BgNVBAMUEnd3dy5heG9sb3Rscy5jby5ucjCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
|
||||
gYkCgYEAttzj5S7qfOZIrh9xg8bgjTOKbSIbLBuMnxAwfGRcUrQO2EQOHd6kMjXR
|
||||
hqY/cG2IG4G8AeqdV3nHlKbrbHbRa1lFgP6b0BQCE8TyxmP+tIAqn5L6/HTm+EEi
|
||||
Ad1Pxjeok6e7F6UXHxJltSGHmOhAf3C5kPq/FQ6QZeG4yD/uzPkCAwEAAaOCAXUw
|
||||
ggFxMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgWgMEcGA1UdHwRAMD4wPKA6oDiGNmh0
|
||||
dHA6Ly9TVlJTZWN1cmUtY3JsLnZlcmlzaWduLmNvbS9TVlJUcmlhbFJvb3QyMDA1
|
||||
LmNybDBKBgNVHSAEQzBBMD8GCmCGSAGG+EUBBxUwMTAvBggrBgEFBQcCARYjaHR0
|
||||
cHM6Ly93d3cudmVyaXNpZ24uY29tL2Nwcy90ZXN0Y2EwHQYDVR0lBBYwFAYIKwYB
|
||||
BQUHAwEGCCsGAQUFBwMCMDQGCCsGAQUFBwEBBCgwJjAkBggrBgEFBQcwAYYYaHR0
|
||||
cDovL29jc3AudmVyaXNpZ24uY29tMG0GCCsGAQUFBwEMBGEwX6FdoFswWTBXMFUW
|
||||
CWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2Oa8PPgGrUSBgsexkuMCUW
|
||||
I2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMA0GCSqGSIb3DQEB
|
||||
BQUAA4GBACtlCTJFENCcHCQLHJfiotqr2XR+oWu0MstNm8dG6WB+zYprrT+kOPDn
|
||||
1rMO7YLx76f67fC+lIXz720kQHk6LsZ8hPBQvIXnfIsKjng73DeFzBmTMFz6Qxjd
|
||||
+E0FUCKplqrdwUkmR4kH6O4pdGE4AlXJNiUI2903yYdSRVMOuLuR
|
||||
-----END CERTIFICATE-----
|
2045
ssl/tls1.c
Executable file
2045
ssl/tls1.c
Executable file
File diff suppressed because it is too large
Load Diff
288
ssl/tls1.h
Executable file
288
ssl/tls1.h
Executable file
@ -0,0 +1,288 @@
|
||||
/*
|
||||
* Copyright(C) 2006 Cameron Rich
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @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"
|
||||
|
||||
/* 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
|
||||
|
||||
#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
|
||||
|
||||
/* 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_SESS;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t *buf;
|
||||
int size;
|
||||
} SSL_CERT;
|
||||
|
||||
struct _SSL
|
||||
{
|
||||
uint32_t flag;
|
||||
uint16_t need_bytes;
|
||||
uint16_t got_bytes;
|
||||
uint8_t record_type;
|
||||
uint8_t chain_length;
|
||||
uint8_t cipher;
|
||||
int16_t next_state;
|
||||
int16_t hs_status;
|
||||
uint8_t *all_pkts;
|
||||
int all_pkts_len;
|
||||
int client_fd;
|
||||
const cipher_info_t *cipher_info;
|
||||
uint8_t *final_finish_mac;
|
||||
uint8_t *key_block;
|
||||
void *encrypt_ctx;
|
||||
void *decrypt_ctx;
|
||||
uint8_t bm_all_data[RT_MAX_PLAIN_LENGTH+RT_EXTRA];
|
||||
uint8_t *bm_data;
|
||||
int bm_index;
|
||||
struct _SSL *next; /* doubly linked list */
|
||||
struct _SSL *prev;
|
||||
SSL_CERT *certs;
|
||||
struct _SSL_CTX *ssl_ctx; /* back reference to a clnt/svr ctx */
|
||||
#ifndef CONFIG_SSL_SKELETON_MODE
|
||||
uint16_t session_index;
|
||||
SSL_SESS *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 client_random[SSL_RANDOM_SIZE]; /* client's random sequence */
|
||||
uint8_t server_random[SSL_RANDOM_SIZE]; /* server's random sequence */
|
||||
uint8_t *master_secret;
|
||||
uint8_t read_sequence[8]; /* 64 bit sequence number */
|
||||
uint8_t write_sequence[8]; /* 64 bit sequence number */
|
||||
uint8_t record_buf[SSL_RECORD_SIZE]; /* storage for hmac calls later */
|
||||
};
|
||||
|
||||
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_SESS **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);
|
||||
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, 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);
|
||||
#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 char *label, const X509_CTX *x509_ctx);
|
||||
void DISPLAY_RSA(SSL *ssl, const char *label, 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,C)
|
||||
#define DISPLAY_RSA(A,B,C)
|
||||
#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_SESS *ssl_session_update(int max_sessions,
|
||||
SSL_SESS *ssl_sessions[], SSL *ssl,
|
||||
const uint8_t *session_id);
|
||||
void kill_ssl_session(SSL_SESS **ssl_sessions, SSL *ssl);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
338
ssl/tls1_clnt.c
Normal file
338
ssl/tls1_clnt.c
Normal file
@ -0,0 +1,338 @@
|
||||
/*
|
||||
* Copyright(C) 2006 Cameron Rich
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <stdio.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)
|
||||
{
|
||||
int ret;
|
||||
SSL *ssl = ssl_new(ssl_ctx, client_fd);
|
||||
|
||||
if (session_id && ssl_ctx->num_sessions)
|
||||
{
|
||||
memcpy(ssl->session_id, session_id, SSL_SESSION_ID_SIZE);
|
||||
SET_SSL_FLAG(SSL_SESSION_RESUME); /* just flag for later */
|
||||
}
|
||||
|
||||
SET_SSL_FLAG(SSL_IS_CLIENT);
|
||||
ret = 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 = SSL_OK;
|
||||
|
||||
/* 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)
|
||||
{
|
||||
ret = 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, hs_len);
|
||||
break;
|
||||
|
||||
case HS_HELLO_REQUEST:
|
||||
ret = do_client_connect(ssl);
|
||||
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_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 */
|
||||
while (ssl->hs_status != SSL_OK)
|
||||
{
|
||||
ret = basic_read(ssl, NULL);
|
||||
|
||||
if (ret < SSL_OK)
|
||||
{
|
||||
if (ret != SSL_ERROR_CONN_LOST)
|
||||
{
|
||||
/* let the server know we are dying and why */
|
||||
if (send_alert(ssl, ret))
|
||||
{
|
||||
/* something nasty happened, so get rid of it */
|
||||
kill_ssl_session(ssl->ssl_ctx->ssl_sessions, ssl);
|
||||
}
|
||||
}
|
||||
|
||||
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] = 0x01;
|
||||
|
||||
/* 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->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 bu user */
|
||||
{
|
||||
buf[offset++] = SSL_SESSION_ID_SIZE;
|
||||
memcpy(&buf[offset], ssl->session_id, SSL_SESSION_ID_SIZE);
|
||||
offset += SSL_SESSION_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 offset;
|
||||
int version = (buf[4] << 4) + buf[5];
|
||||
int num_sessions = ssl->ssl_ctx->num_sessions;
|
||||
int ret = SSL_OK;
|
||||
|
||||
/* check that we are talking to a TLSv1 server */
|
||||
if (version != 0x31)
|
||||
return SSL_ERROR_INVALID_VERSION;
|
||||
|
||||
/* get the server random value */
|
||||
memcpy(ssl->server_random, &buf[6], SSL_RANDOM_SIZE);
|
||||
offset = 7 + SSL_RANDOM_SIZE; /* skip of session id size */
|
||||
|
||||
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], SSL_SESSION_ID_SIZE);
|
||||
}
|
||||
|
||||
memcpy(ssl->session_id, &buf[offset], SSL_SESSION_ID_SIZE);
|
||||
offset += SSL_SESSION_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;
|
||||
|
||||
PARANOIA_CHECK(pkt_size, offset);
|
||||
|
||||
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] = 0x01;
|
||||
get_random(SSL_SECRET_SIZE-2, &premaster_secret[2]);
|
||||
DISPLAY_RSA(ssl, "send_client_key_xchg", 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)
|
||||
{
|
||||
/* 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);
|
||||
return SSL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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, ret;
|
||||
|
||||
DISPLAY_RSA(ssl, "send_cert_verify", 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 */
|
||||
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 */
|
450
ssl/tls1_svr.c
Normal file
450
ssl/tls1_svr.c
Normal file
@ -0,0 +1,450 @@
|
||||
/*
|
||||
* Copyright(C) 2006 Cameron Rich
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.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_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, hs_len);
|
||||
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->record_buf;
|
||||
int pkt_size = ssl->bm_index;
|
||||
int i, j, cs_len, id_len, offset = 6 + SSL_RANDOM_SIZE;
|
||||
int version = (record_buf[1] << 4) + record_buf[2];
|
||||
int ret = SSL_OK;
|
||||
|
||||
/* should be v3.1 (TLSv1) or better - we'll send in v3.1 mode anyway */
|
||||
if (version < 0x31)
|
||||
{
|
||||
ret = SSL_ERROR_INVALID_VERSION;
|
||||
ssl_display_error(ret);
|
||||
goto error;
|
||||
}
|
||||
|
||||
memcpy(ssl->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 */
|
||||
for (j = 0; j < NUM_PROTOCOLS; j++)
|
||||
{
|
||||
for (i = 0; i < cs_len; i += 2)
|
||||
{
|
||||
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 version = (buf[3] << 4) + buf[4];
|
||||
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);
|
||||
|
||||
/* should be v3.1 (TLSv1) or better - we'll send in v3.1 mode anyway */
|
||||
if (version < 0x31)
|
||||
{
|
||||
return SSL_ERROR_INVALID_VERSION;
|
||||
}
|
||||
|
||||
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->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] = 0x01;
|
||||
|
||||
/* server random value */
|
||||
get_random(SSL_RANDOM_SIZE, &buf[6]);
|
||||
memcpy(ssl->server_random, &buf[6], SSL_RANDOM_SIZE);
|
||||
offset = 6 + SSL_RANDOM_SIZE;
|
||||
|
||||
/* send a session id - and put it into the cache */
|
||||
buf[offset++] = SSL_SESSION_ID_SIZE;
|
||||
|
||||
#ifndef CONFIG_SSL_SKELETON_MODE
|
||||
if (IS_SET_SSL_FLAG(SSL_SESSION_RESUME))
|
||||
{
|
||||
/* retrieve id from session cache */
|
||||
memcpy(&buf[offset], ssl->session->session_id,
|
||||
SSL_SESSION_ID_SIZE);
|
||||
memcpy(ssl->session_id, ssl->session->session_id, SSL_SESSION_ID_SIZE);
|
||||
}
|
||||
else /* generate our own session id */
|
||||
#endif
|
||||
{
|
||||
get_random(SSL_SESSION_ID_SIZE, &buf[offset]);
|
||||
memcpy(ssl->session_id, &buf[offset], SSL_SESSION_ID_SIZE);
|
||||
|
||||
#ifndef CONFIG_SSL_SKELETON_MODE
|
||||
/* store id in session cache */
|
||||
if (ssl->ssl_ctx->num_sessions)
|
||||
{
|
||||
memcpy(ssl->session->session_id,
|
||||
ssl->session_id, SSL_SESSION_ID_SIZE);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
offset += SSL_SESSION_ID_SIZE;
|
||||
|
||||
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;
|
||||
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;
|
||||
|
||||
DISPLAY_RSA(ssl, "process_client_key_xchg", rsa_ctx);
|
||||
|
||||
/* 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 || /* check version is 3.1 (TLS) */
|
||||
premaster_secret[1] != 0x01)
|
||||
{
|
||||
/* guard against a Bleichenbacher attack */
|
||||
memset(premaster_secret, 0, SSL_SECRET_SIZE);
|
||||
/* 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
|
||||
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;
|
||||
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, "process_cert_verify", x509_ctx->rsa_ctx);
|
||||
n = RSA_decrypt(x509_ctx->rsa_ctx, &buf[6], dgst_buf, 0);
|
||||
|
||||
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
|
Reference in New Issue
Block a user