diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index c1da7efb..411d357b 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -104,6 +104,11 @@ if (WITH_CLIENT_TESTING) # Allow to auth with bob his public keys on alice account configure_file(keys/id_rsa.pub ${CMAKE_CURRENT_BINARY_DIR}/home/alice/.ssh/authorized_keys @ONLY) + # Copy the signed key to an alternative directory in bob's homedir. + file(COPY keys/certauth/id_rsa DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/home/bob/.ssh_cert/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE) + file(COPY keys/certauth/id_rsa.pub DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/home/bob/.ssh_cert/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE) + file(COPY keys/certauth/id_rsa-cert.pub DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/home/bob/.ssh_cert/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE) + message(STATUS "TORTURE_ENVIRONMENT=${TORTURE_ENVIRONMENT}") add_subdirectory(client) diff --git a/tests/client/torture_auth.c b/tests/client/torture_auth.c index 77a3c555..8a23454e 100644 --- a/tests/client/torture_auth.c +++ b/tests/client/torture_auth.c @@ -147,6 +147,32 @@ static int agent_setup(void **state) return 0; } +static int agent_cert_setup(void **state) +{ + char bob_alt_ssh_key[1024]; + struct passwd *pwd; + int rc; + + rc = agent_setup(state); + if (rc != 0) { + return rc; + } + + pwd = getpwnam("bob"); + assert_non_null(pwd); + + /* remove all keys, load alternative key + cert */ + snprintf(bob_alt_ssh_key, + sizeof(bob_alt_ssh_key), + "ssh-add -D && ssh-add %s/.ssh_cert/id_rsa", + pwd->pw_dir); + + rc = system(bob_alt_ssh_key); + assert_return_code(rc, errno); + + return 0; +} + static int agent_teardown(void **state) { const char *ssh_agent_pidfile; @@ -464,6 +490,69 @@ static void torture_auth_agent_nonblocking(void **state) { assert_int_equal(rc, SSH_AUTH_SUCCESS); } +static void torture_auth_cert(void **state) { + struct torture_state *s = *state; + ssh_session session = s->ssh.session; + ssh_key privkey = NULL; + ssh_key cert = NULL; + char bob_ssh_key[1024]; + char bob_ssh_cert[1024]; + struct passwd *pwd; + int rc; + + privkey = ssh_key_new(); + assert_true(privkey != NULL); + + cert = ssh_key_new(); + assert_true(cert != NULL); + + pwd = getpwnam("bob"); + assert_non_null(pwd); + + snprintf(bob_ssh_key, + sizeof(bob_ssh_key), + "%s/.ssh_cert/id_rsa", + pwd->pw_dir); + snprintf(bob_ssh_cert, + sizeof(bob_ssh_cert), + "%s-cert.pub", + bob_ssh_key); + + /* cert has been signed for login as alice */ + rc = ssh_options_set(session, SSH_OPTIONS_USER, TORTURE_SSH_USER_ALICE); + assert_int_equal(rc, SSH_OK); + + rc = ssh_connect(session); + assert_int_equal(rc, SSH_OK); + + rc = ssh_pki_import_privkey_file(bob_ssh_key, NULL, NULL, NULL, &privkey); + assert_int_equal(rc, SSH_OK); + + rc = ssh_pki_import_cert_file(bob_ssh_cert, &cert); + assert_int_equal(rc, SSH_OK); + + rc = ssh_pki_copy_cert_to_privkey(cert, privkey); + assert_int_equal(rc, SSH_OK); + + rc = ssh_userauth_try_publickey(session, NULL, cert); + assert_int_equal(rc, SSH_AUTH_SUCCESS); + + rc = ssh_userauth_publickey(session, NULL, privkey); + assert_int_equal(rc, SSH_AUTH_SUCCESS); + + ssh_key_free(privkey); + ssh_key_free(cert); +} + +static void torture_auth_agent_cert(void **state) { + /* Setup loads a different key, tests are exactly the same. */ + torture_auth_agent(state); +} + +static void torture_auth_agent_cert_nonblocking(void **state) { + torture_auth_agent_nonblocking(state); +} + int torture_run_tests(void) { int rc; @@ -498,6 +587,15 @@ int torture_run_tests(void) { cmocka_unit_test_setup_teardown(torture_auth_agent_nonblocking, agent_setup, agent_teardown), + cmocka_unit_test_setup_teardown(torture_auth_cert, + pubkey_setup, + session_teardown), + cmocka_unit_test_setup_teardown(torture_auth_agent_cert, + agent_cert_setup, + agent_teardown), + cmocka_unit_test_setup_teardown(torture_auth_agent_cert_nonblocking, + agent_cert_setup, + agent_teardown), }; ssh_init(); diff --git a/tests/keys/certauth/id_rsa b/tests/keys/certauth/id_rsa new file mode 100644 index 00000000..aa86ac2b --- /dev/null +++ b/tests/keys/certauth/id_rsa @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEiwIBAAKB/QMTSsCQqarOIauonYgjAt8E+lgSWBU/43ITyDDzLM4IS4wCcqXB +1Fagz386FU1B2AcUqlPZ1+7RlaXkqgKr4nGHv00U/GG+YAUgUAw1G12kI4cvrnWr +FIXwcq+VTJNej5pHxEqcRLw7ZBorpqm2UsY5KLr5R3uMNap7koj1Hbt9lKsvfDn6 +HjM4qY0ygx8hxf/4wCzIh5V4k9/UAMkqI2CM9c3yEE2aWh/4MDOnAFj+0T2sMAo8 +jyOZ6v+W7hmEtsUc9mEv+5B+hhVeYO/RwxketJAQRPYDSPSi1mjtv9fnzGk15q/l +Hb2V/HP/pyIpao19A4daR0a4ia9Hk4UCAwEAAQKB/QKEaPxjrKzlWoQSWRdUaQY5 +Idyy7yw9hiMa9BK1COh/u66XVlY86Fwb9puR5Fu/WF67WIuX1PpizJXkLBBRtuDs +lvY2BjrPQ/MONtc3JPYp4vbFXYxtAzh6zrTPhMVfcjV7Jr1XWZ+lEVOmhR2G4gvk +P2WDozIKWub3jMLTt4afgHCGaKfKEUpKjFkiAalz8oLVv8qV1FVPPDT2PWeKMuE3 +XfoN7YUaP6+aPlNnjIv/3BDsrPsiKZ+AKXcERdPvVQa/LypzW08cqC6sIJKWVmQI +3KgoYs9VvbDXfQ8jKfcsTApZkSDaLX6tf3Ei+76R0lbV4L1rpypa25qj9YECfwHP +N+v/6yObJFL5/1rEuT7CFbfP8g5J8qUVufcPRKv//ChluLuWNxgLJmIv2ZffWwhe +GKHlT98QPgFvsMSOyLeut4beZYKDSeVNvEt9eCBjOax2jOBGo3hv8j/Fs8yAfZOV +Ardv2qUszubM+DVwjJzb3vaZyEesRucJISqkJeUCfwGzGdMp0LXrZ7aaQGgHj/P2 +DKGq0E2gnj/EBapatjxKm4hMRn/vkTWjCDCryTnvJqkW/00tr4GqWXoeilBFD270 +RcvbOe9LQmGlHIYzgwc5nfLDBQyeNnHRmkeD9LQRUfdTdHj4jf+35pHlsVUT0Rnl +IMNoRA6V07bySFdI3SECfiF+1rbrxuhaCRIA0Ax3pL0eGuuTgksAm8VlbCMTgSiC +kF1CrXXgSAHOZb02C9Bf4cwEFfjh/KxM/4eXDa+Rfg7JQJxmVLivqEAlxIOvIxBp +xDnSWAljmrrllozyQnBsJDbbOm6BLf5+e5wIuryHvnP7vHNEU0J24g/78PxrrQJ/ +AVD4OzYzUfESzbUBFJBmyIZSmhJ0aOpwJOpniNvgLymI8zI/l22uhF/TQ/6HRbsV +sfcBmoA7YKzRx2ZHsIsLvN6p/4u1fsJGkuERCk5yt/HDhfPLwU321IeEeMaVia+w +T1/u4JF/SADhLTU69az3UJrHmQ7zRmh7I0DZDeB8gQJ+XqIqutPeerNtbqMjXGW8 +TdpqZAzAQAv6dPgaH0W0OzJe2hP9uy0D84H5f8Im/irJh/AXo/QL3obXqopyeLf0 +HfcUUnEZEBPlqsirZFtPClD+HL6Orf1je0oVV/aQssPkQl6/aXBNd+kS27U3NBML +LmRhC4+Q+/M5MlRggLtn +-----END RSA PRIVATE KEY----- diff --git a/tests/keys/certauth/id_rsa-cert.pub b/tests/keys/certauth/id_rsa-cert.pub new file mode 100644 index 00000000..615d39f0 --- /dev/null +++ b/tests/keys/certauth/id_rsa-cert.pub @@ -0,0 +1 @@ +ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgHZLan4ufbTFWr8Hl/8JvZTLYa0eNNm2qov9zPlK7qfwAAAADAQABAAAA/QMTSsCQqarOIauonYgjAt8E+lgSWBU/43ITyDDzLM4IS4wCcqXB1Fagz386FU1B2AcUqlPZ1+7RlaXkqgKr4nGHv00U/GG+YAUgUAw1G12kI4cvrnWrFIXwcq+VTJNej5pHxEqcRLw7ZBorpqm2UsY5KLr5R3uMNap7koj1Hbt9lKsvfDn6HjM4qY0ygx8hxf/4wCzIh5V4k9/UAMkqI2CM9c3yEE2aWh/4MDOnAFj+0T2sMAo8jyOZ6v+W7hmEtsUc9mEv+5B+hhVeYO/RwxketJAQRPYDSPSi1mjtv9fnzGk15q/lHb2V/HP/pyIpao19A4daR0a4ia9Hk4UAAAAAAAAAAAAAAAEAAAATdG9ydHVyZV9hdXRoX2NhcmxvcwAAAAkAAAAFYWxpY2UAAAAAAAAAAP//////////AAAAAAAAAIIAAAAVcGVybWl0LVgxMS1mb3J3YXJkaW5nAAAAAAAAABdwZXJtaXQtYWdlbnQtZm9yd2FyZGluZwAAAAAAAAAWcGVybWl0LXBvcnQtZm9yd2FyZGluZwAAAAAAAAAKcGVybWl0LXB0eQAAAAAAAAAOcGVybWl0LXVzZXItcmMAAAAAAAAAAAAAARcAAAAHc3NoLXJzYQAAAAMBAAEAAAEBAKcDafm8fNluz8a9GQaWgk1XUJcchLleeubTke6xQlJbI+rcjWIIwd1gDuh7Mdr0YIVhsh6dpg/L4bpRJBGNhDPxK8BmjTpIU14lKxrWQAirHN09P2QGtGtgrf09lA+xhV9E+pkF2Zz6PCt/P3sgUQnJcwjjsWhMaSASrt67fPanH+10hnfgjkevkMMHGJxmLiOW7JFQkd9I+gHHKEXs6Q9fhtiStzr3WN4hAPG5uXrnRZgseAV9p3TFPMEgUTpdRvnkOnkCBF169KiyjU97QgoXHExWk/rrgsJtgrTou/qRyi18WWm9S1HXLHyNOgZxKirmxLNPC9dIcJBD1kDWG8UAAAEPAAAAB3NzaC1yc2EAAAEAhNLOXT0jyz/Web0HUyrtPCvUZsLkDyBWCNoNTfsxGVoYsE4WCpNwqQO1A4NT5AtIE+R7rn9wfjvXM7sYh6hJyq3HVEWhts1SkQVU7sQBrImTIrj2cWKR3gmQ+ehsgNFGhcFZTK77ugw1fMfzZRvKVTkRWhe6v92wQOtkoINtf3f1fK6xY+vLwAA/E4VdaRJmhwAaNpy3PfMAJytkCLjcjUSWHYDha4hs98/EBPduGNNNiZdyG7lcpSvvq9HBDxzOiHBa/We9m38/Dk4TNVkZ/wrtBFQxH75if6SgGa/feGJrKQHBru7sPh8dO4R1AmZaoLmRzMnzZOtB0oEXmBqHmw== libssh_torture_auth diff --git a/tests/keys/certauth/id_rsa.pub b/tests/keys/certauth/id_rsa.pub new file mode 100644 index 00000000..4cbfc4ce --- /dev/null +++ b/tests/keys/certauth/id_rsa.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAA/QMTSsCQqarOIauonYgjAt8E+lgSWBU/43ITyDDzLM4IS4wCcqXB1Fagz386FU1B2AcUqlPZ1+7RlaXkqgKr4nGHv00U/GG+YAUgUAw1G12kI4cvrnWrFIXwcq+VTJNej5pHxEqcRLw7ZBorpqm2UsY5KLr5R3uMNap7koj1Hbt9lKsvfDn6HjM4qY0ygx8hxf/4wCzIh5V4k9/UAMkqI2CM9c3yEE2aWh/4MDOnAFj+0T2sMAo8jyOZ6v+W7hmEtsUc9mEv+5B+hhVeYO/RwxketJAQRPYDSPSi1mjtv9fnzGk15q/lHb2V/HP/pyIpao19A4daR0a4ia9Hk4U= libssh_torture_auth diff --git a/tests/keys/user_ca b/tests/keys/user_ca new file mode 100644 index 00000000..dc9d80c2 --- /dev/null +++ b/tests/keys/user_ca @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEApwNp+bx82W7Pxr0ZBpaCTVdQlxyEuV565tOR7rFCUlsj6tyN +YgjB3WAO6Hsx2vRghWGyHp2mD8vhulEkEY2EM/ErwGaNOkhTXiUrGtZACKsc3T0/ +ZAa0a2Ct/T2UD7GFX0T6mQXZnPo8K38/eyBRCclzCOOxaExpIBKu3rt89qcf7XSG +d+COR6+QwwcYnGYuI5bskVCR30j6AccoRezpD1+G2JK3OvdY3iEA8bm5eudFmCx4 +BX2ndMU8wSBROl1G+eQ6eQIEXXr0qLKNT3tCChccTFaT+uuCwm2CtOi7+pHKLXxZ +ab1LUdcsfI06BnEqKubEs08L10hwkEPWQNYbxQIDAQABAoIBACW2AaHgS5iVCtln +LVVterKX+pyEVfu9N6cTMqpg4AbUiYGol0wBijTAUd1wo8s6zuiPLLb5BdwfPzLg +y3IjMCzCUgy5mz4Dwr9JSThgFElgyb2y7LNbSDXOuLqrwtjgTqs6WhNfXMmzPw7b +Rqw4mdPJ5u2k7BQO3NXfIhks4ISYzpzNAwj1a2NMphvkZyvfRnWiQ0pvEXQCxwuR +74iGpPFeyFjjku/O4TiHZllPmDdD3ERalkf8RIudQ5gcbL4fRoONTzfZHtmARWoP +Jury4Zfr5b3VGSnkUDaGlzilXvBusAZOCaaU7chvOPVjXMbSAUEpFBmnRHk5dfrH +fCXECcECgYEA0KMtV3IzwMToVdvzcMQc1ovDvKZAQPneLTxFgNpOeycOhzulzY9p +3fRi5QUOA/Ff+LcCL86APqwoEYe4bgam6mwGFFhv1usf4ulbLNk8ZeR51CG6emPt +tLpg6PThxhMnNpu+StrBAOxeo9pZGd+Plt6d4vfoalOHVkPlSv7OC9kCgYEAzO1I +HuZAQkVdKLGuZlf8E4VEaiMBKdl5+H+8w9peOOax6nqAIrwp2d0aZ52LDjwg7d3C +eSmxu0U1jsbzexVVePr/NmdJOu3+gB0GvlzRjS1xT+MCZIye5a7Nxc7lBp5rFmgV +dJTA6XXRoykinZIxz068SHqtNhNOzO4hUmPDN80CgYAlxOR4aBwmUX8dy+uOBnKS +BEsy44XOPW2TEs4iPWLnuHJQ2ONzCvtHSu58NyYKYK/W/opOzTs6HUBDrCYfBOVC +mrufA0N7zKTBFy2COPFOIMZNOK3haiWmCfdxNKOKj/0RTbBtLJyz5hZb4zMuE+KS +lUpPxEE2vlhJrZDcurPiQQKBgQCIEqMKCX/vwVlLlTglsxSp7ZrxEw9Jt6O68y7n +qc9Y3y6ScQc2iVUM2jkXRlA4goqnB9KDW8EthZY7mTXBq/fWXmwqtsi0faW5cgyx +SLbIlL0h+63yEEHOZ5UxXOFM1NJszW45vDCglOBABCd9E79JVZHGWtc7CfUQNKsh +pybQnQKBgHbPnITR7esVQYLq3PHSsdOdkFiiVf3D7wHiNZcXWjJvUqMF4tH5XAzY +QafKqKk0FzO92ZOhQeB5xauFY5wzsa+Xl8cQkyvtWngFIKbWydEehZWVgXcedxEC +xjbZWKmsYDqBYi3bw9Dxb0AvT+kDtq0Azi8QTDAvRwylvtkYj/V8 +-----END RSA PRIVATE KEY----- diff --git a/tests/torture.c b/tests/torture.c index dd958c69..5ee95b62 100644 --- a/tests/torture.c +++ b/tests/torture.c @@ -281,6 +281,15 @@ static const char torture_ed25519_testkey_pp[]= "Y3GsmYTDstmicanQ==\n" "-----END OPENSSH PRIVATE KEY-----\n"; +static const char torture_rsa_certauth_pub[]= + "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCnA2n5vHzZbs/GvRkGloJNV1CXHI" + "S5Xnrm05HusUJSWyPq3I1iCMHdYA7oezHa9GCFYbIenaYPy+G6USQRjYQz8SvAZo06" + "SFNeJSsa1kAIqxzdPT9kBrRrYK39PZQPsYVfRPqZBdmc+jwrfz97IFEJyXMI47FoTG" + "kgEq7eu3z2px/tdIZ34I5Hr5DDBxicZi4jluyRUJHfSPoBxyhF7OkPX4bYkrc691je" + "IQDxubl650WYLHgFfad0xTzBIFE6XUb55Dp5AgRdevSoso1Pe0IKFxxMVpP664LCbY" + "K06Lv6kcotfFlpvUtR1yx8jToGcSoq5sSzTwvXSHCQQ9ZA1hvF " + "torture_certauth_key"; + #define TORTURE_SOCKET_DIR "/tmp/test_socket_wrapper_XXXXXX" #define TORTURE_SSHD_PIDFILE "sshd/sshd.pid" #define TORTURE_SSHD_CONFIG "sshd/sshd_config" @@ -853,6 +862,7 @@ static void torture_setup_create_sshd_config(void **state) char dsa_hostkey[1024]; char rsa_hostkey[1024]; char ecdsa_hostkey[1024]; + char trusted_ca_pubkey[1024]; char sshd_config[2048]; char sshd_path[1024]; struct stat sb; @@ -886,6 +896,12 @@ static void torture_setup_create_sshd_config(void **state) torture_write_file(ecdsa_hostkey, torture_get_testkey(SSH_KEYTYPE_ECDSA, 521, 0)); + snprintf(trusted_ca_pubkey, + sizeof(trusted_ca_pubkey), + "%s/sshd/user_ca.pub", + s->socket_dir); + torture_write_file(trusted_ca_pubkey, torture_rsa_certauth_pub); + assert_non_null(s->socket_dir); sftp_server = "/usr/lib/ssh/sftp-server"; @@ -910,6 +926,8 @@ static void torture_setup_create_sshd_config(void **state) "HostKey %s\n" "HostKey %s\n" "\n" + "TrustedUserCAKeys %s\n" + "\n" "LogLevel DEBUG3\n" "Subsystem sftp %s\n" "\n" @@ -947,6 +965,7 @@ static void torture_setup_create_sshd_config(void **state) dsa_hostkey, rsa_hostkey, ecdsa_hostkey, + trusted_ca_pubkey, sftp_server, s->srv_pidfile);