Overview
Comment: | Code updates for gcc warnings |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
7e672606f56060cce53c0c7bf9485cee |
User & Date: | bohagan on 2024-02-05 00:55:27 |
Other Links: | manifest | tags |
Context
2024-02-09
| ||
19:24 | Added more error messages and quoted certificate fail message. check-in: e3e0021e31 user: bohagan tags: trunk | |
2024-02-05
| ||
00:55 | Code updates for gcc warnings check-in: 7e672606f5 user: bohagan tags: trunk | |
2024-02-04
| ||
02:58 | Added code to handle unexpected EOF on OpenSSL 3 check-in: 5a33efb87b user: bohagan tags: trunk | |
Changes
Modified generic/tls.c from [893e5c4546] to [76576d8a94].
︙ | ︙ | |||
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 | break; case SSL3_RT_HANDSHAKE: type = "Handshake"; break; case SSL3_RT_APPLICATION_DATA: type = "App Data"; break; case DTLS1_RT_HEARTBEAT: type = "Heartbeat"; break; default: type = "unknown"; } /* Needs compile time option "enable-ssl-trace". */ if ((bio = BIO_new(BIO_s_mem())) != NULL) { int n; SSL_trace(write_p, version, content_type, buf, len, ssl, (void *)bio); | > > | | 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 | break; case SSL3_RT_HANDSHAKE: type = "Handshake"; break; case SSL3_RT_APPLICATION_DATA: type = "App Data"; break; #if OPENSSL_VERSION_NUMBER < 0x30000000L case DTLS1_RT_HEARTBEAT: type = "Heartbeat"; break; #endif default: type = "unknown"; } /* Needs compile time option "enable-ssl-trace". */ if ((bio = BIO_new(BIO_s_mem())) != NULL) { int n; SSL_trace(write_p, version, content_type, buf, len, ssl, (void *)bio); n = BIO_read(bio, buffer, BIO_pending(bio) < 15000 ? BIO_pending(bio) : 14999); n = (n<0) ? 0 : n; buffer[n] = 0; (void)BIO_flush(bio); BIO_free(bio); } /* Create command to eval */ |
︙ | ︙ | |||
588 589 590 591 592 593 594 | * Return codes: * 0 = error where session will be immediately removed from the internal cache. * 1 = success where app retains session in session cache, and must call SSL_SESSION_free() when done. * *------------------------------------------------------------------- */ static int | | | 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 | * Return codes: * 0 = error where session will be immediately removed from the internal cache. * 1 = success where app retains session in session cache, and must call SSL_SESSION_free() when done. * *------------------------------------------------------------------- */ static int SessionCallback(SSL *ssl, SSL_SESSION *session) { State *statePtr = (State*)SSL_get_app_data((SSL *)ssl); Tcl_Interp *interp = statePtr->interp; Tcl_Obj *cmdPtr; const unsigned char *ticket; const unsigned char *session_id; size_t len2; unsigned int ulen; |
︙ | ︙ | |||
655 656 657 658 659 660 661 | * supplied list and the server configuration. The connection will be aborted. * SSL_TLSEXT_ERR_NOACK: ALPN protocol not selected, e.g., because no ALPN * protocols are configured for this connection. The connection continues. * *------------------------------------------------------------------- */ static int | | | | | 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 | * supplied list and the server configuration. The connection will be aborted. * SSL_TLSEXT_ERR_NOACK: ALPN protocol not selected, e.g., because no ALPN * protocols are configured for this connection. The connection continues. * *------------------------------------------------------------------- */ static int ALPNCallback(SSL *ssl, const unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg) { State *statePtr = (State*)arg; Tcl_Interp *interp = statePtr->interp; Tcl_Obj *cmdPtr; int code, res; dprintf("Called"); if (ssl == NULL || arg == NULL) { return SSL_TLSEXT_ERR_NOACK; } /* Select protocol */ if (SSL_select_next_proto((unsigned char **) out, outlen, statePtr->protos, statePtr->protos_len, in, inlen) == OPENSSL_NPN_NEGOTIATED) { /* Match found */ res = SSL_TLSEXT_ERR_OK; } else { /* OPENSSL_NPN_NO_OVERLAP = No overlap, so use first item from client protocol list */ res = SSL_TLSEXT_ERR_NOACK; } if (statePtr->vcmd == (Tcl_Obj*)NULL) { return res; } /* Create command to eval */ cmdPtr = Tcl_DuplicateObj(statePtr->vcmd); Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewStringObj("alpn", -1)); Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewStringObj(Tcl_GetChannelName(statePtr->self), -1)); Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewStringObj((const char *) *out, -1)); Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewBooleanObj(res == SSL_TLSEXT_ERR_OK)); /* Eval callback command */ Tcl_IncrRefCount(cmdPtr); if ((code = EvalCallback(interp, statePtr, cmdPtr)) > 1) { res = SSL_TLSEXT_ERR_NOACK; } else if (code == 1) { |
︙ | ︙ | |||
777 778 779 780 781 782 783 | */ static int SNICallback(const SSL *ssl, int *alert, void *arg) { State *statePtr = (State*)arg; Tcl_Interp *interp = statePtr->interp; Tcl_Obj *cmdPtr; int code, res; | | | 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 | */ static int SNICallback(const SSL *ssl, int *alert, void *arg) { State *statePtr = (State*)arg; Tcl_Interp *interp = statePtr->interp; Tcl_Obj *cmdPtr; int code, res; const char *servername = NULL; dprintf("Called"); if (ssl == NULL || arg == NULL) { return SSL_TLSEXT_ERR_NOACK; } |
︙ | ︙ | |||
844 845 846 847 848 849 850 | * SSL_CLIENT_HELLO_RETRY: suspend the handshake, and the handshake function will return immediately * SSL_CLIENT_HELLO_ERROR: failure, terminate connection. Set alert to error code. * SSL_CLIENT_HELLO_SUCCESS: success * *------------------------------------------------------------------- */ static int | | | 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 | * SSL_CLIENT_HELLO_RETRY: suspend the handshake, and the handshake function will return immediately * SSL_CLIENT_HELLO_ERROR: failure, terminate connection. Set alert to error code. * SSL_CLIENT_HELLO_SUCCESS: success * *------------------------------------------------------------------- */ static int HelloCallback(SSL *ssl, int *alert, void *arg) { State *statePtr = (State*)arg; Tcl_Interp *interp = statePtr->interp; Tcl_Obj *cmdPtr; int code, res; const char *servername; const unsigned char *p; size_t len, remaining; |
︙ | ︙ | |||
2220 2221 2222 2223 2224 2225 2226 | /* Get SNI requested server name */ LAPPEND_STR(interp, objPtr, "servername", SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name), -1); /* Get protocol */ LAPPEND_STR(interp, objPtr, "protocol", SSL_get_version(ssl), -1); /* Renegotiation allowed */ | | | 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 | /* Get SNI requested server name */ LAPPEND_STR(interp, objPtr, "servername", SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name), -1); /* Get protocol */ LAPPEND_STR(interp, objPtr, "protocol", SSL_get_version(ssl), -1); /* Renegotiation allowed */ LAPPEND_BOOL(interp, objPtr, "renegotiation_allowed", SSL_get_secure_renegotiation_support((SSL *) ssl)); /* Get security level */ LAPPEND_INT(interp, objPtr, "security_level", SSL_get_security_level(ssl)); /* Session info */ LAPPEND_BOOL(interp, objPtr, "session_reused", SSL_session_reused(ssl)); |
︙ | ︙ | |||
2293 2294 2295 2296 2297 2298 2299 | /* Session info */ session = SSL_get_session(ssl); if (session != NULL) { const unsigned char *ticket; size_t len2; unsigned int ulen; const unsigned char *session_id, *proto; | | | 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 | /* Session info */ session = SSL_get_session(ssl); if (session != NULL) { const unsigned char *ticket; size_t len2; unsigned int ulen; const unsigned char *session_id, *proto; unsigned 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, &len2); LAPPEND_STR(interp, objPtr, "alpn", (char *) proto, (Tcl_Size) len2); /* Report the selected protocol as a result of the NPN negotiation */ #ifdef USE_NPN |
︙ | ︙ | |||
2330 2331 2332 2333 2334 2335 2336 | SSL_SESSION_get0_ticket(session, &ticket, &len2); LAPPEND_BARRAY(interp, objPtr, "session_ticket", ticket, (Tcl_Size) len2); /* Session ticket lifetime hint (in seconds) */ LAPPEND_LONG(interp, objPtr, "lifetime", SSL_SESSION_get_ticket_lifetime_hint(session)); /* Ticket app data */ | > | > | 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 | SSL_SESSION_get0_ticket(session, &ticket, &len2); LAPPEND_BARRAY(interp, objPtr, "session_ticket", ticket, (Tcl_Size) len2); /* Session ticket lifetime hint (in seconds) */ LAPPEND_LONG(interp, objPtr, "lifetime", SSL_SESSION_get_ticket_lifetime_hint(session)); /* Ticket app data */ #if OPENSSL_VERSION_NUMBER < 0x30000000L SSL_SESSION_get0_ticket_appdata((SSL_SESSION *) session, &ticket, &len2); LAPPEND_BARRAY(interp, objPtr, "ticket_app_data", ticket, (Tcl_Size) len2); #endif /* Get master key */ len2 = SSL_SESSION_get_master_key(session, buffer, SSL_MAX_MASTER_KEY_LENGTH); LAPPEND_BARRAY(interp, objPtr, "master_key", buffer, (Tcl_Size) len2); /* Compression id */ unsigned int id = SSL_SESSION_get_compress_id(session); |
︙ | ︙ |
Modified generic/tlsIO.c from [89e79806f0] to [226be28e03].
︙ | ︙ | |||
69 70 71 72 73 74 75 | * Side effects: * Closes the socket of the channel. * *------------------------------------------------------------------- */ static int TlsCloseProc(ClientData instanceData, Tcl_Interp *interp) { State *statePtr = (State *) instanceData; | < | 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | * Side effects: * Closes the socket of the channel. * *------------------------------------------------------------------- */ static int TlsCloseProc(ClientData instanceData, Tcl_Interp *interp) { State *statePtr = (State *) instanceData; dprintf("TlsCloseProc(%p)", (void *) statePtr); Tls_Clean(statePtr); Tcl_EventuallyFree((ClientData)statePtr, Tls_Free); return(0); } |
︙ | ︙ | |||
227 228 229 230 231 232 233 | } else if (backingError == 0 && err == -1) { dprintf("I/O error occurred (errno = %lu)", (unsigned long) Tcl_GetErrno()); *errorCodePtr = Tcl_GetErrno(); if (*errorCodePtr == ECONNRESET) { *errorCodePtr = ECONNABORTED; } | | | | | | 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 | } else if (backingError == 0 && err == -1) { dprintf("I/O error occurred (errno = %lu)", (unsigned long) Tcl_GetErrno()); *errorCodePtr = Tcl_GetErrno(); if (*errorCodePtr == ECONNRESET) { *errorCodePtr = ECONNABORTED; } Tls_Error(statePtr, (char *) Tcl_ErrnoMsg(Tcl_GetErrno())); } else { dprintf("I/O error occurred (backingError = %lu)", backingError); *errorCodePtr = backingError; if (*errorCodePtr == ECONNRESET) { *errorCodePtr = ECONNABORTED; } Tls_Error(statePtr, (char *) ERR_reason_error_string(backingError)); } statePtr->flags |= TLS_TCL_HANDSHAKE_FAILED; return(-1); case SSL_ERROR_SSL: /* A non-recoverable, fatal error in the SSL library occurred, usually a protocol error */ dprintf("SSL_ERROR_SSL: Got permanent fatal SSL error, aborting immediately"); if (backingError != 0) { Tls_Error(statePtr, (char *) ERR_reason_error_string(backingError)); } if (SSL_get_verify_result(statePtr->ssl) != X509_V_OK) { Tls_Error(statePtr, (char *) X509_verify_cert_error_string(SSL_get_verify_result(statePtr->ssl))); } statePtr->flags |= TLS_TCL_HANDSHAKE_FAILED; *errorCodePtr = ECONNABORTED; return(-1); case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: |
︙ | ︙ | |||
365 366 367 368 369 370 371 | dprintBuffer(buf, bytesRead); break; case SSL_ERROR_SSL: /* A non-recoverable, fatal error in the SSL library occurred, usually a protocol error */ dprintf("SSL error, indicating that the connection has been aborted"); if (backingError != 0) { | | | 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 | dprintBuffer(buf, bytesRead); break; case SSL_ERROR_SSL: /* A non-recoverable, fatal error in the SSL library occurred, usually a protocol error */ dprintf("SSL error, indicating that the connection has been aborted"); if (backingError != 0) { Tls_Error(statePtr, (char *) ERR_reason_error_string(backingError)); } *errorCodePtr = ECONNABORTED; bytesRead = -1; #if OPENSSL_VERSION_NUMBER >= 0x30000000L /* Unexpected EOF from the peer for OpenSSL 3.0+ */ if (ERR_GET_REASON(backingError) == SSL_R_UNEXPECTED_EOF_WHILE_READING) { |
︙ | ︙ | |||
395 396 397 398 399 400 401 | bytesRead = 0; Tls_Error(statePtr, "EOF reached"); } else if (backingError == 0 && bytesRead == -1) { dprintf("I/O error occurred (errno = %lu)", (unsigned long) Tcl_GetErrno()); *errorCodePtr = Tcl_GetErrno(); bytesRead = -1; | | | | 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 | bytesRead = 0; Tls_Error(statePtr, "EOF reached"); } else if (backingError == 0 && bytesRead == -1) { dprintf("I/O error occurred (errno = %lu)", (unsigned long) Tcl_GetErrno()); *errorCodePtr = Tcl_GetErrno(); bytesRead = -1; Tls_Error(statePtr, (char *) Tcl_ErrnoMsg(Tcl_GetErrno())); } else { dprintf("I/O error occurred (backingError = %lu)", backingError); *errorCodePtr = backingError; bytesRead = -1; Tls_Error(statePtr, (char *) ERR_reason_error_string(backingError)); } break; case SSL_ERROR_ZERO_RETURN: dprintf("Got SSL_ERROR_ZERO_RETURN, this means an EOF has been reached"); bytesRead = 0; *errorCodePtr = 0; |
︙ | ︙ | |||
563 564 565 566 567 568 569 | written = 0; Tls_Error(statePtr, "EOF reached"); } else if (backingError == 0 && written == -1) { dprintf("I/O error occurred (errno = %lu)", (unsigned long) Tcl_GetErrno()); *errorCodePtr = Tcl_GetErrno(); written = -1; | | | | | 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 | written = 0; Tls_Error(statePtr, "EOF reached"); } else if (backingError == 0 && written == -1) { dprintf("I/O error occurred (errno = %lu)", (unsigned long) Tcl_GetErrno()); *errorCodePtr = Tcl_GetErrno(); written = -1; Tls_Error(statePtr, (char *) Tcl_ErrnoMsg(Tcl_GetErrno())); } else { dprintf("I/O error occurred (backingError = %lu)", backingError); *errorCodePtr = backingError; written = -1; Tls_Error(statePtr, (char *) ERR_reason_error_string(backingError)); } break; case SSL_ERROR_SSL: /* A non-recoverable, fatal error in the SSL library occurred, usually a protocol error */ dprintf("SSL error, indicating that the connection has been aborted"); if (backingError != 0) { Tls_Error(statePtr, (char *) ERR_reason_error_string(backingError)); } *errorCodePtr = ECONNABORTED; written = -1; break; default: dprintf("unknown error: %d", err); |
︙ | ︙ | |||
944 945 946 947 948 949 950 | NULL, /* Flush proc */ TlsNotifyProc, /* Handling of events bubbling up */ NULL, /* Wide seek proc */ NULL, /* Thread action */ NULL /* Truncate */ }; | | | 943 944 945 946 947 948 949 950 951 952 | NULL, /* Flush proc */ TlsNotifyProc, /* Handling of events bubbling up */ NULL, /* Wide seek proc */ NULL, /* Thread action */ NULL /* Truncate */ }; const Tcl_ChannelType *Tls_ChannelType(void) { return &tlsChannelType; } |
Modified generic/tlsInt.h from [07c33eb860] to [0918403850].
︙ | ︙ | |||
170 171 172 173 174 175 176 | int vflags; /* verify flags */ SSL *ssl; /* Struct for SSL processing */ SSL_CTX *ctx; /* SSL Context */ BIO *bio; /* Struct for SSL processing */ BIO *p_bio; /* Parent BIO (that is layered on Tcl_Channel) */ | | | | 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 | int vflags; /* verify flags */ SSL *ssl; /* Struct for SSL processing */ SSL_CTX *ctx; /* SSL Context */ BIO *bio; /* Struct for SSL processing */ BIO *p_bio; /* Parent BIO (that is layered on Tcl_Channel) */ unsigned char *protos; /* List of supported protocols in protocol format */ unsigned int protos_len; /* Length of protos */ char *err; } State; #ifdef USE_TCL_STUBS #ifndef Tcl_StackChannel #error "Unable to compile on this version of Tcl" #endif /* Tcl_GetStackedChannel */ #endif /* USE_TCL_STUBS */ /* * Forward declarations */ const Tcl_ChannelType *Tls_ChannelType(void); Tcl_Channel Tls_GetParent(State *statePtr, int maskFlags); Tcl_Obj *Tls_NewX509Obj(Tcl_Interp *interp, X509 *cert); Tcl_Obj *Tls_NewCAObj(Tcl_Interp *interp, const SSL *ssl, int peer); void Tls_Error(State *statePtr, char *msg); void Tls_Free(char *blockPtr); void Tls_Clean(State *statePtr); |
︙ | ︙ |
Modified generic/tlsX509.c from [37e1c520a1] to [ea8ff7e7c8].
︙ | ︙ | |||
58 59 60 61 62 63 64 | const STACK_OF(X509_EXTENSION) *exts; Tcl_Obj *listPtr = Tcl_NewListObj(0, NULL); if (listPtr == NULL) { return NULL; } | | | | | | | 58 59 60 61 62 63 64 65 66 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 | const STACK_OF(X509_EXTENSION) *exts; Tcl_Obj *listPtr = Tcl_NewListObj(0, NULL); if (listPtr == NULL) { return NULL; } if ((exts = X509_get0_extensions(cert)) != NULL) { for (int i=0; i < X509_get_ext_count(cert); i++) { X509_EXTENSION *ex = sk_X509_EXTENSION_value(exts, i); ASN1_OBJECT *obj = X509_EXTENSION_get_object(ex); /* ASN1_OCTET_STRING *data = X509_EXTENSION_get_data(ex); */ int critical = X509_EXTENSION_get_critical(ex); LAPPEND_BOOL(interp, listPtr, OBJ_nid2ln(OBJ_obj2nid(obj)), critical); } } return listPtr; } /* * Get Authority and Subject Key Identifiers */ Tcl_Obj *Tls_x509Identifier(const ASN1_OCTET_STRING *astring) { Tcl_Obj *resultPtr = NULL; int len = 0; unsigned char buffer[1024]; if (astring != NULL) { len = String_to_Hex((unsigned char *)ASN1_STRING_get0_data(astring), ASN1_STRING_length(astring), buffer, 1024); } resultPtr = Tcl_NewStringObj((char *) &buffer[0], (Tcl_Size) len); return resultPtr; } /* * Get Key Usage */ Tcl_Obj *Tls_x509KeyUsage(Tcl_Interp *interp, X509 *cert, uint32_t xflags) { |
︙ | ︙ | |||
199 200 201 202 203 204 205 | int len; char buffer[1024]; if (listPtr == NULL) { return NULL; } | | | | 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | int len; char buffer[1024]; if (listPtr == NULL) { return NULL; } if ((names = X509_get_ext_d2i(cert, nid, NULL, NULL)) != NULL) { for (int i=0; i < sk_GENERAL_NAME_num(names); i++) { const GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i); len = BIO_to_Buffer(name && GENERAL_NAME_print(bio, (GENERAL_NAME *) name), bio, buffer, 1024); LAPPEND_STR(interp, listPtr, NULL, buffer, (Tcl_Size) len); } sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free); } return listPtr; } |
︙ | ︙ | |||
269 270 271 272 273 274 275 | STACK_OF(DIST_POINT) *crl; Tcl_Obj *listPtr = Tcl_NewListObj(0, NULL); if (listPtr == NULL) { return NULL; } | | | | | | | | 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 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 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 | STACK_OF(DIST_POINT) *crl; Tcl_Obj *listPtr = Tcl_NewListObj(0, NULL); if (listPtr == NULL) { return NULL; } if ((crl = X509_get_ext_d2i(cert, NID_crl_distribution_points, NULL, NULL)) != NULL) { for (int i=0; i < sk_DIST_POINT_num(crl); i++) { DIST_POINT *dp = sk_DIST_POINT_value(crl, i); DIST_POINT_NAME *distpoint = dp->distpoint; if (distpoint->type == 0) { /* full-name GENERALIZEDNAME */ for (int j = 0; j < sk_GENERAL_NAME_num(distpoint->name.fullname); j++) { GENERAL_NAME *gen = sk_GENERAL_NAME_value(distpoint->name.fullname, j); int type; ASN1_STRING *uri = GENERAL_NAME_get0_value(gen, &type); if (type == GEN_URI) { LAPPEND_STR(interp, listPtr, (char *) NULL, (char *) ASN1_STRING_get0_data(uri), (Tcl_Size) ASN1_STRING_length(uri)); } } } else if (distpoint->type == 1) { /* relative-name X509NAME */ STACK_OF(X509_NAME_ENTRY) *sk_relname = distpoint->name.relativename; for (int j = 0; j < sk_X509_NAME_ENTRY_num(sk_relname); j++) { X509_NAME_ENTRY *e = sk_X509_NAME_ENTRY_value(sk_relname, j); ASN1_STRING *d = X509_NAME_ENTRY_get_data(e); LAPPEND_STR(interp, listPtr, (char *) NULL, (char *) ASN1_STRING_data(d), (Tcl_Size) ASN1_STRING_length(d)); } } } CRL_DIST_POINTS_free(crl); } return listPtr; } /* * Get On-line Certificate Status Protocol (OSCP) URL */ Tcl_Obj *Tls_x509Oscp(Tcl_Interp *interp, X509 *cert) { STACK_OF(OPENSSL_STRING) *ocsp; Tcl_Obj *listPtr = Tcl_NewListObj(0, NULL); if (listPtr == NULL) { return NULL; } if ((ocsp = X509_get1_ocsp(cert)) != NULL) { for (int i = 0; i < sk_OPENSSL_STRING_num(ocsp); i++) { LAPPEND_STR(interp, listPtr, NULL, sk_OPENSSL_STRING_value(ocsp, i), -1); } X509_email_free(ocsp); } return listPtr; } /* * Get Certificate Authority (CA) Issuers URL */ Tcl_Obj *Tls_x509CaIssuers(Tcl_Interp *interp, X509 *cert) { STACK_OF(ACCESS_DESCRIPTION) *ads; ACCESS_DESCRIPTION *ad; Tcl_Obj *listPtr = Tcl_NewListObj(0, NULL); unsigned char *buf; int len; if ((ads = X509_get_ext_d2i(cert, NID_info_access, NULL, NULL)) != NULL) { for (int i = 0; i < sk_ACCESS_DESCRIPTION_num(ads); i++) { ad = sk_ACCESS_DESCRIPTION_value(ads, i); if (OBJ_obj2nid(ad->method) == NID_ad_ca_issuers && ad->location) { if (ad->location->type == GEN_URI) { len = ASN1_STRING_to_UTF8(&buf, ad->location->d.uniformResourceIdentifier); Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewStringObj((char *) buf, (Tcl_Size) len)); OPENSSL_free(buf); break; } } } /* sk_ACCESS_DESCRIPTION_pop_free(ads, ACCESS_DESCRIPTION_free); */ AUTHORITY_INFO_ACCESS_free(ads); |
︙ | ︙ | |||
371 372 373 374 375 376 377 378 379 380 381 382 383 384 | */ Tcl_Obj* Tls_NewX509Obj(Tcl_Interp *interp, X509 *cert) { Tcl_Obj *certPtr = Tcl_NewListObj(0, NULL); BIO *bio = BIO_new(BIO_s_mem()); int mdnid, pknid, bits, len; uint32_t xflags; char buffer[BUFSIZ]; unsigned char md[EVP_MAX_MD_SIZE]; unsigned long flags = XN_FLAG_RFC2253 | ASN1_STRFLGS_UTF8_CONVERT; flags &= ~ASN1_STRFLGS_ESC_MSB; if (interp == NULL || cert == NULL || bio == NULL || certPtr == NULL) { | > | 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 | */ Tcl_Obj* Tls_NewX509Obj(Tcl_Interp *interp, X509 *cert) { Tcl_Obj *certPtr = Tcl_NewListObj(0, NULL); BIO *bio = BIO_new(BIO_s_mem()); int mdnid, pknid, bits, len; unsigned int ulen; uint32_t xflags; char buffer[BUFSIZ]; unsigned char md[EVP_MAX_MD_SIZE]; unsigned long flags = XN_FLAG_RFC2253 | ASN1_STRFLGS_UTF8_CONVERT; flags &= ~ASN1_STRFLGS_ESC_MSB; if (interp == NULL || cert == NULL || bio == NULL || certPtr == NULL) { |
︙ | ︙ | |||
394 395 396 397 398 399 400 | const ASN1_BIT_STRING *sig; int sig_nid; X509_get0_signature(&sig, &sig_alg, cert); /* sig_nid = X509_get_signature_nid(cert) */ sig_nid = OBJ_obj2nid(sig_alg->algorithm); LAPPEND_STR(interp, certPtr, "signatureAlgorithm", OBJ_nid2ln(sig_nid), -1); | | | 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 | const ASN1_BIT_STRING *sig; int sig_nid; X509_get0_signature(&sig, &sig_alg, cert); /* sig_nid = X509_get_signature_nid(cert) */ sig_nid = OBJ_obj2nid(sig_alg->algorithm); LAPPEND_STR(interp, certPtr, "signatureAlgorithm", OBJ_nid2ln(sig_nid), -1); len = (sig_nid != NID_undef) ? String_to_Hex(sig->data, sig->length, (unsigned char *) buffer, BUFSIZ) : 0; LAPPEND_STR(interp, certPtr, "signatureValue", buffer, (Tcl_Size) len); } /* Version of the encoded certificate - RFC 5280 section 4.1.2.1 */ LAPPEND_LONG(interp, certPtr, "version", X509_get_version(cert)+1); /* Unique number assigned by CA to certificate - RFC 5280 section 4.1.2.2 */ |
︙ | ︙ | |||
429 430 431 432 433 434 435 | /* 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, (Tcl_Size) len); /* SHA1 Digest (Fingerprint) of cert - DER representation */ | | | | | | | | | | | 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 | /* 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, (Tcl_Size) len); /* SHA1 Digest (Fingerprint) of cert - DER representation */ if (X509_digest(cert, EVP_sha1(), md, &ulen)) { len = String_to_Hex(md, len, (unsigned char *) buffer, BUFSIZ); LAPPEND_STR(interp, certPtr, "sha1_hash", buffer, (Tcl_Size) ulen); } /* SHA256 Digest (Fingerprint) of cert - DER representation */ if (X509_digest(cert, EVP_sha256(), md, &ulen)) { len = String_to_Hex(md, len, (unsigned char *) buffer, BUFSIZ); LAPPEND_STR(interp, certPtr, "sha256_hash", buffer, (Tcl_Size) ulen); } /* Subject Public Key Info specifies the public key and identifies the algorithm with which the key is used. RFC 5280 section 4.1.2.7 */ if (X509_get_signature_info(cert, &mdnid, &pknid, &bits, &xflags)) { ASN1_BIT_STRING *key; unsigned int n; LAPPEND_STR(interp, certPtr, "signingDigest", OBJ_nid2ln(mdnid), -1); LAPPEND_STR(interp, certPtr, "publicKeyAlgorithm", OBJ_nid2ln(pknid), -1); LAPPEND_INT(interp, certPtr, "bits", bits); /* Effective security bits */ key = X509_get0_pubkey_bitstr(cert); len = String_to_Hex(key->data, key->length, (unsigned char *) buffer, BUFSIZ); LAPPEND_STR(interp, certPtr, "publicKey", buffer, (Tcl_Size) len); len = 0; if (X509_pubkey_digest(cert, EVP_get_digestbynid(pknid), md, &n)) { len = String_to_Hex(md, (int) n, (unsigned char *) buffer, BUFSIZ); } LAPPEND_STR(interp, certPtr, "publicKeyHash", buffer, (Tcl_Size) 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, (unsigned char *) buffer, BUFSIZ); } LAPPEND_STR(interp, certPtr, "signatureHash", buffer, (Tcl_Size) 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)); |
︙ | ︙ | |||
491 492 493 494 495 496 497 | and/or issuer names over time. RFC 5280 section 4.1.2.8 */ { const ASN1_BIT_STRING *iuid, *suid; X509_get0_uids(cert, &iuid, &suid); Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj("issuerUniqueId", -1)); if (iuid != NULL) { | | | | 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 | and/or issuer names over time. RFC 5280 section 4.1.2.8 */ { const ASN1_BIT_STRING *iuid, *suid; X509_get0_uids(cert, &iuid, &suid); Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj("issuerUniqueId", -1)); if (iuid != NULL) { Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewByteArrayObj((const unsigned char *)iuid->data, (Tcl_Size) iuid->length)); } else { Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj("", -1)); } Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj("subjectUniqueId", -1)); if (suid != NULL) { Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewByteArrayObj((const unsigned char *)suid->data, (Tcl_Size) suid->length)); } else { Tcl_ListObjAppendElement(interp, certPtr, Tcl_NewStringObj("", -1)); } } /* X509 v3 Extensions - RFC 5280 section 4.1.2.9 */ LAPPEND_INT(interp, certPtr, "extCount", X509_get_ext_count(cert)); |
︙ | ︙ | |||
584 585 586 587 588 589 590 | /* Subject Information Access - RFC 5280 section 4.2.2.2, NID_sinfo_access */ /* Certificate Alias. If uses a PKCS#12 structure, alias will reflect the friendlyName attribute (RFC 2985). */ { len = 0; | | | > > | 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 | /* Subject Information Access - RFC 5280 section 4.2.2.2, NID_sinfo_access */ /* Certificate Alias. If uses a PKCS#12 structure, alias will reflect the friendlyName attribute (RFC 2985). */ { len = 0; unsigned char *string = X509_alias_get0(cert, &len); LAPPEND_STR(interp, certPtr, "alias", (char *) string, (Tcl_Size) len); string = X509_keyid_get0(cert, &len); LAPPEND_STR(interp, certPtr, "keyId", (char *) string, (Tcl_Size) len); } /* Certificate and dump all data */ { char certStr[CERT_STR_SIZE]; /* Get certificate */ |
︙ | ︙ |