diff options
author | Tom Vrancken <dev@tomvrancken.nl> | 2019-08-27 17:10:04 +0200 |
---|---|---|
committer | Tom Vrancken <dev@tomvrancken.nl> | 2019-10-04 23:33:16 +0200 |
commit | 6e9861f77b14aecd0c4e332dec7fd042ba3bc513 (patch) | |
tree | dd21b1465ec921c389248623575287d5c3777b97 /src | |
parent | 1bdcceac380cbfe4fa78b3dd3dc3513663fab972 (diff) | |
download | gnutls-6e9861f77b14aecd0c4e332dec7fd042ba3bc513.tar.gz |
Implemented raw public key support for gnutls-serv application.
Signed-off-by: Tom Vrancken <dev@tomvrancken.nl>
Diffstat (limited to 'src')
-rw-r--r-- | src/serv-args.def | 58 | ||||
-rw-r--r-- | src/serv.c | 49 |
2 files changed, 101 insertions, 6 deletions
diff --git a/src/serv-args.def b/src/serv-args.def index a2e9d1c6f8..996fbe36ba 100644 --- a/src/serv-args.def +++ b/src/serv-args.def @@ -250,6 +250,45 @@ flag = { }; flag = { + name = rawpkkeyfile; + arg-type = string; + descrip = "Private key file (PKCS #8 or PKCS #12) or PKCS #11 URL to use"; + doc = "Specify the private key file or URI to use; it must correspond to +the raw public-key specified in --rawpkfile. Multiple key pairs +can be specified with this option and in that case each occurrence of keyfile +must be followed by the corresponding rawpkfile or vice-versa. + +In order to instruct the application to negotiate raw public keys one +must enable the respective certificate types via the priority strings (i.e. CTYPE-CLI-* +and CTYPE-SRV-* flags). + +Check the GnuTLS manual on section ``Priority strings'' for more +information on how to set certificate types."; + stack-arg; + max = NOLIMIT; +}; + +flag = { + name = rawpkfile; + arg-type = string; + descrip = "Raw public-key file to use"; + doc = "Specify the raw public-key file to use; it must correspond to +the private key specified in --rawpkkeyfile. Multiple key pairs +can be specified with this option and in that case each occurrence of keyfile +must be followed by the corresponding rawpkfile or vice-versa. + +In order to instruct the application to negotiate raw public keys one +must enable the respective certificate types via the priority strings (i.e. CTYPE-CLI-* +and CTYPE-SRV-* flags). + +Check the GnuTLS manual on section ``Priority strings'' for more +information on how to set certificate types."; + stack-arg; + max = NOLIMIT; + flags-must = rawpkkeyfile; +}; + +flag = { name = srppasswd; arg-type = file; file-exists = yes; @@ -478,11 +517,24 @@ gnutls-serv --http --priority NORMAL:+ECDHE-PSK:+PSK \ --pskpasswd psk-passwd.txt @end example +If you want a server with support for raw public-keys we can also add these +credentials. Note however that there is no identity information linked to these +keys as is the case with regular x509 certificates. Authentication must be done +via different means. Also we need to explicitly enable raw public-key certificates +via the priority strings. + +@example +gnutls-serv --http --priority NORMAL:+CTYPE-CLI-RAWPK:+CTYPE-SRV-RAWPK \ + --rawpkfile srv.rawpk.pem \ + --rawpkkeyfile srv.key.pem +@end example + + Finally, we start the server with all the earlier parameters and you get this command: @example -gnutls-serv --http --priority NORMAL:+PSK:+SRP \ +gnutls-serv --http --priority NORMAL:+PSK:+SRP:+CTYPE-CLI-RAWPK:+CTYPE-SRV-RAWPK \ --x509cafile x509-ca.pem \ --x509keyfile x509-server-key.pem \ --x509certfile x509-server.pem \ @@ -490,7 +542,9 @@ gnutls-serv --http --priority NORMAL:+PSK:+SRP \ --x509certfile x509-server-ecc.pem \ --srppasswdconf srp-tpasswd.conf \ --srppasswd srp-passwd.txt \ - --pskpasswd psk-passwd.txt + --pskpasswd psk-passwd.txt \ + --rawpkfile srv.rawpk.pem \ + --rawpkkeyfile srv.key.pem @end example _EOF_; }; diff --git a/src/serv.c b/src/serv.c index cc68abb509..60b02f6983 100644 --- a/src/serv.c +++ b/src/serv.c @@ -76,6 +76,10 @@ const char *x509_cafile = NULL; const char *dh_params_file = NULL; const char *x509_crlfile = NULL; const char *priorities = NULL; +const char **rawpk_keyfile = NULL; +const char **rawpk_file = NULL; +unsigned rawpk_keyfile_size = 0; +unsigned rawpk_file_size = 0; const char **ocsp_responses = NULL; unsigned ocsp_responses_size = 0; @@ -382,7 +386,7 @@ gnutls_session_t initialize_session(int dtls) const char *err; gnutls_datum_t alpn[MAX_ALPN_PROTOCOLS]; unsigned alpn_size; - unsigned flags = GNUTLS_SERVER | GNUTLS_POST_HANDSHAKE_AUTH; + unsigned flags = GNUTLS_SERVER | GNUTLS_POST_HANDSHAKE_AUTH | GNUTLS_ENABLE_RAWPK; if (dtls) flags |= GNUTLS_DATAGRAM; @@ -556,7 +560,7 @@ static char *peer_print_info(gnutls_session_t session, int *ret_length, return http_buffer; } - if (gnutls_certificate_type_get(session) == GNUTLS_CRT_X509) { + if (gnutls_certificate_type_get2(session, GNUTLS_CTYPE_CLIENT) == GNUTLS_CRT_X509) { const gnutls_datum_t *cert_list; unsigned int cert_list_size = 0; @@ -675,10 +679,10 @@ static char *peer_print_info(gnutls_session_t session, int *ret_length, } if (gnutls_auth_get_type(session) == GNUTLS_CRD_CERTIFICATE && - gnutls_certificate_type_get(session) != GNUTLS_CRT_X509) { + gnutls_certificate_type_get2(session, GNUTLS_CTYPE_CLIENT) != GNUTLS_CRT_X509) { tmp = gnutls_certificate_type_get_name - (gnutls_certificate_type_get(session)); + (gnutls_certificate_type_get2(session, GNUTLS_CTYPE_CLIENT)); if (tmp == NULL) tmp = str_unknown; snprintf(tmp_buffer, tmp_buffer_size, @@ -1178,6 +1182,7 @@ int main(int argc, char **argv) exit(1); } + /* X509 credentials */ if (x509_cafile != NULL) { if ((ret = gnutls_certificate_set_x509_trust_file (cert_cred, x509_cafile, x509ctype)) < 0) { @@ -1215,6 +1220,25 @@ int main(int argc, char **argv) cert_set = 1; } } + + /* Raw public-key credentials */ + if (rawpk_file_size > 0 && rawpk_keyfile_size > 0) { + for (i = 0; i < rawpk_keyfile_size; i++) { + ret = gnutls_certificate_set_rawpk_key_file(cert_cred, rawpk_file[i], + rawpk_keyfile[i], + x509ctype, + NULL, 0, NULL, 0, + 0, 0); + if (ret < 0) { + fprintf(stderr, "Error reading '%s' or '%s'\n", + rawpk_file[i], rawpk_keyfile[i]); + GERR(ret); + exit(1); + } else { + cert_set = 1; + } + } + } if (cert_set == 0) { fprintf(stderr, @@ -1808,12 +1832,29 @@ static void cmd_parser(int argc, char **argv) if (x509_certfile_size != x509_keyfile_size) { fprintf(stderr, "The certificate number provided (%u) doesn't match the keys (%u)\n", x509_certfile_size, x509_keyfile_size); + exit(1); } if (HAVE_OPT(X509CAFILE)) x509_cafile = OPT_ARG(X509CAFILE); if (HAVE_OPT(X509CRLFILE)) x509_crlfile = OPT_ARG(X509CRLFILE); + + if (HAVE_OPT(RAWPKKEYFILE)) { + rawpk_keyfile = STACKLST_OPT(RAWPKKEYFILE); + rawpk_keyfile_size = STACKCT_OPT(RAWPKKEYFILE); + } + + if (HAVE_OPT(RAWPKFILE)) { + rawpk_file = STACKLST_OPT(RAWPKFILE); + rawpk_file_size = STACKCT_OPT(RAWPKFILE); + } + + if (rawpk_file_size != rawpk_keyfile_size) { + fprintf(stderr, "The number of raw public-keys provided (%u) doesn't match the number of corresponding private keys (%u)\n", + rawpk_file_size, rawpk_keyfile_size); + exit(1); + } if (HAVE_OPT(SRPPASSWD)) srp_passwd = OPT_ARG(SRPPASSWD); |