From: Rich Salz Date: Wed, 8 Jun 2016 15:37:06 +0000 (-0400) Subject: Add some accessor API's X-Git-Tag: OpenSSL_1_1_0-pre6~512 X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff_plain;h=e417070c9f2162594e8289aed93bd5801e70e60d Add some accessor API's GH1098: Add X509_get_pathlen() (and a test) GH1097: Add SSL_is_dtls() function. Documented. Reviewed-by: Matt Caswell --- diff --git a/.gitignore b/.gitignore index f572413294..b47a348bdd 100644 --- a/.gitignore +++ b/.gitignore @@ -84,6 +84,7 @@ Makefile /test/fips_test_suite /test/ssltest_old /test/x509aux +/test/v3ext *.so* *.dylib* *.dll* diff --git a/crypto/x509v3/v3_purp.c b/crypto/x509v3/v3_purp.c index b0d40ed84b..92a8b1d86a 100644 --- a/crypto/x509v3/v3_purp.c +++ b/crypto/x509v3/v3_purp.c @@ -838,3 +838,12 @@ const ASN1_OCTET_STRING *X509_get0_subject_key_id(X509 *x) X509_check_purpose(x, -1, -1); return x->skid; } + +long X509_get_pathlen(X509 *x) +{ + /* Called for side effect of caching extensions */ + if (X509_check_purpose(x, -1, -1) != 1 + || (x->ex_flags & EXFLAG_BCONS) == 0) + return -1; + return x->ex_pathlen; +} diff --git a/doc/crypto/X509_get_extension_flags.pod b/doc/crypto/X509_get_extension_flags.pod index a2a8a8c842..1452cc8a36 100644 --- a/doc/crypto/X509_get_extension_flags.pod +++ b/doc/crypto/X509_get_extension_flags.pod @@ -2,13 +2,15 @@ =head1 NAME +X509_get_pathlen, X509_get_extension_flags, X509_get_key_usage, X509_get_extended_key_usage - -retrieve certificate extension flags +retrieve certificate extension data =head1 SYNOPSIS #include + long X509_get_pathlen(X509 *x); uint32_t X509_get_extension_flags(X509 *x); uint32_t X509_get_key_usage(X509 *x); uint32_t X509_get_extended_key_usage(X509 *x); @@ -16,7 +18,11 @@ retrieve certificate extension flags =head1 DESCRIPTION -These functions retrieve flags related to commonly used certificate extensions. +These functions retrieve information related to commonly used certificate extensions. + +X509_get_pathlen() retrieves the path length extension from a certificate. +This extension is used to limit the length of a cert chain that may be +issued from that CA. X509_get_extension_flags() retrieves general information about a certificate, it will return one or more of the following flags ored together. @@ -115,6 +121,9 @@ X509_get_ext_d2i(). =head1 RETURN VALUE +X509_get_pathlen() returns the path length value, or -1 if the extension +is not present. + X509_get_extension_flags(), X509_get_key_usage() and X509_get_extended_key_usage() return sets of flags corresponding to the certificate extension values. @@ -127,6 +136,10 @@ is absent or an error occurred during parsing. L +=head1 HISTORY + +X509_get_pathlen() was added in OpenSSL 1.1.0. + =head1 COPYRIGHT Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. diff --git a/doc/ssl/SSL_get_version.pod b/doc/ssl/SSL_get_version.pod index 45e2f1d45b..8e26d43921 100644 --- a/doc/ssl/SSL_get_version.pod +++ b/doc/ssl/SSL_get_version.pod @@ -2,7 +2,7 @@ =head1 NAME -SSL_get_version - get the protocol version of a connection +SSL_get_version, SSL_is_dtls - get the protocol information of a connection =head1 SYNOPSIS @@ -10,14 +10,18 @@ SSL_get_version - get the protocol version of a connection const char *SSL_get_version(const SSL *ssl); + int SSL_is_dtls(const SSL *ssl); + =head1 DESCRIPTION SSL_get_version() returns the name of the protocol used for the connection B. +SSL_is_dtls() returns one if the connection is using DTLS, zero if not. + =head1 RETURN VALUES -The following strings can be returned: +SSL_get_verison() returns one of the following strings: =over 4 @@ -47,6 +51,10 @@ This indicates that no version has been set (no connection established). L +=head1 HISTORY + +SSL_is_dtls() was added in OpenSSL 1.1.0. + =head1 COPYRIGHT Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved. diff --git a/doc/ssl/ssl.pod b/doc/ssl/ssl.pod index 9a95019930..bc62489617 100644 --- a/doc/ssl/ssl.pod +++ b/doc/ssl/ssl.pod @@ -520,6 +520,8 @@ fresh handle for each connection. =item const char *B(const SSL *ssl); +=item int B(const SSL *ssl); + =item int B(const SSL *ssl, int *alg_bits); =item char *B(const SSL *ssl, int n); diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index 2c897c40c8..881c6bbd02 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -1457,6 +1457,7 @@ __owur int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const unsigned char *sid SSL *SSL_new(SSL_CTX *ctx); int SSL_up_ref(SSL *s); +int SSL_is_dtls(const SSL *s); __owur int SSL_set_session_id_context(SSL *ssl, const unsigned char *sid_ctx, unsigned int sid_ctx_len); diff --git a/include/openssl/x509.h b/include/openssl/x509.h index 93ded515ae..906184a5d8 100644 --- a/include/openssl/x509.h +++ b/include/openssl/x509.h @@ -504,6 +504,7 @@ int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey); EVP_PKEY *X509_PUBKEY_get0(X509_PUBKEY *key); EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key); int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain); +long X509_get_pathlen(X509 *x); int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp); EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length); # ifndef OPENSSL_NO_RSA diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index a6957b3e65..d4b8335906 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -671,6 +671,11 @@ SSL *SSL_new(SSL_CTX *ctx) return NULL; } +int SSL_is_dtls(const SSL *s) +{ + return SSL_IS_DTLS(s) ? 1 : 0; +} + int SSL_up_ref(SSL *s) { int i; diff --git a/test/build.info b/test/build.info index c74d71783a..e9228d0dce 100644 --- a/test/build.info +++ b/test/build.info @@ -11,7 +11,7 @@ IF[{- !$disabled{tests} -}] mdc2test rmdtest \ randtest dhtest enginetest casttest \ bftest ssltest_old dsatest exptest rsa_test \ - evp_test evp_extra_test igetest v3nametest \ + evp_test evp_extra_test igetest v3nametest v3ext \ danetest heartbeat_test p5_crpt2_test \ constant_time_test verify_extra_test clienthellotest \ packettest asynctest secmemtest srptest memleaktest \ @@ -163,6 +163,10 @@ IF[{- !$disabled{tests} -}] INCLUDE[v3nametest]="{- rel2abs(catdir($builddir,"../include")) -}" ../include DEPEND[v3nametest]=../libcrypto + SOURCE[v3ext]=v3ext.c + INCLUDE[v3ext]="{- rel2abs(catdir($builddir,"../include")) -}" ../include + DEPEND[v3ext]=../libcrypto + SOURCE[danetest]=danetest.c INCLUDE[danetest]="{- rel2abs(catdir($builddir,"../include")) -}" ../include DEPEND[danetest]=../libcrypto ../libssl diff --git a/test/certs/pathlen.pem b/test/certs/pathlen.pem new file mode 100644 index 0000000000..c0ef75e282 --- /dev/null +++ b/test/certs/pathlen.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDjTCCAnWgAwIBAgIBGzANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJVUzEf +MB0GA1UEChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEVMBMGA1UEAxMMVHJ1c3Qg +QW5jaG9yMB4XDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFowTjELMAkGA1UE +BhMCVVMxHzAdBgNVBAoTFlRlc3QgQ2VydGlmaWNhdGVzIDIwMTExHjAcBgNVBAMT +FXBhdGhMZW5Db25zdHJhaW50NiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAMhrG5ilLNK2JnW0V+GiT392lCKM4vUjPjAOxrg0mdIfK2AI1D9pgYUN +h5jXFarP18NT65fkskd/NPPSbEePcEzi0ZjOBqnaUFS+tA425QiWkqdld/q+r4H/ +1ZF/f6Cz6CrguSUDNPT1a0cmv1t7dlLnae1UTP9HiVBLNCTfabBaTN95vzM3dyVR +mcGYkT+ahiEgXDLYXuoWjqHjkz5Y8yd3+3TQ2IsyrmSN0NJCj4P/fC5sdpzFRDoB +FYCXsCL0gXVUsvfzn/ds1BUqxcHw6O4UUadhBj+Khuleq0forX+77bxFhUnZkGo5 +iO+EZhvr6t32d7IG/MKfXt5nb25jypMCAwEAAaN/MH0wHwYDVR0jBBgwFoAU5H1f +0VyVhggsBa6+dbZlp9ldqGYwHQYDVR0OBBYEFK+8ha7+TK7hjZcjiMilsWALuk7Y +MA4GA1UdDwEB/wQEAwIBBjAXBgNVHSAEEDAOMAwGCmCGSAFlAwIBMAEwEgYDVR0T +AQH/BAgwBgEB/wIBBjANBgkqhkiG9w0BAQsFAAOCAQEAMJCr70MBeik9uEqE4f27 +dR2O/kNaoqIOtzn+Y4PIzJGRspeGRjhkl4E+wafiPgHeyYCWIlO/R2E4BmI/ZNeD +xQCHbIVzPDHeSI7DD6F9N/atZ/b3L3J4VnfU8gFdNq1wsGqf1hxHcvdpLXLTU0LX +2j+th4jY/ogHv4kz3SHT7un1ktxQk2Rhb1u4PSBbQ6lI9oP4Jnda0jtakb1ZqhdZ +8N/sJvsfEQuqxss/jp+j70dmIGH/bDJfxU1oG0xdyi1xP2qjqdrWHI/mEVlygfXi +oxJ8JTfEcEHVsTffYR9fDUn0NylqCLdqFaDwLKqWl+C2inODNMpNusqleDAViw6B +CA== +-----END CERTIFICATE----- diff --git a/test/recipes/25-test_x509.t b/test/recipes/25-test_x509.t index 3ff187dda1..98a8d324e9 100644 --- a/test/recipes/25-test_x509.t +++ b/test/recipes/25-test_x509.t @@ -15,7 +15,7 @@ use OpenSSL::Test qw/:DEFAULT srctop_file/; setup("test_x509"); -plan tests => 4; +plan tests => 5; require_ok(srctop_file('test','recipes','tconversion.pl')); @@ -28,3 +28,7 @@ subtest 'x509 -- first x.509 v3 certificate' => sub { subtest 'x509 -- second x.509 v3 certificate' => sub { tconversion("x509", srctop_file("test","v3-cert2.pem")); }; + +subtest 'x509 -- pathlen' => sub { + ok(run(test(["v3ext", srctop_file("test/certs", "pathlen.pem")]))); +} diff --git a/test/v3ext.c b/test/v3ext.c new file mode 100644 index 0000000000..1c1f788a73 --- /dev/null +++ b/test/v3ext.c @@ -0,0 +1,42 @@ +/* + * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include + +int main(int ac, char **av) +{ + X509 *x = NULL; + BIO *b = NULL; + long pathlen; + int ret = 1; + + if (ac != 2) { + fprintf(stderr, "Usage error\n"); + goto end; + } + b = BIO_new_file(av[1], "r"); + if (b == NULL) + goto end; + x = PEM_read_bio_X509(b, NULL, NULL, NULL); + if (x == NULL) + goto end; + pathlen = X509_get_pathlen(x); + if (pathlen == 6) + ret = 0; + +end: + ERR_print_errors_fp(stderr); + BIO_free(b); + X509_free(x); + return ret; +} diff --git a/util/libcrypto.num b/util/libcrypto.num index 8c659c5dfb..a87fc252bc 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -4147,3 +4147,4 @@ X509_STORE_set_verify 4088 1_1_0 EXIST::FUNCTION: X509_OBJECT_new 4089 1_1_0 EXIST::FUNCTION: X509_STORE_get0_param 4090 1_1_0 EXIST::FUNCTION: PEM_write_bio_PrivateKey_traditional 4091 1_1_0 EXIST::FUNCTION: +X509_get_pathlen 4092 1_1_0 EXIST::FUNCTION: diff --git a/util/libssl.num b/util/libssl.num index 9ea918cb20..d023293808 100644 --- a/util/libssl.num +++ b/util/libssl.num @@ -395,3 +395,4 @@ SSL_CTX_get_ciphers 395 1_1_0 EXIST::FUNCTION: SSL_SESSION_get0_hostname 396 1_1_0 EXIST::FUNCTION: SSL_client_version 397 1_1_0 EXIST::FUNCTION: SSL_SESSION_get_protocol_version 398 1_1_0 EXIST::FUNCTION: +SSL_is_dtls 399 1_1_0 EXIST::FUNCTION: