Index: generic/tlsX509.c
==================================================================
--- generic/tlsX509.c
+++ generic/tlsX509.c
@@ -69,34 +69,31 @@
 
 Tcl_Obj*
 Tls_NewX509Obj(Tcl_Interp *interp, X509 *cert) {
     Tcl_Obj *certPtr = Tcl_NewListObj(0, NULL);
     BIO *bio;
-    int n;
-    unsigned long flags;
+    int nid, pknid, bits, num_of_exts, len;
+    uint32_t xflags;
     char subject[BUFSIZ];
     char issuer[BUFSIZ];
     char serial[BUFSIZ];
     char notBefore[BUFSIZ];
     char notAfter[BUFSIZ];
     char buffer[BUFSIZ];
-    char certStr[CERT_STR_SIZE], *certStr_p;
-    int certStr_len, toRead;
-    unsigned char sha1_hash_binary[SHA_DIGEST_LENGTH];
-    unsigned char sha256_hash_binary[SHA256_DIGEST_LENGTH];
-    int nid, pknid, bits, num_of_exts, len;
-    uint32_t xflags;
+    char certStr[CERT_STR_SIZE];
+    unsigned char md[EVP_MAX_MD_SIZE];
     STACK_OF(GENERAL_NAME) *san;
 
     certStr[0]   = 0;
     subject[0]   = 0;
     issuer[0]    = 0;
     serial[0]    = 0;
     notBefore[0] = 0;
     notAfter[0]  = 0;
     if ((bio = BIO_new(BIO_s_mem())) != NULL) {
-	flags = XN_FLAG_RFC2253 | ASN1_STRFLGS_UTF8_CONVERT;
+	int n;
+	unsigned long flags = XN_FLAG_RFC2253 | ASN1_STRFLGS_UTF8_CONVERT;
 	flags &= ~ASN1_STRFLGS_ESC_MSB;
 
 	/* Get subject name */
 	if (X509_NAME_print_ex(bio, X509_get_subject_name(cert), 0, flags) > 0) {
 	    n = BIO_read(bio, subject, min(BIO_pending(bio), BUFSIZ - 1));
@@ -118,14 +115,14 @@
 	    (void)BIO_flush(bio);
 	}
 
         /* Get certificate */
         if (PEM_write_bio_X509(bio, cert)) {
-            certStr_p = certStr;
-            certStr_len = 0;
+            char *certStr_p = certStr;
+            int certStr_len = 0;
             while (1) {
-                toRead = min(BIO_pending(bio), CERT_STR_SIZE - certStr_len - 1);
+                int toRead = min(BIO_pending(bio), CERT_STR_SIZE - certStr_len - 1);
                 toRead = min(toRead, BUFSIZ);
                 if (toRead == 0) {
                     break;
                 }
                 dprintf("Reading %i bytes from the certificate...", toRead);
@@ -149,18 +146,18 @@
 	    Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj("all", -1));
 	    Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj(all, n));
 	}
 
 	/* Get Validity - Not Before */
-	if (ASN1_TIME_print(bio, X509_get_notBefore(cert))) {
+	if (ASN1_TIME_print(bio, X509_get0_notBefore(cert))) {
 	    n = BIO_read(bio, notBefore, min(BIO_pending(bio), BUFSIZ - 1));
 	    notBefore[max(n, 0)] = 0;
 	    (void)BIO_flush(bio);
 	}
 
 	/* Get Validity - Not After */
-	if (ASN1_TIME_print(bio, X509_get_notAfter(cert))) {
+	if (ASN1_TIME_print(bio, X509_get0_notAfter(cert))) {
 	    n = BIO_read(bio, notAfter, min(BIO_pending(bio), BUFSIZ - 1));
 	    notAfter[max(n, 0)] = 0;
 	    (void)BIO_flush(bio);
 	}
 
@@ -174,18 +171,18 @@
     /* Signature algorithm */
     Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj("signature", -1));
     Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj(OBJ_nid2ln(X509_get_signature_nid(cert)),-1));
 
     /* SHA1 Fingerprint of cert - DER representation */
-    X509_digest(cert, EVP_sha1(), sha1_hash_binary, &len);
-    len = String_to_Hex(sha1_hash_binary, len, buffer, BUFSIZ);
+    X509_digest(cert, EVP_sha1(), md, &len);
+    len = String_to_Hex(md, len, buffer, BUFSIZ);
     Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj("sha1_hash", -1));
     Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj(buffer, len));
 
     /* SHA256 Fingerprint of cert - DER representation */
-    X509_digest(cert, EVP_sha256(), sha256_hash_binary, &len);
-    len = String_to_Hex(sha256_hash_binary, len, buffer, BUFSIZ);
+    X509_digest(cert, EVP_sha256(), md, &len);
+    len = String_to_Hex(md, len, buffer, BUFSIZ);
     Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj("sha256_hash", -1));
     Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj(buffer, len));
 
     Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj("subject", -1));
     Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj(subject, -1));
@@ -292,18 +289,17 @@
 	sk_GENERAL_NAME_pop_free(san, GENERAL_NAME_free);
 	Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj("subjectAltName", -1));
 	Tcl_ListObjAppendElement(interp, certPtr, namesPtr);
     }
 
-    /* Certificate Alias  */
+    /* Certificate Alias as UTF-8 string */
     {
 	unsigned char *bstring;
 	len = 0;
 	bstring = X509_alias_get0(cert, &len);
-	len = String_to_Hex(bstring, len, buffer, BUFSIZ);
 	Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj("alias", -1));
-	Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj(buffer, len));
+	Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj((char *)bstring, len));
     }
 
     /* Get Subject Key id, Authority Key id */
     {
 	ASN1_OCTET_STRING *astring;
@@ -310,20 +306,20 @@
 	/* X509_keyid_get0 */
 	astring = X509_get0_subject_key_id(cert);
 	Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj("subjectKeyIdentifier", -1));
 	if (astring != NULL) {
 	    len = String_to_Hex((char *)ASN1_STRING_get0_data(astring), ASN1_STRING_length(astring), buffer, BUFSIZ);
-	    Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewByteArrayObj(buffer, len));
+	    Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj(buffer, len));
 	} else {
 	    Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj("", -1));
 	}
 
 	astring = X509_get0_authority_key_id(cert);
 	Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj("authorityKeyIdentifier", -1));
 	if (astring != NULL) {
 	    len = String_to_Hex((char *)ASN1_STRING_get0_data(astring), ASN1_STRING_length(astring), buffer, BUFSIZ);
-	    Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewByteArrayObj(buffer, len));
+	    Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj(buffer, len));
 	} else {
 	    Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj("", -1));
 	}
 	
 	/*  const GENERAL_NAMES *X509_get0_authority_issuer(cert);
@@ -364,8 +360,27 @@
 	    Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj(buffer, len));
 	} else {
 	    Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj("", -1));
 	}
     }
+
+    /* Certificate purposes */
+    {
+	Tcl_Obj *purpPtr = Tcl_NewListObj(0, NULL);
+	for (int j = 0; j < X509_PURPOSE_get_count(); j++) {
+	    X509_PURPOSE *ptmp = X509_PURPOSE_get0(j);
+	    Tcl_Obj *tmpPtr = Tcl_NewListObj(0, NULL);
+
+	    for (int i = 0; i < 2; i++) {
+		int idret = X509_check_purpose(cert, X509_PURPOSE_get_id(ptmp), i);
+		Tcl_ListObjAppendElement(interp, tmpPtr, Tcl_NewStringObj(i ? "CA" : "nonCA", -1));
+		Tcl_ListObjAppendElement(interp, tmpPtr, Tcl_NewStringObj(idret ? "Yes" : "No", -1));
+	    }
+	    Tcl_ListObjAppendElement(interp, purpPtr, Tcl_NewStringObj(X509_PURPOSE_get0_name(ptmp), -1));
+	    Tcl_ListObjAppendElement(interp, purpPtr, tmpPtr);
+	}
+	Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj("certificatePurpose", -1));
+	Tcl_ListObjAppendElement(interp, certPtr, purpPtr);
+    }
 
     return certPtr;
 }