Index: azure_iot_hub_f767zi/trunk/wolfssl-4.7.0/wolfssl/wolfcrypt/asn.h
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/wolfssl/wolfcrypt/asn.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.7.0/wolfssl/wolfcrypt/asn.h	(revision 464)
@@ -24,4 +24,12 @@
 */
 
+/*
+
+DESCRIPTION
+This library provides the interface to Abstract Syntax Notation One (ASN.1) objects.
+ASN.1 is a standard interface description language for defining data structures
+that can be serialized and deserialized in a cross-platform way.
+
+*/
 #ifndef WOLF_CRYPT_ASN_H
 #define WOLF_CRYPT_ASN_H
@@ -93,4 +101,5 @@
     ASN_SET               = 0x11,
     ASN_PRINTABLE_STRING  = 0x13,
+    ASN_IA5_STRING        = 0x16,
     ASN_UTC_TIME          = 0x17,
     ASN_OTHER_TYPE        = 0x00,
@@ -134,4 +143,7 @@
     ASN_DOMAIN_COMPONENT = 0x19  /* DC */
 };
+
+/* This is the size of the smallest possible PEM header and footer */
+extern const int pem_struct_min_sz;
 
 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
@@ -195,4 +207,5 @@
     NID_sha384 = 673,
     NID_sha512 = 674,
+    NID_pkcs9_challengePassword = 54,
     NID_hw_name_oid = 73,
     NID_id_pkix_OCSP_basic = 74,
@@ -221,4 +234,5 @@
     NID_tlsfeature = 1020,             /* id-pe 24 */
     NID_commonName = 0x03,             /* matches ASN_COMMON_NAME in asn.h */
+    NID_buildingName = 1494,
 
 
@@ -234,4 +248,5 @@
     NID_businessCategory = ASN_BUS_CAT,
     NID_domainComponent = ASN_DOMAIN_COMPONENT,
+    NID_userId = 458,
     NID_emailAddress = 0x30,           /* emailAddress */
     NID_id_on_dnsSRV = 82,             /* 1.3.6.1.5.5.7.8.7 */
@@ -292,5 +307,5 @@
     RSA_INTS            =   8,     /* RSA ints in private key */
     DSA_INTS            =   5,     /* DSA ints in private key */
-    MIN_DATE_SIZE       =  13,
+    MIN_DATE_SIZE       =  12,
     MAX_DATE_SIZE       =  32,
     ASN_GEN_TIME_SZ     =  15,     /* 7 numbers * 2 + Zulu tag */
@@ -327,4 +342,6 @@
     MAX_DER_DIGEST_ASN_SZ = MAX_ENCODED_DIG_ASN_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ,
                             /* Maximum DER digest ASN header size */
+                            /* Max X509 header length indicates the max length + 2 ('\n', '\0') */
+    MAX_X509_HEADER_SZ  = (37 + 2), /* Maximum PEM Header/Footer Size */
 #ifdef WOLFSSL_CERT_GEN
     #ifdef WOLFSSL_CERT_REQ
@@ -340,5 +357,6 @@
                                    /* Max total extensions, id + len + others */
 #endif
-#if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA) || defined(HAVE_PKCS7)
+#if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA) || \
+        defined(HAVE_PKCS7) || defined(OPENSSL_EXTRA_X509_SMALL)
     MAX_OID_SZ          = 32,      /* Max DER length of OID*/
     MAX_OID_STRING_SZ   = 64,      /* Max string length representation of OID*/
@@ -355,5 +373,4 @@
 #endif
     MAX_AIA_SZ          = 2,       /* Max Authority Info Access extension size*/
-    MAX_NAME_ENTRIES    = 5,       /* extra entries added to x509 name struct */
     OCSP_NONCE_EXT_SZ   = 35,      /* OCSP Nonce Extension size */
     MAX_OCSP_EXT_SZ     = 58,      /* Max OCSP Extension length */
@@ -370,4 +387,9 @@
     ASN_TAG_SZ          = 1,       /* single byte ASN.1 tag */
     MIN_VERSION_SZ      = 3,       /* Min bytes needed for GetMyVersion */
+    MAX_X509_VERSION    = 3,       /* Max X509 version allowed */
+    MIN_X509_VERSION    = 0,       /* Min X509 version allowed */
+    WOLFSSL_X509_V1     = 0,
+    WOLFSSL_X509_V2     = 1,
+    WOLFSSL_X509_V3     = 2,
 #if defined(OPENSSL_ALL)  || defined(WOLFSSL_MYSQL_COMPATIBLE) || \
     defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
@@ -378,6 +400,13 @@
     PKCS5_SALT_SZ       = 8,
 
-    PEM_LINE_LEN       = 80,       /* PEM line max + fudge */
-};
+    PEM_LINE_SZ        = 64,               /* Length of Base64 encoded line, not including new line */
+    PEM_LINE_LEN       = PEM_LINE_SZ + 12, /* PEM line max + fudge */
+};
+
+#ifndef WC_MAX_NAME_ENTRIES
+    /* entries added to x509 name struct */
+    #define WC_MAX_NAME_ENTRIES 13
+#endif
+#define MAX_NAME_ENTRIES WC_MAX_NAME_ENTRIES
 
 
@@ -403,4 +432,5 @@
     oidTlsExtType       = 18,
     oidCrlExtType       = 19,
+    oidCsrAttrType      = 20,
     oidIgnoreType
 };
@@ -519,5 +549,7 @@
     ISSUE_ALT_NAMES_OID       = 132,
     TLS_FEATURE_OID           = 92,  /* id-pe 24 */
-    NETSCAPE_CT_OID           = 753  /* 2.16.840.1.113730.1.1 */
+    NETSCAPE_CT_OID           = 753, /* 2.16.840.1.113730.1.1 */
+    OCSP_NOCHECK_OID          = 121  /* 1.3.6.1.5.5.7.48.1.5
+                                         id-pkix-ocsp-nocheck */
 };
 
@@ -564,4 +596,12 @@
     SKID_TYPE = 0,
     AKID_TYPE = 1
+};
+#endif
+
+#ifdef WOLFSSL_CERT_REQ
+enum CsrAttrType {
+    CHALLENGE_PASSWORD_OID = 659,
+    SERIAL_NUMBER_OID = 94,
+    EXTENSION_REQUEST_OID = 666,
 };
 #endif
@@ -607,62 +647,4 @@
 };
 
-#define DOMAIN_COMPONENT_MAX 10
-#define DN_NAMES_MAX 9
-
-struct DecodedName {
-    char*   fullName;
-    int     fullNameLen;
-    int     entryCount;
-    int     cnIdx;
-    int     cnLen;
-    int     cnNid;
-    int     snIdx;
-    int     snLen;
-    int     snNid;
-    int     cIdx;
-    int     cLen;
-    int     cNid;
-    int     lIdx;
-    int     lLen;
-    int     lNid;
-    int     stIdx;
-    int     stLen;
-    int     stNid;
-    int     oIdx;
-    int     oLen;
-    int     oNid;
-    int     ouIdx;
-    int     ouLen;
-#ifdef WOLFSSL_CERT_EXT
-    int     bcIdx;
-    int     bcLen;
-    int     jcIdx;
-    int     jcLen;
-    int     jsIdx;
-    int     jsLen;
-#endif
-    int     ouNid;
-    int     emailIdx;
-    int     emailLen;
-    int     emailNid;
-    int     uidIdx;
-    int     uidLen;
-    int     uidNid;
-    int     serialIdx;
-    int     serialLen;
-    int     serialNid;
-    int     dcIdx[DOMAIN_COMPONENT_MAX];
-    int     dcLen[DOMAIN_COMPONENT_MAX];
-    int     dcNum;
-    int     dcMode;
-#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
-    /* hold the location / order with which each of the DN tags was found
-     *
-     * example of ASN_DOMAIN_COMPONENT at index 0 if first found and so on.
-     */
-    int     loc[DOMAIN_COMPONENT_MAX + DN_NAMES_MAX];
-    int     locSz;
-#endif
-};
 
 enum SignatureState {
@@ -697,7 +679,10 @@
 #ifndef NO_RSA
     byte* out;
-    byte* plain;
-#endif
-#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448)
+#endif
+#if !(defined(NO_RSA) && defined(NO_DSA))
+    byte* sigCpy;
+#endif
+#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) || \
+    !defined(NO_DSA)
     int verify;
 #endif
@@ -705,4 +690,7 @@
     #ifndef NO_RSA
         struct RsaKey*      rsa;
+    #endif
+    #ifndef NO_DSA
+        struct DsaKey*      dsa;
     #endif
     #ifdef HAVE_ECC
@@ -782,5 +770,4 @@
 
 typedef struct DecodedCert DecodedCert;
-typedef struct DecodedName DecodedName;
 typedef struct Signer      Signer;
 #ifdef WOLFSSL_TRUST_PEER_CERT
@@ -804,4 +791,5 @@
 #ifndef IGNORE_NAME_CONSTRAINTS
     DNS_entry* altEmailNames;        /* alt names list of RFC822 entries */
+    DNS_entry* altDirNames;          /* alt names list of DIR entries    */
     Base_entry* permittedNames;      /* Permitted name bases             */
     Base_entry* excludedNames;       /* Excluded name bases              */
@@ -909,6 +897,7 @@
 #endif /* WOLFSSL_CERT_GEN */
 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
-    DecodedName issuerName;
-    DecodedName subjectName;
+    /* WOLFSSL_X509_NAME structures (used void* to avoid including ssl.h) */
+    void* issuerName;
+    void* subjectName;
 #endif /* OPENSSL_EXTRA */
 #ifdef WOLFSSL_SEP
@@ -925,4 +914,12 @@
 #endif /* defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT) */
 
+#ifdef WOLFSSL_CERT_REQ
+    /* CSR attributes */
+    char*   cPwd; /* challengePassword */
+    int     cPwdLen;
+    char*   sNum; /* Serial Number */
+    int     sNumLen;
+#endif /* WOLFSSL_CERT_REQ */
+
     Signer* ca;
 #ifndef NO_CERTS
@@ -948,4 +945,7 @@
     byte extKeyUsageSet : 1;
     byte extExtKeyUsageSet : 1;    /* Extended Key Usage set */
+#ifdef HAVE_OCSP
+    byte ocspNoCheckSet : 1;       /* id-pkix-ocsp-nocheck set */
+#endif
     byte extCRLdistSet : 1;
     byte extAuthInfoSet : 1;
@@ -973,5 +973,7 @@
     byte extCertPolicyCrit : 1;
 #endif
-
+#ifdef WOLFSSL_CERT_REQ
+    byte isCSR : 1;                /* Do we intend on parsing a CSR? */
+#endif
 };
 
@@ -1049,5 +1051,42 @@
 #endif
 
+#ifdef HAVE_SMIME
+#define MIME_HEADER_ASCII_MIN   33
+#define MIME_HEADER_ASCII_MAX   126
+
+typedef struct MimeParam MimeParam;
+typedef struct MimeHdr MimeHdr;
+
+struct MimeParam
+{
+    MimeParam*  next;
+    char*       attribute;
+    char*       value;
+};
+
+struct MimeHdr
+{
+    MimeHdr*    next;
+    MimeParam*  params;
+    char*       name;
+    char*       body;
+};
+
+typedef enum MimeTypes
+{
+    MIME_HDR,
+    MIME_PARAM
+} MimeTypes;
+
+typedef enum MimeStatus
+{
+    MIME_NAMEATTR,
+    MIME_BODYVAL
+} MimeStatus;
+#endif /* HAVE_SMIME */
+
+
 WOLFSSL_LOCAL int CalcHashId(const byte* data, word32 len, byte* hash);
+WOLFSSL_LOCAL int GetName(DecodedCert* cert, int nameType, int maxIdx);
 
 WOLFSSL_ASN_API int wc_BerToDer(const byte* ber, word32 berSz, byte* der,
@@ -1069,4 +1108,10 @@
 WOLFSSL_LOCAL int CheckCertSignaturePubKey(const byte* cert, word32 certSz,
         void* heap, const byte* pubKey, word32 pubKeySz, int pubKeyOID);
+#ifdef WOLFSSL_CERT_REQ
+WOLFSSL_LOCAL int CheckCSRSignaturePubKey(const byte* cert, word32 certSz, void* heap,
+        const byte* pubKey, word32 pubKeySz, int pubKeyOID);
+#endif /* WOLFSSL_CERT_REQ */
+WOLFSSL_LOCAL int AddSignature(byte* buf, int bodySz, const byte* sig, int sigSz,
+                        int sigAlgoType);
 WOLFSSL_LOCAL int ParseCertRelative(DecodedCert*,int type,int verify,void* cm);
 WOLFSSL_LOCAL int DecodeToKey(DecodedCert*, int verify);
@@ -1116,5 +1161,5 @@
                                                  wolfssl_tm* certTime, int* idx);
 WOLFSSL_LOCAL int DateGreaterThan(const struct tm* a, const struct tm* b);
-WOLFSSL_LOCAL int ValidateDate(const byte* date, byte format, int dateType);
+WOLFSSL_LOCAL int wc_ValidateDate(const byte* date, byte format, int dateType);
 WOLFSSL_LOCAL int wc_OBJ_sn2nid(const char *sn);
 
@@ -1122,4 +1167,6 @@
 #ifdef WOLFSSL_CERT_GEN
 WOLFSSL_ASN_API int SetName(byte* output, word32 outputSz, CertName* name);
+WOLFSSL_LOCAL const char* GetOneCertName(CertName* name, int idx);
+WOLFSSL_LOCAL byte GetCertNameId(int idx);
 #endif
 WOLFSSL_LOCAL int GetShortInt(const byte* input, word32* inOutIdx, int* number,
@@ -1139,4 +1186,6 @@
 WOLFSSL_LOCAL int GetOctetString(const byte* input, word32* inOutIdx, int* len,
                          word32 maxIdx);
+WOLFSSL_LOCAL int CheckBitString(const byte* input, word32* inOutIdx, int* len,
+                          word32 maxIdx, int zeroBits, byte* unusedBits);
 WOLFSSL_LOCAL int GetSet(const byte* input, word32* inOutIdx, int* len,
                         word32 maxIdx);
@@ -1173,4 +1222,5 @@
 WOLFSSL_LOCAL int wc_DhPrivKeyToDer(DhKey* key, byte* out, word32* outSz);
 #endif
+WOLFSSL_LOCAL int SetASNInt(int len, byte firstByte, byte* output);
 WOLFSSL_LOCAL word32 SetBitString(word32 len, byte unusedBits, byte* output);
 WOLFSSL_LOCAL word32 SetImplicit(byte tag,byte number,word32 len,byte* output);
@@ -1185,5 +1235,7 @@
 WOLFSSL_LOCAL int GetNameHash(const byte* source, word32* idx, byte* hash,
                              int maxIdx);
-WOLFSSL_LOCAL int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der);
+WOLFSSL_LOCAL int wc_CheckPrivateKeyCert(const byte* key, word32 keySz, DecodedCert* der);
+WOLFSSL_LOCAL int wc_CheckPrivateKey(const byte* privKey, word32 privKeySz,
+                                     const byte* pubKey, word32 pubKeySz, enum Key_Sum ks);
 WOLFSSL_LOCAL int StoreDHparams(byte* out, word32* outLen, mp_int* p, mp_int* g);
 WOLFSSL_LOCAL int FlattenAltNames( byte*, word32, const DNS_entry*);
@@ -1193,4 +1245,10 @@
     WOLFSSL_LOCAL int StoreECC_DSA_Sig(byte* out, word32* outLen, mp_int* r,
                                       mp_int* s);
+    WOLFSSL_LOCAL int StoreECC_DSA_Sig_Bin(byte* out, word32* outLen, 
+        const byte* r, word32 rLen, const byte* s, word32 sLen);
+    WOLFSSL_LOCAL int DecodeECC_DSA_Sig_Bin(const byte* sig, word32 sigLen, 
+        byte* r, word32* rLen, byte* s, word32* sLen);
+#endif
+#if defined(HAVE_ECC) || !defined(NO_DSA)
     WOLFSSL_LOCAL int DecodeECC_DSA_Sig(const byte* sig, word32 sigLen,
                                        mp_int* r, mp_int* s);
@@ -1215,4 +1273,14 @@
 
 #endif /* !NO_CERTS */
+
+#ifdef HAVE_SMIME
+WOLFSSL_LOCAL int wc_MIME_parse_headers(char* in, int inLen, MimeHdr** hdrs);
+WOLFSSL_LOCAL int wc_MIME_header_strip(char* in, char** out, size_t start, size_t end);
+WOLFSSL_LOCAL int wc_MIME_create_header(char* name, char* body, MimeHdr** hdr);
+WOLFSSL_LOCAL int wc_MIME_create_parameter(char* attribute, char* value, MimeParam** param);
+WOLFSSL_LOCAL MimeHdr* wc_MIME_find_header_name(const char* name, MimeHdr* hdr);
+WOLFSSL_LOCAL MimeParam* wc_MIME_find_param_attr(const char* attribute, MimeParam* param);
+WOLFSSL_LOCAL int wc_MIME_free_hdrs(MimeHdr* head);
+#endif /* HAVE_SMIME */
 
 #ifdef WOLFSSL_CERT_GEN
@@ -1231,5 +1299,6 @@
     ECC_KEY         = 12,
     ED25519_KEY     = 13,
-    ED448_KEY       = 14
+    ED448_KEY       = 14,
+    DSA_KEY         = 15
 };
 
@@ -1282,4 +1351,7 @@
     byte serial[EXTERNAL_SERIAL_SIZE];
     int serialSz;
+#ifdef OPENSSL_EXTRA
+    WOLFSSL_ASN1_INTEGER* serialInt;
+#endif
 
     int status;
@@ -1289,5 +1361,5 @@
     byte thisDateFormat;
     byte nextDateFormat;
-#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
+#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || defined(HAVE_LIGHTY)
     WOLFSSL_ASN1_TIME thisDateParsed;
     WOLFSSL_ASN1_TIME nextDateParsed;
@@ -1300,5 +1372,32 @@
 };
 
-
+typedef struct OcspEntry OcspEntry;
+
+#ifdef NO_SHA
+#define OCSP_DIGEST_SIZE WC_SHA256_DIGEST_SIZE
+#else
+#define OCSP_DIGEST_SIZE WC_SHA_DIGEST_SIZE
+#endif
+
+struct OcspEntry
+{
+    OcspEntry *next;                      /* next entry                */
+    word32 hashAlgoOID;                   /* hash algo ID              */
+    byte issuerHash[OCSP_DIGEST_SIZE];    /* issuer hash               */
+    byte issuerKeyHash[OCSP_DIGEST_SIZE]; /* issuer public key hash    */
+    CertStatus *status;                   /* OCSP response list        */
+    int totalStatus;                      /* number on list            */
+    byte* rawCertId;                      /* raw bytes of the CertID   */
+    int rawCertIdSize;                    /* num bytes in raw CertID   */
+    /* option bits - using 32-bit for alignment */
+    word32 isDynamic:1;                   /* was dynamically allocated */
+
+};
+
+/* TODO: Long-term, it would be helpful if we made this struct and other OCSP
+         structs conform to the ASN spec as described in RFC 6960. It will help
+         with readability and with implementing OpenSSL compatibility API
+         functions, because OpenSSL's OCSP data structures conform to the
+         RFC. */
 struct OcspResponse {
     int     responseStatus;  /* return code from Responder */
@@ -1310,6 +1409,4 @@
                              /* Date at which this response was signed */
     byte    producedDateFormat; /* format of the producedDate */
-    byte*   issuerHash;
-    byte*   issuerKeyHash;
 
     byte*   cert;
@@ -1320,5 +1417,5 @@
     word32  sigOID;          /* OID for hash used for sig */
 
-    CertStatus* status;      /* certificate status to fill out */
+    OcspEntry* single;       /* chain of OCSP single responses */
 
     byte*   nonce;           /* pointer to nonce inside ASN.1 response */
@@ -1331,4 +1428,5 @@
     int     verifyError;
 #endif
+    void*  heap;
 };
 
@@ -1351,23 +1449,7 @@
 };
 
-typedef struct OcspEntry OcspEntry;
-
-#ifdef NO_SHA
-#define OCSP_DIGEST_SIZE WC_SHA256_DIGEST_SIZE
-#else
-#define OCSP_DIGEST_SIZE WC_SHA_DIGEST_SIZE
-#endif
-
-struct OcspEntry
-{
-    OcspEntry *next;                      /* next entry             */
-    byte issuerHash[OCSP_DIGEST_SIZE];    /* issuer hash            */
-    byte issuerKeyHash[OCSP_DIGEST_SIZE]; /* issuer public key hash */
-    CertStatus *status;                   /* OCSP response list     */
-    int totalStatus;                      /* number on list         */
-};
-
-WOLFSSL_LOCAL void InitOcspResponse(OcspResponse*, CertStatus*, byte*, word32);
-WOLFSSL_LOCAL int  OcspResponseDecode(OcspResponse*, void*, void* heap, int);
+WOLFSSL_LOCAL void InitOcspResponse(OcspResponse*, OcspEntry*, CertStatus*, byte*, word32, void*);
+WOLFSSL_LOCAL void FreeOcspResponse(OcspResponse*);
+WOLFSSL_LOCAL int OcspResponseDecode(OcspResponse*, void*, void* heap, int);
 
 WOLFSSL_LOCAL int    InitOcspRequest(OcspRequest*, DecodedCert*, byte, void*);
@@ -1447,10 +1529,11 @@
 
 enum PBESTypes {
-    PBE_MD5_DES      = 0,
-    PBE_SHA1_RC4_128 = 1,
-    PBE_SHA1_DES     = 2,
-    PBE_SHA1_DES3    = 3,
-    PBE_AES256_CBC   = 4,
-    PBE_AES128_CBC   = 5,
+    PBE_MD5_DES        = 0,
+    PBE_SHA1_RC4_128   = 1,
+    PBE_SHA1_DES       = 2,
+    PBE_SHA1_DES3      = 3,
+    PBE_AES256_CBC     = 4,
+    PBE_AES128_CBC     = 5,
+    PBE_SHA1_40RC2_CBC = 6,
 
     PBE_SHA1_RC4_128_SUM = 657,
