Diff
EuroTcl/OpenACS 11 - 12 JULY 2024, VIENNA

Differences From Artifact [b50e8f8920]:

To Artifact [a4177f2631]:


67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96

97
98
99
100
101
102
103
104

#define CERT_STR_SIZE 32768

Tcl_Obj*
Tls_NewX509Obj(Tcl_Interp *interp, X509 *cert) {
    Tcl_Obj *certPtr = Tcl_NewListObj(0, NULL);
    BIO *bio;
    int n;
    unsigned long flags;
    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;
    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;
	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));
	    subject[max(n, 0)] = 0;
	    (void)BIO_flush(bio);







|
|






|
<
|
<
<
<









>
|







67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82

83



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101

#define CERT_STR_SIZE 32768

Tcl_Obj*
Tls_NewX509Obj(Tcl_Interp *interp, X509 *cert) {
    Tcl_Obj *certPtr = Tcl_NewListObj(0, NULL);
    BIO *bio;
    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];

    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) {
	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));
	    subject[max(n, 0)] = 0;
	    (void)BIO_flush(bio);
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
	    n = BIO_read(bio, serial, min(BIO_pending(bio), BUFSIZ - 1));
	    serial[max(n, 0)] = 0;
	    (void)BIO_flush(bio);
	}

        /* Get certificate */
        if (PEM_write_bio_X509(bio, cert)) {
            certStr_p = certStr;
            certStr_len = 0;
            while (1) {
                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);
                n = BIO_read(bio, certStr_p, toRead);
                if (n <= 0) {







|
|

|







113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
	    n = BIO_read(bio, serial, min(BIO_pending(bio), BUFSIZ - 1));
	    serial[max(n, 0)] = 0;
	    (void)BIO_flush(bio);
	}

        /* Get certificate */
        if (PEM_write_bio_X509(bio, cert)) {
            char *certStr_p = certStr;
            int certStr_len = 0;
            while (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);
                n = BIO_read(bio, certStr_p, toRead);
                if (n <= 0) {
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
	    all[max(n, 0)] = 0;
	    (void)BIO_flush(bio);
	    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))) {
	    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))) {
	    n = BIO_read(bio, notAfter, min(BIO_pending(bio), BUFSIZ - 1));
	    notAfter[max(n, 0)] = 0;
	    (void)BIO_flush(bio);
	}

	BIO_free(bio);
    }

    /* Version */
    Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj("version", -1));
    Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewLongObj(X509_get_version(cert)+1));

    /* 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);
    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);
    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));

    Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj("issuer", -1));







|






|

















|
|




|
|







144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
	    all[max(n, 0)] = 0;
	    (void)BIO_flush(bio);
	    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_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_get0_notAfter(cert))) {
	    n = BIO_read(bio, notAfter, min(BIO_pending(bio), BUFSIZ - 1));
	    notAfter[max(n, 0)] = 0;
	    (void)BIO_flush(bio);
	}

	BIO_free(bio);
    }

    /* Version */
    Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj("version", -1));
    Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewLongObj(X509_get_version(cert)+1));

    /* 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(), 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(), 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));

    Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj("issuer", -1));
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
	    }
	}
	sk_GENERAL_NAME_pop_free(san, GENERAL_NAME_free);
	Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj("subjectAltName", -1));
	Tcl_ListObjAppendElement(interp, certPtr, namesPtr);
    }

    /* Certificate Alias  */
    {
	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));
    }

    /* Get Subject Key id, Authority Key id */
    {
	ASN1_OCTET_STRING *astring;
	/* 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));
	} 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));
	} else {
	    Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj("", -1));
	}
	
	/*  const GENERAL_NAMES *X509_get0_authority_issuer(cert);
	const ASN1_INTEGER *X509_get0_authority_serial(cert); */
    }







|




<

|










|








|







287
288
289
290
291
292
293
294
295
296
297
298

299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
	    }
	}
	sk_GENERAL_NAME_pop_free(san, GENERAL_NAME_free);
	Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj("subjectAltName", -1));
	Tcl_ListObjAppendElement(interp, certPtr, namesPtr);
    }

    /* Certificate Alias as UTF-8 string */
    {
	unsigned char *bstring;
	len = 0;
	bstring = X509_alias_get0(cert, &len);

	Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj("alias", -1));
	Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj((char *)bstring, len));
    }

    /* Get Subject Key id, Authority Key id */
    {
	ASN1_OCTET_STRING *astring;
	/* 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_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_NewStringObj(buffer, len));
	} else {
	    Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj("", -1));
	}
	
	/*  const GENERAL_NAMES *X509_get0_authority_issuer(cert);
	const ASN1_INTEGER *X509_get0_authority_serial(cert); */
    }
362
363
364
365
366
367
368



















369
370
371
	if (sig_nid != NID_undef) {
	    len = String_to_Hex(sig->data, sig->length, buffer, BUFSIZ);
	    Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj(buffer, len));
	} else {
	    Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj("", -1));
	}
    }




















    return certPtr;
}







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
	if (sig_nid != NID_undef) {
	    len = String_to_Hex(sig->data, sig->length, buffer, BUFSIZ);
	    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;
}