Index: generic/tlsX509.c ================================================================== --- generic/tlsX509.c +++ generic/tlsX509.c @@ -7,10 +7,11 @@ #include #include #include #include #include +#include #include #include "tlsInt.h" /* Define maximum certificate size. Max PEM size 100kB and DER size is 24kB. */ #define CERT_STR_SIZE 32768 @@ -38,14 +39,14 @@ } /* * Binary string to hex string */ -int String_to_Hex(char* input, int len, char *output, int size) { +int String_to_Hex(char* input, int ilen, char *output, int olen) { int count = 0; - for (int i = 0; i < len && count < size - 1; i++, count += 2) { + for (int i = 0; i < ilen && count < olen - 1; i++, count += 2) { sprintf(output + count, "%02X", input[i] & 0xff); } output[count] = 0; return count; } @@ -115,11 +116,11 @@ if (listPtr == NULL) { return NULL; } - if ((xflags & EXFLAG_KUSAGE) && usage < 0xffffff) { + if ((xflags & EXFLAG_KUSAGE) && usage < UINT32_MAX) { if (usage & KU_DIGITAL_SIGNATURE) { Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewStringObj("Digital Signature", -1)); } if (usage & KU_NON_REPUDIATION) { Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewStringObj("Non-Repudiation", -1)); @@ -143,10 +144,12 @@ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewStringObj("Encipher Only", -1)); } if (usage & KU_DECIPHER_ONLY) { Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewStringObj("Decipher Only", -1)); } + } else { + Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewStringObj("unrestricted", -1)); } return listPtr; } /* @@ -238,11 +241,11 @@ if (listPtr == NULL) { return NULL; } - if (xflags & EXFLAG_XKUSAGE) { + if ((xflags & EXFLAG_XKUSAGE) && usage < UINT32_MAX) { usage = X509_get_extended_key_usage(cert); if (usage & XKU_SSL_SERVER) { Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewStringObj("TLS Web Server Authentication", -1)); } @@ -268,10 +271,12 @@ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewStringObj("DVCS", -1)); } if (usage & XKU_ANYEKU) { Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewStringObj("Any Extended Key Usage", -1)); } + } else { + Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewStringObj("unrestricted", -1)); } return listPtr; } /* @@ -442,17 +447,17 @@ /* Subject identifies the entity associated with the public key stored in the subject public key field. RFC 5280 section 4.1.2.6 */ len = BIO_to_Buffer(X509_NAME_print_ex(bio, X509_get_subject_name(cert), 0, flags), bio, buffer, BUFSIZ); LAPPEND_STR(interp, certPtr, "subject", buffer, len); - /* SHA1 Fingerprint of cert - DER representation */ + /* SHA1 Digest (Fingerprint) of cert - DER representation */ if (X509_digest(cert, EVP_sha1(), md, &len)) { len = String_to_Hex(md, len, buffer, BUFSIZ); LAPPEND_STR(interp, certPtr, "sha1_hash", buffer, len); } - /* SHA256 Fingerprint of cert - DER representation */ + /* SHA256 Digest (Fingerprint) of cert - DER representation */ if (X509_digest(cert, EVP_sha256(), md, &len)) { len = String_to_Hex(md, len, buffer, BUFSIZ); LAPPEND_STR(interp, certPtr, "sha256_hash", buffer, len); } @@ -474,24 +479,32 @@ if (X509_pubkey_digest(cert, EVP_get_digestbynid(pknid), md, &n)) { len = String_to_Hex(md, (int)n, buffer, BUFSIZ); } LAPPEND_STR(interp, certPtr, "publicKeyHash", buffer, len); + /* digest of the DER representation of the certificate */ len = 0; if (X509_digest(cert, EVP_get_digestbynid(mdnid), md, &n)) { len = String_to_Hex(md, (int)n, buffer, BUFSIZ); } LAPPEND_STR(interp, certPtr, "signatureHash", buffer, len); } + /* Certificate Purpose. Call before checking for extensions. */ + LAPPEND_STR(interp, certPtr, "purpose", Tls_x509Purpose(cert), -1); + LAPPEND_OBJ(interp, certPtr, "certificatePurpose", Tls_x509Purposes(interp, cert)); + /* Get extensions flags */ xflags = X509_get_extension_flags(cert); LAPPEND_INT(interp, certPtr, "extFlags", xflags); /* Check if cert was issued by CA cert issuer or self signed */ LAPPEND_BOOL(interp, certPtr, "selfIssued", xflags & EXFLAG_SI); LAPPEND_BOOL(interp, certPtr, "selfSigned", xflags & EXFLAG_SS); + LAPPEND_BOOL(interp, certPtr, "isProxyCert", xflags & EXFLAG_PROXY); + LAPPEND_BOOL(interp, certPtr, "extInvalid", xflags & EXFLAG_INVALID); + LAPPEND_BOOL(interp, certPtr, "isCACert", X509_check_ca(cert)); /* The Unique Ids are used to handle the possibility of reuse of subject and/or issuer names over time. RFC 5280 section 4.1.2.8 */ { const ASN1_BIT_STRING *iuid, *suid; @@ -528,16 +541,10 @@ /* Key usage extension defines the purpose (e.g., encipherment, signature, certificate signing) of the key in the certificate. RFC 5280 section 4.2.1.3, NID_key_usage */ LAPPEND_OBJ(interp, certPtr, "keyUsage", Tls_x509KeyUsage(interp, cert, xflags)); - /* Certificate Purpose */ - LAPPEND_STR(interp, certPtr, "purpose", Tls_x509Purpose(cert), -1); - - /* Get purposes */ - LAPPEND_OBJ(interp, certPtr, "certificatePurpose", Tls_x509Purposes(interp, cert)); - /* Certificate Policies - indicates the issuing CA considers its issuerDomainPolicy equivalent to the subject CA's subjectDomainPolicy. RFC 5280 section 4.2.1.4, NID_certificate_policies */ if (xflags & EXFLAG_INVALID_POLICY) { /* Reject cert */ } @@ -555,15 +562,16 @@ /* Subject Directory Attributes provides identification attributes (e.g., nationality) of the subject. RFC 5280 section 4.2.1.8 (subjectDirectoryAttributes) */ /* Basic Constraints identifies whether the subject of the cert is a CA and the max depth of valid cert paths for this cert. RFC 5280 section 4.2.1.9, NID_basic_constraints */ - if (xflags & EXFLAG_BCONS) { + if (!(xflags & EXFLAG_PROXY)) { LAPPEND_LONG(interp, certPtr, "pathLen", X509_get_pathlen(cert)); + } else { + LAPPEND_LONG(interp, certPtr, "pathLen", X509_get_proxy_pathlen(cert)); } LAPPEND_BOOL(interp, certPtr, "basicConstraintsCA", xflags & EXFLAG_CA); - LAPPEND_BOOL(interp, certPtr, "basicConstraintsCritical", xflags & EXFLAG_CRITICAL); /* Name Constraints is only used in CA certs to indicate the name space for all subject names in subsequent certificates in a certification path MUST be located. RFC 5280 section 4.2.1.10, NID_name_constraints */ @@ -583,12 +591,12 @@ } /* Authority Information Access indicates how to access info and services for the certificate issuer. RFC 5280 section 4.2.2.1, NID_info_access */ - /* Get On-line Certificate Status Protocol (OSCP) URL */ - LAPPEND_OBJ(interp, certPtr, "ocsp", Tls_x509Oscp(interp, cert)); + /* Get On-line Certificate Status Protocol (OSCP) Responders URL */ + LAPPEND_OBJ(interp, certPtr, "ocspResponders", Tls_x509Oscp(interp, cert)); /* Get Certificate Authority (CA) Issuers URL */ LAPPEND_OBJ(interp, certPtr, "caIssuers", Tls_x509CaIssuers(interp, cert)); /* Subject Information Access - RFC 5280 section 4.2.2.2, NID_sinfo_access */