Selaa lähdekoodia

Merge branch 'thirdparty' into thirdparty_dev

Source commit: db597cd71c56c408ba8e678ac95a7e4003076c63
Martin Prikryl 3 vuotta sitten
vanhempi
sitoutus
fddb87bfc5

+ 13 - 0
libs/openssl/CHANGES

@@ -7,6 +7,19 @@
  https://github.com/openssl/openssl/commits/ and pick the appropriate
  https://github.com/openssl/openssl/commits/ and pick the appropriate
  release branch.
  release branch.
 
 
+ Changes between 1.1.1p and 1.1.1q [5 Jul 2022]
+
+  *) AES OCB mode for 32-bit x86 platforms using the AES-NI assembly optimised
+     implementation would not encrypt the entirety of the data under some
+     circumstances.  This could reveal sixteen bytes of data that was
+     preexisting in the memory that wasn't written.  In the special case of
+     "in place" encryption, sixteen bytes of the plaintext would be revealed.
+
+     Since OpenSSL does not support OCB based cipher suites for TLS and DTLS,
+     they are both unaffected.
+     (CVE-2022-2097)
+     [Alex Chernyakhovsky, David Benjamin, Alejandro Sedeño]
+
  Changes between 1.1.1o and 1.1.1p [21 Jun 2022]
  Changes between 1.1.1o and 1.1.1p [21 Jun 2022]
 
 
   *) In addition to the c_rehash shell command injection identified in
   *) In addition to the c_rehash shell command injection identified in

+ 5 - 0
libs/openssl/NEWS

@@ -5,6 +5,11 @@
   This file gives a brief overview of the major changes between each OpenSSL
   This file gives a brief overview of the major changes between each OpenSSL
   release. For more details please read the CHANGES file.
   release. For more details please read the CHANGES file.
 
 
+  Major changes between OpenSSL 1.1.1p and OpenSSL 1.1.1q [5 Jul 2022]
+
+      o Fixed AES OCB failure to encrypt some bytes on 32-bit x86 platforms
+        (CVE-2022-2097)
+
   Major changes between OpenSSL 1.1.1o and OpenSSL 1.1.1p [21 Jun 2022]
   Major changes between OpenSSL 1.1.1o and OpenSSL 1.1.1p [21 Jun 2022]
 
 
       o Fixed additional bugs in the c_rehash script which was not properly
       o Fixed additional bugs in the c_rehash script which was not properly

+ 1 - 1
libs/openssl/README

@@ -1,5 +1,5 @@
 
 
- OpenSSL 1.1.1p 21 Jun 2022
+ OpenSSL 1.1.1q 5 Jul 2022
 
 
  Copyright (c) 1998-2022 The OpenSSL Project
  Copyright (c) 1998-2022 The OpenSSL Project
  Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson
  Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson

+ 3 - 3
libs/openssl/crypto/aes/asm/aesni-x86.pl

@@ -1,5 +1,5 @@
 #! /usr/bin/env perl
 #! /usr/bin/env perl
-# Copyright 2009-2020 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2009-2022 The OpenSSL Project Authors. All Rights Reserved.
 #
 #
 # Licensed under the OpenSSL license (the "License").  You may not use
 # Licensed under the OpenSSL license (the "License").  You may not use
 # this file except in compliance with the License.  You can obtain a copy
 # this file except in compliance with the License.  You can obtain a copy
@@ -2027,7 +2027,7 @@ my ($l_,$block,$i1,$i3,$i5) = ($rounds_,$key_,$rounds,$len,$out);
 	&movdqu		(&QWP(-16*2,$out,$inp),$inout4);
 	&movdqu		(&QWP(-16*2,$out,$inp),$inout4);
 	&movdqu		(&QWP(-16*1,$out,$inp),$inout5);
 	&movdqu		(&QWP(-16*1,$out,$inp),$inout5);
 	&cmp		($inp,$len);			# done yet?
 	&cmp		($inp,$len);			# done yet?
-	&jb		(&label("grandloop"));
+	&jbe		(&label("grandloop"));
 
 
 &set_label("short");
 &set_label("short");
 	&add		($len,16*6);
 	&add		($len,16*6);
@@ -2453,7 +2453,7 @@ my ($l_,$block,$i1,$i3,$i5) = ($rounds_,$key_,$rounds,$len,$out);
 	&pxor		($rndkey1,$inout5);
 	&pxor		($rndkey1,$inout5);
 	&movdqu		(&QWP(-16*1,$out,$inp),$inout5);
 	&movdqu		(&QWP(-16*1,$out,$inp),$inout5);
 	&cmp		($inp,$len);			# done yet?
 	&cmp		($inp,$len);			# done yet?
-	&jb		(&label("grandloop"));
+	&jbe		(&label("grandloop"));
 
 
 &set_label("short");
 &set_label("short");
 	&add		($len,16*6);
 	&add		($len,16*6);

+ 5 - 3
libs/openssl/crypto/bn/bn_gcd.c

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
  *
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
  * this file except in compliance with the License.  You can obtain a copy
@@ -47,7 +47,8 @@ BIGNUM *bn_mod_inverse_no_branch(BIGNUM *in,
     if (R == NULL)
     if (R == NULL)
         goto err;
         goto err;
 
 
-    BN_one(X);
+    if (!BN_one(X))
+        goto err;
     BN_zero(Y);
     BN_zero(Y);
     if (BN_copy(B, a) == NULL)
     if (BN_copy(B, a) == NULL)
         goto err;
         goto err;
@@ -235,7 +236,8 @@ BIGNUM *int_bn_mod_inverse(BIGNUM *in,
     if (R == NULL)
     if (R == NULL)
         goto err;
         goto err;
 
 
-    BN_one(X);
+    if (!BN_one(X))
+        goto err;
     BN_zero(Y);
     BN_zero(Y);
     if (BN_copy(B, a) == NULL)
     if (BN_copy(B, a) == NULL)
         goto err;
         goto err;

+ 2 - 2
libs/openssl/crypto/ec/ec_asn1.c

@@ -794,7 +794,7 @@ EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params)
     }
     }
 
 
     /* extract the order */
     /* extract the order */
-    if ((a = ASN1_INTEGER_to_BN(params->order, a)) == NULL) {
+    if (ASN1_INTEGER_to_BN(params->order, a) == NULL) {
         ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_ASN1_LIB);
         ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_ASN1_LIB);
         goto err;
         goto err;
     }
     }
@@ -811,7 +811,7 @@ EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params)
     if (params->cofactor == NULL) {
     if (params->cofactor == NULL) {
         BN_free(b);
         BN_free(b);
         b = NULL;
         b = NULL;
-    } else if ((b = ASN1_INTEGER_to_BN(params->cofactor, b)) == NULL) {
+    } else if (ASN1_INTEGER_to_BN(params->cofactor, b) == NULL) {
         ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_ASN1_LIB);
         ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_ASN1_LIB);
         goto err;
         goto err;
     }
     }

+ 13 - 3
libs/openssl/crypto/x509v3/v3_addr.c

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved.
  *
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
  * this file except in compliance with the License.  You can obtain a copy
@@ -13,6 +13,8 @@
 
 
 #include <stdio.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdlib.h>
+#include <assert.h>
+#include <string.h>
 
 
 #include "internal/cryptlib.h"
 #include "internal/cryptlib.h"
 #include <openssl/conf.h>
 #include <openssl/conf.h>
@@ -342,8 +344,13 @@ static int range_should_be_prefix(const unsigned char *min,
     unsigned char mask;
     unsigned char mask;
     int i, j;
     int i, j;
 
 
-    if (memcmp(min, max, length) <= 0)
-        return -1;
+    /*
+     * It is the responsibility of the caller to confirm min <= max. We don't
+     * use ossl_assert() here since we have no way of signalling an error from
+     * this function - so we just use a plain assert instead.
+     */
+    assert(memcmp(min, max, length) <= 0);
+
     for (i = 0; i < length && min[i] == max[i]; i++) ;
     for (i = 0; i < length && min[i] == max[i]; i++) ;
     for (j = length - 1; j >= 0 && min[j] == 0x00 && max[j] == 0xFF; j--) ;
     for (j = length - 1; j >= 0 && min[j] == 0x00 && max[j] == 0xFF; j--) ;
     if (i < j)
     if (i < j)
@@ -426,6 +433,9 @@ static int make_addressRange(IPAddressOrRange **result,
     IPAddressOrRange *aor;
     IPAddressOrRange *aor;
     int i, prefixlen;
     int i, prefixlen;
 
 
+    if (memcmp(min, max, length) > 0)
+        return 0;
+
     if ((prefixlen = range_should_be_prefix(min, max, length)) >= 0)
     if ((prefixlen = range_should_be_prefix(min, max, length)) >= 0)
         return make_addressPrefix(result, min, prefixlen);
         return make_addressPrefix(result, min, prefixlen);
 
 

+ 2 - 0
libs/openssl/crypto/x509v3/v3_sxnet.c

@@ -78,6 +78,8 @@ static int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out,
     for (i = 0; i < sk_SXNETID_num(sx->ids); i++) {
     for (i = 0; i < sk_SXNETID_num(sx->ids); i++) {
         id = sk_SXNETID_value(sx->ids, i);
         id = sk_SXNETID_value(sx->ids, i);
         tmp = i2s_ASN1_INTEGER(NULL, id->zone);
         tmp = i2s_ASN1_INTEGER(NULL, id->zone);
+        if (tmp == NULL)
+            return 0;
         BIO_printf(out, "\n%*sZone: %s, User: ", indent, "", tmp);
         BIO_printf(out, "\n%*sZone: %s, User: ", indent, "", tmp);
         OPENSSL_free(tmp);
         OPENSSL_free(tmp);
         ASN1_STRING_print(out, id->user);
         ASN1_STRING_print(out, id->user);

+ 3 - 3
libs/openssl/doc/man3/SSL_get_current_cipher.pod

@@ -10,8 +10,8 @@ SSL_get_pending_cipher - get SSL_CIPHER of a connection
 
 
  #include <openssl/ssl.h>
  #include <openssl/ssl.h>
 
 
- SSL_CIPHER *SSL_get_current_cipher(const SSL *ssl);
- SSL_CIPHER *SSL_get_pending_cipher(const SSL *ssl);
+ const SSL_CIPHER *SSL_get_current_cipher(const SSL *ssl);
+ const SSL_CIPHER *SSL_get_pending_cipher(const SSL *ssl);
 
 
  const char *SSL_get_cipher_name(const SSL *s);
  const char *SSL_get_cipher_name(const SSL *s);
  const char *SSL_get_cipher(const SSL *s);
  const char *SSL_get_cipher(const SSL *s);
@@ -61,7 +61,7 @@ L<ssl(7)>, L<SSL_CIPHER_get_name(3)>
 
 
 =head1 COPYRIGHT
 =head1 COPYRIGHT
 
 
-Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2000-2022 The OpenSSL Project Authors. All Rights Reserved.
 
 
 Licensed under the OpenSSL license (the "License").  You may not use
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
 this file except in compliance with the License.  You can obtain a copy

+ 2 - 2
libs/openssl/include/openssl/opensslv.h

@@ -39,8 +39,8 @@ extern "C" {
  * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
  * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
  *  major minor fix final patch/beta)
  *  major minor fix final patch/beta)
  */
  */
-# define OPENSSL_VERSION_NUMBER  0x1010110fL
-# define OPENSSL_VERSION_TEXT    "OpenSSL 1.1.1p  21 Jun 2022"
+# define OPENSSL_VERSION_NUMBER  0x1010111fL
+# define OPENSSL_VERSION_TEXT    "OpenSSL 1.1.1q  5 Jul 2022"
 
 
 /*-
 /*-
  * The macros below are to be used for shared library (.so, .dll, ...)
  * The macros below are to be used for shared library (.so, .dll, ...)

+ 51 - 1
libs/openssl/test/recipes/30-test_evp_data/evpciph.txt

@@ -1,5 +1,5 @@
 #
 #
-# Copyright 2001-2019 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2001-2022 The OpenSSL Project Authors. All Rights Reserved.
 #
 #
 # Licensed under the OpenSSL license (the "License").  You may not use
 # Licensed under the OpenSSL license (the "License").  You may not use
 # this file except in compliance with the License.  You can obtain a copy
 # this file except in compliance with the License.  You can obtain a copy
@@ -1188,6 +1188,56 @@ Ciphertext = 09A4FD29DE949D9A9AA9924248422097AD4883B4713E6C214FF6567ADA08A967B21
 Operation = DECRYPT
 Operation = DECRYPT
 Result = CIPHERFINAL_ERROR
 Result = CIPHERFINAL_ERROR
 
 
+#Test vectors generated to validate aesni_ocb_encrypt on x86
+Cipher = aes-128-ocb
+Key = 000102030405060708090A0B0C0D0E0F
+IV = 000000000001020304050607
+Tag = C14DFF7D62A13C4A3422456207453190
+Plaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
+Ciphertext = F5186C9CC3506386919B6FD9443956E05B203313F8AB35E916AB36932EBDDCD2945901BABE7CF29404929F322F954C916065FABF8F1E52F4BD7C538C0F96899519DBC6BC504D837D8EBD1436B45D33F528CB642FA2EB2C403FE604C12B819333
+
+Cipher = aes-128-ocb
+Key = 000102030405060708090A0B0C0D0E0F
+IV = 000000000001020304050607
+Tag = D47D84F6FF912C79B6A4223AB9BE2DB8
+Plaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F
+Ciphertext = F5186C9CC3506386919B6FD9443956E05B203313F8AB35E916AB36932EBDDCD2945901BABE7CF29404929F322F954C916065FABF8F1E52F4BD7C538C0F96899519DBC6BC504D837D8EBD1436B45D33F528CB642FA2EB2C403FE604C12B8193332374120A78A1171D23ED9E9CB1ADC204
+
+Cipher = aes-128-ocb
+Key = 000102030405060708090A0B0C0D0E0F
+IV = 000000000001020304050607
+Tag = 41970D13737B7BD1B5FBF49ED4412CA5
+Plaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F7071000102030405060708090A0B0C0D
+Ciphertext = F5186C9CC3506386919B6FD9443956E05B203313F8AB35E916AB36932EBDDCD2945901BABE7CF29404929F322F954C916065FABF8F1E52F4BD7C538C0F96899519DBC6BC504D837D8EBD1436B45D33F528CB642FA2EB2C403FE604C12B8193332374120A78A1171D23ED9E9CB1ADC20412C017AD0CA498827C768DDD99B26E91
+
+Cipher = aes-128-ocb
+Key = 000102030405060708090A0B0C0D0E0F
+IV = 000000000001020304050607
+Tag = BE0228651ED4E48A11BDED68D953F3A0
+Plaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F7071000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D
+Ciphertext = F5186C9CC3506386919B6FD9443956E05B203313F8AB35E916AB36932EBDDCD2945901BABE7CF29404929F322F954C916065FABF8F1E52F4BD7C538C0F96899519DBC6BC504D837D8EBD1436B45D33F528CB642FA2EB2C403FE604C12B8193332374120A78A1171D23ED9E9CB1ADC20412C017AD0CA498827C768DDD99B26E91EDB8681700FF30366F07AEDE8CEACC1F
+
+Cipher = aes-128-ocb
+Key = 000102030405060708090A0B0C0D0E0F
+IV = 000000000001020304050607
+Tag = 17BC6E10B16E5FDC52836E7D589518C7
+Plaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F7071000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D
+Ciphertext = F5186C9CC3506386919B6FD9443956E05B203313F8AB35E916AB36932EBDDCD2945901BABE7CF29404929F322F954C916065FABF8F1E52F4BD7C538C0F96899519DBC6BC504D837D8EBD1436B45D33F528CB642FA2EB2C403FE604C12B8193332374120A78A1171D23ED9E9CB1ADC20412C017AD0CA498827C768DDD99B26E91EDB8681700FF30366F07AEDE8CEACC1F39BE69B91BC808FA7A193F7EEA43137B
+
+Cipher = aes-128-ocb
+Key = 000102030405060708090A0B0C0D0E0F
+IV = 000000000001020304050607
+Tag = E84AAC18666116990A3A37B3A5FC55BD
+Plaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F7071000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D
+Ciphertext = F5186C9CC3506386919B6FD9443956E05B203313F8AB35E916AB36932EBDDCD2945901BABE7CF29404929F322F954C916065FABF8F1E52F4BD7C538C0F96899519DBC6BC504D837D8EBD1436B45D33F528CB642FA2EB2C403FE604C12B8193332374120A78A1171D23ED9E9CB1ADC20412C017AD0CA498827C768DDD99B26E91EDB8681700FF30366F07AEDE8CEACC1F39BE69B91BC808FA7A193F7EEA43137B11CF99263D693AEBDF8ADE1A1D838DED
+
+Cipher = aes-128-ocb
+Key = 000102030405060708090A0B0C0D0E0F
+IV = 000000000001020304050607
+Tag = 3E5EA7EE064FE83B313E28D411E91EAD
+Plaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F7071000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D
+Ciphertext = F5186C9CC3506386919B6FD9443956E05B203313F8AB35E916AB36932EBDDCD2945901BABE7CF29404929F322F954C916065FABF8F1E52F4BD7C538C0F96899519DBC6BC504D837D8EBD1436B45D33F528CB642FA2EB2C403FE604C12B8193332374120A78A1171D23ED9E9CB1ADC20412C017AD0CA498827C768DDD99B26E91EDB8681700FF30366F07AEDE8CEACC1F39BE69B91BC808FA7A193F7EEA43137B11CF99263D693AEBDF8ADE1A1D838DED48D9E09F452F8E6FBEB76A3DED47611C
+
 Title = AES XTS test vectors from IEEE Std 1619-2007
 Title = AES XTS test vectors from IEEE Std 1619-2007
 
 
 # Using the same key twice for encryption is always banned.
 # Using the same key twice for encryption is always banned.

+ 115 - 0
libs/openssl/test/v3ext.c

@@ -12,6 +12,7 @@
 #include <openssl/x509v3.h>
 #include <openssl/x509v3.h>
 #include <openssl/pem.h>
 #include <openssl/pem.h>
 #include <openssl/err.h>
 #include <openssl/err.h>
+#include "internal/nelem.h"
 
 
 #include "testutil.h"
 #include "testutil.h"
 
 
@@ -37,6 +38,7 @@ end:
     return ret;
     return ret;
 }
 }
 
 
+#ifndef OPENSSL_NO_RFC3779
 static int test_asid(void)
 static int test_asid(void)
 {
 {
     ASN1_INTEGER *val1 = NULL, *val2 = NULL;
     ASN1_INTEGER *val1 = NULL, *val2 = NULL;
@@ -114,12 +116,125 @@ static int test_asid(void)
     return testresult;
     return testresult;
 }
 }
 
 
+static struct ip_ranges_st {
+    const unsigned int afi;
+    const char *ip1;
+    const char *ip2;
+    int rorp;
+} ranges[] = {
+    { IANA_AFI_IPV4, "192.168.0.0", "192.168.0.1", IPAddressOrRange_addressPrefix},
+    { IANA_AFI_IPV4, "192.168.0.0", "192.168.0.2", IPAddressOrRange_addressRange},
+    { IANA_AFI_IPV4, "192.168.0.0", "192.168.0.3", IPAddressOrRange_addressPrefix},
+    { IANA_AFI_IPV4, "192.168.0.0", "192.168.0.254", IPAddressOrRange_addressRange},
+    { IANA_AFI_IPV4, "192.168.0.0", "192.168.0.255", IPAddressOrRange_addressPrefix},
+    { IANA_AFI_IPV4, "192.168.0.1", "192.168.0.255", IPAddressOrRange_addressRange},
+    { IANA_AFI_IPV4, "192.168.0.1", "192.168.0.1", IPAddressOrRange_addressPrefix},
+    { IANA_AFI_IPV4, "192.168.0.0", "192.168.255.255", IPAddressOrRange_addressPrefix},
+    { IANA_AFI_IPV4, "192.168.1.0", "192.168.255.255", IPAddressOrRange_addressRange},
+    { IANA_AFI_IPV6, "2001:0db8::0", "2001:0db8::1", IPAddressOrRange_addressPrefix},
+    { IANA_AFI_IPV6, "2001:0db8::0", "2001:0db8::2", IPAddressOrRange_addressRange},
+    { IANA_AFI_IPV6, "2001:0db8::0", "2001:0db8::3", IPAddressOrRange_addressPrefix},
+    { IANA_AFI_IPV6, "2001:0db8::0", "2001:0db8::fffe", IPAddressOrRange_addressRange},
+    { IANA_AFI_IPV6, "2001:0db8::0", "2001:0db8::ffff", IPAddressOrRange_addressPrefix},
+    { IANA_AFI_IPV6, "2001:0db8::1", "2001:0db8::ffff", IPAddressOrRange_addressRange},
+    { IANA_AFI_IPV6, "2001:0db8::1", "2001:0db8::1", IPAddressOrRange_addressPrefix},
+    { IANA_AFI_IPV6, "2001:0db8::0:0", "2001:0db8::ffff:ffff", IPAddressOrRange_addressPrefix},
+    { IANA_AFI_IPV6, "2001:0db8::1:0", "2001:0db8::ffff:ffff", IPAddressOrRange_addressRange}
+};
+
+static int check_addr(IPAddrBlocks *addr, int type)
+{
+    IPAddressFamily *fam;
+    IPAddressOrRange *aorr;
+
+    if (!TEST_int_eq(sk_IPAddressFamily_num(addr), 1))
+        return 0;
+
+    fam = sk_IPAddressFamily_value(addr, 0);
+    if (!TEST_ptr(fam))
+        return 0;
+
+    if (!TEST_int_eq(fam->ipAddressChoice->type, IPAddressChoice_addressesOrRanges))
+        return 0;
+
+    if (!TEST_int_eq(sk_IPAddressOrRange_num(fam->ipAddressChoice->u.addressesOrRanges), 1))
+        return 0;
+
+    aorr = sk_IPAddressOrRange_value(fam->ipAddressChoice->u.addressesOrRanges, 0);
+    if (!TEST_ptr(aorr))
+        return 0;
+
+    if (!TEST_int_eq(aorr->type, type))
+        return 0;
+
+    return 1;
+}
+
+static int test_addr_ranges(void)
+{
+    IPAddrBlocks *addr = NULL;
+    ASN1_OCTET_STRING *ip1 = NULL, *ip2 = NULL;
+    size_t i;
+    int testresult = 0;
+
+    for (i = 0; i < OSSL_NELEM(ranges); i++) {
+        addr = sk_IPAddressFamily_new_null();
+        if (!TEST_ptr(addr))
+            goto end;
+        /*
+         * Has the side effect of installing the comparison function onto the
+         * stack.
+         */
+        if (!TEST_true(X509v3_addr_canonize(addr)))
+            goto end;
+
+        ip1 = a2i_IPADDRESS(ranges[i].ip1);
+        if (!TEST_ptr(ip1))
+            goto end;
+        if (!TEST_true(ip1->length == 4 || ip1->length == 16))
+            goto end;
+        ip2 = a2i_IPADDRESS(ranges[i].ip2);
+        if (!TEST_ptr(ip2))
+            goto end;
+        if (!TEST_int_eq(ip2->length, ip1->length))
+            goto end;
+        if (!TEST_true(memcmp(ip1->data, ip2->data, ip1->length) <= 0))
+            goto end;
+
+        if (!TEST_true(X509v3_addr_add_range(addr, ranges[i].afi, NULL, ip1->data, ip2->data)))
+            goto end;
+
+        if (!TEST_true(X509v3_addr_is_canonical(addr)))
+            goto end;
+
+        if (!check_addr(addr, ranges[i].rorp))
+            goto end;
+
+        sk_IPAddressFamily_pop_free(addr, IPAddressFamily_free);
+        addr = NULL;
+        ASN1_OCTET_STRING_free(ip1);
+        ASN1_OCTET_STRING_free(ip2);
+        ip1 = ip2 = NULL;
+    }
+
+    testresult = 1;
+ end:
+    sk_IPAddressFamily_pop_free(addr, IPAddressFamily_free);
+    ASN1_OCTET_STRING_free(ip1);
+    ASN1_OCTET_STRING_free(ip2);
+    return testresult;
+}
+#endif /* OPENSSL_NO_RFC3779 */
+
 int setup_tests(void)
 int setup_tests(void)
 {
 {
     if (!TEST_ptr(infile = test_get_argument(0)))
     if (!TEST_ptr(infile = test_get_argument(0)))
         return 0;
         return 0;
 
 
     ADD_TEST(test_pathlen);
     ADD_TEST(test_pathlen);
+#ifndef OPENSSL_NO_RFC3779
     ADD_TEST(test_asid);
     ADD_TEST(test_asid);
+    ADD_TEST(test_addr_ranges);
+#endif /* OPENSSL_NO_RFC3779 */
     return 1;
     return 1;
 }
 }