summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Vrancken <dev@tomvrancken.nl>2019-08-27 17:10:04 +0200
committerTom Vrancken <dev@tomvrancken.nl>2019-10-04 23:33:16 +0200
commit6e9861f77b14aecd0c4e332dec7fd042ba3bc513 (patch)
treedd21b1465ec921c389248623575287d5c3777b97 /src
parent1bdcceac380cbfe4fa78b3dd3dc3513663fab972 (diff)
downloadgnutls-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.def58
-rw-r--r--src/serv.c49
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);