diff --git a/src/session_client_tls.c b/src/session_client_tls.c index 04486e1c..f39e170d 100644 --- a/src/session_client_tls.c +++ b/src/session_client_tls.c @@ -293,7 +293,9 @@ nc_client_tls_session_new(int sock, const char *host, int timeout, struct nc_cli } /* set client's verify mode flags */ - nc_client_tls_set_verify_wrap(tls_cfg); + if (nc_client_tls_set_verify_wrap(tls_cfg)) { + goto fail; + } /* init TLS context and store data which may be needed later in it */ if (nc_tls_init_ctx_wrap(cli_cert, cli_pkey, cert_store, crl_store, tls_ctx)) { @@ -304,7 +306,7 @@ nc_client_tls_session_new(int sock, const char *host, int timeout, struct nc_cli cli_cert = cli_pkey = cert_store = crl_store = NULL; /* setup config from ctx */ - if (nc_tls_setup_config_from_ctx_wrap(tls_ctx, NC_CLIENT, tls_cfg)) { + if (nc_tls_setup_config_from_ctx_wrap(tls_ctx, tls_cfg)) { goto fail; } diff --git a/src/session_mbedtls.c b/src/session_mbedtls.c index 48156a18..62ecdaf1 100644 --- a/src/session_mbedtls.c +++ b/src/session_mbedtls.c @@ -295,14 +295,29 @@ nc_tls_session_destroy_wrap(void *tls_session) } void * -nc_tls_config_new_wrap(int UNUSED(side)) +nc_tls_config_new_wrap(int side) { + int r; mbedtls_ssl_config *tls_cfg; tls_cfg = malloc(sizeof *tls_cfg); NC_CHECK_ERRMEM_RET(!tls_cfg, NULL); mbedtls_ssl_config_init(tls_cfg); + + /* set default config data */ + if (side == NC_SERVER) { + r = mbedtls_ssl_config_defaults(tls_cfg, MBEDTLS_SSL_IS_SERVER, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT); + } else { + r = mbedtls_ssl_config_defaults(tls_cfg, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT); + } + if (r) { + nc_mbedtls_strerr(NULL, r, "Setting default TLS config failed"); + mbedtls_ssl_config_free(tls_cfg); + free(tls_cfg); + return NULL; + } + return tls_cfg; } @@ -659,10 +674,11 @@ nc_server_tls_set_verify_wrap(void *tls_cfg, struct nc_tls_verify_cb_data *cb_da mbedtls_ssl_conf_verify(tls_cfg, nc_server_tls_verify_cb, cb_data); } -void +int nc_client_tls_set_verify_wrap(void *tls_cfg) { mbedtls_ssl_conf_authmode(tls_cfg, MBEDTLS_SSL_VERIFY_REQUIRED); + return 0; } char * @@ -1143,27 +1159,15 @@ nc_tls_init_ctx_wrap(void *cert, void *pkey, void *cert_store, void *crl_store, } int -nc_tls_setup_config_from_ctx_wrap(struct nc_tls_ctx *tls_ctx, int side, void *tls_cfg) +nc_tls_setup_config_from_ctx_wrap(struct nc_tls_ctx *tls_ctx, void *tls_cfg) { - int rc; - - /* set default config data */ - if (side == NC_SERVER) { - rc = mbedtls_ssl_config_defaults(tls_cfg, MBEDTLS_SSL_IS_SERVER, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT); - } else { - rc = mbedtls_ssl_config_defaults(tls_cfg, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT); - } - if (rc) { - nc_mbedtls_strerr(NULL, rc, "Setting default TLS config failed"); - return 1; - } - /* set config's rng */ mbedtls_ssl_conf_rng(tls_cfg, mbedtls_ctr_drbg_random, tls_ctx->ctr_drbg); /* set config's cert and key */ mbedtls_ssl_conf_own_cert(tls_cfg, tls_ctx->cert, tls_ctx->pkey); /* set config's CA and CRL cert store */ mbedtls_ssl_conf_ca_chain(tls_cfg, tls_ctx->cert_store, tls_ctx->crl_store); + return 0; } diff --git a/src/session_openssl.c b/src/session_openssl.c index d6bc3479..de8ad54f 100644 --- a/src/session_openssl.c +++ b/src/session_openssl.c @@ -383,6 +383,9 @@ nc_server_tls_verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx) /* copy the client cert */ data->session->opts.server.client_cert = X509_dup(cert); NC_CHECK_ERRMEM_RET(!data->session->opts.server.client_cert, 0); + + /* verification was successful, override the in-built verification result */ + X509_STORE_CTX_set_error(x509_ctx, X509_V_OK); } return 1; } else { @@ -404,10 +407,38 @@ nc_server_tls_set_verify_wrap(void *tls_cfg, struct nc_tls_verify_cb_data *cb_da SSL_CTX_set_verify(tls_cfg, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nc_server_tls_verify_cb); } -void +int nc_client_tls_set_verify_wrap(void *tls_cfg) { + int ret = 0; + X509_VERIFY_PARAM *vpm = NULL; + + /* set the verify flag */ SSL_CTX_set_verify(tls_cfg, SSL_VERIFY_PEER, NULL); + + vpm = X509_VERIFY_PARAM_new(); + NC_CHECK_ERRMEM_RET(!vpm, 1); + + /* set the partial chain flag to allow verification of a certificate chain + * to succeed even if the chain is not complete. + * See https://github.com/openssl/openssl/issues/7871 + * This is not set for the server, because all the CA certs in the chain + * may be needed for CTN, so such partial chain cases are handled manually. */ + if (!X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_PARTIAL_CHAIN)) { + ERR(NULL, "Setting X509_V_FLAG_PARTIAL_CHAIN flag failed (%s).", ERR_reason_error_string(ERR_get_error())); + ret = 1; + goto cleanup; + } + + if (!SSL_CTX_set1_param(tls_cfg, vpm)) { + ERR(NULL, "Failed to set verify param (%s).", ERR_reason_error_string(ERR_get_error())); + ret = 1; + goto cleanup; + } + +cleanup: + X509_VERIFY_PARAM_free(vpm); + return ret; } char * @@ -774,7 +805,7 @@ nc_tls_move_crls_to_store(const X509_STORE *src, X509_STORE *dst) } int -nc_tls_setup_config_from_ctx_wrap(struct nc_tls_ctx *tls_ctx, int side, void *tls_cfg) +nc_tls_setup_config_from_ctx_wrap(struct nc_tls_ctx *tls_ctx, void *tls_cfg) { if (SSL_CTX_use_certificate(tls_cfg, tls_ctx->cert) != 1) { ERR(NULL, "Setting up TLS certificate failed (%s).", ERR_reason_error_string(ERR_get_error())); @@ -786,11 +817,6 @@ nc_tls_setup_config_from_ctx_wrap(struct nc_tls_ctx *tls_ctx, int side, void *tl return 1; } - /* disable server-side automatic chain building */ - if (side == NC_SERVER) { - SSL_CTX_set_mode(tls_cfg, SSL_MODE_NO_AUTO_CHAIN); - } - if (tls_ctx->crl_store) { /* move CRLs from crl_store to cert_store, because SSL_CTX can only have one store */ if (nc_tls_move_crls_to_store(tls_ctx->crl_store, tls_ctx->cert_store)) { diff --git a/src/session_server_tls.c b/src/session_server_tls.c index 5e7fe3fc..ac41f128 100644 --- a/src/session_server_tls.c +++ b/src/session_server_tls.c @@ -885,7 +885,7 @@ nc_accept_tls_session(struct nc_session *session, struct nc_server_tls_opts *opt srv_cert = srv_pkey = cert_store = crl_store = NULL; /* setup config from ctx */ - if (nc_tls_setup_config_from_ctx_wrap(&session->ti.tls.ctx, NC_SERVER, tls_cfg)) { + if (nc_tls_setup_config_from_ctx_wrap(&session->ti.tls.ctx, tls_cfg)) { goto fail; } session->ti.tls.config = tls_cfg; diff --git a/src/session_wrapper.h b/src/session_wrapper.h index 1e556593..9332a29d 100644 --- a/src/session_wrapper.h +++ b/src/session_wrapper.h @@ -219,8 +219,9 @@ void nc_server_tls_set_verify_wrap(void *tls_cfg, struct nc_tls_verify_cb_data * * @brief Set TLS client's verify flags. * * @param[in] tls_cfg TLS configuration. + * @return 0 on success, 1 on error. */ -void nc_client_tls_set_verify_wrap(void *tls_cfg); +int nc_client_tls_set_verify_wrap(void *tls_cfg); /** * @brief Verify the certificate. @@ -451,11 +452,10 @@ int nc_tls_init_ctx_wrap(void *cert, void *pkey, void *cert_store, void *crl_sto * @brief Setup a TLS configuration from a TLS context. * * @param[in] tls_ctx TLS context. - * @param[in] side Side of the TLS connection. * @param[in,out] tls_cfg TLS configuration. * @return 0 on success, non-zero on fail. */ -int nc_tls_setup_config_from_ctx_wrap(struct nc_tls_ctx *tls_ctx, int side, void *tls_cfg); +int nc_tls_setup_config_from_ctx_wrap(struct nc_tls_ctx *tls_ctx, void *tls_cfg); /** * @brief Get the error code from a TLS session's verification. diff --git a/tests/data/certs/0b527f1f.0 b/tests/data/certs/0b527f1f.0 new file mode 120000 index 00000000..98654d3f --- /dev/null +++ b/tests/data/certs/0b527f1f.0 @@ -0,0 +1 @@ +rootca.pem \ No newline at end of file diff --git a/tests/data/certs/a96df0b1.0 b/tests/data/certs/a96df0b1.0 new file mode 120000 index 00000000..799a1c62 --- /dev/null +++ b/tests/data/certs/a96df0b1.0 @@ -0,0 +1 @@ +client.pem \ No newline at end of file diff --git a/tests/data/certs/acf0d71a.0 b/tests/data/certs/acf0d71a.0 new file mode 120000 index 00000000..fdd1020b --- /dev/null +++ b/tests/data/certs/acf0d71a.0 @@ -0,0 +1 @@ +intermediate_ca.pem \ No newline at end of file diff --git a/tests/data/certs/client.key b/tests/data/certs/client.key new file mode 100644 index 00000000..9a52c1e3 --- /dev/null +++ b/tests/data/certs/client.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDSs0VI4Hb5bjVU +auqaT92xKRn1efE7xeA5qfWv6uYMA8APj9aPC4zLUoEixeoJjJfnwpz9Kslt5lOm +ul+30OSGQkkIvjQ3xZJlNJPlDqp/ro2M8Mv5zVleVsGX6eEvVOtgjzbfBaXnscxa +uxIDHwvsBf39W6op742Mjwmp1c5bhMAywQQgNXv9+rvmOiAmXfazVzZ01L1XLQmt +tRPLhUcFkEWrF4nvuXzd9M5d6wZ/PUJM49OE8gp/OvbVTKSwCGxiPYcyNFr1+7kD +Ni83a7pTkOGj9eWc6Pz+kqU/bdrpKp++Ju75iVKO8tbOoJleomY9XEmUc8FKp0IZ +Kw2iUU4xAgMBAAECggEABBNnMvRyoLsWyYIC9Ua3u2JX5/V6quUWRA9LWyKQXimh +aLun0x8OU22OZXGOKC6hzqAnYMdX26ohsp821Eu0a/tyxbpGMND/1rjYZo0s06j5 +AIG09GlaQfasKofh7QQ3xGeo0FIf5jY8hYHKZKiQVrm78s934HVLl+05auFhq0gC +Yn3kN754q7pM8gRA+OJ1rl7PXtSYUCERG/ShKlo6YZH155VRKf9s2L/HaBMSgZ5K +XlJjw7FhbxgqVLX0NhlawfpR8g0nP21vUXq3y/kUCm2z16j7Kn0765YOsa/MjlSB +fksQTJqW36WYMo0GHzs2LDU/+kaoeOQmXtvz6QXbMQKBgQDpkngR/73Uw5aS88wr +nzw1KBMLzmugA8xougsTjZCONVliXcUgC/GSOc7nxVHEcdf8HMHPhpuslFwKa0vX +19fv+UV/irHE6xgXYv+TzGWSzHH3UBHhBJwcp9BmpvrjN1Z0znA8DvV/WcXLiTsk +WRM6wmjcrXv4NySMGz4Btm1K6QKBgQDm7pQ5bqCpqVvlb/3Irjg1L0mrztrGC6pJ +NSSZnQmGODDvnG9KYA1prAxtAwV6QIaLlGQHtmuLTo4QiNdehzN+T9ADIwW7O3ez +AmVMeW/dA2lfraKGpT6BxRGl/HUjynO654YdjakVPhFCXoruYdNXarYAGxbvFH7f +Ly7FjYjMCQKBgCRpwjBEJ2sJButn+JeAXpmG4tk/WAX9MZvODTYCJtwUsxejuLyT +QBjkzD3TxDiU6vAR56Ebwh84jdTN/2fp7W8q9Eu66pXhdMMImwGGpvsoxkehAviK +iG/rNZEbTRepI+BX4qVqS5mL/EsL3N2AyX+qmUB2B1Kd/iOdh6AquYUpAoGBANI+ +j3AiSd9tMx8V8MWN59pz7OygbQk1gZkY6vN3xz4NVnAvyhq6jDuSydVNlOUSbewR +82gaKpsvr6NaEkobaUQsQcM5VXR61aWCHtubC7755iuXl4piUyAuXLzztWoaXXbi +ZnXtjOysD2aPUIlrQtApdP1vrFeKH1/uQvTUwKCRAoGAPHffvNXu6AlpN103jj+k +UUuq3Dg7Kg2vwWd+EIICLDbJ9wvQxamzIfHlklvjU3fLorkxMiTKSKT0YayztqUb +SwT4ClaSe7Mi39IOnoo0uZ6VQEKLdM62WWHGt+odyBSy5wf28iw9Bgb2v2pswsxW +j9CGEUZ5K2VCxU7kSm9Xtss= +-----END PRIVATE KEY----- diff --git a/tests/data/certs/client.pem b/tests/data/certs/client.pem new file mode 100644 index 00000000..7819b4ab --- /dev/null +++ b/tests/data/certs/client.pem @@ -0,0 +1,76 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 2 (0x2) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=CZ, ST=Some-State, O=CESNET, OU=TMC, CN=Intermediate Client CA + Validity + Not Before: Jun 3 11:57:09 2025 GMT + Not After : Jun 1 11:57:09 2035 GMT + Subject: C=CZ, ST=Some-State, O=CESNET, OU=TMC, CN=client + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:d2:b3:45:48:e0:76:f9:6e:35:54:6a:ea:9a:4f: + dd:b1:29:19:f5:79:f1:3b:c5:e0:39:a9:f5:af:ea: + e6:0c:03:c0:0f:8f:d6:8f:0b:8c:cb:52:81:22:c5: + ea:09:8c:97:e7:c2:9c:fd:2a:c9:6d:e6:53:a6:ba: + 5f:b7:d0:e4:86:42:49:08:be:34:37:c5:92:65:34: + 93:e5:0e:aa:7f:ae:8d:8c:f0:cb:f9:cd:59:5e:56: + c1:97:e9:e1:2f:54:eb:60:8f:36:df:05:a5:e7:b1: + cc:5a:bb:12:03:1f:0b:ec:05:fd:fd:5b:aa:29:ef: + 8d:8c:8f:09:a9:d5:ce:5b:84:c0:32:c1:04:20:35: + 7b:fd:fa:bb:e6:3a:20:26:5d:f6:b3:57:36:74:d4: + bd:57:2d:09:ad:b5:13:cb:85:47:05:90:45:ab:17: + 89:ef:b9:7c:dd:f4:ce:5d:eb:06:7f:3d:42:4c:e3: + d3:84:f2:0a:7f:3a:f6:d5:4c:a4:b0:08:6c:62:3d: + 87:32:34:5a:f5:fb:b9:03:36:2f:37:6b:ba:53:90: + e1:a3:f5:e5:9c:e8:fc:fe:92:a5:3f:6d:da:e9:2a: + 9f:be:26:ee:f9:89:52:8e:f2:d6:ce:a0:99:5e:a2: + 66:3d:5c:49:94:73:c1:4a:a7:42:19:2b:0d:a2:51: + 4e:31 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Key Identifier: + C4:30:21:DE:F9:75:98:59:AE:63:B7:5B:70:0F:E1:C0:72:B1:EF:7F + X509v3 Authority Key Identifier: + F2:CF:C5:9A:C6:63:7A:AB:A0:59:60:41:FE:7D:3F:5D:BE:9A:D5:3F + Signature Algorithm: sha256WithRSAEncryption + Signature Value: + 78:e4:53:ad:ce:4c:38:ed:3f:74:89:78:66:79:1a:45:bb:98: + 03:95:27:9b:c9:72:77:10:2a:ac:df:99:7d:b0:35:91:52:9e: + 45:ff:f7:ff:40:30:8b:84:8b:78:5f:b0:2a:8e:f6:7c:af:4d: + 6c:46:de:2b:c1:35:db:5e:1f:5e:b9:df:d1:65:34:03:99:fd: + 89:3b:b9:e1:52:1d:ac:03:ce:3e:7b:78:43:6b:c7:4d:65:f2: + 13:da:d6:88:4b:a4:f9:00:c0:29:c7:70:e7:37:a6:58:bd:41: + b2:c6:22:00:93:23:2d:78:df:88:15:00:f3:38:0d:dc:6d:67: + 5a:5c:56:2d:9f:04:74:25:29:9a:fc:25:56:a8:3d:43:4d:53: + 6f:04:3c:34:25:e1:d5:16:4c:a4:39:39:82:3e:df:c9:98:ef: + 67:55:c4:8b:99:4b:5c:9f:93:b0:51:17:9c:0b:bc:48:16:64: + 79:0c:47:75:69:61:02:0d:34:dd:d8:c4:74:fc:2b:71:3b:3e: + f2:e8:9b:2f:eb:c4:55:22:d7:4e:fd:ff:29:92:f1:05:bc:77: + 57:96:6f:80:73:67:84:82:dc:4a:8d:8f:91:97:85:66:a0:dc: + 2e:12:53:dc:e0:b2:5d:e0:a3:31:9a:97:4e:c6:b6:5d:48:30: + 9f:81:9e:14 +-----BEGIN CERTIFICATE----- +MIIDcTCCAlmgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBiMQswCQYDVQQGEwJDWjET +MBEGA1UECAwKU29tZS1TdGF0ZTEPMA0GA1UECgwGQ0VTTkVUMQwwCgYDVQQLDANU +TUMxHzAdBgNVBAMMFkludGVybWVkaWF0ZSBDbGllbnQgQ0EwHhcNMjUwNjAzMTE1 +NzA5WhcNMzUwNjAxMTE1NzA5WjBSMQswCQYDVQQGEwJDWjETMBEGA1UECAwKU29t +ZS1TdGF0ZTEPMA0GA1UECgwGQ0VTTkVUMQwwCgYDVQQLDANUTUMxDzANBgNVBAMM +BmNsaWVudDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANKzRUjgdvlu +NVRq6ppP3bEpGfV58TvF4Dmp9a/q5gwDwA+P1o8LjMtSgSLF6gmMl+fCnP0qyW3m +U6a6X7fQ5IZCSQi+NDfFkmU0k+UOqn+ujYzwy/nNWV5WwZfp4S9U62CPNt8Fpeex +zFq7EgMfC+wF/f1bqinvjYyPCanVzluEwDLBBCA1e/36u+Y6ICZd9rNXNnTUvVct +Ca21E8uFRwWQRasXie+5fN30zl3rBn89Qkzj04TyCn869tVMpLAIbGI9hzI0WvX7 +uQM2LzdrulOQ4aP15Zzo/P6SpT9t2ukqn74m7vmJUo7y1s6gmV6iZj1cSZRzwUqn +QhkrDaJRTjECAwEAAaNCMEAwHQYDVR0OBBYEFMQwId75dZhZrmO3W3AP4cByse9/ +MB8GA1UdIwQYMBaAFPLPxZrGY3qroFlgQf59P12+mtU/MA0GCSqGSIb3DQEBCwUA +A4IBAQB45FOtzkw47T90iXhmeRpFu5gDlSebyXJ3ECqs35l9sDWRUp5F//f/QDCL +hIt4X7AqjvZ8r01sRt4rwTXbXh9eud/RZTQDmf2JO7nhUh2sA84+e3hDa8dNZfIT +2taIS6T5AMApx3DnN6ZYvUGyxiIAkyMteN+IFQDzOA3cbWdaXFYtnwR0JSma/CVW +qD1DTVNvBDw0JeHVFkykOTmCPt/JmO9nVcSLmUtcn5OwURecC7xIFmR5DEd1aWEC +DTTd2MR0/CtxOz7y6Jsv68RVItdO/f8pkvEFvHdXlm+Ac2eEgtxKjY+Rl4VmoNwu +ElPc4LJd4KMxmpdOxrZdSDCfgZ4U +-----END CERTIFICATE----- diff --git a/tests/data/certs/eab22c76.0 b/tests/data/certs/eab22c76.0 new file mode 120000 index 00000000..8f18c71d --- /dev/null +++ b/tests/data/certs/eab22c76.0 @@ -0,0 +1 @@ +server.pem \ No newline at end of file diff --git a/tests/data/certs/intermediate_ca.key b/tests/data/certs/intermediate_ca.key new file mode 100644 index 00000000..d891b11d --- /dev/null +++ b/tests/data/certs/intermediate_ca.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDBfCEtO655d2Ey +bmcaoZ6dKfAYPG//80d9kLxgpu5z4rrydnsUbTqymuCBk6J7UNAGQqsIYMz/TOiq +emDBxYhsQS484TY2KSCdKsECR89V6zU4zhuer8FOtrJTOi2I3eAO3kiT6fpSmVby ++M5io1GpZRIOoG8sv5heOx8Ngb5WNweTuSeruVbiAQF5ze6w6RytCZq4m/6DmyTn +xowJeAJzCpN804JIZead7ili23ZGDqX/hL0WR0ZZ3bxfbw0lWT87okAMkyjJ3ZWi +mDf44+cnOEex5jelh6rdMglkKYEaBnLrP+MTIh0jtNCBN8vkOszbbRlZPZKszf5H +mj/iuKg9AgMBAAECggEAEf2moMFFEsKmH92Cf8hEao0M6AFX/Al/0xijXiyszSC+ +zQR1owDEbaQXY7pkaClWVnwE0ZVyqlCD7TTON2ZUg5W3T2402hS5QB6gGMQFmZHH +0/Lc6u9LvwkfjBFDok+DNyQLGpnYhAKsbOZJW9mfd8FP9wU1oTMQNL7e6c9vxoNT +f/i0OIS2BACIWSirYMu4NMNsCLO3eu33N93efS79MSd0wZHwxRQRSjg8ZvlI2O5o +2we4/ROPUZfTr/J1MXLsACI5Pggu2HZelFfw8p/yheNBUloz0aY4JrbniOVzsPtJ +mF/5YZhUC6I+x0VBwPFyWkiLjBjaUshirb0AnO4+3wKBgQD1BD4MqjNlLNIkrfJO +yb1laZC17bP7InwCyLrjpV+nYeHtHRxXpQqGeDkV5kdO6c9p5rNRru+T3RumeWEb +mZNXHmmnOQIwMVADlWAook1cC9vNlrdPKuf/SbrugTYXhWLmMHN4BJDCRvpRu9Gm +xdpYmiOg47e+Z0nnMuW7pKk5vwKBgQDKKIVFUHntj5NK/JahERXXvqkGOiMtGlSg +XEOUJ3SAj8ij+m3L3tesexdGj8TxBpeskP9ZbpZS9TjHdH8HGAgUwQynLtl2xBDl +5N4pNNg9hZzwZNighcvzJjlG/bYom8KpYzD/5rvbF2PKeMzEQcaIP7ynedcHveEC +nCaX1fPFAwKBgQDk5zi9BkmLzUrqP6QvnWQXGX+7p75M8hOfWj7XrMlnjBfROTAg +Za0moazbW87k16USEBkZR/DFWH2bkqx5Z4nyixQzyRvVQEy7fFNgwvi49M8+C/9n +s/MYWp6MciTB5rjVyxAlYUaIal0z/N9KCnAJ9L8ycWxZMxAlMjTUkGoU6wKBgQC3 +uKulmsW0iE8sTvH13zkioTurVRqy2sMeGbuw4UqXrBSEMgumxBbtwdAdaHtrMLqX +Mg9ej4o+Sm4Xll/7anOtqOR+66zmqrlQtPbSLBx5jPxb3Mqi1/XKPGrBgcISlbwL +hQH7Dw6axl8Cm1Y85iovmP0ylyA9AOuFG7RXOTIZUQKBgQC+NhR6B7eIy4RxwgWu +QvPeqmpREtBZr/SIt38Q43Y001YjJT1UHxyCgkKEU7h2RHa+bzgIXD3LN4FNORYA +O1e3JaZ3uESGAWcjHtWuF5mbQH77T6sXqwKC3lL0/VcdT+JGFyYOApOWyI92U2FL +Sq1PGhXgcEt6b/BJtBUgo3gdEQ== +-----END PRIVATE KEY----- diff --git a/tests/data/certs/intermediate_ca.pem b/tests/data/certs/intermediate_ca.pem new file mode 100644 index 00000000..98a86d61 --- /dev/null +++ b/tests/data/certs/intermediate_ca.pem @@ -0,0 +1,81 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=CZ, ST=Some-State, O=CESNET, OU=TMC, CN=clientca + Validity + Not Before: Oct 25 11:04:52 2024 GMT + Not After : Oct 23 11:04:52 2034 GMT + Subject: C=CZ, ST=Some-State, O=CESNET, OU=TMC, CN=Intermediate Client CA + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:c1:7c:21:2d:3b:ae:79:77:61:32:6e:67:1a:a1: + 9e:9d:29:f0:18:3c:6f:ff:f3:47:7d:90:bc:60:a6: + ee:73:e2:ba:f2:76:7b:14:6d:3a:b2:9a:e0:81:93: + a2:7b:50:d0:06:42:ab:08:60:cc:ff:4c:e8:aa:7a: + 60:c1:c5:88:6c:41:2e:3c:e1:36:36:29:20:9d:2a: + c1:02:47:cf:55:eb:35:38:ce:1b:9e:af:c1:4e:b6: + b2:53:3a:2d:88:dd:e0:0e:de:48:93:e9:fa:52:99: + 56:f2:f8:ce:62:a3:51:a9:65:12:0e:a0:6f:2c:bf: + 98:5e:3b:1f:0d:81:be:56:37:07:93:b9:27:ab:b9: + 56:e2:01:01:79:cd:ee:b0:e9:1c:ad:09:9a:b8:9b: + fe:83:9b:24:e7:c6:8c:09:78:02:73:0a:93:7c:d3: + 82:48:65:e6:9d:ee:29:62:db:76:46:0e:a5:ff:84: + bd:16:47:46:59:dd:bc:5f:6f:0d:25:59:3f:3b:a2: + 40:0c:93:28:c9:dd:95:a2:98:37:f8:e3:e7:27:38: + 47:b1:e6:37:a5:87:aa:dd:32:09:64:29:81:1a:06: + 72:eb:3f:e3:13:22:1d:23:b4:d0:81:37:cb:e4:3a: + cc:db:6d:19:59:3d:92:ac:cd:fe:47:9a:3f:e2:b8: + a8:3d + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Certificate Sign + X509v3 Subject Key Identifier: + F2:CF:C5:9A:C6:63:7A:AB:A0:59:60:41:FE:7D:3F:5D:BE:9A:D5:3F + X509v3 Authority Key Identifier: + CD:59:B8:BB:EB:BA:27:B2:66:3C:1C:05:76:9B:71:8A:68:EA:30:FD + Signature Algorithm: sha256WithRSAEncryption + Signature Value: + 9e:58:d0:f1:42:e7:02:a1:21:34:d6:a8:9c:37:0e:7b:a3:c2: + e6:76:b9:33:1f:df:88:9c:84:39:58:d1:ef:d2:59:59:5c:7a: + 80:36:a7:9c:3a:0f:27:62:b6:dd:f7:13:b6:d3:6b:c1:4a:95: + db:c7:95:a8:51:fd:b0:8f:04:1e:5c:ce:4b:24:4e:69:a6:6e: + e9:ff:ea:47:8a:33:e9:a7:8c:0e:35:8a:43:7a:9c:ca:ec:77: + 2d:b9:6d:df:72:b1:26:0e:2c:90:6b:0c:61:a2:d3:63:3a:c4: + bd:fd:d3:f2:77:47:1f:6c:b2:61:53:44:76:68:e6:d9:93:2c: + 81:f1:ce:ea:cc:25:34:b6:7b:70:95:c2:35:d2:ee:9d:36:60: + 26:36:bd:16:32:85:96:2a:da:43:e5:34:6e:0b:21:4e:48:70: + 37:73:c5:b4:f1:98:e5:e7:8a:a7:d5:01:df:09:c3:e9:82:62: + 52:25:ab:22:d3:a9:41:a0:f2:27:d7:e2:50:14:c1:7e:56:2e: + a6:d6:4a:1a:f4:b1:ba:27:75:f5:bf:b6:9e:f4:73:73:c7:21: + 7d:c4:f1:ba:01:66:12:a3:f3:3f:4a:af:55:67:ca:ac:2a:09: + 7f:1c:d8:82:04:d3:ec:89:33:f4:3c:6f:8d:4a:2e:73:f6:67: + 3b:e8:4c:19 +-----BEGIN CERTIFICATE----- +MIIDlDCCAnygAwIBAgIBATANBgkqhkiG9w0BAQsFADBUMQswCQYDVQQGEwJDWjET +MBEGA1UECAwKU29tZS1TdGF0ZTEPMA0GA1UECgwGQ0VTTkVUMQwwCgYDVQQLDANU +TUMxETAPBgNVBAMMCGNsaWVudGNhMB4XDTI0MTAyNTExMDQ1MloXDTM0MTAyMzEx +MDQ1MlowYjELMAkGA1UEBhMCQ1oxEzARBgNVBAgMClNvbWUtU3RhdGUxDzANBgNV +BAoMBkNFU05FVDEMMAoGA1UECwwDVE1DMR8wHQYDVQQDDBZJbnRlcm1lZGlhdGUg +Q2xpZW50IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwXwhLTuu +eXdhMm5nGqGenSnwGDxv//NHfZC8YKbuc+K68nZ7FG06sprggZOie1DQBkKrCGDM +/0zoqnpgwcWIbEEuPOE2NikgnSrBAkfPVes1OM4bnq/BTrayUzotiN3gDt5Ik+n6 +UplW8vjOYqNRqWUSDqBvLL+YXjsfDYG+VjcHk7knq7lW4gEBec3usOkcrQmauJv+ +g5sk58aMCXgCcwqTfNOCSGXmne4pYtt2Rg6l/4S9FkdGWd28X28NJVk/O6JADJMo +yd2Vopg3+OPnJzhHseY3pYeq3TIJZCmBGgZy6z/jEyIdI7TQgTfL5DrM220ZWT2S +rM3+R5o/4rioPQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE +AwICBDAdBgNVHQ4EFgQU8s/FmsZjequgWWBB/n0/Xb6a1T8wHwYDVR0jBBgwFoAU +zVm4u+u6J7JmPBwFdptximjqMP0wDQYJKoZIhvcNAQELBQADggEBAJ5Y0PFC5wKh +ITTWqJw3DnujwuZ2uTMf34ichDlY0e/SWVlceoA2p5w6Dyditt33E7bTa8FKldvH +lahR/bCPBB5czkskTmmmbun/6keKM+mnjA41ikN6nMrsdy25bd9ysSYOLJBrDGGi +02M6xL390/J3Rx9ssmFTRHZo5tmTLIHxzurMJTS2e3CVwjXS7p02YCY2vRYyhZYq +2kPlNG4LIU5IcDdzxbTxmOXniqfVAd8Jw+mCYlIlqyLTqUGg8ifX4lAUwX5WLqbW +Shr0sbondfW/tp70c3PHIX3E8boBZhKj8z9Kr1VnyqwqCX8c2IIE0+yJM/Q8b41K +LnP2ZzvoTBk= +-----END CERTIFICATE----- diff --git a/tests/data/certs/rootca.key b/tests/data/certs/rootca.key new file mode 100644 index 00000000..be7f93a8 --- /dev/null +++ b/tests/data/certs/rootca.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDTWVYboHXOUGbO +YHdph4+8akKDbGRJiRBUWSrNx4WDot1mM3LpL0ZUnKCL98d2AdS+KlRqYyQqZaCQ +/mNxM852djf6bxxmhtkZHypypKz5VpVY0PXDHcCpwv6Jy6wEGKD6FOsYQkZ7/P6m +tiZwwEXEeZxTuQtx1Mh0k4aApXY4Fg5/pS68xE/les3vQQsCnj3w2GKqLIloUSJE +asIvvHcQIDjd8FvLMaI8nieiP9FhJRQ1BasQD/H5SUDlFo/jaTJR+QEgzrEY5x8R +duw8dPeZvaFOU2+JpJVqc65tmn7zeBHfvYlb5qHBC5JXurptsI7XXGDArsrgbTFr +B/GYimYvAgMBAAECggEAKbzuTuVo7nYdX2tYmbweTDDV8ttgkM8jLO0xEVNyUBVF +UO4fJuLhqksGP64Os4TYDTgR1LLAjSjlxUyfudbn0qg1FN2Fh8/gpt/rQ5m22UTa +mKAnsME676ulFfRlg6eTft/Lr85C2jCT37uAKuslvA/iKfyUwIWrkq4htV031ApW +4qjRgYAonKVb5AZ1H+d8kEGPwuO7NWvIqlmlUY37fGgtl0uRJBZY1DWxQVMBtr4X +g1vnlp7cYYhTouHI2A9+ibC7zz8PIO06gylO8qpWjYet11q+c5vFd1slqsuHYM1D +79BU+AWfcKDtJ9KNc3IrKad5AOAtppcUSmJ7nKYOTQKBgQD8iD1LUOITeSkDi5UE +Fo6znR8sj/EZOTELRjkcxxlMhxAwJYrECVLZNJG0gv0zyGA2zwKDFmYmQLsT8pPu +T1mV0PjVLu8AonTVu7FS2S552cXH3o/W89upAc0NWnFzLAjMdCTX3aoG6ON5+tfK +NcWLNob4i1xYLPFPS4gMC9D4awKBgQDWQFHrbQmgEVVAVqt12ZWMkTdlbTVkv5PM +xsjZdI8Cfk8fK7/eehbxGCOaRqBwuKrywHJ6VnsgFXeDtQ5XXh1i0ocR4qVcdUrJ +lFvTFgKDfRaM1rJIXHVm3OyXAhEUUT9eo1IagcaHtlsIS/XzgwUAr0AbJjJibUpv +qHgiF9KKTQKBgQDgeAFzxwuNn67zNclZfuuNgGZLaA85CnsruFnf2KIGQjADe/ti +0Z7Q70dsmtqSgtPzJALpnqlh6zvfOUqBFAtffgcRB8zuVXlg2pt+Nwp2yTpitNRK +jyx7h9xKuFALveJ8SejN8HzH847vyCaz2SQk4G0M1GNbBWfhwhPGEWLIzQKBgQDG +xLt7gBha8Vm3K/E8j5WH6L2NEqljg7zaUV3LKLD4rjg3gf4qp/gayrtVCMsWaKzo +M5TBXPQzytarUVExyvXWVdzLwgqJ4aN1qncaOaQxWt6N4S1bprOgr7urSVaRE+OH +qFumjdmi1JJV+yr+NQJyJSSDS4eY+y4Aszpo3tMMTQKBgQD2INK+WeHc/n9yBeOL +fX+8QTFwz4T+57301TxFz08U1l8fWEPrzeZQjukWWkT58zyMzXWBKU5+u9G0Z4iw +WKBxvC8pROe72V6PMGKjNgBKFHkgs3jDWK+njsKfLGrOKSjFSoPE8eBDUxT/ioG7 +hpWFj1R5xoOkdfrtQyYlJc/uHQ== +-----END PRIVATE KEY----- diff --git a/tests/data/certs/rootca.pem b/tests/data/certs/rootca.pem new file mode 100644 index 00000000..48831263 --- /dev/null +++ b/tests/data/certs/rootca.pem @@ -0,0 +1,78 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 0 (0x0) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=CZ, ST=Some-State, O=CESNET, OU=TMC, CN=clientca + Validity + Not Before: Oct 25 11:00:37 2024 GMT + Not After : Oct 23 11:00:37 2034 GMT + Subject: C=CZ, ST=Some-State, O=CESNET, OU=TMC, CN=clientca + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:d3:59:56:1b:a0:75:ce:50:66:ce:60:77:69:87: + 8f:bc:6a:42:83:6c:64:49:89:10:54:59:2a:cd:c7: + 85:83:a2:dd:66:33:72:e9:2f:46:54:9c:a0:8b:f7: + c7:76:01:d4:be:2a:54:6a:63:24:2a:65:a0:90:fe: + 63:71:33:ce:76:76:37:fa:6f:1c:66:86:d9:19:1f: + 2a:72:a4:ac:f9:56:95:58:d0:f5:c3:1d:c0:a9:c2: + fe:89:cb:ac:04:18:a0:fa:14:eb:18:42:46:7b:fc: + fe:a6:b6:26:70:c0:45:c4:79:9c:53:b9:0b:71:d4: + c8:74:93:86:80:a5:76:38:16:0e:7f:a5:2e:bc:c4: + 4f:e5:7a:cd:ef:41:0b:02:9e:3d:f0:d8:62:aa:2c: + 89:68:51:22:44:6a:c2:2f:bc:77:10:20:38:dd:f0: + 5b:cb:31:a2:3c:9e:27:a2:3f:d1:61:25:14:35:05: + ab:10:0f:f1:f9:49:40:e5:16:8f:e3:69:32:51:f9: + 01:20:ce:b1:18:e7:1f:11:76:ec:3c:74:f7:99:bd: + a1:4e:53:6f:89:a4:95:6a:73:ae:6d:9a:7e:f3:78: + 11:df:bd:89:5b:e6:a1:c1:0b:92:57:ba:ba:6d:b0: + 8e:d7:5c:60:c0:ae:ca:e0:6d:31:6b:07:f1:98:8a: + 66:2f + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Certificate Sign + X509v3 Subject Key Identifier: + CD:59:B8:BB:EB:BA:27:B2:66:3C:1C:05:76:9B:71:8A:68:EA:30:FD + Signature Algorithm: sha256WithRSAEncryption + Signature Value: + a6:2d:e1:9e:04:a5:0c:9d:6b:82:b9:f2:59:85:9f:ef:e4:ea: + eb:b9:ab:70:73:50:fa:1d:5d:0b:d7:7f:3e:32:f6:e5:27:01: + 47:69:3a:a2:a2:d2:e0:4d:16:ad:9d:98:3c:ed:81:05:c6:12: + a1:92:85:95:7f:22:e7:d2:77:fe:53:be:fe:2c:74:2c:24:7b: + 66:97:8c:0b:00:88:3e:96:87:1c:6a:0e:70:98:81:10:c1:84: + f4:98:4b:60:77:9c:24:a7:b2:a5:44:e8:05:da:a5:6c:62:77: + 68:f9:2e:73:3c:c6:2c:ad:3a:ff:4a:67:a0:da:23:84:ea:bc: + d9:cb:f9:45:13:e3:38:26:c7:f1:60:95:f3:3f:2f:81:98:0b: + 58:60:72:5f:c9:ef:1f:76:b2:05:03:8d:4f:3a:a8:eb:0a:c5: + a8:fd:a3:5f:a8:29:83:cb:9e:cb:13:24:a6:4a:33:95:22:fc: + 26:90:dc:97:2c:53:ac:24:1a:60:d6:aa:e4:cd:14:12:84:61: + ea:15:28:5a:79:f3:18:1e:bb:77:03:61:2c:b4:b6:d5:c5:99: + 7c:a7:7c:8a:1b:c8:a0:2c:50:53:5d:fb:b4:81:23:bf:0a:b1: + 9f:f0:b0:d3:ed:08:e2:4d:a7:50:44:be:3a:a0:c0:2c:70:0c: + e4:c8:71:15 +-----BEGIN CERTIFICATE----- +MIIDZTCCAk2gAwIBAgIBADANBgkqhkiG9w0BAQsFADBUMQswCQYDVQQGEwJDWjET +MBEGA1UECAwKU29tZS1TdGF0ZTEPMA0GA1UECgwGQ0VTTkVUMQwwCgYDVQQLDANU +TUMxETAPBgNVBAMMCGNsaWVudGNhMB4XDTI0MTAyNTExMDAzN1oXDTM0MTAyMzEx +MDAzN1owVDELMAkGA1UEBhMCQ1oxEzARBgNVBAgMClNvbWUtU3RhdGUxDzANBgNV +BAoMBkNFU05FVDEMMAoGA1UECwwDVE1DMREwDwYDVQQDDAhjbGllbnRjYTCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANNZVhugdc5QZs5gd2mHj7xqQoNs +ZEmJEFRZKs3HhYOi3WYzcukvRlScoIv3x3YB1L4qVGpjJCploJD+Y3EzznZ2N/pv +HGaG2RkfKnKkrPlWlVjQ9cMdwKnC/onLrAQYoPoU6xhCRnv8/qa2JnDARcR5nFO5 +C3HUyHSThoCldjgWDn+lLrzET+V6ze9BCwKePfDYYqosiWhRIkRqwi+8dxAgON3w +W8sxojyeJ6I/0WElFDUFqxAP8flJQOUWj+NpMlH5ASDOsRjnHxF27Dx095m9oU5T +b4mklWpzrm2afvN4Ed+9iVvmocELkle6um2wjtdcYMCuyuBtMWsH8ZiKZi8CAwEA +AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAgQwHQYDVR0OBBYE +FM1ZuLvruieyZjwcBXabcYpo6jD9MA0GCSqGSIb3DQEBCwUAA4IBAQCmLeGeBKUM +nWuCufJZhZ/v5Orruatwc1D6HV0L138+MvblJwFHaTqiotLgTRatnZg87YEFxhKh +koWVfyLn0nf+U77+LHQsJHtml4wLAIg+loccag5wmIEQwYT0mEtgd5wkp7KlROgF +2qVsYndo+S5zPMYsrTr/Smeg2iOE6rzZy/lFE+M4JsfxYJXzPy+BmAtYYHJfye8f +drIFA41POqjrCsWo/aNfqCmDy57LEySmSjOVIvwmkNyXLFOsJBpg1qrkzRQShGHq +FShaefMYHrt3A2EstLbVxZl8p3yKG8igLFBTXfu0gSO/CrGf8LDT7QjiTadQRL46 +oMAscAzkyHEV +-----END CERTIFICATE----- diff --git a/tests/data/certs/server.key b/tests/data/certs/server.key new file mode 100644 index 00000000..154f458e --- /dev/null +++ b/tests/data/certs/server.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDh1xEWNKOHzrKy +Spm2uLZM+2p6KH3Sd6yCxb+aaSv8lIBwOcFQhzaRuWHsMeJSS1zeWK4phCmDZDGG +5fj1NwzGrLERy+zgrd8Er82npv/xqAoMXxozJexQI2WzmNT80NjxK0pmKCgDPr6R +kpJASgL1kZGWMnXiT5OMnK5/YnR4jXSH+4TKferHMzGv4XXyy4SoEbPVaCIjjOYr +U1uOjVbtSxCH2gheB52EqULyH6t3G6siOjptsroRkTnQYSykJlXNtTG0W4HqBEk8 +Y8BFF1Q7yC7OnPhaw6GX+Rj5r5dgs2w+0Yw6gVQJJoNHhKexzd9NQIMDOMWl1qSq +XVGGKXJHAgMBAAECggEAKZRRHwd9/CkAGXdGqa+EUNQRHICL+c3ywvjpd+JZKN2m +cAMSJmNelqHM95GPm5soc/9bwWUFx50QyUdZ+Luz7Hgq+Z3T9OHOJ6y+bll+0d0g +THrN9hDLW03JEbHXtNw2tOBFiF1oUICi0WZs6s01kkTEyyRrM8l23vKR5f4Yd4Eq +/LXIN1XPGQQh0izHeSpGdPL6633Ls+xtMMnfzpfIb+wcoXegiCyeaK41zucE5xR6 +Q2NB3FuUm/aI3EtqGQSeV34AEH5XIOp/o2IZCb6oWBJVVH9oe0p1m/v2OxLcB9CT +RrLjg1Wq2ufXzJW28V8WHR18dLkYqpaTIT+vmy3/sQKBgQD+5jC9VwORSvf7Q/zc +WmO+6FcA9ftNDH7LFI/qaV6WQLQrSMcpHdKNS1nXh1uLXxz1vAYAllrU+3Hv33jI +Z+6FcaX5xm9Z4fdGFiHDBrAENvyWORlqcA+8cQSoltceNNLdmE7/TAjX9sjwUQwO +U6Y+XewR6GceSo9nd/8nNb7aQwKBgQDi0L/apk/98G4ShDHLKJlXsYatpLmGw6Dm +vi6+PJJy8VHYRU5SNPAjrFVvTByaV4fd7QZUPivJQoaN0RO1JXVl70DVF3+eu63H +vs+fYnpytrQko4BPBA7PgHSq9uolAwsjGPLzqGNkK23ExTdjn8xoc7AQetADBOZ0 +Z/x3OjCRrQKBgEdL5ZggLYxHNuOeGa0cz0eHv0Yyh27+rrxo7PQ5Ms6+HGb6/VH/ +2HPS/rctUirCmNwXEmq5o4BtMGpSzHrpryq+JhmeKmkurjZ5XEorpbIYG0B9iiFe +ZNhlmFL7lgIJ7m0y++2mu9aEXaHyWXfsZ9SL+srrgWRUoJXlV4YFH3P3AoGAd1BO +jEuOqsvOa2kk9HT/7VSSv0d23QCN5LPIzQP6GgL+BeG3aKE2bd2a97g3F63R6Blm +iexGhlG7jGCemF0DG8M2/KGm3a5mpTun5nUcarnXm6pytZ4x2E//j2viEeQ++JCI +RUqgNjJuRONl1r9Z/NxWkuS4Bc6PGE8XTPTMVeUCgYBpTRgzlpma/w3M+lyIdaXC +AZZYjDJ8l2ALMdcyEdWUV74NkqVCmTMrDI2xkqSZOyNfvnb6fLW7Q1V7ygy7zb7L +ejQJ+aSvuJ9wxCD68X0jyXbPssiiV38Z0DJy/jsMog1l6q+6NYRtifk4P5GgX3uU +4n8pKZtIK5i5AHkgIRrFrw== +-----END PRIVATE KEY----- diff --git a/tests/data/certs/server.pem b/tests/data/certs/server.pem new file mode 100644 index 00000000..99fbe396 --- /dev/null +++ b/tests/data/certs/server.pem @@ -0,0 +1,76 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=CZ, ST=Some-State, O=CESNET, OU=TMC, CN=Intermediate Client CA + Validity + Not Before: Jun 3 11:56:18 2025 GMT + Not After : Jun 1 11:56:18 2035 GMT + Subject: C=CZ, ST=Some-State, O=CESNET, OU=TMC, CN=localhost + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:e1:d7:11:16:34:a3:87:ce:b2:b2:4a:99:b6:b8: + b6:4c:fb:6a:7a:28:7d:d2:77:ac:82:c5:bf:9a:69: + 2b:fc:94:80:70:39:c1:50:87:36:91:b9:61:ec:31: + e2:52:4b:5c:de:58:ae:29:84:29:83:64:31:86:e5: + f8:f5:37:0c:c6:ac:b1:11:cb:ec:e0:ad:df:04:af: + cd:a7:a6:ff:f1:a8:0a:0c:5f:1a:33:25:ec:50:23: + 65:b3:98:d4:fc:d0:d8:f1:2b:4a:66:28:28:03:3e: + be:91:92:92:40:4a:02:f5:91:91:96:32:75:e2:4f: + 93:8c:9c:ae:7f:62:74:78:8d:74:87:fb:84:ca:7d: + ea:c7:33:31:af:e1:75:f2:cb:84:a8:11:b3:d5:68: + 22:23:8c:e6:2b:53:5b:8e:8d:56:ed:4b:10:87:da: + 08:5e:07:9d:84:a9:42:f2:1f:ab:77:1b:ab:22:3a: + 3a:6d:b2:ba:11:91:39:d0:61:2c:a4:26:55:cd:b5: + 31:b4:5b:81:ea:04:49:3c:63:c0:45:17:54:3b:c8: + 2e:ce:9c:f8:5a:c3:a1:97:f9:18:f9:af:97:60:b3: + 6c:3e:d1:8c:3a:81:54:09:26:83:47:84:a7:b1:cd: + df:4d:40:83:03:38:c5:a5:d6:a4:aa:5d:51:86:29: + 72:47 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Key Identifier: + D9:09:EE:AA:F0:9D:9B:83:99:92:C2:FA:16:71:AB:67:AA:D5:6A:22 + X509v3 Authority Key Identifier: + F2:CF:C5:9A:C6:63:7A:AB:A0:59:60:41:FE:7D:3F:5D:BE:9A:D5:3F + Signature Algorithm: sha256WithRSAEncryption + Signature Value: + 9f:d0:5b:0b:21:62:22:c7:a9:5b:92:bc:37:b5:fa:42:52:59: + 47:68:62:21:bf:b6:57:d5:38:c5:47:a6:67:a4:c7:40:ff:6c: + 40:99:89:7d:72:16:3f:ff:5c:b6:c1:24:cf:33:aa:55:25:76: + 94:f1:08:6c:7e:d5:79:81:0c:1b:0f:c7:76:0e:b1:09:84:8d: + 7e:8b:77:6a:e9:0f:bd:dd:fa:85:b9:83:c5:1e:e0:85:32:c0: + 49:5d:f7:25:d7:0c:4f:28:f4:20:45:b3:a2:72:b4:5d:c9:7a: + ac:e4:e3:89:e8:a8:3f:35:d6:2d:2a:57:e2:4d:06:0b:88:34: + 39:14:a1:d0:4d:08:02:92:82:c3:7a:23:df:b4:c9:e3:8b:b0: + 0a:1c:f9:e5:57:db:d7:cd:22:6d:4d:e9:59:0e:e2:b8:f3:38: + 4c:20:3b:d0:18:16:e9:85:7d:2a:80:f9:99:10:1c:65:94:b3: + 29:8d:d3:a1:5b:9f:e3:cc:26:80:1f:d4:8f:a8:ab:82:29:7b: + 8e:2d:29:f5:bf:ab:86:ae:41:9b:1b:ef:fc:ef:9b:4f:0e:24: + 46:3e:86:28:25:af:fb:c9:5c:9a:46:ae:44:73:8f:bd:84:56: + 8b:6b:c0:22:26:e0:57:c9:f4:08:14:f5:aa:dc:e3:6f:2d:59: + a4:8a:f8:5c +-----BEGIN CERTIFICATE----- +MIIDdDCCAlygAwIBAgIBATANBgkqhkiG9w0BAQsFADBiMQswCQYDVQQGEwJDWjET +MBEGA1UECAwKU29tZS1TdGF0ZTEPMA0GA1UECgwGQ0VTTkVUMQwwCgYDVQQLDANU +TUMxHzAdBgNVBAMMFkludGVybWVkaWF0ZSBDbGllbnQgQ0EwHhcNMjUwNjAzMTE1 +NjE4WhcNMzUwNjAxMTE1NjE4WjBVMQswCQYDVQQGEwJDWjETMBEGA1UECAwKU29t +ZS1TdGF0ZTEPMA0GA1UECgwGQ0VTTkVUMQwwCgYDVQQLDANUTUMxEjAQBgNVBAMM +CWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOHXERY0 +o4fOsrJKmba4tkz7anoofdJ3rILFv5ppK/yUgHA5wVCHNpG5Yewx4lJLXN5YrimE +KYNkMYbl+PU3DMassRHL7OCt3wSvzaem//GoCgxfGjMl7FAjZbOY1PzQ2PErSmYo +KAM+vpGSkkBKAvWRkZYydeJPk4ycrn9idHiNdIf7hMp96sczMa/hdfLLhKgRs9Vo +IiOM5itTW46NVu1LEIfaCF4HnYSpQvIfq3cbqyI6Om2yuhGROdBhLKQmVc21MbRb +geoESTxjwEUXVDvILs6c+FrDoZf5GPmvl2CzbD7RjDqBVAkmg0eEp7HN301AgwM4 +xaXWpKpdUYYpckcCAwEAAaNCMEAwHQYDVR0OBBYEFNkJ7qrwnZuDmZLC+hZxq2eq +1WoiMB8GA1UdIwQYMBaAFPLPxZrGY3qroFlgQf59P12+mtU/MA0GCSqGSIb3DQEB +CwUAA4IBAQCf0FsLIWIix6lbkrw3tfpCUllHaGIhv7ZX1TjFR6ZnpMdA/2xAmYl9 +chY//1y2wSTPM6pVJXaU8QhsftV5gQwbD8d2DrEJhI1+i3dq6Q+93fqFuYPFHuCF +MsBJXfcl1wxPKPQgRbOicrRdyXqs5OOJ6Kg/NdYtKlfiTQYLiDQ5FKHQTQgCkoLD +eiPftMnji7AKHPnlV9vXzSJtTelZDuK48zhMIDvQGBbphX0qgPmZEBxllLMpjdOh +W5/jzCaAH9SPqKuCKXuOLSn1v6uGrkGbG+/875tPDiRGPoYoJa/7yVyaRq5Ec4+9 +hFaLa8AiJuBXyfQIFPWq3ONvLVmkivhc +-----END CERTIFICATE----- diff --git a/tests/test_tls.c b/tests/test_tls.c index 98c2bcdb..e7bdc9ce 100644 --- a/tests/test_tls.c +++ b/tests/test_tls.c @@ -27,6 +27,12 @@ #define KEYLOG_FILENAME "ln2_test_tls_keylog.txt" +struct test_tls_data { + struct lyd_node *tree; /**< Test data for the server configuration. */ + int root_ca; /**< Whether the root CA is used (client-only). */ + int intermediate_ca; /**< Whether the intermediate CA is used (client-only). */ +}; + int TEST_PORT = 10050; const char *TEST_PORT_STR = "10050"; @@ -75,20 +81,211 @@ test_nc_tls(void **state) } static void -test_nc_tls_ec_key(void **state) +test_nc_tls_ca_cert_only(void **state) { int ret, i; pthread_t tids[2]; - struct ln2_test_ctx *test_ctx; + struct ln2_test_ctx *test_ctx = *state; + struct test_tls_data *test_data = test_ctx->test_data; - assert_non_null(state); - test_ctx = *state; + /* delete a client certificate so that only CA certs are used */ + assert_int_equal(nc_server_config_del_tls_client_cert("endpt", + "client_cert", &test_data->tree), 0); + + /* apply the configuration */ + assert_int_equal(nc_server_config_setup_data(test_data->tree), 0); + + ret = pthread_create(&tids[0], NULL, client_thread, *state); + assert_int_equal(ret, 0); + ret = pthread_create(&tids[1], NULL, ln2_glob_test_server_thread, *state); + assert_int_equal(ret, 0); + + for (i = 0; i < 2; i++) { + pthread_join(tids[i], NULL); + } +} + +static void +test_nc_tls_ee_cert_only(void **state) +{ + int ret, i; + pthread_t tids[2]; + struct ln2_test_ctx *test_ctx = *state; + struct test_tls_data *test_data = test_ctx->test_data; + + /* delete a CA certificate so that only end entity client cert is used */ + assert_int_equal(nc_server_config_del_tls_ca_cert("endpt", + "client_ca", &test_data->tree), 0); + + /* apply the configuration */ + assert_int_equal(nc_server_config_setup_data(test_data->tree), 0); + + ret = pthread_create(&tids[0], NULL, client_thread, *state); + assert_int_equal(ret, 0); + ret = pthread_create(&tids[1], NULL, ln2_glob_test_server_thread, *state); + assert_int_equal(ret, 0); + + for (i = 0; i < 2; i++) { + pthread_join(tids[i], NULL); + } +} + +static void * +client_thread_intermediate_ca(void *arg) +{ + int ret; + struct nc_session *session = NULL; + struct ln2_test_ctx *test_ctx = arg; + struct test_tls_data *test_data = test_ctx->test_data; + + ret = nc_client_set_schema_searchpath(MODULES_DIR); + assert_int_equal(ret, 0); + + /* set client cert */ + ret = nc_client_tls_set_cert_key_paths(TESTS_DIR "/data/certs/client.pem", TESTS_DIR "/data/certs/client.key"); + assert_int_equal(ret, 0); + + if (test_data->root_ca && test_data->intermediate_ca) { + /* set the dir with the root and intermediate CAs */ + ret = nc_client_tls_set_trusted_ca_paths(NULL, TESTS_DIR "/data/certs"); + } else if (test_data->root_ca) { + /* set the root CA */ + ret = nc_client_tls_set_trusted_ca_paths(TESTS_DIR "/data/certs/rootca.pem", NULL); + } else if (test_data->intermediate_ca) { + /* set the intermediate CA */ + ret = nc_client_tls_set_trusted_ca_paths(TESTS_DIR "/data/certs/intermediate_ca.pem", NULL); + } + + pthread_barrier_wait(&test_ctx->barrier); + + session = nc_connect_tls("localhost", TEST_PORT, NULL); + assert_non_null(session); + + nc_session_free(session, NULL); + return NULL; +} + +static void +test_nc_tls_intermediate_ca_server(void **state) +{ + int ret, i; + pthread_t tids[2]; + struct ln2_test_ctx *test_ctx = *state; + struct test_tls_data *test_data = test_ctx->test_data; + + printf("\nINTERMEDIATE CA ALL\n\n"); + + /* all certs are set */ + test_data->root_ca = 1; + test_data->intermediate_ca = 1; + ret = pthread_create(&tids[0], NULL, client_thread_intermediate_ca, *state); + assert_int_equal(ret, 0); + ret = pthread_create(&tids[1], NULL, ln2_glob_test_server_thread, *state); + assert_int_equal(ret, 0); + for (i = 0; i < 2; i++) { + pthread_join(tids[i], NULL); + } + +#ifndef HAVE_MBEDTLS + /* this use case is not supported by mbedTLS, so skip it for now */ + + printf("\nINTERMEDIATE CA ROOT ONLY\n\n"); + + /* delete server's intermediate CA */ + assert_int_equal(nc_server_config_del_tls_ca_cert("endpt", + "intermediate_ca", &test_data->tree), 0); + assert_int_equal(nc_server_config_setup_data(test_data->tree), 0); + ret = pthread_create(&tids[0], NULL, client_thread_intermediate_ca, *state); + assert_int_equal(ret, 0); + ret = pthread_create(&tids[1], NULL, ln2_glob_test_server_thread, *state); + assert_int_equal(ret, 0); + for (i = 0; i < 2; i++) { + pthread_join(tids[i], NULL); + } +#endif + + printf("\nINTERMEDIATE CA INTERMEDIATE ONLY\n\n"); + + /* delete server's root CA */ + assert_int_equal(nc_server_config_del_tls_ca_cert("endpt", + "root_ca", &test_data->tree), 0); + /* add back the intermediate CA, expect success */ + assert_int_equal(nc_server_config_add_tls_ca_cert(test_ctx->ctx, "endpt", "intermediate_ca", + TESTS_DIR "/data/certs/intermediate_ca.pem", &test_data->tree), 0); + assert_int_equal(nc_server_config_setup_data(test_data->tree), 0); + ret = pthread_create(&tids[0], NULL, client_thread_intermediate_ca, *state); + assert_int_equal(ret, 0); + ret = pthread_create(&tids[1], NULL, ln2_glob_test_server_thread, *state); + assert_int_equal(ret, 0); + for (i = 0; i < 2; i++) { + pthread_join(tids[i], NULL); + } +} + +static void +test_nc_tls_intermediate_ca_client(void **state) +{ + int ret, i; + pthread_t tids[2]; + struct ln2_test_ctx *test_ctx = *state; + struct test_tls_data *test_data = test_ctx->test_data; + + printf("\nINTERMEDIATE CA ALL\n\n"); + + /* all certs are set */ + test_data->root_ca = 1; + test_data->intermediate_ca = 1; + ret = pthread_create(&tids[0], NULL, client_thread_intermediate_ca, *state); + assert_int_equal(ret, 0); + ret = pthread_create(&tids[1], NULL, ln2_glob_test_server_thread, *state); + assert_int_equal(ret, 0); + for (i = 0; i < 2; i++) { + pthread_join(tids[i], NULL); + } + +#ifndef HAVE_MBEDTLS + /* this use case is not supported by mbedTLS, so skip it for now */ + + printf("\nINTERMEDIATE CA ROOT ONLY\n\n"); + + /* delete client's intermediate CA */ + test_data->intermediate_ca = 0; + ret = pthread_create(&tids[0], NULL, client_thread_intermediate_ca, *state); + assert_int_equal(ret, 0); + ret = pthread_create(&tids[1], NULL, ln2_glob_test_server_thread, *state); + assert_int_equal(ret, 0); + for (i = 0; i < 2; i++) { + pthread_join(tids[i], NULL); + } +#endif + + printf("\nINTERMEDIATE CA INTERMEDIATE ONLY\n\n"); + + /* delete client's root CA, expect success */ + test_data->root_ca = 0; + test_data->intermediate_ca = 1; + ret = pthread_create(&tids[0], NULL, client_thread_intermediate_ca, *state); + assert_int_equal(ret, 0); + ret = pthread_create(&tids[1], NULL, ln2_glob_test_server_thread, *state); + assert_int_equal(ret, 0); + for (i = 0; i < 2; i++) { + pthread_join(tids[i], NULL); + } +} + +static void +test_nc_tls_ec_key(void **state) +{ + int ret, i; + pthread_t tids[2]; + struct ln2_test_ctx *test_ctx = *state; + struct test_tls_data *test_data = test_ctx->test_data; ret = nc_server_config_add_tls_server_cert(test_ctx->ctx, "endpt", TESTS_DIR "/data/ec_server.key", - NULL, TESTS_DIR "/data/ec_server.crt", (struct lyd_node **)&test_ctx->test_data); + NULL, TESTS_DIR "/data/ec_server.crt", &test_data->tree); assert_int_equal(ret, 0); - ret = nc_server_config_setup_data(test_ctx->test_data); + ret = nc_server_config_setup_data(test_data->tree); assert_int_equal(ret, 0); ret = pthread_create(&tids[0], NULL, client_thread, *state); @@ -162,7 +359,10 @@ test_nc_tls_keylog(void **state) static void test_nc_tls_free_test_data(void *test_data) { - lyd_free_all(test_data); + struct test_tls_data *data = test_data; + + lyd_free_all(data->tree); + free(data); } static int @@ -171,6 +371,7 @@ setup_f(void **state) int ret; struct lyd_node *tree = NULL; struct ln2_test_ctx *test_ctx; + struct test_tls_data *test_data; ret = ln2_glob_test_setup(&test_ctx); assert_int_equal(ret, 0); @@ -203,7 +404,62 @@ setup_f(void **state) ret = nc_server_config_setup_data(tree); assert_int_equal(ret, 0); - test_ctx->test_data = tree; + test_data = calloc(1, sizeof *test_data); + assert_non_null(test_data); + + test_data->tree = tree; + + test_ctx->test_data = test_data; + test_ctx->free_test_data = test_nc_tls_free_test_data; + + return 0; +} + +static int +setup_intermediate_ca(void **state) +{ + int ret; + struct lyd_node *tree = NULL; + struct ln2_test_ctx *test_ctx; + struct test_tls_data *test_data; + + ret = ln2_glob_test_setup(&test_ctx); + assert_int_equal(ret, 0); + + *state = test_ctx; + + /* create new address and port data */ + ret = nc_server_config_add_address_port(test_ctx->ctx, "endpt", NC_TI_TLS, "127.0.0.1", TEST_PORT, &tree); + assert_int_equal(ret, 0); + + /* create new server certificate data */ + ret = nc_server_config_add_tls_server_cert(test_ctx->ctx, "endpt", TESTS_DIR "/data/certs/server.key", NULL, TESTS_DIR "/data/certs/server.pem", &tree); + assert_int_equal(ret, 0); + + /* add the root CA */ + ret = nc_server_config_add_tls_ca_cert(test_ctx->ctx, "endpt", "root_ca", TESTS_DIR "/data/certs/rootca.pem", &tree); + assert_int_equal(ret, 0); + + /* add the intermediate CA */ + ret = nc_server_config_add_tls_ca_cert(test_ctx->ctx, "endpt", "intermediate_ca", TESTS_DIR "/data/certs/intermediate_ca.pem", &tree); + assert_int_equal(ret, 0); + + /* create new cert-to-name */ + ret = nc_server_config_add_tls_ctn(test_ctx->ctx, "endpt", 1, + "04:9F:36:25:23:52:1C:9D:9F:31:2C:A3:07:DF:71:8C:FD:66:93:E1:FA:7B:90:E7:C5:1D:50:A8:16:10:5B:F0:52", + NC_TLS_CTN_SPECIFIED, "client", &tree); + assert_int_equal(ret, 0); + + /* configure the server based on the data */ + ret = nc_server_config_setup_data(tree); + assert_int_equal(ret, 0); + + test_data = calloc(1, sizeof *test_data); + assert_non_null(test_data); + + test_data->tree = tree; + + test_ctx->test_data = test_data; test_ctx->free_test_data = test_nc_tls_free_test_data; return 0; @@ -223,6 +479,10 @@ main(void) { const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown(test_nc_tls, setup_f, ln2_glob_test_teardown), + cmocka_unit_test_setup_teardown(test_nc_tls_ca_cert_only, setup_f, ln2_glob_test_teardown), + cmocka_unit_test_setup_teardown(test_nc_tls_ee_cert_only, setup_f, ln2_glob_test_teardown), + cmocka_unit_test_setup_teardown(test_nc_tls_intermediate_ca_server, setup_intermediate_ca, ln2_glob_test_teardown), + cmocka_unit_test_setup_teardown(test_nc_tls_intermediate_ca_client, setup_intermediate_ca, ln2_glob_test_teardown), cmocka_unit_test_setup_teardown(test_nc_tls_ec_key, setup_f, ln2_glob_test_teardown), cmocka_unit_test_setup_teardown(test_nc_tls_keylog, keylog_setup_f, ln2_glob_test_teardown) };