diff --git a/Makefile.am b/Makefile.am index a502fe4f1..95d4ead56 100644 --- a/Makefile.am +++ b/Makefile.am @@ -39,6 +39,7 @@ EXTRA_DIST+= cyassl.sln include cyassl/include.am include certs/include.am +include certs/crl/include.am include doc/include.am include swig/include.am diff --git a/certs/crl/crl.pem b/certs/crl/crl.pem new file mode 100644 index 000000000..90af3b8ec --- /dev/null +++ b/certs/crl/crl.pem @@ -0,0 +1,41 @@ +Certificate Revocation List (CRL): + Version 2 (0x1) + Signature Algorithm: sha1WithRSAEncryption + Issuer: /C=US/ST=Montana/L=Bozeman/O=Sawtooth/OU=Consulting/CN=www.yassl.com/emailAddress=info@yassl.com + Last Update: May 15 23:51:25 2012 GMT + Next Update: Jun 14 23:51:25 2012 GMT + CRL extensions: + X509v3 CRL Number: + 4 +Revoked Certificates: + Serial Number: 02 + Revocation Date: May 4 17:06:05 2012 GMT + Signature Algorithm: sha1WithRSAEncryption + aa:e4:44:9b:6b:c9:0b:d3:6f:ba:09:3d:90:93:ae:96:86:73: + f6:90:28:ba:93:3b:95:0c:91:c9:10:53:f1:15:fd:43:9a:ba: + 4e:dc:8e:e8:10:4d:d8:8b:be:a8:a2:12:4c:19:c1:13:9f:3c: + fe:54:60:32:b7:45:77:17:2a:40:f2:16:52:9e:68:fe:be:03: + 99:9c:b1:d3:4b:be:87:5b:f4:12:3c:9e:3d:59:c8:b9:a2:2c: + 78:94:9c:cd:b0:17:d0:b3:bd:86:99:2b:1d:38:b5:03:d8:d1: + 0d:8f:1a:8c:97:ff:87:01:4f:91:22:30:c2:a5:10:bb:e3:fb: + 31:b7:44:8a:5a:82:e1:e5:30:69:84:d1:4b:c2:d3:07:bf:21: + d5:33:2d:ad:4b:e4:6f:83:c1:66:16:74:31:7d:f9:d6:1e:10: + 66:fd:7d:ad:66:3c:32:cc:a3:98:75:63:16:5c:df:e1:37:3d: + e9:08:d2:7b:05:dd:4c:31:92:53:0c:f1:ea:8e:be:31:d1:eb: + ac:37:a8:cd:c4:30:c5:91:cc:38:a3:55:4a:51:01:39:cf:7d: + 50:57:d2:f2:47:4a:1d:7f:3a:32:16:89:e8:5a:1b:f8:64:33: + 48:e5:b8:ef:ba:2e:f3:52:7e:ba:28:0e:9b:f7:07:b8:b6:38: + f9:d0:dd:78 +-----BEGIN X509 CRL----- +MIICADCB6QIBATANBgkqhkiG9w0BAQUFADCBkDELMAkGA1UEBhMCVVMxEDAOBgNV +BAgTB01vbnRhbmExEDAOBgNVBAcTB0JvemVtYW4xETAPBgNVBAoTCFNhd3Rvb3Ro +MRMwEQYDVQQLEwpDb25zdWx0aW5nMRYwFAYDVQQDEw13d3cueWFzc2wuY29tMR0w +GwYJKoZIhvcNAQkBFg5pbmZvQHlhc3NsLmNvbRcNMTIwNTE1MjM1MTI1WhcNMTIw +NjE0MjM1MTI1WjAUMBICAQIXDTEyMDUwNDE3MDYwNVqgDjAMMAoGA1UdFAQDAgEE +MA0GCSqGSIb3DQEBBQUAA4IBAQCq5ESba8kL02+6CT2Qk66WhnP2kCi6kzuVDJHJ +EFPxFf1DmrpO3I7oEE3Yi76oohJMGcETnzz+VGAyt0V3FypA8hZSnmj+vgOZnLHT +S76HW/QSPJ49Wci5oix4lJzNsBfQs72GmSsdOLUD2NENjxqMl/+HAU+RIjDCpRC7 +4/sxt0SKWoLh5TBphNFLwtMHvyHVMy2tS+Rvg8FmFnQxffnWHhBm/X2tZjwyzKOY +dWMWXN/hNz3pCNJ7Bd1MMZJTDPHqjr4x0eusN6jNxDDFkcw4o1VKUQE5z31QV9Ly +R0odfzoyFonoWhv4ZDNI5bjvui7zUn66KA6b9we4tjj50N14 +-----END X509 CRL----- diff --git a/certs/crl/include.am b/certs/crl/include.am new file mode 100644 index 000000000..da58bbb8a --- /dev/null +++ b/certs/crl/include.am @@ -0,0 +1,9 @@ +# vim:ft=automake +# All paths should be given relative to the root +# + +certs_DATA+= \ + certs/crl/crl.pem + +EXTRA_DIST+= ${certs_DATA} + diff --git a/configure.ac b/configure.ac index 38d149b0c..63a47696e 100644 --- a/configure.ac +++ b/configure.ac @@ -6,7 +6,7 @@ # # -AC_INIT([cyassl],[2.1.5],[http://www.yassl.com]) +AC_INIT([cyassl],[2.1.7],[http://www.yassl.com]) AC_CONFIG_AUX_DIR(config) @@ -491,6 +491,21 @@ fi AM_CONDITIONAL([BUILD_OCSP], [test "x$ENABLED_OCSP" = "xyes"]) +# CRL +AC_ARG_ENABLE(crl, + [ --enable-crl Enable CRL (default: disabled)], + [ ENABLED_CRL=$enableval ], + [ ENABLED_CRL=no ], + ) + +if test "$ENABLED_CRL" = "yes" +then + AM_CFLAGS="$AM_CFLAGS -DHAVE_CRL" +fi + +AM_CONDITIONAL([BUILD_CRL], [test "x$ENABLED_CRL" = "xyes"]) + + # NTRU ntruHome=`pwd`/NTRU_algorithm ntruInclude=$ntruHome/cryptolib diff --git a/ctaocrypt/src/asn.c b/ctaocrypt/src/asn.c index c4806de84..c981dea73 100644 --- a/ctaocrypt/src/asn.c +++ b/ctaocrypt/src/asn.c @@ -356,6 +356,8 @@ static int GetMyVersion(const byte* input, word32* inOutIdx, int* version) { word32 idx = *inOutIdx; + CYASSL_ENTER("GetMyVersion"); + if (input[idx++] != ASN_INTEGER) return ASN_PARSE_E; @@ -399,6 +401,7 @@ static int GetExplicitVersion(const byte* input, word32* inOutIdx, int* version) { word32 idx = *inOutIdx; + CYASSL_ENTER("GetExplicitVersion"); if (input[idx++] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) { *inOutIdx = ++idx; /* eat header */ return GetMyVersion(input, inOutIdx, version); @@ -472,7 +475,9 @@ static int GetAlgoId(const byte* input, word32* inOutIdx, word32* oid, word32 i = *inOutIdx; byte b; *oid = 0; - + + CYASSL_ENTER("GetAlgoId"); + if (GetSequence(input, &i, &length, maxIdx) < 0) return ASN_PARSE_E; @@ -1074,6 +1079,10 @@ void InitDecodedCert(DecodedCert* cert, byte* source, word32 inSz, void* heap) cert->subjectOULen = 0; cert->subjectEmail = 0; cert->subjectEmailLen = 0; + cert->beforeDate = 0; + cert->beforeDateLen = 0; + cert->afterDate = 0; + cert->afterDateLen = 0; #endif /* CYASSL_CERT_GEN */ } @@ -1280,8 +1289,6 @@ static int GetName(DecodedCert* cert, int nameType) char* full = (nameType == ISSUER) ? cert->issuer : cert->subject; word32 idx = 0; - InitSha(&sha); - if (cert->source[cert->srcIdx] == ASN_OBJECT_ID) { CYASSL_MSG("Trying optional prefix..."); @@ -1295,6 +1302,13 @@ static int GetName(DecodedCert* cert, int nameType) if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0) return ASN_PARSE_E; + InitSha(&sha); + ShaUpdate(&sha, &cert->source[cert->srcIdx], length); + if (nameType == ISSUER) + ShaFinal(&sha, cert->issuerHash); + else + ShaFinal(&sha, cert->subjectHash); + length += cert->srcIdx; while (cert->srcIdx < (word32)length) { @@ -1425,7 +1439,6 @@ static int GetName(DecodedCert* cert, int nameType) idx += strLen; } - ShaUpdate(&sha, &cert->source[cert->srcIdx], strLen); cert->srcIdx += strLen; } else { @@ -1480,11 +1493,6 @@ static int GetName(DecodedCert* cert, int nameType) } full[idx++] = 0; - if (nameType == ISSUER) - ShaFinal(&sha, cert->issuerHash); - else - ShaFinal(&sha, cert->subjectHash); - return 0; } @@ -1583,8 +1591,18 @@ static int GetDate(DecodedCert* cert, int dateType) { int length; byte date[MAX_DATE_SIZE]; - byte b = cert->source[cert->srcIdx++]; + byte b; +#ifdef CYASSL_CERT_GEN + word32 startIdx = 0; + if (dateType == BEFORE) + cert->beforeDate = &cert->source[cert->srcIdx]; + else + cert->afterDate = &cert->source[cert->srcIdx]; + startIdx = cert->srcIdx; +#endif + + b = cert->source[cert->srcIdx++]; if (b != ASN_UTC_TIME && b != ASN_GENERALIZED_TIME) return ASN_TIME_E; @@ -1597,6 +1615,13 @@ static int GetDate(DecodedCert* cert, int dateType) XMEMCPY(date, &cert->source[cert->srcIdx], length); cert->srcIdx += length; +#ifdef CYASSL_CERT_GEN + if (dateType == BEFORE) + cert->beforeDateLen = cert->srcIdx - startIdx; + else + cert->afterDateLen = cert->srcIdx - startIdx; +#endif + if (!XVALIDATE_DATE(date, b, dateType)) { if (dateType == BEFORE) return ASN_BEFORE_DATE_E; @@ -2047,25 +2072,25 @@ static int ConfirmSignature(const byte* buf, word32 bufSz, static void DecodeBasicCaConstraint(byte* input, int sz, DecodedCert* cert) { - word32 index = 0; + word32 idx = 0; int length = 0; CYASSL_ENTER("DecodeBasicCaConstraint"); - if (GetSequence(input, &index, &length, sz) < 0) return; + if (GetSequence(input, &idx, &length, sz) < 0) return; - if (input[index++] != ASN_BOOLEAN) + if (input[idx++] != ASN_BOOLEAN) { CYASSL_MSG("\tfail: constraint not BOOLEAN"); return; } - if (GetLength(input, &index, &length, sz) < 0) + if (GetLength(input, &idx, &length, sz) < 0) { CYASSL_MSG("\tfail: length"); return; } - if (input[index]) + if (input[idx]) cert->isCA = 1; } @@ -2077,69 +2102,68 @@ static void DecodeBasicCaConstraint(byte* input, int sz, DecodedCert* cert) static void DecodeCrlDist(byte* input, int sz, DecodedCert* cert) { - word32 index = 0; + word32 idx = 0; int length = 0; - word32 oid; CYASSL_ENTER("DecodeCrlDist"); /* Unwrap the list of Distribution Points*/ - if (GetSequence(input, &index, &length, sz) < 0) return; + if (GetSequence(input, &idx, &length, sz) < 0) return; /* Unwrap a single Distribution Point */ - if (GetSequence(input, &index, &length, sz) < 0) return; + if (GetSequence(input, &idx, &length, sz) < 0) return; /* The Distribution Point has three explicit optional members * First check for a DistributionPointName */ - if (input[index] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) + if (input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) { - index++; - if (GetLength(input, &index, &length, sz) < 0) return; + idx++; + if (GetLength(input, &idx, &length, sz) < 0) return; - if (input[index] == + if (input[idx] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CRLDP_FULL_NAME)) { - index++; - if (GetLength(input, &index, &length, sz) < 0) return; + idx++; + if (GetLength(input, &idx, &length, sz) < 0) return; - if (input[index] == (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI)) + if (input[idx] == (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI)) { - index++; - if (GetLength(input, &index, &length, sz) < 0) return; + idx++; + if (GetLength(input, &idx, &length, sz) < 0) return; cert->extCrlInfoSz = length; - cert->extCrlInfo = input + index; - index += length; + cert->extCrlInfo = input + idx; + idx += length; } else /* This isn't a URI, skip it. */ - index += length; + idx += length; } else /* This isn't a FULLNAME, skip it. */ - index += length; + idx += length; } /* Check for reasonFlags */ - if (index < sz && - input[index] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) + if (idx < (word32)sz && + input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) { - index++; - if (GetLength(input, &index, &length, sz) < 0) return; - index += length; + idx++; + if (GetLength(input, &idx, &length, sz) < 0) return; + idx += length; } /* Check for cRLIssuer */ - if (index < sz && - input[index] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2)) + if (idx < (word32)sz && + input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2)) { - index++; - if (GetLength(input, &index, &length, sz) < 0) return; - index += length; + idx++; + if (GetLength(input, &idx, &length, sz) < 0) return; + idx += length; } - if (index < sz) + if (idx < (word32)sz) { CYASSL_MSG("\tThere are more CRL Distribution Point records, " "but we only use the first one."); @@ -2155,38 +2179,38 @@ static void DecodeAuthInfo(byte* input, int sz, DecodedCert* cert) * any issues, return without saving the record. */ { - word32 index = 0; + word32 idx = 0; int length = 0; word32 oid; /* Unwrap the list of AIAs */ - if (GetSequence(input, &index, &length, sz) < 0) return; + if (GetSequence(input, &idx, &length, sz) < 0) return; /* Unwrap a single AIA */ - if (GetSequence(input, &index, &length, sz) < 0) return; + if (GetSequence(input, &idx, &length, sz) < 0) return; oid = 0; - if (GetObjectId(input, &index, &oid, sz) < 0) return; + if (GetObjectId(input, &idx, &oid, sz) < 0) return; /* Only supporting URIs right now. */ - if (input[index] == (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI)) + if (input[idx] == (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI)) { - index++; - if (GetLength(input, &index, &length, sz) < 0) return; + idx++; + if (GetLength(input, &idx, &length, sz) < 0) return; cert->extAuthInfoSz = length; - cert->extAuthInfo = input + index; - index += length; + cert->extAuthInfo = input + idx; + idx += length; } else { /* Skip anything else. */ - index++; - if (GetLength(input, &index, &length, sz) < 0) return; - index += length; + idx++; + if (GetLength(input, &idx, &length, sz) < 0) return; + idx += length; } - if (index < sz) + if (idx < (word32)sz) { CYASSL_MSG("\tThere are more Authority Information Access records, " "but we only use first one."); @@ -2202,7 +2226,7 @@ static void DecodeCertExtensions(DecodedCert* cert) * index. It is works starting with the recorded extensions pointer. */ { - word32 index = 0; + word32 idx = 0; int sz = cert->extensionsSz; byte* input = cert->extensions; int length; @@ -2212,59 +2236,59 @@ static void DecodeCertExtensions(DecodedCert* cert) if (input == NULL || sz == 0) return; - if (input[index++] != ASN_EXTENSIONS) return; + if (input[idx++] != ASN_EXTENSIONS) return; - if (GetLength(input, &index, &length, sz) < 0) return; + if (GetLength(input, &idx, &length, sz) < 0) return; - if (GetSequence(input, &index, &length, sz) < 0) return; + if (GetSequence(input, &idx, &length, sz) < 0) return; - while (index < sz) { - if (GetSequence(input, &index, &length, sz) < 0) { + while (idx < (word32)sz) { + if (GetSequence(input, &idx, &length, sz) < 0) { CYASSL_MSG("\tfail: should be a SEQUENCE"); return; } oid = 0; - if (GetObjectId(input, &index, &oid, sz) < 0) { + if (GetObjectId(input, &idx, &oid, sz) < 0) { CYASSL_MSG("\tfail: OBJECT ID"); return; } /* check for critical flag */ - if (input[index] == ASN_BOOLEAN) { + if (input[idx] == ASN_BOOLEAN) { CYASSL_MSG("\tfound optional critical flag, moving past"); - index += (ASN_BOOL_SIZE + 1); + idx += (ASN_BOOL_SIZE + 1); } /* process the extension based on the OID */ - if (input[index++] != ASN_OCTET_STRING) { + if (input[idx++] != ASN_OCTET_STRING) { CYASSL_MSG("\tfail: should be an OCTET STRING"); return; } - if (GetLength(input, &index, &length, sz) < 0) { + if (GetLength(input, &idx, &length, sz) < 0) { CYASSL_MSG("\tfail: extension data length"); return; } switch (oid) { case BASIC_CA_OID: - DecodeBasicCaConstraint(&input[index], length, cert); + DecodeBasicCaConstraint(&input[idx], length, cert); break; case CRL_DIST_OID: - DecodeCrlDist(&input[index], length, cert); + DecodeCrlDist(&input[idx], length, cert); break; case AUTH_INFO_OID: - DecodeAuthInfo(&input[index], length, cert); + DecodeAuthInfo(&input[idx], length, cert); break; default: CYASSL_MSG("\tExtension type not handled, skipping"); break; } - index += length; + idx += length; } return; @@ -2309,7 +2333,7 @@ int ParseCert(DecodedCert* cert, int type, int verify, void* cm) #ifdef __cplusplus extern "C" { #endif - CYASSL_LOCAL Signer* GetCA(Signer* signers, byte* hash); + CYASSL_LOCAL Signer* GetCA(void* signers, byte* hash); #ifdef __cplusplus } #endif @@ -2845,7 +2869,9 @@ void InitCert(Cert* cert) cert->isCA = 0; cert->bodySz = 0; #ifdef CYASSL_ALT_NAMES - cert->altNamesSz = 0; + cert->altNamesSz = 0; + cert->beforeDateSz = 0; + cert->afterDateSz = 0; #endif cert->keyType = RSA_KEY; XMEMSET(cert->serial, 0, CTC_SERIAL_SIZE); @@ -3029,6 +3055,26 @@ static void SetTime(struct tm* date, byte* output) } +#ifdef CYASSL_ALT_NAMES + +/* Copy Dates from cert, return bytes written */ +static int CopyValidity(byte* output, Cert* cert) +{ + int seqSz; + + CYASSL_ENTER("CopyValidity"); + + /* headers and output */ + seqSz = SetSequence(cert->beforeDateSz + cert->afterDateSz, output); + XMEMCPY(output + seqSz, cert->beforeDate, cert->beforeDateSz); + XMEMCPY(output + seqSz + cert->beforeDateSz, cert->afterDate, + cert->afterDateSz); + return seqSz + cert->beforeDateSz + cert->afterDateSz; +} + +#endif + + /* Set Date validity from now until now + daysValid */ static int SetValidity(byte* output, int daysValid) { @@ -3360,10 +3406,22 @@ static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, RNG* rng, #endif } + der->validitySz = 0; +#ifdef CYASSL_ALT_NAMES + /* date validity copy ? */ + if (cert->beforeDateSz && cert->afterDateSz) { + der->validitySz = CopyValidity(der->validity, cert); + if (der->validitySz == 0) + return DATE_E; + } +#endif + /* date validity */ - der->validitySz = SetValidity(der->validity, cert->daysValid); - if (der->validitySz == 0) - return DATE_E; + if (der->validitySz == 0) { + der->validitySz = SetValidity(der->validity, cert->daysValid); + if (der->validitySz == 0) + return DATE_E; + } /* subject name */ der->subjectSz = SetName(der->subject, &cert->subject); @@ -3601,8 +3659,10 @@ static int SetAltNamesFromCert(Cert* cert, const byte* der, int derSz) InitDecodedCert(&decoded, (byte*)der, derSz, 0); ret = ParseCertRelative(&decoded, CA_TYPE, NO_VERIFY, 0); - if (ret < 0) + if (ret < 0) { + FreeDecodedCert(&decoded); return ret; + } if (decoded.extensions) { byte b; @@ -3671,6 +3731,49 @@ static int SetAltNamesFromCert(Cert* cert, const byte* der, int derSz) return 0; } + +/* Set Dates from der cert, return 0 on success */ +static int SetDatesFromCert(Cert* cert, const byte* der, int derSz) +{ + DecodedCert decoded; + int ret; + + CYASSL_ENTER("SetDatesFromCert"); + if (derSz < 0) + return derSz; + + InitDecodedCert(&decoded, (byte*)der, derSz, 0); + ret = ParseCertRelative(&decoded, CA_TYPE, NO_VERIFY, 0); + + if (ret < 0) { + CYASSL_MSG("ParseCertRelative error"); + FreeDecodedCert(&decoded); + return ret; + } + + if (decoded.beforeDate == NULL || decoded.afterDate == NULL) { + CYASSL_MSG("Couldn't extract dates"); + FreeDecodedCert(&decoded); + return -1; + } + + if (decoded.beforeDateLen > MAX_DATE_SIZE || decoded.afterDateLen > + MAX_DATE_SIZE) { + CYASSL_MSG("Bad date size"); + FreeDecodedCert(&decoded); + return -1; + } + + XMEMCPY(cert->beforeDate, decoded.beforeDate, decoded.beforeDateLen); + XMEMCPY(cert->afterDate, decoded.afterDate, decoded.afterDateLen); + + cert->beforeDateSz = decoded.beforeDateLen; + cert->afterDateSz = decoded.afterDateLen; + + return 0; +} + + #endif /* CYASSL_ALT_NAMES */ @@ -3809,6 +3912,12 @@ int SetAltNamesBuffer(Cert* cert, const byte* der, int derSz) return SetAltNamesFromCert(cert, der, derSz); } +/* Set cert dates from DER buffer */ +int SetDatesBuffer(Cert* cert, const byte* der, int derSz) +{ + return SetDatesFromCert(cert, der, derSz); +} + #endif /* CYASSL_ALT_NAMES */ #endif /* CYASSL_CERT_GEN */ @@ -4478,3 +4587,263 @@ int CompareOcspReqResp(OcspRequest* req, OcspResponse* resp) } #endif + + +#ifdef HAVE_CRL + +/* initialize decoded CRL */ +void InitDecodedCRL(DecodedCRL* dcrl) +{ + CYASSL_MSG("InitDecodedCRL"); + + dcrl->certBegin = 0; + dcrl->sigIndex = 0; + dcrl->sigLength = 0; + dcrl->signatureOID = 0; + dcrl->certs = NULL; + dcrl->totalCerts = 0; +} + + +/* free decoded CRL resources */ +void FreeDecodedCRL(DecodedCRL* dcrl) +{ + RevokedCert* tmp = dcrl->certs; + + CYASSL_MSG("FreeDecodedCRL"); + + while(tmp) { + RevokedCert* next = tmp->next; + XFREE(tmp, NULL, DYNAMIC_TYPE_REVOKED); + tmp = next; + } +} + + +/* store SHA1 hash of NAME */ +static int GetNameHash(const byte* source, word32* idx, byte* hash, int maxIdx) +{ + Sha sha; + int length; /* length of all distinguished names */ + + CYASSL_ENTER("GetNameHash"); + + if (source[*idx] == ASN_OBJECT_ID) { + CYASSL_MSG("Trying optional prefix..."); + + if (GetLength(source, idx, &length, maxIdx) < 0) + return ASN_PARSE_E; + + *idx += length; + CYASSL_MSG("Got optional prefix"); + } + + if (GetSequence(source, idx, &length, maxIdx) < 0) + return ASN_PARSE_E; + + InitSha(&sha); + ShaUpdate(&sha, &source[*idx], length); + ShaFinal(&sha, hash); + + *idx += length; + + return 0; +} + + +/* Get raw Date only, no processing, 0 on success */ +static int GetBasicDate(const byte* source, word32* idx, byte* date, int maxIdx) +{ + int length; + byte b = source[*idx]; + + CYASSL_ENTER("GetBasicDate"); + + *idx += 1; + if (b != ASN_UTC_TIME && b != ASN_GENERALIZED_TIME) + return ASN_TIME_E; + + if (GetLength(source, idx, &length, maxIdx) < 0) + return ASN_PARSE_E; + + if (length > MAX_DATE_SIZE || length < MIN_DATE_SIZE) + return ASN_DATE_SZ_E; + + XMEMCPY(date, &source[*idx], length); + *idx += length; + + return 0; +} + + +/* Get Revoked Cert list, 0 on success */ +static int GetRevoked(const byte* buff, word32* idx, DecodedCRL* dcrl, + int maxIdx) +{ + int len; + word32 end; + byte b; + RevokedCert* rc; + + CYASSL_ENTER("GetRevoked"); + + if (GetSequence(buff, idx, &len, maxIdx) < 0) + return ASN_PARSE_E; + + end = *idx + len; + + /* get serial number */ + b = buff[*idx]; + *idx += 1; + + if (b != ASN_INTEGER) { + CYASSL_MSG("Expecting Integer"); + return ASN_PARSE_E; + } + + if (GetLength(buff, idx, &len, maxIdx) < 0) + return ASN_PARSE_E; + + if (len > EXTERNAL_SERIAL_SIZE) { + CYASSL_MSG("Serial Size too big"); + return ASN_PARSE_E; + } + + rc = XMALLOC(sizeof(RevokedCert), NULL, DYNAMIC_TYPE_CRL); + if (rc == NULL) { + CYASSL_MSG("Alloc Revoked Cert failed"); + return MEMORY_E; + } + + XMEMCPY(rc->serialNumber, &buff[*idx], len); + rc->serialSz = len; + + /* add to list */ + rc->next = dcrl->certs; + dcrl->certs = rc; + dcrl->totalCerts++; + + *idx += len; + + /* get date */ + b = buff[*idx]; + *idx += 1; + + if (b != ASN_UTC_TIME && b != ASN_GENERALIZED_TIME) { + CYASSL_MSG("Expecting Date"); + return ASN_PARSE_E; + } + + if (GetLength(buff, idx, &len, maxIdx) < 0) + return ASN_PARSE_E; + + /* skip for now */ + *idx += len; + + if (*idx != end) /* skip extensions */ + *idx = end; + + return 0; +} + + +/* Get CRL Signature, 0 on success */ +static int GetCRL_Signature(const byte* source, word32* idx, DecodedCRL* dcrl, + int maxIdx) +{ + int length; + byte b; + + CYASSL_ENTER("GetCRL_Signature"); + + b = source[*idx]; + *idx += 1; + if (b != ASN_BIT_STRING) + return ASN_BITSTR_E; + + if (GetLength(source, idx, &length, maxIdx) < 0) + return ASN_PARSE_E; + + dcrl->sigLength = length; + + b = source[*idx]; + *idx += 1; + if (b != 0x00) + return ASN_EXPECT_0_E; + + dcrl->sigLength--; + dcrl->signature = (byte*)&source[*idx]; + + *idx += dcrl->sigLength; + + return 0; +} + + +/* prase crl buffer into decoded state, 0 on success */ +int ParseCRL(DecodedCRL* dcrl, const byte* buff, long sz) +{ + int version, len; + word32 oid, idx = 0; + Md5 md5; + + CYASSL_MSG("ParseCRL"); + + /* raw crl hash */ + InitMd5(&md5); + Md5Update(&md5, buff, sz); + Md5Final(&md5, dcrl->crlHash); + + if (GetSequence(buff, &idx, &len, sz) < 0) + return ASN_PARSE_E; + + dcrl->certBegin = idx; + + if (GetSequence(buff, &idx, &len, sz) < 0) + return ASN_PARSE_E; + dcrl->sigIndex = len + idx; + + /* may have version */ + if (buff[idx] == ASN_INTEGER) { + if (GetMyVersion(buff, &idx, &version) < 0) + return ASN_PARSE_E; + } + + if (GetAlgoId(buff, &idx, &oid, sz) < 0) + return ASN_PARSE_E; + + if (GetNameHash(buff, &idx, dcrl->issuerHash, sz) < 0) + return ASN_PARSE_E; + + if (GetBasicDate(buff, &idx, dcrl->lastDate, sz) < 0) + return ASN_PARSE_E; + + if (GetBasicDate(buff, &idx, dcrl->nextDate, sz) < 0) + return ASN_PARSE_E; + + + if (idx != dcrl->sigIndex) { + if (GetSequence(buff, &idx, &len, sz) < 0) + return ASN_PARSE_E; + + len += idx; + + while (idx < (word32)len) { + if (GetRevoked(buff, &idx, dcrl, sz) < 0) + return ASN_PARSE_E; + } + } + + if (idx != dcrl->sigIndex) + idx = dcrl->sigIndex; /* skip extensions */ + + if (GetAlgoId(buff, &idx, &dcrl->signatureOID, sz) < 0) + return ASN_PARSE_E; + + if (GetCRL_Signature(buff, &idx, dcrl, sz) < 0) + return ASN_PARSE_E; + + return 0; +} + +#endif /* HAVE_CRL */ diff --git a/ctaocrypt/src/rsa.c b/ctaocrypt/src/rsa.c index 35b14917d..7f511df1c 100644 --- a/ctaocrypt/src/rsa.c +++ b/ctaocrypt/src/rsa.c @@ -406,7 +406,7 @@ static int rand_prime(mp_int* N, int len, RNG* rng, void* heap) } /* allocate buffer to work with */ - buf = XMALLOC(len, heap, DYNAMIC_TYPE_RSA); + buf = (byte*)XMALLOC(len, heap, DYNAMIC_TYPE_RSA); if (buf == NULL) { return MEMORY_E; } diff --git a/cyassl/crl.h b/cyassl/crl.h new file mode 100644 index 000000000..918927cc2 --- /dev/null +++ b/cyassl/crl.h @@ -0,0 +1,47 @@ +/* crl.h + * + * Copyright (C) 2006-2012 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * CyaSSL 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 General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#ifndef CYASSL_CRL_H +#define CYASSL_CRL_H + +#include +#include + +#ifdef __cplusplus + extern "C" { +#endif + +typedef struct CYASSL_CRL CYASSL_CRL; + +CYASSL_LOCAL int InitCRL(CYASSL_CRL*, CYASSL_CERT_MANAGER*); +CYASSL_LOCAL void FreeCRL(CYASSL_CRL*); + +CYASSL_LOCAL int LoadCRL(CYASSL_CRL* crl, const char* path, int type); +CYASSL_LOCAL int BufferLoadCRL(CYASSL_CRL*, const byte*, long, int); +CYASSL_LOCAL int CheckCertCRL(CYASSL_CRL*, DecodedCert*); + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* CYASSL_CRL_H */ diff --git a/cyassl/ctaocrypt/asn.h b/cyassl/ctaocrypt/asn.h index eb1a6752e..5ed0bf55e 100644 --- a/cyassl/ctaocrypt/asn.h +++ b/cyassl/ctaocrypt/asn.h @@ -28,6 +28,7 @@ #include #include #include +#include #include /* public interface */ #ifdef HAVE_ECC #include @@ -252,6 +253,10 @@ struct DecodedCert { int subjectOULen; char* subjectEmail; int subjectEmailLen; + byte* beforeDate; + int beforeDateLen; + byte* afterDate; + int afterDateLen; #endif /* CYASSL_CERT_GEN */ }; @@ -407,6 +412,41 @@ CYASSL_LOCAL int CompareOcspReqResp(OcspRequest*, OcspResponse*); #endif /* HAVE_OCSP */ +/* for pointer use */ +typedef struct RevokedCert RevokedCert; + +#ifdef HAVE_CRL + +struct RevokedCert { + byte serialNumber[EXTERNAL_SERIAL_SIZE]; + int serialSz; + RevokedCert* next; +}; + +typedef struct DecodedCRL DecodedCRL; + +struct DecodedCRL { + word32 certBegin; /* offset to start of cert */ + word32 sigIndex; /* offset to start of signature */ + word32 sigLength; /* length of signature */ + word32 signatureOID; /* sum of algorithm object id */ + byte* signature; /* pointer into raw source, not owned */ + byte issuerHash[SHA_DIGEST_SIZE]; /* issuer hash */ + byte crlHash[MD5_DIGEST_SIZE]; /* raw crl data hash */ + byte lastDate[MAX_DATE_SIZE]; /* last date updated */ + byte nextDate[MAX_DATE_SIZE]; /* next update date */ + RevokedCert* certs; /* revoked cert list */ + int totalCerts; /* number on list */ +}; + +CYASSL_LOCAL void InitDecodedCRL(DecodedCRL*); +CYASSL_LOCAL int ParseCRL(DecodedCRL*, const byte* buff, long sz); +CYASSL_LOCAL void FreeDecodedCRL(DecodedCRL*); + + +#endif /* HAVE_CRL */ + + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/cyassl/ctaocrypt/asn_public.h b/cyassl/ctaocrypt/asn_public.h index 8a16b5ef2..efc21fd83 100644 --- a/cyassl/ctaocrypt/asn_public.h +++ b/cyassl/ctaocrypt/asn_public.h @@ -39,6 +39,7 @@ enum CertType { CERT_TYPE = 0, PRIVATEKEY_TYPE, DH_PARAM_TYPE, + CRL_TYPE, CA_TYPE }; @@ -63,6 +64,7 @@ enum Ctc_SigType { enum Ctc_Misc { CTC_NAME_SIZE = 64, + CTC_DATE_SIZE = 32, CTC_MAX_ALT_SIZE = 8192, /* may be huge */ CTC_SERIAL_SIZE = 8 }; @@ -95,6 +97,10 @@ typedef struct Cert { #ifdef CYASSL_ALT_NAMES byte altNames[CTC_MAX_ALT_SIZE]; /* altNames copy */ int altNamesSz; /* altNames size in bytes */ + byte beforeDate[CTC_DATE_SIZE]; /* before date copy */ + int beforeDateSz; /* size of copy */ + byte afterDate[CTC_DATE_SIZE]; /* after date copy */ + int afterDateSz; /* size of copy */ #endif } Cert; @@ -125,6 +131,7 @@ CYASSL_API int SetSubject(Cert*, const char*); CYASSL_API int SetIssuerBuffer(Cert*, const byte*, int); CYASSL_API int SetSubjectBuffer(Cert*, const byte*, int); CYASSL_API int SetAltNamesBuffer(Cert*, const byte*, int); +CYASSL_API int SetDatesBuffer(Cert*, const byte*, int); #ifdef HAVE_NTRU CYASSL_API int MakeNtruCert(Cert*, byte* derBuffer, word32 derSz, diff --git a/cyassl/ctaocrypt/tfm.h b/cyassl/ctaocrypt/tfm.h index 37fa98523..af74a9034 100644 --- a/cyassl/ctaocrypt/tfm.h +++ b/cyassl/ctaocrypt/tfm.h @@ -415,7 +415,7 @@ int fp_cmp_d(fp_int *a, fp_digit b); void fp_add_d(fp_int *a, fp_digit b, fp_int *c); /* c = a - b */ -/*void fp_sub_d(fp_int *a, fp_digit b, fp_int *c);*/ +void fp_sub_d(fp_int *a, fp_digit b, fp_int *c); /* c = a * b */ void fp_mul_d(fp_int *a, fp_digit b, fp_int *c); diff --git a/cyassl/ctaocrypt/types.h b/cyassl/ctaocrypt/types.h index 06aeb99d9..7468e73b0 100644 --- a/cyassl/ctaocrypt/types.h +++ b/cyassl/ctaocrypt/types.h @@ -202,7 +202,10 @@ enum { DYNAMIC_TYPE_WRITEV = 19, DYNAMIC_TYPE_OPENSSL = 20, DYNAMIC_TYPE_DSA = 21, - DYNAMIC_TYPE_CERT_MANAGER = 22 + DYNAMIC_TYPE_CRL = 22, + DYNAMIC_TYPE_REVOKED = 23, + DYNAMIC_TYPE_CRL_ENTRY = 24, + DYNAMIC_TYPE_CERT_MANAGER = 25 }; /* stack protection */ diff --git a/cyassl/error.h b/cyassl/error.h index 0d8d8d273..fd6781c19 100644 --- a/cyassl/error.h +++ b/cyassl/error.h @@ -92,14 +92,16 @@ enum CyaSSL_ErrorCodes { NOT_CA_ERROR = -257, /* Not a CA cert error */ BAD_PATH_ERROR = -258, /* Bad path for opendir */ BAD_CERT_MANAGER_ERROR = -259, /* Bad Cert Manager */ + OCSP_CERT_REVOKED = -260, + CRL_CERT_REVOKED = -261, /* CRL Certificate revoked */ + CRL_MISSING = -262, /* CRL Not loaded */ /* add strings to SetErrorString !!!!! */ /* begin negotiation parameter errors */ UNSUPPORTED_SUITE = -270, /* unsupported cipher suite */ - MATCH_SUITE_ERROR = -271, /* can't match cipher suite */ + MATCH_SUITE_ERROR = -271 /* can't match cipher suite */ /* end negotiation parameter errors only 10 for now */ /* add strings to SetErrorString !!!!! */ - OCSP_CERT_REVOKED = -272 }; diff --git a/cyassl/include.am b/cyassl/include.am index 8d8a4f3e2..f2b07a767 100644 --- a/cyassl/include.am +++ b/cyassl/include.am @@ -16,4 +16,5 @@ nobase_include_HEADERS+= \ cyassl/callbacks.h \ cyassl/test.h \ cyassl/version.h \ - cyassl/ocsp.h + cyassl/ocsp.h \ + cyassl/crl.h diff --git a/cyassl/internal.h b/cyassl/internal.h index 76c970aa6..f584a7bca 100644 --- a/cyassl/internal.h +++ b/cyassl/internal.h @@ -25,6 +25,7 @@ #include +#include #include #include #include @@ -622,12 +623,39 @@ CYASSL_LOCAL int LockMutex(CyaSSL_Mutex*); CYASSL_LOCAL int UnLockMutex(CyaSSL_Mutex*); + +typedef struct CRL_Entry CRL_Entry; + +/* Complete CRL */ +struct CRL_Entry { + CRL_Entry* next; /* next entry */ + byte issuerHash[SHA_DIGEST_SIZE]; /* issuer hash */ + byte crlHash[MD5_DIGEST_SIZE]; /* raw crl data hash */ + byte lastDate[MAX_DATE_SIZE]; /* last date updated */ + byte nextDate[MAX_DATE_SIZE]; /* next update date */ + RevokedCert* certs; /* revoked cert list */ + int totalCerts; /* number on list */ +}; + + +/* CyaSSL CRL controller */ +struct CYASSL_CRL { + CYASSL_CERT_MANAGER* cm; /* pointer back to cert manager */ + CRL_Entry* crlList; /* our CRL list */ + CyaSSL_Mutex crlLock; /* CRL list lock */ +}; + + /* CyaSSL Certificate Manager */ struct CYASSL_CERT_MANAGER { Signer* caList; /* the CA signer list */ CyaSSL_Mutex caLock; /* CA list lock */ CallbackCACache caCacheCallback; /* CA cache addition callback */ void* heap; /* heap helper */ + CYASSL_CRL* crl; /* CRL checker */ + byte crlEnabled; /* is CRL on ? */ + byte crlCheckAll; /* always leaf, but all ? */ + CbMissingCRL cbMissingCRL; /* notify through cb of missing crl */ }; @@ -958,6 +986,7 @@ typedef struct Options { byte downgrade; /* allow downgrade of versions */ byte sendVerify; /* false = 0, true = 1, sendBlank = 2 */ byte resuming; + byte haveSessionId; /* server may not send */ byte tls; /* using TLS ? */ byte tls1_1; /* using TLSv1.1+ ? */ byte dtls; /* using datagrams ? */ @@ -1137,6 +1166,14 @@ typedef struct EncryptedInfo { CYASSL_CTX* ctx; /* CTX owner */ } EncryptedInfo; +CYASSL_LOCAL int PemToDer(const unsigned char* buff, long sz, int type, + buffer* der, void* heap, EncryptedInfo* info, + int* eccKey); + +CYASSL_LOCAL int ProcessFile(CYASSL_CTX* ctx, const char* fname, int format, + int type, CYASSL* ssl, int userChain, + CYASSL_CRL* crl); + #ifdef CYASSL_CALLBACKS CYASSL_LOCAL diff --git a/cyassl/ssl.h b/cyassl/ssl.h index 97ef23297..c30a9ac52 100644 --- a/cyassl/ssl.h +++ b/cyassl/ssl.h @@ -384,7 +384,6 @@ CYASSL_API char* CyaSSL_alert_type_string_long(int); CYASSL_API char* CyaSSL_alert_desc_string_long(int); CYASSL_API char* CyaSSL_state_string_long(CYASSL*); -CYASSL_API void CyaSSL_RSA_free(CYASSL_RSA*); CYASSL_API CYASSL_RSA* CyaSSL_RSA_generate_key(int, unsigned long, void(*)(int, int, void*), void*); CYASSL_API void CyaSSL_CTX_set_tmp_rsa_callback(CYASSL_CTX*, @@ -429,6 +428,8 @@ enum { OCSP_RESPONSE = 8, OCSP_BASICRESP = 16, + CYASSL_CRL_CHECKALL = 1, + ASN1_GENERALIZEDTIME = 4, SSL_OP_MICROSOFT_SESS_ID_BUG = 1, @@ -776,6 +777,7 @@ CYASSL_API int CyaSSL_KeyPemToDer(const unsigned char*, int sz, unsigned char*, int, const char*); typedef void (*CallbackCACache)(unsigned char* der, int sz, int type); +typedef void (*CbMissingCRL)(const char* url); CYASSL_API void CyaSSL_CTX_SetCACb(CYASSL_CTX*, CallbackCACache); @@ -787,6 +789,22 @@ CYASSL_API int CyaSSL_CertManagerLoadCA(CYASSL_CERT_MANAGER*, const char* f, const char* d); CYASSL_API int CyaSSL_CertManagerVerify(CYASSL_CERT_MANAGER*, const char* f, int format); +CYASSL_API int CyaSSL_CertManagerEnableCRL(CYASSL_CERT_MANAGER*, int options); +CYASSL_API int CyaSSL_CertManagerDisableCRL(CYASSL_CERT_MANAGER*); +CYASSL_API int CyaSSL_CertManagerLoadCRL(CYASSL_CERT_MANAGER*, const char*,int); +CYASSL_API int CyaSSL_CertManagerSetCRL_Cb(CYASSL_CERT_MANAGER*, CbMissingCRL); + +CYASSL_API int CyaSSL_EnableCRL(CYASSL* ssl, int options); +CYASSL_API int CyaSSL_DisableCRL(CYASSL* ssl); +CYASSL_API int CyaSSL_LoadCRL(CYASSL*, const char*, int); +CYASSL_API int CyaSSL_SetCRL_Cb(CYASSL*, CbMissingCRL); + +CYASSL_API int CyaSSL_CTX_EnableCRL(CYASSL_CTX* ctx, int options); +CYASSL_API int CyaSSL_CTX_DisableCRL(CYASSL_CTX* ctx); +CYASSL_API int CyaSSL_CTX_LoadCRL(CYASSL_CTX*, const char*, int); +CYASSL_API int CyaSSL_CTX_SetCRL_Cb(CYASSL_CTX*, CbMissingCRL); + + #ifdef CYASSL_CALLBACKS diff --git a/cyassl/test.h b/cyassl/test.h index 57986f835..d68ad64b7 100644 --- a/cyassl/test.h +++ b/cyassl/test.h @@ -109,6 +109,7 @@ static const char* ntruKey = "./certs/ntru-key.raw"; static const char* dhParam = "./certs/dh2048.pem"; static const char* cliEccKey = "./certs/ecc-client-key.pem"; static const char* cliEccCert = "./certs/client-ecc-cert.pem"; +static const char* crlPemDir = "./certs/crl"; typedef struct tcp_ready { int ready; /* predicate */ @@ -574,6 +575,16 @@ static int myVerify(int preverify, CYASSL_X509_STORE_CTX* store) #endif /* VERIFY_CALLBACK */ +#ifdef HAVE_CRL + +static void CRL_CallBack(char* url) +{ + printf("CRL callback url = %s\n", url); +} + +#endif + + static INLINE void CaCb(unsigned char* der, int sz, int type) { printf("Got CA cache add callback, derSz = %d, type = %d\n", sz, type); diff --git a/examples/client/client.c b/examples/client/client.c index 0f2b72bbd..d09ec8cd3 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -136,6 +136,7 @@ void client_test(void* args) CyaSSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, myVerify); #endif + if (argc == 3) { /* ./client server securePort */ CyaSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0); /* TODO: add ca cert */ @@ -206,6 +207,11 @@ void client_test(void* args) ssl = CyaSSL_new(ctx); CyaSSL_set_fd(ssl, sockfd); +#ifdef HAVE_CRL + CyaSSL_EnableCRL(ssl, 0); + CyaSSL_LoadCRL(ssl, crlPemDir, SSL_FILETYPE_PEM); + CyaSSL_SetCRL_Cb(ssl, CRL_CallBack); +#endif if (argc != 3) CyaSSL_check_domain_name(ssl, "www.yassl.com"); #ifdef NON_BLOCKING diff --git a/src/crl.c b/src/crl.c new file mode 100644 index 000000000..b3211d274 --- /dev/null +++ b/src/crl.c @@ -0,0 +1,299 @@ +/* crl.c + * + * Copyright (C) 2006-2012 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * CyaSSL 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 General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + + +#ifdef HAVE_CRL + +#include +#include + +#include +#include + + +/* Initialze CRL members */ +int InitCRL(CYASSL_CRL* crl, CYASSL_CERT_MANAGER* cm) +{ + CYASSL_ENTER("InitCRL"); + + crl->cm = cm; + crl->crlList = NULL; + if (InitMutex(&crl->crlLock) != 0) + return BAD_MUTEX_ERROR; + + return 0; +} + + +/* Initialze CRL Entry */ +static int InitCRL_Entry(CRL_Entry* crle, DecodedCRL* dcrl) +{ + CYASSL_ENTER("FreeCRL_Entry"); + + XMEMCPY(crle->issuerHash, dcrl->issuerHash, SHA_DIGEST_SIZE); + XMEMCPY(crle->crlHash, dcrl->crlHash, MD5_DIGEST_SIZE); + XMEMCPY(crle->lastDate, dcrl->lastDate, MAX_DATE_SIZE); + XMEMCPY(crle->nextDate, dcrl->nextDate, MAX_DATE_SIZE); + + crle->certs = dcrl->certs; /* take ownsership */ + dcrl->certs = NULL; + crle->totalCerts = dcrl->totalCerts; + + return 0; +} + + +/* Free all CRL Entry resources */ +static void FreeCRL_Entry(CRL_Entry* crle) +{ + RevokedCert* tmp = crle->certs; + + CYASSL_ENTER("FreeCRL_Entry"); + + while(tmp) { + RevokedCert* next = tmp->next; + XFREE(tmp, NULL, DYNAMIC_TYPE_REVOKED); + tmp = next; + } +} + + + +/* Free all CRL resources */ +void FreeCRL(CYASSL_CRL* crl) +{ + CRL_Entry* tmp = crl->crlList; + + CYASSL_ENTER("FreeCRL"); + + while(tmp) { + CRL_Entry* next = tmp->next; + FreeCRL_Entry(tmp); + XFREE(tmp, NULL, DYNAMIC_TYPE_CRL_ENTRY); + tmp = next; + } + + FreeMutex(&crl->crlLock); +} + + +/* Is the cert ok with CRL, return 0 on success */ +int CheckCertCRL(CYASSL_CRL* crl, DecodedCert* cert) +{ + CRL_Entry* crle; + int foundEntry = 0; + int revoked = 0; + int ret = 0; + + CYASSL_ENTER("CheckCertCRL"); + + if (LockMutex(&crl->crlLock) != 0) { + CYASSL_MSG("LockMutex failed"); + return BAD_MUTEX_ERROR; + } + + crle = crl->crlList; + + while (crle) { + if (XMEMCMP(crle->issuerHash, cert->issuerHash, SHA_DIGEST_SIZE) == 0) { + CYASSL_MSG("Found CRL Entry on list"); + foundEntry = 1; + break; + } + crle = crle->next; + } + + if (foundEntry) { + RevokedCert* rc = crle->certs; + + while (rc) { + if (XMEMCMP(rc->serialNumber, cert->serial, rc->serialSz) == 0) { + CYASSL_MSG("Cert revoked"); + revoked = 1; + ret = CRL_CERT_REVOKED; + break; + } + rc = rc->next; + } + } + + UnLockMutex(&crl->crlLock); + + if (foundEntry == 0) { + CYASSL_MSG("Couldn't find CRL for status check"); + ret = CRL_MISSING; + if (crl->cm->cbMissingCRL) { + char url[256]; + + CYASSL_MSG("Issuing missing CRL callback"); + url[0] = '\0'; + if (cert->extCrlInfoSz < (int)sizeof(url) -1 ) { + XMEMCPY(url, cert->extCrlInfo, cert->extCrlInfoSz); + url[cert->extCrlInfoSz] = '\0'; + } + else { + CYASSL_MSG("CRL url too long"); + } + crl->cm->cbMissingCRL(url); + } + } + + + return ret; +} + + +/* Add Decoded CRL, 0 on success */ +static int AddCRL(CYASSL_CRL* crl, DecodedCRL* dcrl) +{ + CRL_Entry* crle; + + CYASSL_ENTER("AddCRL"); + + crle = (CRL_Entry*)XMALLOC(sizeof(CRL_Entry), NULL, DYNAMIC_TYPE_CRL_ENTRY); + if (crle == NULL) { + CYASSL_MSG("alloc CRL Entry failed"); + return -1; + } + + if (InitCRL_Entry(crle, dcrl) < 0) { + CYASSL_MSG("Init CRL Entry failed"); + return -1; + } + + if (LockMutex(&crl->crlLock) != 0) { + CYASSL_MSG("LockMutex failed"); + FreeCRL_Entry(crle); + return BAD_MUTEX_ERROR; + } + crle->next = crl->crlList; + crl->crlList = crle; + UnLockMutex(&crl->crlLock); + + return 0; +} + + +/* Load CRL File of type, SSL_SUCCESS on ok */ +int BufferLoadCRL(CYASSL_CRL* crl, const byte* buff, long sz, int type) +{ + int ret = SSL_SUCCESS; + const byte* myBuffer = buff; /* if DER ok, otherwise switch */ + buffer der; + DecodedCRL dcrl; + + der.buffer = NULL; + + CYASSL_ENTER("BufferLoadCRL"); + + if (crl == NULL || buff == NULL || sz == 0) + return BAD_FUNC_ARG; + + if (type == SSL_FILETYPE_PEM) { + int eccKey = 0; /* not used */ + EncryptedInfo info; + info.ctx = NULL; + + ret = PemToDer(buff, sz, CRL_TYPE, &der, NULL, &info, &eccKey); + if (ret == 0) { + myBuffer = der.buffer; + sz = der.length; + } + else { + CYASSL_MSG("Pem to Der failed"); + return -1; + } + } + + InitDecodedCRL(&dcrl); + ret = ParseCRL(&dcrl, myBuffer, sz); + if (ret != 0) { + CYASSL_MSG("ParseCRL error"); + } + else { + ret = AddCRL(crl, &dcrl); + if (ret != 0) { + CYASSL_MSG("AddCRL error"); + } + } + FreeDecodedCRL(&dcrl); + + if (der.buffer) + XFREE(der.buffer, NULL, DYNAMIC_TYPE_CRL); + + if (ret == 0) + return SSL_SUCCESS; /* convert */ + return ret; +} + + +/* Load CRL path files of type, SSL_SUCCESS on ok */ +int LoadCRL(CYASSL_CRL* crl, const char* path, int type) +{ + struct dirent* entry; + DIR* dir; + int ret = SSL_SUCCESS; + + CYASSL_ENTER("LoadCRL"); + if (crl == NULL) + return BAD_FUNC_ARG; + + dir = opendir(path); + if (dir == NULL) { + CYASSL_MSG("opendir path crl load failed"); + return BAD_PATH_ERROR; + } + while ( ret == SSL_SUCCESS && (entry = readdir(dir)) != NULL) { + if (entry->d_type & DT_REG) { + char name[MAX_FILENAME_SZ]; + + if (type == SSL_FILETYPE_PEM) { + if (strstr(entry->d_name, ".pem") == NULL) { + CYASSL_MSG("not .pem file, skipping"); + continue; + } + } + else { + if (strstr(entry->d_name, ".der") == NULL && + strstr(entry->d_name, ".crl") == NULL) { + + CYASSL_MSG("not .der or .crl file, skipping"); + continue; + } + } + + XMEMSET(name, 0, sizeof(name)); + XSTRNCPY(name, path, MAX_FILENAME_SZ/2 - 2); + XSTRNCAT(name, "/", 1); + XSTRNCAT(name, entry->d_name, MAX_FILENAME_SZ/2); + + ret = ProcessFile(NULL, name, type, CRL_TYPE, NULL, 0, crl); + } + } + + return SSL_SUCCESS; +} + +#endif /* HAVE_CRL */ diff --git a/src/include.am b/src/include.am index e4fab5f52..9890a8f7e 100644 --- a/src/include.am +++ b/src/include.am @@ -70,3 +70,7 @@ if BUILD_OCSP src_libcyassl_la_SOURCES += src/ocsp.c endif +if BUILD_CRL +src_libcyassl_la_SOURCES += src/crl.c +endif + diff --git a/src/internal.c b/src/internal.c index bfe2a9ddf..561d9c0ac 100644 --- a/src/internal.c +++ b/src/internal.c @@ -460,6 +460,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, byte haveDH, byte havePSK, (void)haveDH; (void)havePSK; (void)haveNTRU; + (void)haveStaticECC; if (suites->setSuites) return; /* trust user settings, don't override */ @@ -858,6 +859,7 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx) ssl->options.sendVerify = ctx->sendVerify; ssl->options.resuming = 0; + ssl->options.haveSessionId = 0; ssl->hmac = Hmac; /* default to SSLv3 */ ssl->heap = ctx->heap; /* defaults to self */ ssl->options.tls = 0; @@ -1696,12 +1698,23 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx) #ifdef HAVE_OCSP if (CyaSSL_OCSP_Lookup_Cert(&ssl->ctx->ocsp, &dCert) == CERT_REVOKED) { - CYASSL_MSG("\tOCSP Lookup returned revoked"); - ret = OCSP_CERT_REVOKED; - fatal = 0; - } + CYASSL_MSG("\tOCSP Lookup returned revoked"); + ret = OCSP_CERT_REVOKED; + fatal = 0; + } #endif +#ifdef HAVE_CRL + if (ssl->ctx->cm->crlEnabled) { + ret = CheckCertCRL(ssl->ctx->cm->crl, &dCert); + + if (ret != 0) { + CYASSL_MSG("\tCRL check not ok"); + fatal = 0; + } + } +#endif /* HAVE_CRL */ + #ifdef OPENSSL_EXTRA /* set X509 format for peer cert even if fatal */ XSTRNCPY(ssl->peerCert.issuer.name, dCert.issuer, ASN_NAME_MAX); @@ -3509,6 +3522,14 @@ void SetErrorString(int error, char* str) XSTRNCPY(str, "OCSP Cert revoked", max); break; + case CRL_CERT_REVOKED: + XSTRNCPY(str, "CRL Cert revoked", max); + break; + + case CRL_MISSING: + XSTRNCPY(str, "CRL missing, not loaded", max); + break; + default : XSTRNCPY(str, "unknown error number", max); } @@ -4150,7 +4171,6 @@ int SetCipherList(Suites* s, const char* list) byte compression; ProtocolVersion pv; word32 i = *inOutIdx; - int serverResumption = 0; #ifdef CYASSL_CALLBACKS if (ssl->hsInfoOn) AddPacketName("ServerHello", &ssl->handShakeInfo); @@ -4192,7 +4212,7 @@ int SetCipherList(Suites* s, const char* list) if (b) { XMEMCPY(ssl->arrays.sessionID, input + i, b); i += b; - serverResumption = 1; + ssl->options.haveSessionId = 1; } ssl->options.cipherSuite0 = input[i++]; ssl->options.cipherSuite = input[i++]; @@ -4208,7 +4228,7 @@ int SetCipherList(Suites* s, const char* list) *inOutIdx = i; if (ssl->options.resuming) { - if (serverResumption && XMEMCMP(ssl->arrays.sessionID, + if (ssl->options.haveSessionId && XMEMCMP(ssl->arrays.sessionID, ssl->session.sessionID, ID_LEN) == 0) { if (SetCipherSpecs(ssl) == 0) { int ret; @@ -4221,9 +4241,10 @@ int SetCipherList(Suites* s, const char* list) ssl->options.serverState = SERVER_HELLODONE_COMPLETE; return ret; } - else + else { CYASSL_MSG("Unsupported cipher suite, DoServerHello"); return UNSUPPORTED_SUITE; + } } else { CYASSL_MSG("Server denied resumption attempt"); @@ -5551,6 +5572,7 @@ int SetCipherList(Suites* s, const char* list) ssl->options.clientState = CLIENT_HELLO_COMPLETE; *inOutIdx = idx; + ssl->options.haveSessionId = 1; /* DoClientHello uses same resume code */ while (ssl->options.resuming) { /* let's try */ int ret; @@ -5706,6 +5728,7 @@ int SetCipherList(Suites* s, const char* list) if ( (i - begin) < helloSz) *inOutIdx = begin + helloSz; /* skip extensions */ + ssl->options.haveSessionId = 1; /* ProcessOld uses same resume code */ while (ssl->options.resuming) { /* let's try */ int ret; diff --git a/src/ssl.c b/src/ssl.c index cf39c1c55..b478e2d7a 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -375,6 +375,10 @@ CYASSL_CERT_MANAGER* CyaSSL_CertManagerNew(void) cm->caList = NULL; cm->heap = NULL; cm->caCacheCallback = NULL; + cm->crl = NULL; + cm->crlEnabled = 0; + cm->crlCheckAll = 0; + cm->cbMissingCRL = NULL; if (InitMutex(&cm->caLock) != 0) { CYASSL_MSG("Bad mutex init"); @@ -392,6 +396,10 @@ void CyaSSL_CertManagerFree(CYASSL_CERT_MANAGER* cm) CYASSL_ENTER("CyaSSL_CertManagerFree"); if (cm) { + #ifdef HAVE_CRL + if (cm->crl) + FreeCRL(cm->crl); + #endif FreeSigners(cm->caList, NULL); FreeMutex(&cm->caLock); XFREE(cm, NULL, DYNAMIC_TYPE_CERT_MANAGER); @@ -629,7 +637,7 @@ int AddCA(CYASSL_CERT_MANAGER* cm, buffer der, int type, int verify) /* 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, + int PemToDer(const unsigned char* buff, long sz, int type, buffer* der, void* heap, EncryptedInfo* info, int* eccKey) { char header[PEM_LINE_LEN]; @@ -655,6 +663,10 @@ int AddCA(CYASSL_CERT_MANAGER* cm, buffer der, int type, int verify) XSTRNCPY(header, "-----BEGIN DH PARAMETERS-----", sizeof(header)); XSTRNCPY(footer, "-----END DH PARAMETERS-----", sizeof(footer)); dynamicType = DYNAMIC_TYPE_KEY; + } else if (type == CRL_TYPE) { + XSTRNCPY(header, "-----BEGIN X509 CRL-----", sizeof(header)); + XSTRNCPY(footer, "-----END X509 CRL-----", sizeof(footer)); + dynamicType = DYNAMIC_TYPE_CRL; } else { XSTRNCPY(header, "-----BEGIN RSA PRIVATE KEY-----", sizeof(header)); XSTRNCPY(footer, "-----END RSA PRIVATE KEY-----", sizeof(footer)); @@ -1077,6 +1089,9 @@ int AddCA(CYASSL_CERT_MANAGER* cm, buffer der, int type, int verify) if (ssl) ssl->options.haveECDSA = 1; break; + default: + CYASSL_MSG("Not ECDSA cert signature"); + break; } FreeDecodedCert(&cert); @@ -1144,8 +1159,8 @@ static int ProcessChainBuffer(CYASSL_CTX* ctx, const unsigned char* buff, /* process a file with name fname into ctx of format and type userChain specifies a user certificate chain to pass during handshake */ -static int ProcessFile(CYASSL_CTX* ctx, const char* fname, int format, int type, - CYASSL* ssl, int userChain) +int ProcessFile(CYASSL_CTX* ctx, const char* fname, int format, int type, + CYASSL* ssl, int userChain, CYASSL_CRL* crl) { byte staticBuffer[FILE_BUFFER_SIZE]; byte* myBuffer = staticBuffer; @@ -1154,6 +1169,8 @@ static int ProcessFile(CYASSL_CTX* ctx, const char* fname, int format, int type, long sz = 0; XFILE* file = XFOPEN(fname, "rb"); + (void)crl; + if (!file) return SSL_BAD_FILE; XFSEEK(file, 0, XSEEK_END); sz = XFTELL(file); @@ -1174,6 +1191,10 @@ static int ProcessFile(CYASSL_CTX* ctx, const char* fname, int format, int type, else { if (type == CA_TYPE && format == SSL_FILETYPE_PEM) ret = ProcessChainBuffer(ctx, myBuffer, sz, format, type, ssl); +#ifdef HAVE_CRL + else if (type == CRL_TYPE) + ret = BufferLoadCRL(crl, myBuffer, sz, format); +#endif else ret = ProcessBuffer(ctx, myBuffer, sz, format, type, ssl, NULL, userChain); @@ -1199,7 +1220,7 @@ int CyaSSL_CTX_load_verify_locations(CYASSL_CTX* ctx, const char* file, return SSL_FAILURE; if (file) - ret = ProcessFile(ctx, file, SSL_FILETYPE_PEM, CA_TYPE, NULL, 0); + ret = ProcessFile(ctx, file, SSL_FILETYPE_PEM, CA_TYPE, NULL, 0, NULL); if (ret == SSL_SUCCESS && path) { /* try to load each regular file in path */ @@ -1224,7 +1245,8 @@ int CyaSSL_CTX_load_verify_locations(CYASSL_CTX* ctx, const char* file, XSTRNCAT(name, "\\", 2); XSTRNCAT(name, FindFileData.cFileName, MAX_FILENAME_SZ/2); - ret = ProcessFile(ctx, name, SSL_FILETYPE_PEM, CA_TYPE, NULL,0); + ret = ProcessFile(ctx, name, SSL_FILETYPE_PEM, CA_TYPE, NULL,0, + NULL); } } while (ret == SSL_SUCCESS && FindNextFileA(hFind, &FindFileData)); @@ -1246,7 +1268,8 @@ int CyaSSL_CTX_load_verify_locations(CYASSL_CTX* ctx, const char* file, XSTRNCAT(name, "/", 1); XSTRNCAT(name, entry->d_name, MAX_FILENAME_SZ/2); - ret = ProcessFile(ctx, name, SSL_FILETYPE_PEM, CA_TYPE, NULL,0); + ret = ProcessFile(ctx, name, SSL_FILETYPE_PEM, CA_TYPE, NULL,0, + NULL); } } closedir(dir); @@ -1356,6 +1379,168 @@ int CyaSSL_CertManagerLoadCA(CYASSL_CERT_MANAGER* cm, const char* file, } +/* turn on CRL if off and compiled in, set options */ +int CyaSSL_CertManagerEnableCRL(CYASSL_CERT_MANAGER* cm, int options) +{ + (void)options; + + CYASSL_ENTER("CyaSSL_CertManagerEnableCRL"); + if (cm == NULL) + return BAD_FUNC_ARG; + + #ifndef HAVE_CRL + return NOT_COMPILED_IN; + #else + if (cm->crl == NULL) { + cm->crl = (CYASSL_CRL*)XMALLOC(sizeof(CYASSL_CRL), cm->heap, + DYNAMIC_TYPE_CRL); + if (cm->crl == NULL) + return MEMORY_E; + + if (InitCRL(cm->crl, cm) != 0) { + CYASSL_MSG("Init CRL failed"); + FreeCRL(cm->crl); + cm->crl = NULL; + return SSL_FAILURE; + } + } + cm->crlEnabled = 1; + if (options & CYASSL_CRL_CHECKALL) + cm->crlCheckAll = 1; + #endif + + return SSL_SUCCESS; +} + + +int CyaSSL_CertManagerDisableCRL(CYASSL_CERT_MANAGER* cm) +{ + CYASSL_ENTER("CyaSSL_CertManagerDisableCRL"); + if (cm == NULL) + return BAD_FUNC_ARG; + + cm->crlEnabled = 0; + + return SSL_SUCCESS; +} + + +#ifdef HAVE_CRL + + +int CyaSSL_CertManagerSetCRL_Cb(CYASSL_CERT_MANAGER* cm, CbMissingCRL cb) +{ + CYASSL_ENTER("CyaSSL_CertManagerLoadCRL"); + if (cm == NULL) + return BAD_FUNC_ARG; + + cm->cbMissingCRL = cb; + + return SSL_SUCCESS; +} + + +int CyaSSL_CertManagerLoadCRL(CYASSL_CERT_MANAGER* cm, const char* path, + int type) +{ + CYASSL_ENTER("CyaSSL_CertManagerLoadCRL"); + if (cm == NULL) + return BAD_FUNC_ARG; + + if (cm->crl == NULL) { + if (CyaSSL_CertManagerEnableCRL(cm, 0) != SSL_SUCCESS) { + CYASSL_MSG("Enable CRL failed"); + return -1; + } + } + + return LoadCRL(cm->crl, path, type); +} + + +int CyaSSL_EnableCRL(CYASSL* ssl, int options) +{ + CYASSL_ENTER("CyaSSL_EnableCRL"); + if (ssl) + return CyaSSL_CertManagerEnableCRL(ssl->ctx->cm, options); + else + return BAD_FUNC_ARG; +} + + +int CyaSSL_DisableCRL(CYASSL* ssl) +{ + CYASSL_ENTER("CyaSSL_DisableCRL"); + if (ssl) + return CyaSSL_CertManagerDisableCRL(ssl->ctx->cm); + else + return BAD_FUNC_ARG; +} + + +int CyaSSL_LoadCRL(CYASSL* ssl, const char* path, int type) +{ + CYASSL_ENTER("CyaSSL_LoadCRL"); + if (ssl) + return CyaSSL_CertManagerLoadCRL(ssl->ctx->cm, path, type); + else + return BAD_FUNC_ARG; +} + + +int CyaSSL_SetCRL_Cb(CYASSL* ssl, CbMissingCRL cb) +{ + CYASSL_ENTER("CyaSSL_SetCRL_Cb"); + if (ssl) + return CyaSSL_CertManagerSetCRL_Cb(ssl->ctx->cm, cb); + else + return BAD_FUNC_ARG; +} + + +int CyaSSL_CTX_EnableCRL(CYASSL_CTX* ctx, int options) +{ + CYASSL_ENTER("CyaSSL_CTX_EnableCRL"); + if (ctx) + return CyaSSL_CertManagerEnableCRL(ctx->cm, options); + else + return BAD_FUNC_ARG; +} + + +int CyaSSL_CTX_DisableCRL(CYASSL_CTX* ctx) +{ + CYASSL_ENTER("CyaSSL_CTX_DisableCRL"); + if (ctx) + return CyaSSL_CertManagerDisableCRL(ctx->cm); + else + return BAD_FUNC_ARG; +} + + +int CyaSSL_CTX_LoadCRL(CYASSL_CTX* ctx, const char* path, int type) +{ + CYASSL_ENTER("CyaSSL_CTX_LoadCRL"); + if (ctx) + return CyaSSL_CertManagerLoadCRL(ctx->cm, path, type); + else + return BAD_FUNC_ARG; +} + + +int CyaSSL_CTX_SetCRL_Cb(CYASSL_CTX* ctx, CbMissingCRL cb) +{ + CYASSL_ENTER("CyaSSL_CTX_SetCRL_Cb"); + if (ctx) + return CyaSSL_CertManagerSetCRL_Cb(ctx->cm, cb); + else + return BAD_FUNC_ARG; +} + + +#endif /* HAVE_CRL */ + + #ifdef CYASSL_DER_LOAD /* Add format parameter to allow DER load of CA files */ @@ -1366,7 +1551,7 @@ int CyaSSL_CTX_der_load_verify_locations(CYASSL_CTX* ctx, const char* file, if (ctx == NULL || file == NULL) return SSL_FAILURE; - if (ProcessFile(ctx, file, format, CA_TYPE, NULL, 0) == SSL_SUCCESS) + if (ProcessFile(ctx, file, format, CA_TYPE, NULL, 0, NULL) == SSL_SUCCESS) return SSL_SUCCESS; return SSL_FAILURE; @@ -1436,7 +1621,7 @@ int CyaSSL_CTX_use_certificate_file(CYASSL_CTX* ctx, const char* file, int format) { CYASSL_ENTER("CyaSSL_CTX_use_certificate_file"); - if (ProcessFile(ctx, file, format, CERT_TYPE, NULL, 0) == SSL_SUCCESS) + if (ProcessFile(ctx, file, format, CERT_TYPE, NULL, 0, NULL) == SSL_SUCCESS) return SSL_SUCCESS; return SSL_FAILURE; @@ -1446,7 +1631,8 @@ int CyaSSL_CTX_use_certificate_file(CYASSL_CTX* ctx, const char* file, int CyaSSL_CTX_use_PrivateKey_file(CYASSL_CTX* ctx, const char* file,int format) { CYASSL_ENTER("CyaSSL_CTX_use_PrivateKey_file"); - if (ProcessFile(ctx, file, format, PRIVATEKEY_TYPE, NULL, 0) == SSL_SUCCESS) + if (ProcessFile(ctx, file, format, PRIVATEKEY_TYPE, NULL, 0, NULL) + == SSL_SUCCESS) return SSL_SUCCESS; return SSL_FAILURE; @@ -1457,7 +1643,8 @@ int CyaSSL_CTX_use_certificate_chain_file(CYASSL_CTX* ctx, const char* file) { /* procces up to MAX_CHAIN_DEPTH plus subject cert */ CYASSL_ENTER("CyaSSL_CTX_use_certificate_chain_file"); - if (ProcessFile(ctx, file, SSL_FILETYPE_PEM,CERT_TYPE,NULL,1) == SSL_SUCCESS) + if (ProcessFile(ctx, file, SSL_FILETYPE_PEM,CERT_TYPE,NULL,1, NULL) + == SSL_SUCCESS) return SSL_SUCCESS; return SSL_FAILURE; @@ -1470,7 +1657,8 @@ int CyaSSL_CTX_use_certificate_chain_file(CYASSL_CTX* ctx, const char* file) int CyaSSL_use_certificate_file(CYASSL* ssl, const char* file, int format) { CYASSL_ENTER("CyaSSL_use_certificate_file"); - if (ProcessFile(ssl->ctx, file, format, CERT_TYPE, ssl, 0) == SSL_SUCCESS) + if (ProcessFile(ssl->ctx, file, format, CERT_TYPE, ssl, 0, NULL) + == SSL_SUCCESS) return SSL_SUCCESS; return SSL_FAILURE; @@ -1480,7 +1668,7 @@ int CyaSSL_use_certificate_file(CYASSL* ssl, const char* file, int format) int CyaSSL_use_PrivateKey_file(CYASSL* ssl, const char* file, int format) { CYASSL_ENTER("CyaSSL_use_PrivateKey_file"); - if (ProcessFile(ssl->ctx, file, format, PRIVATEKEY_TYPE, ssl, 0) + if (ProcessFile(ssl->ctx, file, format, PRIVATEKEY_TYPE, ssl, 0, NULL) == SSL_SUCCESS) return SSL_SUCCESS; @@ -1492,7 +1680,7 @@ int CyaSSL_use_certificate_chain_file(CYASSL* ssl, const char* file) { /* procces up to MAX_CHAIN_DEPTH plus subject cert */ CYASSL_ENTER("CyaSSL_use_certificate_chain_file"); - if (ProcessFile(ssl->ctx, file, SSL_FILETYPE_PEM, CERT_TYPE, ssl, 1) + if (ProcessFile(ssl->ctx, file, SSL_FILETYPE_PEM, CERT_TYPE, ssl, 1, NULL) == SSL_SUCCESS) return SSL_SUCCESS; @@ -1652,7 +1840,7 @@ int CyaSSL_CTX_SetTmpDH_file(CYASSL_CTX* ctx, const char* fname, int format) int CyaSSL_CTX_use_NTRUPrivateKey_file(CYASSL_CTX* ctx, const char* file) { CYASSL_ENTER("CyaSSL_CTX_use_NTRUPrivateKey_file"); - if (ProcessFile(ctx, file, SSL_FILETYPE_RAW, PRIVATEKEY_TYPE, NULL, 0) + if (ProcessFile(ctx, file, SSL_FILETYPE_RAW, PRIVATEKEY_TYPE, NULL, 0, NULL) == SSL_SUCCESS) { ctx->haveNTRU = 1; return SSL_SUCCESS; @@ -1671,7 +1859,8 @@ int CyaSSL_CTX_use_NTRUPrivateKey_file(CYASSL_CTX* ctx, const char* file) int format) { CYASSL_ENTER("SSL_CTX_use_RSAPrivateKey_file"); - if (ProcessFile(ctx, file,format,PRIVATEKEY_TYPE,NULL,0) == SSL_SUCCESS) + if (ProcessFile(ctx, file,format,PRIVATEKEY_TYPE,NULL,0, NULL) + == SSL_SUCCESS) return SSL_SUCCESS; return SSL_FAILURE; @@ -1680,7 +1869,7 @@ int CyaSSL_CTX_use_NTRUPrivateKey_file(CYASSL_CTX* ctx, const char* file) int CyaSSL_use_RSAPrivateKey_file(CYASSL* ssl, const char* file, int format) { CYASSL_ENTER("CyaSSL_use_RSAPrivateKey_file"); - if (ProcessFile(ssl->ctx, file, format, PRIVATEKEY_TYPE, ssl, 0) + if (ProcessFile(ssl->ctx, file, format, PRIVATEKEY_TYPE, ssl, 0, NULL) == SSL_SUCCESS) return SSL_SUCCESS; @@ -2390,7 +2579,10 @@ CYASSL_SESSION* GetSession(CYASSL* ssl, byte* masterSecret) int idx; if (ssl->options.sessionCacheOff) - return 0; + return NULL; + + if (ssl->options.haveSessionId == 0) + return NULL; row = HashSession(id) % SESSION_ROWS; @@ -2453,6 +2645,9 @@ int AddSession(CYASSL* ssl) if (ssl->options.sessionCacheOff) return 0; + if (ssl->options.haveSessionId == 0) + return 0; + row = HashSession(ssl->arrays.sessionID) % SESSION_ROWS; if (LockMutex(&session_mutex) != 0) @@ -3948,26 +4143,6 @@ int CyaSSL_set_compression(CYASSL* ssl) return 0; /* failure */ } - if (key) - CYASSL_MSG("have key"); - - if (iv) - CYASSL_MSG("have iv"); - - if (enc == 1) { - CYASSL_MSG("encrypt side"); - } - else if (enc == 0) { - CYASSL_MSG("decrypt side"); - } - else { - CYASSL_MSG("no side"); - if (ctx->enc) - CYASSL_MSG("no side enc"); - else - CYASSL_MSG("no side dec"); - } - if (ctx->cipherType == AES_128_CBC_TYPE || (type && XSTRNCMP(type, "AES128-CBC", 10) == 0)) { CYASSL_MSG("AES-128-CBC"); @@ -4135,13 +4310,6 @@ int CyaSSL_set_compression(CYASSL* ssl) return 0; /* failure */ } - if (ctx->enc) - CYASSL_MSG("encrypting"); - else - CYASSL_MSG("decrypting"); - - - switch (ctx->cipherType) { case AES_128_CBC_TYPE : @@ -5663,6 +5831,9 @@ static int initGlobalRNG = 0; CYASSL_MSG("CyaSSL_RAND_seed"); + (void)seed; + (void)len; + if (initGlobalRNG == 0) { if (InitRng(&globalRNG) < 0) { CYASSL_MSG("CyaSSL Init Global RNG failed"); @@ -5705,12 +5876,14 @@ static int initGlobalRNG = 0; void CyaSSL_BN_CTX_init(CYASSL_BN_CTX* ctx) { + (void)ctx; CYASSL_MSG("CyaSSL_BN_CTX_init"); } void CyaSSL_BN_CTX_free(CYASSL_BN_CTX* ctx) { + (void)ctx; CYASSL_MSG("CyaSSL_BN_CTX_free"); /* do free since static ctx that does nothing */ @@ -5761,7 +5934,7 @@ static int initGlobalRNG = 0; CYASSL_MSG("CyaSSL_BN_free"); if (bn) { if (bn->internal) { - mp_clear(bn->internal); + mp_clear((mp_int*)bn->internal); XFREE(bn->internal, NULL, DYNAMIC_TYPE_BIGINT); bn->internal = NULL; } @@ -5798,6 +5971,7 @@ static int initGlobalRNG = 0; int CyaSSL_BN_mod(CYASSL_BIGNUM* r, const CYASSL_BIGNUM* a, const CYASSL_BIGNUM* b, const CYASSL_BN_CTX* c) { + (void)c; CYASSL_MSG("CyaSSL_BN_mod"); if (r == NULL || a == NULL || b == NULL) @@ -5868,7 +6042,7 @@ static int initGlobalRNG = 0; if (bn == NULL || bn->internal == NULL) return 0; - if (mp_cmp_d((mp_int*)bn->internal, 1) == 0); + if (mp_cmp_d((mp_int*)bn->internal, 1) == 0) return 1; return 0; @@ -5888,7 +6062,6 @@ static int initGlobalRNG = 0; int CyaSSL_BN_cmp(const CYASSL_BIGNUM* a, const CYASSL_BIGNUM* b) { - int ret; CYASSL_MSG("CyaSSL_BN_cmp"); if (a == NULL || a->internal == NULL || b == NULL || b->internal ==NULL) @@ -5930,8 +6103,9 @@ static int initGlobalRNG = 0; return NULL; } } - else + else { CYASSL_MSG("CyaSSL_BN_bin2bn wants return bignum"); + } return ret; } @@ -5939,6 +6113,8 @@ static int initGlobalRNG = 0; int CyaSSL_mask_bits(CYASSL_BIGNUM* bn, int n) { + (void)bn; + (void)n; CYASSL_MSG("CyaSSL_BN_mask_bits"); return -1; @@ -5947,12 +6123,14 @@ static int initGlobalRNG = 0; int CyaSSL_BN_rand(CYASSL_BIGNUM* bn, int bits, int top, int bottom) { - byte buffer[1024]; + byte buff[1024]; RNG tmpRNG; RNG* rng = &tmpRNG; int ret; int len = bits/8; + (void)top; + (void)bottom; CYASSL_MSG("CyaSSL_BN_rand"); if (bn == NULL || bn->internal == NULL) { @@ -5972,11 +6150,11 @@ static int initGlobalRNG = 0; rng = &globalRNG; } - RNG_GenerateBlock(rng, buffer, len); - buffer[0] |= 0x80 | 0x40; - buffer[len-1] |= 0x01; + RNG_GenerateBlock(rng, buff, len); + buff[0] |= 0x80 | 0x40; + buff[len-1] |= 0x01; - if (mp_read_unsigned_bin(bn->internal, buffer, len) != MP_OKAY) { + if (mp_read_unsigned_bin((mp_int*)bn->internal,buff,len) != MP_OKAY) { CYASSL_MSG("mp read bin failed"); return 0; } @@ -5987,6 +6165,9 @@ static int initGlobalRNG = 0; int CyaSSL_BN_is_bit_set(const CYASSL_BIGNUM* bn, int n) { + (void)bn; + (void)n; + CYASSL_MSG("CyaSSL_BN_is_bit_set"); return 0; @@ -5997,7 +6178,6 @@ static int initGlobalRNG = 0; { byte decoded[1024]; word32 decSz = sizeof(decoded); - int ret; CYASSL_MSG("CyaSSL_BN_hex2bn"); @@ -6060,6 +6240,9 @@ static int initGlobalRNG = 0; CYASSL_BIGNUM* CyaSSL_BN_copy(CYASSL_BIGNUM* r, const CYASSL_BIGNUM* bn) { + (void)r; + (void)bn; + CYASSL_MSG("CyaSSL_BN_copy"); return NULL; @@ -6068,6 +6251,9 @@ static int initGlobalRNG = 0; int CyaSSL_BN_set_word(CYASSL_BIGNUM* bn, unsigned long w) { + (void)bn; + (void)w; + CYASSL_MSG("CyaSSL_BN_set_word"); return -1; @@ -6076,6 +6262,9 @@ static int initGlobalRNG = 0; int CyaSSL_BN_dec2bn(CYASSL_BIGNUM** bn, const char* str) { + (void)bn; + (void)str; + CYASSL_MSG("CyaSSL_BN_dec2bn"); return -1; @@ -6084,6 +6273,8 @@ static int initGlobalRNG = 0; char* CyaSSL_BN_bn2dec(const CYASSL_BIGNUM* bn) { + (void)bn; + CYASSL_MSG("CyaSSL_BN_bn2dec"); return NULL; @@ -6139,7 +6330,7 @@ static int initGlobalRNG = 0; if (dh) { if (dh->internal) { - FreeDhKey(dh->internal); + FreeDhKey((DhKey*)dh->internal); XFREE(dh->internal, NULL, DYNAMIC_TYPE_DH); dh->internal = NULL; } @@ -6288,7 +6479,6 @@ static int initGlobalRNG = 0; word32 pubSz = sizeof(pub); word32 privSz = sizeof(priv); word32 keySz; - int ret; CYASSL_MSG("CyaSSL_DH_compute_key"); @@ -6303,12 +6493,12 @@ static int initGlobalRNG = 0; return 0; } - if (CyaSSL_BN_bn2bin(dh->priv_key, NULL) > privSz) { + if (CyaSSL_BN_bn2bin(dh->priv_key, NULL) > (int)privSz) { CYASSL_MSG("Bad priv internal size"); return 0; } - if (CyaSSL_BN_bn2bin(otherPub, NULL) > pubSz) { + if (CyaSSL_BN_bn2bin(otherPub, NULL) > (int)pubSz) { CYASSL_MSG("Bad otherPub size"); return 0; } @@ -6382,7 +6572,7 @@ static int initGlobalRNG = 0; if (dsa) { if (dsa->internal) { - FreeDsaKey(dsa->internal); + FreeDsaKey((DsaKey*)dsa->internal); XFREE(dsa->internal, NULL, DYNAMIC_TYPE_DSA); dsa->internal = NULL; } @@ -6400,6 +6590,8 @@ static int initGlobalRNG = 0; int CyaSSL_DSA_generate_key(CYASSL_DSA* dsa) { + (void)dsa; + CYASSL_MSG("CyaSSL_DSA_generate_key"); return 0; /* key gen not needed by server */ @@ -6410,6 +6602,14 @@ static int initGlobalRNG = 0; unsigned char* seed, int seedLen, int* counterRet, unsigned long* hRet, void* cb) { + (void)dsa; + (void)bits; + (void)seed; + (void)seedLen; + (void)counterRet; + (void)hRet; + (void)cb; + CYASSL_MSG("CyaSSL_DSA_generate_parameters_ex"); return 0; /* key gen not needed by server */ @@ -6469,7 +6669,7 @@ static int initGlobalRNG = 0; if (rsa) { if (rsa->internal) { - FreeRsaKey(rsa->internal); + FreeRsaKey((RsaKey*)rsa->internal); XFREE(rsa->internal, NULL, DYNAMIC_TYPE_RSA); rsa->internal = NULL; } @@ -6505,7 +6705,7 @@ static int initGlobalRNG = 0; } } - if (mp_copy(mpi, (*bn)->internal) != MP_OKAY) { + if (mp_copy(mpi, (mp_int*)((*bn)->internal)) != MP_OKAY) { CYASSL_MSG("mp_copy error"); return -1; } @@ -6631,7 +6831,7 @@ static int initGlobalRNG = 0; } #ifdef CYASSL_KEY_GEN - if (MakeRsaKey(rsa->internal, bits, 65537, &rng) < 0) { + if (MakeRsaKey((RsaKey*)rsa->internal, bits, 65537, &rng) < 0) { CYASSL_MSG("MakeRsaKey failed"); return -1; } @@ -6653,6 +6853,9 @@ static int initGlobalRNG = 0; int CyaSSL_RSA_blinding_on(CYASSL_RSA* rsa, CYASSL_BN_CTX* bn) { + (void)rsa; + (void)bn; + CYASSL_MSG("CyaSSL_RSA_blinding_on"); return 1; /* on by default */ @@ -6662,6 +6865,12 @@ static int initGlobalRNG = 0; int CyaSSL_RSA_public_encrypt(int len, unsigned char* fr, unsigned char* to, CYASSL_RSA* rsa, int padding) { + (void)len; + (void)fr; + (void)to; + (void)rsa; + (void)padding; + CYASSL_MSG("CyaSSL_RSA_public_encrypt"); return -1; @@ -6671,6 +6880,12 @@ static int initGlobalRNG = 0; int CyaSSL_RSA_private_decrypt(int len, unsigned char* fr, unsigned char* to, CYASSL_RSA* rsa, int padding) { + (void)len; + (void)fr; + (void)to; + (void)rsa; + (void)padding; + CYASSL_MSG("CyaSSL_RSA_private_decrypt"); return -1; @@ -6692,7 +6907,6 @@ static int initGlobalRNG = 0; int CyaSSL_DSA_do_sign(const unsigned char* d, unsigned char* sigRet, CYASSL_DSA* dsa) { - word32 signSz; RNG tmpRNG; RNG* rng = &tmpRNG; @@ -6779,14 +6993,14 @@ static int initGlobalRNG = 0; } signSz = EncodeSignature(encodedSig, m, mLen, type); - if (signSz < 0) { + if (signSz == 0) { CYASSL_MSG("Bad Encode Signature"); return 0; } *sigLen = RsaSSL_Sign(encodedSig, signSz, sigRet, outLen, (RsaKey*)rsa->internal, rng); - if (sigLen < 0) { + if (*sigLen <= 0) { CYASSL_MSG("Bad Rsa Sign"); return 0; } @@ -6799,6 +7013,12 @@ static int initGlobalRNG = 0; int CyaSSL_RSA_public_decrypt(int flen, unsigned char* from, unsigned char* to, CYASSL_RSA* rsa, int padding) { + (void)flen; + (void)from; + (void)to; + (void)rsa; + (void)padding; + CYASSL_MSG("CyaSSL_RSA_public_decrypt"); return -1; @@ -6877,13 +7097,14 @@ static int initGlobalRNG = 0; CYASSL_MSG("sha hmac"); ctx->type = SHA; } - else + else { CYASSL_MSG("bad init type"); + } } if (key && keylen) { CYASSL_MSG("keying hmac"); - HmacSetKey(&ctx->hmac, ctx->type, key, (word32)keylen); + HmacSetKey(&ctx->hmac, ctx->type, (const byte*)key, (word32)keylen); } } @@ -6934,6 +7155,8 @@ static int initGlobalRNG = 0; void CyaSSL_HMAC_cleanup(CYASSL_HMAC_CTX* ctx) { + (void)ctx; + CYASSL_MSG("CyaSSL_HMAC_cleanup"); } @@ -6962,6 +7185,7 @@ static int initGlobalRNG = 0; CYASSL_RSA* CyaSSL_EVP_PKEY_get1_RSA(CYASSL_EVP_PKEY* key) { + (void)key; CYASSL_MSG("CyaSSL_EVP_PKEY_get1_RSA"); return NULL; @@ -6970,6 +7194,7 @@ static int initGlobalRNG = 0; CYASSL_DSA* CyaSSL_EVP_PKEY_get1_DSA(CYASSL_EVP_PKEY* key) { + (void)key; CYASSL_MSG("CyaSSL_EVP_PKEY_get1_DSA"); return NULL; @@ -7021,6 +7246,8 @@ static int initGlobalRNG = 0; void CyaSSL_3des_iv(CYASSL_EVP_CIPHER_CTX* ctx, int doset, unsigned char* iv, int len) { + (void)len; + CYASSL_MSG("CyaSSL_3des_iv"); if (ctx == NULL || iv == NULL) { @@ -7038,6 +7265,8 @@ static int initGlobalRNG = 0; void CyaSSL_aes_ctr_iv(CYASSL_EVP_CIPHER_CTX* ctx, int doset, unsigned char* iv, int len) { + (void)len; + CYASSL_MSG("CyaSSL_aes_ctr_iv"); if (ctx == NULL || iv == NULL) { @@ -7158,6 +7387,14 @@ static int initGlobalRNG = 0; unsigned char* passwd, int len, pem_password_cb cb, void* arg) { + (void)bio; + (void)rsa; + (void)cipher; + (void)passwd; + (void)len; + (void)cb; + (void)arg; + CYASSL_MSG("CyaSSL_PEM_write_bio_RSAPrivateKey"); return -1; @@ -7170,6 +7407,14 @@ static int initGlobalRNG = 0; unsigned char* passwd, int len, pem_password_cb cb, void* arg) { + (void)bio; + (void)rsa; + (void)cipher; + (void)passwd; + (void)len; + (void)cb; + (void)arg; + CYASSL_MSG("CyaSSL_PEM_write_bio_DSAPrivateKey"); return -1; @@ -7180,6 +7425,11 @@ static int initGlobalRNG = 0; CYASSL_EVP_PKEY* CyaSSL_PEM_read_bio_PrivateKey(CYASSL_BIO* bio, CYASSL_EVP_PKEY** key, pem_password_cb cb, void* arg) { + (void)bio; + (void)key; + (void)cb; + (void)arg; + CYASSL_MSG("CyaSSL_PEM_read_bio_PrivateKey"); return NULL; @@ -7196,6 +7446,8 @@ int CyaSSL_KeyPemToDer(const unsigned char* pem, int pemSz, unsigned char* buff, int ret; buffer der; + (void)pass; + CYASSL_ENTER("CyaSSL_KeyPemToDer"); if (pem == NULL || buff == NULL || buffSz <= 0) { @@ -7213,7 +7465,7 @@ int CyaSSL_KeyPemToDer(const unsigned char* pem, int pemSz, unsigned char* buff, CYASSL_MSG("Bad Pem To Der"); } else { - if (der.length <= buffSz) { + if (der.length <= (word32)buffSz) { XMEMCPY(buff, der.buffer, der.length); ret = der.length; } @@ -7242,7 +7494,7 @@ int CyaSSL_RSA_LoadDer(CYASSL_RSA* rsa, const unsigned char* der, int derSz) return BAD_FUNC_ARG; } - ret = RsaPrivateKeyDecode(der, &idx, rsa->internal, derSz); + ret = RsaPrivateKeyDecode(der, &idx, (RsaKey*)rsa->internal, derSz); if (ret < 0) { CYASSL_MSG("RsaPrivateKeyDecode failed"); return ret; @@ -7272,7 +7524,7 @@ int CyaSSL_DSA_LoadDer(CYASSL_DSA* dsa, const unsigned char* der, int derSz) return BAD_FUNC_ARG; } - ret = DsaPrivateKeyDecode(der, &idx, dsa->internal, derSz); + ret = DsaPrivateKeyDecode(der, &idx, (DsaKey*)dsa->internal, derSz); if (ret < 0) { CYASSL_MSG("DsaPrivateKeyDecode failed"); return ret;