Index: doc/tls.html
==================================================================
--- doc/tls.html
+++ doc/tls.html
@@ -232,39 +232,55 @@
If -local is given, then the certificate information
is the one used locally.
- - issuer dn
- - The distinguished name (DN) of the certificate
- issuer.
+ - version value
+ - The certification version
+ - signature_algorithm algorithm
+ - Cipher algorithm used for certificate signature.
+ - digest version
+ - Certificate signature digest.
+ - public_key_algorithm algorithm
+ - Certificate signature public key algorithm.
+ - bits n
+ - Number of bits used for certificate signature key
+ - self_signed boolean
+ - Is certificate signature self signed.
+ - sha1_hash hash
+ - The SHA1 hash of the certificate.
+ - sha256_hash hash
+ - The SHA256 hash of the certificate.
- subject dn
- - The distinguished name (DN) of the certificate
- subject.
+ - The distinguished name (DN) of the certificate subject.
+ - issuer dn
+ - The distinguished name (DN) of the certificate issuer.
- notBefore date
- The begin date for the validity of the certificate.
- notAfter date
- The expiry date for the certificate.
- serial n
- The serial number of the certificate.
+ - certificate cert
+ - The PEM encoded certificate.
+ - num_extensions n
+ - Number of certificate extensions.
+ - extensions list
+ - List of certificate extension names.
+ - peername name
+ - The peername from the certificate.
+ - sbits n
+ - The number of bits used for the session key.
- cipher cipher
- The current cipher in use between the client and
server channels.
- - sbits n
- - The number of bits used for the session key.
- - certificate cert
- - The PEM encoded certificate.
- - sha1_hash hash
- - The SHA1 hash of the certificate.
- - sha256_hash hash
- - The SHA256 hash of the certificate.
- validation result
- Certificate validation result.
- alpn protocol
- The protocol selected after Application-Layer Protocol
Negotiation (ALPN).
- - version value
+ - protocol value
- The protocol version used for the connection:
SSLv2, SSLv3, TLSv1, TLSv1.1, TLSv1.2, TLSv1.3, or unknown
@@ -457,10 +473,11 @@
header from the client where servername is the client
specified servername. Used to allow multiple names for
same server so the right certificate can be used.
+
verify channel depth cert status error
Index: generic/tls.c
==================================================================
--- generic/tls.c
+++ generic/tls.c
@@ -475,11 +475,11 @@
session_id = SSL_SESSION_get_id(session, &ulen);
Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewByteArrayObj(session_id, (int) ulen));
/* Session ticket */
SSL_SESSION_get0_ticket(session, &ticket, &len2);
- Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewStringObj(ticket, (int)len2));
+ Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewByteArrayObj(ticket, (int) len2));
/* Lifetime - number of seconds */
Tcl_ListObjAppendElement(interp, cmdPtr,
Tcl_NewLongObj((long) SSL_SESSION_get_ticket_lifetime_hint(session)));
@@ -715,11 +715,11 @@
remaining = len;
servername = (const char *)p;
cmdPtr = Tcl_DuplicateObj(statePtr->callback);
Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewStringObj("hello", -1));
- Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewStringObj(servername, (int)len));
+ Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewStringObj(servername, (int) len));
Tcl_Preserve((ClientData) interp);
Tcl_Preserve((ClientData) statePtr);
Tcl_IncrRefCount(cmdPtr);
@@ -1858,11 +1858,11 @@
Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj(proto, -1));
/* Report the selected protocol as a result of the negotiation */
SSL_get0_alpn_selected(statePtr->ssl, &proto, &len);
Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("alpn", -1));
- Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj((char *)proto, (int)len));
+ Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj((char *)proto, (int) len));
Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("protocol", -1));
Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj(SSL_get_version(statePtr->ssl), -1));
Tcl_SetObjResult(interp, objPtr);
return TCL_OK;
@@ -1982,31 +1982,27 @@
unsigned int ulen;
const unsigned char *session_id;
char buffer[SSL_MAX_MASTER_KEY_LENGTH];
/* Report the selected protocol as a result of the ALPN negotiation */
- SSL_SESSION_get0_alpn_selected(session, &proto, &len);
+ SSL_SESSION_get0_alpn_selected(session, &proto, &len2);
Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("alpn", -1));
- Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj((char *)proto, (int) len));
-
- /* Peer */
- Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("peer", -1));
- Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj(SSL_SESSION_get0_peer(session), -1));
+ Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj((char *)proto, (int) len2));
/* Resumable session */
Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("resumable", -1));
Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewIntObj(SSL_SESSION_is_resumable(session)));
- /* Start time */
+ /* Session start time (seconds since epoch) */
Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("start_time", -1));
Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewLongObj(SSL_SESSION_get_time(session)));
- /* Timeout value */
+ /* Timeout value - SSL_CTX_get_timeout (in seconds) */
Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("timeout", -1));
Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewLongObj(SSL_SESSION_get_timeout(session)));
- /* Lifetime hint */
+ /* Session ticket lifetime hint (in seconds) */
Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("lifetime", -1));
Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewLongObj(SSL_SESSION_get_ticket_lifetime_hint(session)));
/* Session id */
session_id = SSL_SESSION_get_id(session, &ulen);
@@ -2551,10 +2547,11 @@
#endif
/* Initialize BOTH libcrypto and libssl. */
OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS | OPENSSL_INIT_LOAD_CRYPTO_STRINGS
| OPENSSL_INIT_ADD_ALL_CIPHERS | OPENSSL_INIT_ADD_ALL_DIGESTS, NULL);
+
BIO_new_tcl(NULL, 0);
#if 0
/*
Index: generic/tlsX509.c
==================================================================
--- generic/tlsX509.c
+++ generic/tlsX509.c
@@ -91,10 +91,11 @@
#define CERT_STR_SIZE 16384
Tcl_Obj*
Tls_NewX509Obj(Tcl_Interp *interp, X509 *cert) {
Tcl_Obj *certPtr = Tcl_NewListObj(0, NULL);
+ Tcl_Obj *extsPtr = Tcl_NewListObj(0, NULL);
BIO *bio;
int n;
unsigned long flags;
char subject[BUFSIZ];
char issuer[BUFSIZ];
@@ -106,13 +107,13 @@
char sha1_hash_ascii[SHA_DIGEST_LENGTH * 2 + 1];
unsigned char sha1_hash_binary[SHA_DIGEST_LENGTH];
char sha256_hash_ascii[SHA256_DIGEST_LENGTH * 2 + 1];
unsigned char sha256_hash_binary[SHA256_DIGEST_LENGTH];
const char *shachars="0123456789ABCDEF";
- int nid, pknid, bits;
- long version;
+ int nid, pknid, bits, num_of_exts;
uint32_t xflags;
+ const STACK_OF(X509_EXTENSION) *exts;
sha1_hash_ascii[SHA_DIGEST_LENGTH * 2] = '\0';
sha256_hash_ascii[SHA256_DIGEST_LENGTH * 2] = '\0';
certStr[0] = 0;
@@ -169,26 +170,34 @@
strcpy(notBefore, ASN1_UTCTIME_tostr(X509_getm_notBefore(cert)));
strcpy(notAfter, ASN1_UTCTIME_tostr(X509_getm_notAfter(cert)));
/* Version */
Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj("version", -1));
- version = X509_get_version(cert)+1;
- Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewLongObj(version));
-
- /* Signature NID */
- Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj("signature_nid", -1));
- Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewIntObj(X509_get_signature_nid(cert)));
-
- if (X509_get_signature_info(cert, &nid, &pknid, &bits, &xflags) == 1) {
- Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj("digest_nid", -1));
- Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewIntObj(nid));
- Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj("public_key_nid", -1));
- Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewIntObj(pknid));
+ Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewLongObj(X509_get_version(cert)+1));
+
+ /* Signature algorithm */
+ Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj("signature_algorithm", -1));
+ Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj(OBJ_nid2ln(X509_get_signature_nid(cert)),-1));
+
+ /* Information about the signature of certificate cert */
+ if (X509_get_signature_info(cert, &nid, &pknid, &bits, &xflags) == 1) {
+ Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj("digest", -1));
+ Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj(OBJ_nid2ln(nid),-1));
+ Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj("public_key_algorithm", -1));
+ Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj(OBJ_nid2ln(pknid),-1));
Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj("bits", -1));
Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewIntObj(bits));
Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj("extension_flags", -1));
Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewIntObj(xflags));
+
+ if (pknid == NID_rsaEncryption || pknid == NID_dsa) {
+ EVP_PKEY *pkey = X509_get_pubkey(cert);
+ }
+
+ /* Check if cert was issued by CA cert issuer or self signed */
+ Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj("self_signed", -1));
+ Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewBooleanObj(X509_check_issued(cert, cert) == X509_V_OK));
}
/* SHA1 - DER representation*/
X509_digest(cert, EVP_sha1(), sha1_hash_binary, NULL);
for (int n = 0; n < SHA_DIGEST_LENGTH; n++) {
@@ -223,7 +232,22 @@
Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj( serial, -1));
Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj("certificate", -1));
Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj( certStr, -1));
+ num_of_exts = X509_get_ext_count(cert);
+ Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj("num_extensions", -1));
+ Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewIntObj(num_of_exts));
+
+ /* Get extensions */
+ Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj("extensions", -1));
+ exts = X509_get0_extensions(cert);
+ for (int i=0; i < num_of_exts; i++) {
+ X509_EXTENSION *ex = sk_X509_EXTENSION_value(exts, i);
+ ASN1_OBJECT *obj = X509_EXTENSION_get_object(ex);
+ unsigned nid2 = OBJ_obj2nid(obj);
+ Tcl_ListObjAppendElement(interp, extsPtr, Tcl_NewStringObj(OBJ_nid2ln(nid2), -1));
+ }
+ Tcl_ListObjAppendElement(interp, certPtr, extsPtr);
+
return certPtr;
}