add use cert chain handling

This commit is contained in:
Todd A Ouska 2011-04-09 13:08:56 -07:00
parent 0c6015fb86
commit 831f4b6be9
8 changed files with 159 additions and 16 deletions

View File

@ -37,3 +37,59 @@ Kp5+VqW2h58VxxhmfhZ34qcCAwEAATANBgkqhkiG9w0BAQQFAANBAFipmOcWUkxA
5+FHkhkbOo+XbHu3sMsgba2100dY2OTyPjLp74d35VQ29I1QjQe0d0XqnaQzNpsL
4HRYEcUBe00=
-----END CERTIFICATE-----
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
8a:37:22:65:73:f5:aa:e8
Signature Algorithm: md5WithRSAEncryption
Issuer: C=US, ST=Montana, L=Bozeman, O=sawtooth, OU=consulting, CN=www.sawtooth-consulting.com/emailAddress=info@yassl.com
Validity
Not Before: Jun 30 18:47:10 2010 GMT
Not After : Mar 26 18:47:10 2013 GMT
Subject: C=US, ST=Montana, L=Bozeman, O=sawtooth, OU=consulting, CN=www.sawtooth-consulting.com/emailAddress=info@yassl.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (512 bit)
Modulus (512 bit):
00:97:30:b9:1a:92:ef:25:4f:ca:4c:11:31:95:1a:
e1:c0:10:19:0a:20:b9:37:80:1a:57:38:02:4e:1b:
c5:0f:28:4f:da:e3:c9:16:aa:50:bd:4a:fb:b7:71:
c7:35:cc:63:81:c1:dd:9d:33:f9:38:16:88:32:a0:
aa:56:23:03:a3
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Key Identifier:
3B:66:FD:A0:40:C6:F4:E2:70:CF:21:1A:0C:4F:67:FE:B7:4B:42:09
X509v3 Authority Key Identifier:
keyid:3B:66:FD:A0:40:C6:F4:E2:70:CF:21:1A:0C:4F:67:FE:B7:4B:42:09
DirName:/C=US/ST=Montana/L=Bozeman/O=sawtooth/OU=consulting/CN=www.sawtooth-consulting.com/emailAddress=info@yassl.com
serial:8A:37:22:65:73:F5:AA:E8
X509v3 Basic Constraints:
CA:TRUE
Signature Algorithm: md5WithRSAEncryption
32:65:a2:b1:dc:6d:e0:8d:8b:c8:58:29:8e:b8:18:4b:62:88:
13:67:f8:6c:75:46:75:8f:8a:19:a6:a3:d5:3c:fc:57:4e:7a:
68:a9:fc:93:dc:ae:29:7d:bb:4e:ec:ea:55:fa:a4:e3:00:61:
f4:b0:34:6d:d1:d5:a4:64:24:f8
-----BEGIN CERTIFICATE-----
MIIDQDCCAuqgAwIBAgIJAIo3ImVz9aroMA0GCSqGSIb3DQEBBAUAMIGeMQswCQYD
VQQGEwJVUzEQMA4GA1UECBMHTW9udGFuYTEQMA4GA1UEBxMHQm96ZW1hbjERMA8G
A1UEChMIc2F3dG9vdGgxEzARBgNVBAsTCmNvbnN1bHRpbmcxJDAiBgNVBAMTG3d3
dy5zYXd0b290aC1jb25zdWx0aW5nLmNvbTEdMBsGCSqGSIb3DQEJARYOaW5mb0B5
YXNzbC5jb20wHhcNMTAwNjMwMTg0NzEwWhcNMTMwMzI2MTg0NzEwWjCBnjELMAkG
A1UEBhMCVVMxEDAOBgNVBAgTB01vbnRhbmExEDAOBgNVBAcTB0JvemVtYW4xETAP
BgNVBAoTCHNhd3Rvb3RoMRMwEQYDVQQLEwpjb25zdWx0aW5nMSQwIgYDVQQDExt3
d3cuc2F3dG9vdGgtY29uc3VsdGluZy5jb20xHTAbBgkqhkiG9w0BCQEWDmluZm9A
eWFzc2wuY29tMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJcwuRqS7yVPykwRMZUa
4cAQGQoguTeAGlc4Ak4bxQ8oT9rjyRaqUL1K+7dxxzXMY4HB3Z0z+TgWiDKgqlYj
A6MCAwEAAaOCAQcwggEDMB0GA1UdDgQWBBQ7Zv2gQMb04nDPIRoMT2f+t0tCCTCB
0wYDVR0jBIHLMIHIgBQ7Zv2gQMb04nDPIRoMT2f+t0tCCaGBpKSBoTCBnjELMAkG
A1UEBhMCVVMxEDAOBgNVBAgTB01vbnRhbmExEDAOBgNVBAcTB0JvemVtYW4xETAP
BgNVBAoTCHNhd3Rvb3RoMRMwEQYDVQQLEwpjb25zdWx0aW5nMSQwIgYDVQQDExt3
d3cuc2F3dG9vdGgtY29uc3VsdGluZy5jb20xHTAbBgkqhkiG9w0BCQEWDmluZm9A
eWFzc2wuY29tggkAijciZXP1qugwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQF
AANBADJlorHcbeCNi8hYKY64GEtiiBNn+Gx1RnWPihmmo9U8/FdOemip/JPcril9
u07s6lX6pOMAYfSwNG3R1aRkJPg=
-----END CERTIFICATE-----

View File

@ -1,6 +1,6 @@
AC_INIT
AC_CANONICAL_SYSTEM
AM_INIT_AUTOMAKE(cyassl,1.9.5) # !!! also change in ssl.h !!!
AM_INIT_AUTOMAKE(cyassl,1.9.6) # !!! also change in ssl.h !!!
AM_CONFIG_HEADER(ctaocrypt/include/config.h)

View File

@ -79,7 +79,7 @@
#define STDC_HEADERS 1
/* Version number of package */
#define VERSION "1.9.5"
#define VERSION "1.9.6"
/* Define to 1 if your processor stores words with the most significant byte
first (like Motorola and SPARC, unlike Intel and VAX). */

View File

@ -96,9 +96,9 @@ THREAD_RETURN CYASSL_API server_test(void* args)
!= SSL_SUCCESS)
err_sys("can't load ntru key file");
#else /* normal */
if (SSL_CTX_use_certificate_file(ctx, svrCert, SSL_FILETYPE_PEM)
if (SSL_CTX_use_certificate_chain_file(ctx, svrCert)
!= SSL_SUCCESS)
err_sys("can't load server cert file");
err_sys("can't load server cert chain file");
if (SSL_CTX_use_PrivateKey_file(ctx, svrKey, SSL_FILETYPE_PEM)
!= SSL_SUCCESS)

View File

@ -92,6 +92,9 @@
typedef byte word24[3];
/* used by ssl.c and cyassl_int.c */
void c32to24(word32 in, word24 out);
/* Define or comment out the cipher suites you'd like to be compiled in
make sure to use at least one BUILD_SSL_xxx or BUILD_TLS_xxx is defined
@ -576,6 +579,8 @@ struct SSL_CIPHER {
struct SSL_CTX {
SSL_METHOD* method;
buffer certificate;
buffer certChain;
/* chain after self, in DER, with leading size for each cert */
buffer privateKey;
Signer* caList; /* SSL_CTX owns this, SSL will reference */
Suites suites;
@ -837,6 +842,8 @@ enum AcceptState {
typedef struct Buffers {
buffer certificate; /* SSL_CTX owns, unless we own */
buffer key; /* SSL_CTX owns, unless we own */
buffer certChain; /* SSL_CTX owns */
/* chain after self, in DER, with leading size for each cert */
buffer domainName; /* for client check */
buffer serverDH_P;
buffer serverDH_G;
@ -1029,11 +1036,12 @@ enum {
typedef struct EncryptedInfo {
char name[NAME_SZ];
byte iv[IV_SZ];
word32 ivSz;
byte set;
SSL_CTX* ctx;
char name[NAME_SZ]; /* encryption name */
byte iv[IV_SZ]; /* encrypted IV */
word32 ivSz; /* encrypted IV size */
long consumed; /* tracks PEM bytes consumed */
byte set; /* if encryption set */
SSL_CTX* ctx; /* CTX owner */
} EncryptedInfo;

View File

@ -39,7 +39,7 @@
#include "prefix_ssl.h"
#endif
#define CYASSL_VERSION "1.9.5"
#define CYASSL_VERSION "1.9.6"
#undef X509_NAME /* wincrypt.h clash */

View File

@ -148,7 +148,8 @@ static byte GetEntropy(ENTROPY_CMD cmd, byte* out)
#endif /* HAVE_NTRU */
static INLINE void c32to24(word32 in, word24 out)
/* used by ssl.c too */
void c32to24(word32 in, word24 out)
{
out[0] = (in >> 16) & 0xff;
out[1] = (in >> 8) & 0xff;
@ -318,6 +319,7 @@ void InitSSL_Ctx(SSL_CTX* ctx, SSL_METHOD* method)
{
ctx->method = method;
ctx->certificate.buffer = 0;
ctx->certChain.buffer = 0;
ctx->privateKey.buffer = 0;
ctx->haveDH = 0;
ctx->haveNTRU = 0; /* start off */
@ -376,6 +378,7 @@ void SSL_CtxResourceFree(SSL_CTX* ctx)
{
XFREE(ctx->privateKey.buffer, ctx->heap, DYNAMIC_TYPE_KEY);
XFREE(ctx->certificate.buffer, ctx->heap, DYNAMIC_TYPE_CERT);
XFREE(ctx->certChain.buffer, ctx->heap, DYNAMIC_TYPE_CERT);
XFREE(ctx->method, ctx->heap, DYNAMIC_TYPE_METHOD);
FreeSigners(ctx->caList, ctx->heap);
@ -611,6 +614,7 @@ int InitSSL(SSL* ssl, SSL_CTX* ctx)
ssl->buffers.certificate.buffer = 0;
ssl->buffers.key.buffer = 0;
ssl->buffers.certChain.buffer = 0;
ssl->buffers.inputBuffer.length = 0;
ssl->buffers.inputBuffer.idx = 0;
ssl->buffers.inputBuffer.buffer = ssl->buffers.inputBuffer.staticBuffer;
@ -695,8 +699,9 @@ int InitSSL(SSL* ssl, SSL_CTX* ctx)
ssl->options.partialWrite = ctx->partialWrite;
ssl->options.quietShutdown = ctx->quietShutdown;
/* SSL_CTX still owns certificate, key, and caList buffers */
/* SSL_CTX still owns certificate, certChain, key, and caList buffers */
ssl->buffers.certificate = ctx->certificate;
ssl->buffers.certChain = ctx->certChain;
ssl->buffers.key = ctx->privateKey;
ssl->buffers.weOwnCert = 0;
ssl->buffers.weOwnKey = 0;
@ -785,6 +790,7 @@ void SSL_ResourceFree(SSL* ssl)
XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, DYNAMIC_TYPE_DH);
XFREE(ssl->buffers.domainName.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN);
/* SSL_CTX always owns certChain */
if (ssl->buffers.weOwnCert)
XFREE(ssl->buffers.certificate.buffer, ssl->heap, DYNAMIC_TYPE_CERT);
if (ssl->buffers.weOwnKey)
@ -2534,6 +2540,12 @@ int SendCertificate(SSL* ssl)
/* list + cert size */
length = certSz + 2 * CERT_HEADER_SZ;
listSz = certSz + CERT_HEADER_SZ;
/* may need to send rest of chain, already has leading size(s) */
if (ssl->buffers.certChain.buffer) {
length += ssl->buffers.certChain.length;
listSz += ssl->buffers.certChain.length;
}
}
sendSz = length + RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
@ -2564,6 +2576,13 @@ int SendCertificate(SSL* ssl)
i += CERT_HEADER_SZ;
XMEMCPY(output + i, ssl->buffers.certificate.buffer, certSz);
i += certSz;
/* send rest of chain? */
if (ssl->buffers.certChain.buffer) {
XMEMCPY(output + i, ssl->buffers.certChain.buffer,
ssl->buffers.certChain.length);
i += ssl->buffers.certChain.length;
}
}
HashOutput(ssl, output, sendSz, 0);
#ifdef CYASSL_CALLBACKS

View File

@ -364,6 +364,8 @@ static int AddCA(SSL_CTX* ctx, buffer der)
#endif /* NO_SESSION_CACHE */
/* Remove PEM header/footer, convert to ASN1, store any encrypted data
info->consumed tracks of PEM bytes consumed in case multiple parts */
static int PemToDer(const unsigned char* buff, long sz, int type,
buffer* der, void* heap, EncryptedInfo* info, int* eccKey)
{
@ -371,6 +373,7 @@ static int AddCA(SSL_CTX* ctx, buffer der)
char footer[PEM_LINE_LEN];
char* headerEnd;
char* footerEnd;
char* consumedEnd;
long neededSz;
int pkcs8 = 0;
int pkcs8Enc = 0;
@ -475,6 +478,18 @@ static int AddCA(SSL_CTX* ctx, buffer der)
footerEnd = XSTRSTR((char*)buff, footer);
if (!footerEnd) return SSL_BAD_FILE;
consumedEnd = footerEnd + XSTRLEN(footer);
/* get next line */
if (consumedEnd[0] == '\n')
consumedEnd++;
else if (consumedEnd[1] == '\n')
consumedEnd += 2;
else
return SSL_BAD_FILE;
info->consumed = (long)(consumedEnd - (char*)buff);
/* set up der buffer */
neededSz = (long)(footerEnd - headerEnd);
if (neededSz > sz || neededSz < 0) return SSL_BAD_FILE;
@ -515,9 +530,10 @@ static int AddCA(SSL_CTX* ctx, buffer der)
int dynamicType;
int eccKey = 0;
info.set = 0;
info.ctx = ctx;
der.buffer = 0;
info.set = 0;
info.ctx = ctx;
info.consumed = 0;
der.buffer = 0;
if (format != SSL_FILETYPE_ASN1 && format != SSL_FILETYPE_PEM
&& format != SSL_FILETYPE_RAW)
@ -536,6 +552,50 @@ static int AddCA(SSL_CTX* ctx, buffer der)
XFREE(der.buffer, ctx->heap, dynamicType);
return ret;
}
/* we may have a cert chain */
if (type == CERT_TYPE && info.consumed < sz) {
/* allow a chain of MAX_DEPTH plus subject, 5 by default */
byte chainBuffer[MAX_X509_SIZE * MAX_CHAIN_DEPTH];
long consumed = info.consumed;
word32 idx = 0;
CYASSL_MSG("Processing Cert Chain");
while (consumed < sz) {
buffer part;
info.consumed = 0;
part.buffer = 0;
ret = PemToDer(buff + consumed, sz - consumed, type, &part,
ctx->heap, &info, &eccKey);
if (ret == 0) {
if ( (idx + part.length) > sizeof(chainBuffer)) {
CYASSL_MSG(" Cert Chain bigger than buffer");
ret = BUFFER_E;
}
else {
c32to24(part.length, &chainBuffer[idx]);
idx += CERT_HEADER_SZ;
XMEMCPY(&chainBuffer[idx], part.buffer,part.length);
idx += part.length;
consumed += info.consumed;
}
}
XFREE(part.buffer, ctx->heap, dynamicType);
if (ret < 0) {
CYASSL_MSG(" Error in Cert in Chain");
return ret;
}
CYASSL_MSG(" Consumed another Cert in Chain");
}
CYASSL_MSG("Finished Processing Cert Chain");
ctx->certChain.buffer = (byte*)XMALLOC(idx, ctx->heap,
dynamicType);
if (ctx->certChain.buffer == NULL)
return MEMORY_E;
ctx->certChain.length = idx;
XMEMCPY(ctx->certChain.buffer, chainBuffer, idx);
}
}
else { /* ASN1 (DER) or RAW (NTRU) */
der.buffer = (byte*) XMALLOC(sz, ctx->heap, dynamicType);
@ -830,7 +890,7 @@ int SSL_CTX_use_PrivateKey_file(SSL_CTX* ctx, const char* file, int format)
int SSL_CTX_use_certificate_chain_file(SSL_CTX* ctx, const char* file)
{
/* add first to ctx, all tested implementations support this */
/* procces up to MAX_CHAIN_DEPTH plus subject cert */
if (ProcessFile(ctx, file, SSL_FILETYPE_PEM, CERT_TYPE, NULL) == SSL_SUCCESS)
return SSL_SUCCESS;