Add some accessor API's
authorRich Salz <rsalz@openssl.org>
Wed, 8 Jun 2016 15:37:06 +0000 (11:37 -0400)
committerRich Salz <rsalz@openssl.org>
Wed, 8 Jun 2016 15:37:06 +0000 (11:37 -0400)
GH1098: Add X509_get_pathlen() (and a test)
GH1097:  Add SSL_is_dtls() function.

Documented.

Reviewed-by: Matt Caswell <matt@openssl.org>
14 files changed:
.gitignore
crypto/x509v3/v3_purp.c
doc/crypto/X509_get_extension_flags.pod
doc/ssl/SSL_get_version.pod
doc/ssl/ssl.pod
include/openssl/ssl.h
include/openssl/x509.h
ssl/ssl_lib.c
test/build.info
test/certs/pathlen.pem [new file with mode: 0644]
test/recipes/25-test_x509.t
test/v3ext.c [new file with mode: 0644]
util/libcrypto.num
util/libssl.num

index f5724132946ec8011bca4f95cb2a9d721b0a374a..b47a348bdd37ea825c90b4aa5888b28fdbd815a7 100644 (file)
@@ -84,6 +84,7 @@ Makefile
 /test/fips_test_suite
 /test/ssltest_old
 /test/x509aux
+/test/v3ext
 *.so*
 *.dylib*
 *.dll*
index b0d40ed84bb14c396587cf3b822d7aaf3eacef6b..92a8b1d86a79722b75a59fec62c93e4a0bc8c42b 100644 (file)
@@ -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;
+}
index a2a8a8c84290385ccaf398dbacef364ce41da0c3..1452cc8a36253062a671c32b627e828eb5ba4188 100644 (file)
@@ -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 <openssl/x509v3.h>
 
+   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<X509_check_purpose(3)>
 
+=head1 HISTORY
+
+X509_get_pathlen() was added in OpenSSL 1.1.0.
+
 =head1 COPYRIGHT
 
 Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
index 45e2f1d45b4573553bfe61c845fe78e07f71ab73..8e26d439215be8ada8f2264b563b87cb9cae288b 100644 (file)
@@ -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>.
 
+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<ssl(3)>
 
+=head1 HISTORY
+
+SSL_is_dtls() was added in OpenSSL 1.1.0.
+
 =head1 COPYRIGHT
 
 Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
index 9a95019930d49d9ee0335edd8604a6e61217eea3..bc62489617b7043e2a25e45d649a2e4ca91cd133 100644 (file)
@@ -520,6 +520,8 @@ fresh handle for each connection.
 
 =item const char *B<SSL_get_cipher>(const SSL *ssl);
 
+=item int B<SSL_is_dtls>(const SSL *ssl);
+
 =item int B<SSL_get_cipher_bits>(const SSL *ssl, int *alg_bits);
 
 =item char *B<SSL_get_cipher_list>(const SSL *ssl, int n);
index 2c897c40c8a5309a772b15676c943c6fda491120..881c6bbd0262467d569cbb9f4952ee2d32dd9818 100644 (file)
@@ -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);
 
index 93ded515ae5e75e98e1b6fec12f71abc48365007..906184a5d841ccc5859d2087ee72bc7d92883766 100644 (file)
@@ -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
index a6957b3e65b99811d209b1beb67513cf4e2e8c7c..d4b83359061e2fb5c73237c24a7b69f3cde9b288 100644 (file)
@@ -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;
index c74d71783aa6bc6bec67bfddc5fb6fe087b3a257..e9228d0dced8c9858acd358ba9dcd18cfd1b89ef 100644 (file)
@@ -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 (file)
index 0000000..c0ef75e
--- /dev/null
@@ -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-----
index 3ff187dda1815b87a54734c380cebf4d77766994..98a8d324e9cf729bd3af25a381368d32cd5658f3 100644 (file)
@@ -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 (file)
index 0000000..1c1f788
--- /dev/null
@@ -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 <stdio.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/pem.h>
+#include <openssl/err.h>
+
+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;
+}
index 8c659c5dfb2cc0570dff648aa3cad0920b535394..a87fc252bc556abb1c1fdc2eb28ae6e859da2b29 100644 (file)
@@ -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:
index 9ea918cb20fd5fb6a916f60a7521bacc9d27a8f9..d023293808c73bba456079a3c2e4787de1ed06f6 100644 (file)
@@ -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: