diff --git a/configure.ac b/configure.ac index 38921369a..f30b0da97 100644 --- a/configure.ac +++ b/configure.ac @@ -186,7 +186,7 @@ AC_ARG_ENABLE(bump, if test "$ENABLED_BUMP" = "yes" then - AM_CFLAGS="$AM_CFLAGS -DSESSION_CERTS -DLARGE_STATIC_BUFFERS -DCYASSL_CERT_GEN -DCYASSL_KEY_GEN -DOPENSSL_EXTRA -DFP_MAX_BITS=8192" + AM_CFLAGS="$AM_CFLAGS -DSESSION_CERTS -DLARGE_STATIC_BUFFERS -DCYASSL_CERT_GEN -DCYASSL_KEY_GEN -DHUGE_SESSION_CACHE -DOPENSSL_EXTRA -DFP_MAX_BITS=8192" fi # fastmath @@ -196,11 +196,6 @@ AC_ARG_ENABLE(fastmath, [ ENABLED_FASTMATH=no ] ) -if test "$ENABLED_BUMP" = "yes" -then - ENABLED_FASTMATH="yes" -fi - if test "x$ENABLED_FASTMATH" = "xyes" then AM_CFLAGS="$AM_CFLAGS -DUSE_FAST_MATH" @@ -214,6 +209,11 @@ AC_ARG_ENABLE(fasthugemath, [ ENABLED_FASTHUGEMATH=no ] ) +if test "$ENABLED_BUMP" = "yes" +then + ENABLED_FASTHUGEMATH="yes" +fi + if test "$ENABLED_FASTHUGEMATH" = "yes" then ENABLED_FASTMATH="yes" diff --git a/ctaocrypt/src/asn.c b/ctaocrypt/src/asn.c index 2fc3115f7..5c98f9173 100644 --- a/ctaocrypt/src/asn.c +++ b/ctaocrypt/src/asn.c @@ -963,6 +963,9 @@ void InitDecodedCert(DecodedCert* cert, byte* source, word32 inSz, void* heap) cert->heap = heap; XMEMSET(cert->serial, 0, EXTERNAL_SERIAL_SIZE); cert->serialSz = 0; + cert->extensions = 0; + cert->extensionsSz = 0; + cert->extensionsIdx = 0; #ifdef CYASSL_CERT_GEN cert->subjectSN = 0; cert->subjectSNLen = 0; @@ -1922,8 +1925,16 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, return ret; } - if (cert->srcIdx != cert->sigIndex) + if (cert->srcIdx != cert->sigIndex) { + if (cert->srcIdx < cert->sigIndex) { + /* save extensions */ + cert->extensions = &cert->source[cert->srcIdx]; + cert->extensionsSz = cert->sigIndex - cert->srcIdx; + cert->extensionsIdx = cert->srcIdx; /* for potential later use */ + } + /* advance past extensions */ cert->srcIdx = cert->sigIndex; + } if ((ret = GetAlgoId(cert->source, &cert->srcIdx, &confirmOID, cert->maxIdx)) < 0) @@ -2413,6 +2424,7 @@ void InitCert(Cert* cert) cert->selfSigned = 1; cert->isCA = 0; cert->bodySz = 0; + cert->altNamesSz = 0; cert->keyType = RSA_KEY; XMEMSET(cert->serial, 0, CTC_SERIAL_SIZE); @@ -2733,23 +2745,23 @@ static byte GetNameId(int idx) /* encode all extensions, return total bytes written */ -static int SetExtensions(byte* output, const byte* ca, int caSz) +static int SetExtensions(byte* output, const byte* ext, int extSz) { byte sequence[MAX_SEQ_SZ]; byte len[MAX_LENGTH_SZ]; int sz = 0; - int seqSz = SetSequence(caSz, sequence); - int lenSz = SetLength(seqSz + caSz, len); + int seqSz = SetSequence(extSz, sequence); + int lenSz = SetLength(seqSz + extSz, len); - output[0] = 0xa3; /* extensions id */ + output[0] = ASN_EXTENSIONS; /* extensions id */ sz++; - memcpy(&output[sz], len, lenSz); /* length */ + XMEMCPY(&output[sz], len, lenSz); /* length */ sz += lenSz; - memcpy(&output[sz], sequence, seqSz); /* sequence */ + XMEMCPY(&output[sz], sequence, seqSz); /* sequence */ sz += seqSz; - memcpy(&output[sz], ca, caSz); /* ca */ - sz += caSz; + XMEMCPY(&output[sz], ext, extSz); /* extensions */ + sz += extSz; return sz; } @@ -2761,7 +2773,7 @@ static int SetCa(byte* output) static const byte ca[] = { 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff }; - memcpy(output, ca, sizeof(ca)); + XMEMCPY(output, ca, sizeof(ca)); return (int)sizeof(ca); } @@ -2956,6 +2968,13 @@ static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, RNG* rng, else der->extensionsSz = 0; + if (der->extensionsSz == 0 && cert->altNamesSz) { + der->extensionsSz = SetExtensions(der->extensions, cert->altNames, + cert->altNamesSz); + if (der->extensionsSz == 0) + return EXTENSIONS_E; + } + der->total = der->versionSz + der->serialSz + der->sigAlgoSz + der->publicKeySz + der->validitySz + der->subjectSz + der->issuerSz + der->extensionsSz; @@ -3118,6 +3137,88 @@ int MakeSelfCert(Cert* cert, byte* buffer, word32 buffSz, RsaKey* key, RNG* rng) } +/* Set Alt Names from der cert, return 0 on success */ +static int SetAltNamesFromCert(Cert* cert, const byte* der, int derSz) +{ + DecodedCert decoded; + int ret; + int sz; + + if (derSz < 0) + return derSz; + + InitDecodedCert(&decoded, (byte*)der, derSz, 0); + ret = ParseCertRelative(&decoded, CA_TYPE, NO_VERIFY, 0); + + if (ret < 0) + return ret; + + if (decoded.extensions) { + byte b; + int length; + word32 maxExtensionsIdx; + + decoded.srcIdx = decoded.extensionsIdx; + b = decoded.source[decoded.srcIdx++]; + if (b != ASN_EXTENSIONS) { + FreeDecodedCert(&decoded); + return ASN_PARSE_E; + } + + if (GetLength(decoded.source, &decoded.srcIdx, &length, + decoded.maxIdx) < 0) { + FreeDecodedCert(&decoded); + return ASN_PARSE_E; + } + + if (GetSequence(decoded.source, &decoded.srcIdx, &length, + decoded.maxIdx) < 0) { + FreeDecodedCert(&decoded); + return ASN_PARSE_E; + } + + maxExtensionsIdx = decoded.srcIdx + length; + + while (decoded.srcIdx < maxExtensionsIdx) { + word32 oid; + word32 startIdx = decoded.srcIdx; + word32 tmpIdx; + + if (GetSequence(decoded.source, &decoded.srcIdx, &length, + decoded.maxIdx) < 0) { + FreeDecodedCert(&decoded); + return ASN_PARSE_E; + } + + tmpIdx = decoded.srcIdx; + decoded.srcIdx = startIdx; + + if (GetAlgoId(decoded.source, &decoded.srcIdx, &oid, + decoded.maxIdx) < 0) { + FreeDecodedCert(&decoded); + return ASN_PARSE_E; + } + + if (oid == ALT_NAMES_OID) { + cert->altNamesSz = length + (tmpIdx - startIdx); + + if (cert->altNamesSz < sizeof(cert->altNames)) + XMEMCPY(cert->altNames, &decoded.source[startIdx], + cert->altNamesSz); + else { + cert->altNamesSz = 0; + CYASSL_MSG("AltNames extensions too big"); + } + } + decoded.srcIdx = tmpIdx + length; + } + } + FreeDecodedCert(&decoded); + + return 0; +} + + /* Set cn name from der buffer, return 0 on success */ static int SetNameFromCert(CertName* cn, const byte* der, int derSz) { @@ -3214,6 +3315,16 @@ int SetSubject(Cert* cert, const char* subjectFile) return SetNameFromCert(&cert->subject, der, derSz); } + +/* Set atl names from file in PEM */ +int SetAltNames(Cert* cert, const char* file) +{ + byte der[8192]; + int derSz = CyaSSL_PemCertToDer(file, der, sizeof(der)); + + return SetAltNamesFromCert(cert, der, derSz); +} + #endif /* NO_FILESYSTEM */ /* Set cert issuer from DER buffer */ @@ -3231,6 +3342,13 @@ int SetSubjectBuffer(Cert* cert, const byte* der, int derSz) } +/* Set cert alt names from DER buffer */ +int SetAltNamesBuffer(Cert* cert, const byte* der, int derSz) +{ + return SetAltNamesFromCert(cert, der, derSz); +} + + #endif /* CYASSL_CERT_GEN */ diff --git a/ctaocrypt/test/test.c b/ctaocrypt/test/test.c index 1bb0f021b..0fff2a5d6 100644 --- a/ctaocrypt/test/test.c +++ b/ctaocrypt/test/test.c @@ -1298,7 +1298,7 @@ int rsa_test() ret = SetIssuer(&myCert, caCertFile); if (ret < 0) - return -406; + return -405; certSz = MakeCert(&myCert, derCert, sizeof(derCert), &key, &rng); if (certSz < 0) diff --git a/cyassl/ctaocrypt/asn.h b/cyassl/ctaocrypt/asn.h index bd49fc5c8..157cebf0c 100644 --- a/cyassl/ctaocrypt/asn.h +++ b/cyassl/ctaocrypt/asn.h @@ -59,6 +59,7 @@ enum ASN_Tags { ASN_SET = 0x11, ASN_UTC_TIME = 0x17, ASN_GENERALIZED_TIME = 0x18, + ASN_EXTENSIONS = 0xa3, ASN_LONG_LENGTH = 0x80 }; @@ -118,8 +119,10 @@ enum Misc_ASN { MAX_LENGTH_SZ = 4, /* Max length size for DER encoding */ MAX_RSA_E_SZ = 16, /* Max RSA public e size */ MAX_CA_SZ = 32, /* Max encoded CA basic constraint length */ - MAX_EXTENSIONS_SZ = 1 + MAX_LENGTH_SZ + MAX_CA_SZ, +#ifdef CYASSL_CERT_GEN + MAX_EXTENSIONS_SZ = 1 + MAX_LENGTH_SZ + CTC_MAX_ALT_SIZE, /* Max total extensions, id + len + others */ +#endif MAX_PUBLIC_KEY_SZ = MAX_NTRU_ENC_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ * 2 /* use bigger NTRU size */ }; @@ -171,6 +174,11 @@ enum KDF_Sum { }; +enum Extensions_Sum { + ALT_NAMES_OID = 131 +}; + + enum VerifyType { NO_VERIFY = 0, VERIFY = 1 @@ -204,6 +212,9 @@ struct DecodedCert { void* heap; /* for user memory overrides */ byte serial[EXTERNAL_SERIAL_SIZE]; /* raw serial number */ int serialSz; /* raw serial bytes stored */ + byte* extensions; /* not owned, points into raw cert */ + int extensionsSz; /* length of cert extensions */ + word32 extensionsIdx; /* if want to go back and parse later */ #ifdef CYASSL_CERT_GEN /* easy access to subject info for other sign */ char* subjectSN; diff --git a/cyassl/ctaocrypt/asn_public.h b/cyassl/ctaocrypt/asn_public.h index 76372f958..3b4a2e658 100644 --- a/cyassl/ctaocrypt/asn_public.h +++ b/cyassl/ctaocrypt/asn_public.h @@ -44,8 +44,9 @@ enum CertType { #ifdef CYASSL_CERT_GEN enum Ctc_Misc { - CTC_NAME_SIZE = 64, - CTC_SERIAL_SIZE = 8 + CTC_NAME_SIZE = 64, + CTC_MAX_ALT_SIZE = 512, + CTC_SERIAL_SIZE = 8 }; typedef struct CertName { @@ -73,6 +74,8 @@ typedef struct Cert { /* internal use only */ int bodySz; /* pre sign total size */ int keyType; /* public key type of subject */ + byte altNames[CTC_MAX_ALT_SIZE]; /* altNames copy */ + int altNamesSz; /* altNames size in bytes */ } Cert; @@ -96,8 +99,10 @@ CYASSL_API int MakeSelfCert(Cert*, byte* derBuffer, word32 derSz, RsaKey*, RNG*); CYASSL_API int SetIssuer(Cert*, const char*); CYASSL_API int SetSubject(Cert*, const char*); +CYASSL_API int SetAltNames(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); #ifdef HAVE_NTRU CYASSL_API int MakeNtruCert(Cert*, byte* derBuffer, word32 derSz,