add use cert chain handling
This commit is contained in:
parent
0c6015fb86
commit
831f4b6be9
@ -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-----
|
||||
|
@ -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)
|
||||
|
||||
|
||||
|
@ -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). */
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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
|
||||
|
68
src/ssl.c
68
src/ssl.c
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user