diff --git a/backport-APPS-x509-With-CA-but-both-CAserial-and-CAcreateseri.patch b/backport-APPS-x509-With-CA-but-both-CAserial-and-CAcreateseri.patch new file mode 100644 index 0000000000000000000000000000000000000000..63c03f236119a85a9925a328f2f25c9931e850bb --- /dev/null +++ b/backport-APPS-x509-With-CA-but-both-CAserial-and-CAcreateseri.patch @@ -0,0 +1,187 @@ +From 55eafed6fbefbc1e725bf7b17b2bbca083a457fc Mon Sep 17 00:00:00 2001 +From: "Dr. David von Oheimb" +Date: Mon, 30 May 2022 16:53:05 +0200 +Subject: [PATCH] APPS/x509: With -CA but both -CAserial and -CAcreateserial + not given, use random serial. + +Also improve openssl-x509.pod.in and error handling of load_serial() in apps.c. +Backported from https://github.com/openssl/openssl/pull/18373 + +Reviewed-by: Hugo Landau +Reviewed-by: Tomas Mraz +Reviewed-by: David von Oheimb +(Merged from https://github.com/openssl/openssl/pull/18803) +--- + apps/apps.c | 15 +++++++++++++-- + apps/apps.h | 9 ++++++--- + apps/ca.c | 6 ++++-- + apps/x509.c | 12 ++++++++---- + doc/man1/x509.pod | 12 +++++++----- + 5 files changed, 38 insertions(+), 16 deletions(-) + +diff --git a/apps/apps.c b/apps/apps.c +index db5b48e4cf..f2447fb0be 100644 +--- a/apps/apps.c ++++ b/apps/apps.c +@@ -1376,7 +1376,8 @@ static IMPLEMENT_LHASH_HASH_FN(index_name, OPENSSL_CSTRING) + static IMPLEMENT_LHASH_COMP_FN(index_name, OPENSSL_CSTRING) + #undef BSIZE + #define BSIZE 256 +-BIGNUM *load_serial(const char *serialfile, int create, ASN1_INTEGER **retai) ++BIGNUM *load_serial(const char *serialfile, int *exists, int create, ++ ASN1_INTEGER **retai) + { + BIO *in = NULL; + BIGNUM *ret = NULL; +@@ -1388,6 +1389,8 @@ BIGNUM *load_serial(const char *serialfile, int create, ASN1_INTEGER **retai) + goto err; + + in = BIO_new_file(serialfile, "r"); ++ if (exists != NULL) ++ *exists = in != NULL; + if (in == NULL) { + if (!create) { + perror(serialfile); +@@ -1395,8 +1398,14 @@ BIGNUM *load_serial(const char *serialfile, int create, ASN1_INTEGER **retai) + } + ERR_clear_error(); + ret = BN_new(); +- if (ret == NULL || !rand_serial(ret, ai)) ++ if (ret == NULL) { + BIO_printf(bio_err, "Out of memory\n"); ++ } else if (!rand_serial(ret, ai)) { ++ BIO_printf(bio_err, "Error creating random number to store in %s\n", ++ serialfile); ++ BN_free(ret); ++ ret = NULL; ++ } + } else { + if (!a2i_ASN1_INTEGER(in, ai, buf, 1024)) { + BIO_printf(bio_err, "unable to load number from %s\n", +@@ -1416,6 +1425,8 @@ BIGNUM *load_serial(const char *serialfile, int create, ASN1_INTEGER **retai) + ai = NULL; + } + err: ++ if (ret == NULL) ++ ERR_print_errors(bio_err); + BIO_free(in); + ASN1_INTEGER_free(ai); + return ret; +diff --git a/apps/apps.h b/apps/apps.h +index 34c3fd8633..775342b4f3 100644 +--- a/apps/apps.h ++++ b/apps/apps.h +@@ -527,9 +527,12 @@ typedef struct ca_db_st { + } CA_DB; + + void* app_malloc(int sz, const char *what); +-BIGNUM *load_serial(const char *serialfile, int create, ASN1_INTEGER **retai); +-int save_serial(const char *serialfile, const char *suffix, const BIGNUM *serial, +- ASN1_INTEGER **retai); ++ ++/* load_serial, save_serial, and rotate_serial are also used for CRL numbers */ ++BIGNUM *load_serial(const char *serialfile, int *exists, int create, ++ ASN1_INTEGER **retai); ++int save_serial(const char *serialfile, const char *suffix, ++ const BIGNUM *serial, ASN1_INTEGER **retai); + int rotate_serial(const char *serialfile, const char *new_suffix, + const char *old_suffix); + int rand_serial(BIGNUM *b, ASN1_INTEGER *ai); +diff --git a/apps/ca.c b/apps/ca.c +index 390ac37493..ad01bba55a 100755 +--- a/apps/ca.c ++++ b/apps/ca.c +@@ -842,7 +842,8 @@ end_of_options: + goto end; + } + } else { +- if ((serial = load_serial(serialfile, create_ser, NULL)) == NULL) { ++ serial = load_serial(serialfile, NULL, create_ser, NULL); ++ if (serial == NULL) { + BIO_printf(bio_err, "error while loading serial number\n"); + goto end; + } +@@ -1078,7 +1079,8 @@ end_of_options: + + if ((crlnumberfile = NCONF_get_string(conf, section, ENV_CRLNUMBER)) + != NULL) +- if ((crlnumber = load_serial(crlnumberfile, 0, NULL)) == NULL) { ++ if ((crlnumber = load_serial(crlnumberfile, NULL, 0, NULL)) ++ == NULL) { + BIO_printf(bio_err, "error while loading CRL number\n"); + goto end; + } +diff --git a/apps/x509.c b/apps/x509.c +index 1f53504209..67a70e7fea 100644 +--- a/apps/x509.c ++++ b/apps/x509.c +@@ -400,7 +400,7 @@ int x509_main(int argc, char **argv) + aliasout = ++num; + break; + case OPT_CACREATESERIAL: +- CA_createserial = ++num; ++ CA_createserial = 1; + break; + case OPT_CLREXT: + clrext = 1; +@@ -916,6 +916,7 @@ static ASN1_INTEGER *x509_load_serial(const char *CAfile, + char *buf = NULL; + ASN1_INTEGER *bs = NULL; + BIGNUM *serial = NULL; ++ int defaultfile = 0, file_exists; + + if (serialfile == NULL) { + const char *p = strrchr(CAfile, '.'); +@@ -925,9 +926,10 @@ static ASN1_INTEGER *x509_load_serial(const char *CAfile, + memcpy(buf, CAfile, len); + memcpy(buf + len, POSTFIX, sizeof(POSTFIX)); + serialfile = buf; ++ defaultfile = 1; + } + +- serial = load_serial(serialfile, create, NULL); ++ serial = load_serial(serialfile, &file_exists, create || defaultfile, NULL); + if (serial == NULL) + goto end; + +@@ -936,8 +938,10 @@ static ASN1_INTEGER *x509_load_serial(const char *CAfile, + goto end; + } + +- if (!save_serial(serialfile, NULL, serial, &bs)) +- goto end; ++ if (file_exists || create) ++ save_serial(serialfile, NULL, serial, &bs); ++ else ++ bs = BN_to_ASN1_INTEGER(serial, NULL); + + end: + OPENSSL_free(buf); +diff --git a/doc/man1/x509.pod b/doc/man1/x509.pod +index 3c9b2f2263..67d131389a 100644 +--- a/doc/man1/x509.pod ++++ b/doc/man1/x509.pod +@@ -443,13 +443,15 @@ The default filename consists of the CA certificate file base name with + ".srl" appended. For example if the CA certificate file is called + "mycacert.pem" it expects to find a serial number file called "mycacert.srl". + ++If the B<-CA> option is specified and both the <-CAserial> and <-CAcreateserial> ++options are not given and the default serial number file does not exist, ++a random number is generated; this is the recommended practice. ++ + =item B<-CAcreateserial> + +-With this option the CA serial number file is created if it does not exist: +-it will contain the serial number "02" and the certificate being signed will +-have the 1 as its serial number. If the B<-CA> option is specified +-and the serial number file does not exist a random number is generated; +-this is the recommended practice. ++With this option the CA serial number file is created if it does not exist. ++A random number is generated, used for the certificate, and saved into the ++serial number file in that case. + + =item B<-extfile filename> + +-- +2.17.1 + diff --git a/backport-Add-test-for-EC_KEY_set_private_key.patch b/backport-Add-test-for-EC_KEY_set_private_key.patch new file mode 100644 index 0000000000000000000000000000000000000000..c6def396daa5f57737545f83b8c63be4a601d8de --- /dev/null +++ b/backport-Add-test-for-EC_KEY_set_private_key.patch @@ -0,0 +1,71 @@ +From 1c2f52bed3ebee6222cf078278074c72717df4ec Mon Sep 17 00:00:00 2001 +From: Roberto Hueso Gomez +Date: Mon, 1 Aug 2022 02:08:47 +0200 +Subject: [PATCH] Add test for EC_KEY_set_private_key() + +This tests the behavior and API of the EC_KEY_set_private_key function. +It tests compliance with legacy features related to NULL private keys +too. + +Reviewed-by: Nicola Tuveri +Reviewed-by: Matt Caswell +(Merged from https://github.com/openssl/openssl/pull/18874) +--- + test/ec_internal_test.c | 34 ++++++++++++++++++++++++++++++++++ + 1 file changed, 34 insertions(+) + +diff --git a/test/ec_internal_test.c b/test/ec_internal_test.c +index 45a36ab94a..4da842a8a7 100644 +--- a/test/ec_internal_test.c ++++ b/test/ec_internal_test.c +@@ -183,6 +183,39 @@ static int field_tests_default(int n) + return ret; + } + ++/* ++ * Tests behavior of the EC_KEY_set_private_key ++ */ ++static int set_private_key(void) ++{ ++ EC_KEY *key = NULL, *aux_key = NULL; ++ int testresult = 0; ++ ++ key = EC_KEY_new_by_curve_name(NID_secp224r1); ++ aux_key = EC_KEY_new_by_curve_name(NID_secp224r1); ++ if (!TEST_ptr(key) ++ || !TEST_ptr(aux_key) ++ || !TEST_int_eq(EC_KEY_generate_key(key), 1) ++ || !TEST_int_eq(EC_KEY_generate_key(aux_key), 1)) ++ goto err; ++ ++ /* Test setting a valid private key */ ++ if (!TEST_int_eq(EC_KEY_set_private_key(key, aux_key->priv_key), 1)) ++ goto err; ++ ++ /* Test compliance with legacy behavior for NULL private keys */ ++ if (!TEST_int_eq(EC_KEY_set_private_key(key, NULL), 0) ++ || !TEST_ptr_null(key->priv_key)) ++ goto err; ++ ++ testresult = 1; ++ ++ err: ++ EC_KEY_free(key); ++ EC_KEY_free(aux_key); ++ return testresult; ++} ++ + /* + * Tests behavior of the decoded_from_explicit_params flag and API + */ +@@ -337,6 +370,7 @@ int setup_tests(void) + ADD_TEST(field_tests_ec2_simple); + #endif + ADD_ALL_TESTS(field_tests_default, crv_len); ++ ADD_TEST(set_private_key); + ADD_TEST(decoded_flag_test); + ADD_ALL_TESTS(ecpkparams_i2d2i_test, crv_len); + +-- +2.17.1 + diff --git a/backport-Fix-EC_KEY_set_private_key-priv_key-regression.patch b/backport-Fix-EC_KEY_set_private_key-priv_key-regression.patch new file mode 100644 index 0000000000000000000000000000000000000000..a0354a90fb6fd4fbfd4094c9bf329805098263f0 --- /dev/null +++ b/backport-Fix-EC_KEY_set_private_key-priv_key-regression.patch @@ -0,0 +1,42 @@ +From 143d7d4c791df8b9051356be51d9f77bc241fe4c Mon Sep 17 00:00:00 2001 +From: Roberto Hueso Gomez +Date: Tue, 26 Jul 2022 20:41:02 +0200 +Subject: [PATCH] Fix EC_KEY_set_private_key() priv_key regression + +This allows to set EC_KEY's private key to NULL and fixes regression +issue following OTC guideline in +https://github.com/openssl/openssl/issues/18744#issuecomment-1195175696 + +Fixes #18744. + +Reviewed-by: Nicola Tuveri +Reviewed-by: Matt Caswell +(Merged from https://github.com/openssl/openssl/pull/18874) +--- + crypto/ec/ec_key.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/crypto/ec/ec_key.c b/crypto/ec/ec_key.c +index 3017f0936c..63799002bc 100644 +--- a/crypto/ec/ec_key.c ++++ b/crypto/ec/ec_key.c +@@ -443,6 +443,16 @@ int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key) + && key->meth->set_private(key, priv_key) == 0) + return 0; + ++ /* ++ * Return `0` to comply with legacy behavior for this function, see ++ * https://github.com/openssl/openssl/issues/18744#issuecomment-1195175696 ++ */ ++ if (priv_key == NULL) { ++ BN_clear_free(key->priv_key); ++ key->priv_key = NULL; ++ return 0; /* intentional for legacy compatibility */ ++ } ++ + /* + * We should never leak the bit length of the secret scalar in the key, + * so we always set the `BN_FLG_CONSTTIME` flag on the internal `BIGNUM` +-- +2.17.1 + diff --git a/backport-Fix-SSL_pending-and-SSL_has_pending-with-DTLS.patch b/backport-Fix-SSL_pending-and-SSL_has_pending-with-DTLS.patch new file mode 100644 index 0000000000000000000000000000000000000000..c39270400fd0eb71b21be3d15055893109838fac --- /dev/null +++ b/backport-Fix-SSL_pending-and-SSL_has_pending-with-DTLS.patch @@ -0,0 +1,89 @@ +From 01fc812cb0aafc3cfc271303b6646d1c0a86b020 Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Mon, 25 Jul 2022 15:59:38 +0100 +Subject: [PATCH] Fix SSL_pending() and SSL_has_pending() with DTLS + +If app data is received before a Finished message in DTLS then we buffer +it to return later. The function SSL_pending() is supposed to tell you +how much processed app data we have already buffered, and SSL_has_pending() +is supposed to tell you if we have any data buffered (whether processed or +not, and whether app data or not). + +Neither SSL_pending() or SSL_has_pending() were taking account of this +DTLS specific app data buffer. + +Reviewed-by: Hugo Landau +Reviewed-by: Tomas Mraz +(Merged from https://github.com/openssl/openssl/pull/18976) +--- + ssl/record/rec_layer_s3.c | 14 +++++++++++++- + ssl/ssl_lib.c | 24 +++++++++++++++++++----- + 2 files changed, 32 insertions(+), 6 deletions(-) + +diff --git a/ssl/record/rec_layer_s3.c b/ssl/record/rec_layer_s3.c +index 8249b4ace9..23cd4219e9 100644 +--- a/ssl/record/rec_layer_s3.c ++++ b/ssl/record/rec_layer_s3.c +@@ -115,10 +115,22 @@ size_t ssl3_pending(const SSL *s) + if (s->rlayer.rstate == SSL_ST_READ_BODY) + return 0; + ++ /* Take into account DTLS buffered app data */ ++ if (SSL_IS_DTLS(s)) { ++ DTLS1_RECORD_DATA *rdata; ++ pitem *item, *iter; ++ ++ iter = pqueue_iterator(s->rlayer.d->buffered_app_data.q); ++ while ((item = pqueue_next(&iter)) != NULL) { ++ rdata = item->data; ++ num += rdata->rrec.length; ++ } ++ } ++ + for (i = 0; i < RECORD_LAYER_get_numrpipes(&s->rlayer); i++) { + if (SSL3_RECORD_get_type(&s->rlayer.rrec[i]) + != SSL3_RT_APPLICATION_DATA) +- return 0; ++ return num; + num += SSL3_RECORD_get_length(&s->rlayer.rrec[i]); + } + +diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c +index 25a1a44785..47adc3211c 100644 +--- a/ssl/ssl_lib.c ++++ b/ssl/ssl_lib.c +@@ -1510,12 +1510,26 @@ int SSL_has_pending(const SSL *s) + { + /* + * Similar to SSL_pending() but returns a 1 to indicate that we have +- * unprocessed data available or 0 otherwise (as opposed to the number of +- * bytes available). Unlike SSL_pending() this will take into account +- * read_ahead data. A 1 return simply indicates that we have unprocessed +- * data. That data may not result in any application data, or we may fail +- * to parse the records for some reason. ++ * processed or unprocessed data available or 0 otherwise (as opposed to the ++ * number of bytes available). Unlike SSL_pending() this will take into ++ * account read_ahead data. A 1 return simply indicates that we have data. ++ * That data may not result in any application data, or we may fail to parse ++ * the records for some reason. + */ ++ ++ /* Check buffered app data if any first */ ++ if (SSL_IS_DTLS(s)) { ++ DTLS1_RECORD_DATA *rdata; ++ pitem *item, *iter; ++ ++ iter = pqueue_iterator(s->rlayer.d->buffered_app_data.q); ++ while ((item = pqueue_next(&iter)) != NULL) { ++ rdata = item->data; ++ if (rdata->rrec.length > 0) ++ return 1; ++ } ++ } ++ + if (RECORD_LAYER_processed_read_pending(&s->rlayer)) + return 1; + +-- +2.17.1 + diff --git a/backport-Fix-a-crash-in-v2i_IPAddrBlocks.patch b/backport-Fix-a-crash-in-v2i_IPAddrBlocks.patch new file mode 100644 index 0000000000000000000000000000000000000000..90f12eab47c49320053c9befe1a38fa1793b09fb --- /dev/null +++ b/backport-Fix-a-crash-in-v2i_IPAddrBlocks.patch @@ -0,0 +1,76 @@ +From 264a3f453c418dc01f4b74928ed2a76a08a65513 Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Fri, 10 Jun 2022 12:33:45 +0100 +Subject: [PATCH] Fix a crash in v2i_IPAddrBlocks() + +If an IP address prefix value is supplied that is too large then a crash +can result. v2i_IPAddrBlocks() should sanity check the prefix value, as +should X509v3_addr_add_prefix(). + +Reported by Theo Buehler (@botovq) + +Reviewed-by: Tomas Mraz +Reviewed-by: Dmitry Belyavskiy +Reviewed-by: Hugo Landau +(Merged from https://github.com/openssl/openssl/pull/18847) +--- + crypto/x509v3/v3_addr.c | 17 ++++--- + test/v3ext.c | 99 +++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 111 insertions(+), 5 deletions(-) + +diff --git a/crypto/x509v3/v3_addr.c b/crypto/x509v3/v3_addr.c +index ccce34ef2e..f9c368bea4 100644 +--- a/crypto/x509v3/v3_addr.c ++++ b/crypto/x509v3/v3_addr.c +@@ -392,12 +392,14 @@ static int range_should_be_prefix(const unsigned char *min, + /* + * Construct a prefix. + */ +-static int make_addressPrefix(IPAddressOrRange **result, +- unsigned char *addr, const int prefixlen) ++static int make_addressPrefix(IPAddressOrRange **result, unsigned char *addr, ++ const int prefixlen, const int afilen) + { + int bytelen = (prefixlen + 7) / 8, bitlen = prefixlen % 8; + IPAddressOrRange *aor = IPAddressOrRange_new(); + ++ if (prefixlen < 0 || prefixlen > (afilen * 8)) ++ return 0; + if (aor == NULL) + return 0; + aor->type = IPAddressOrRange_addressPrefix; +@@ -437,7 +439,7 @@ static int make_addressRange(IPAddressOrRange **result, + return 0; + + if ((prefixlen = range_should_be_prefix(min, max, length)) >= 0) +- return make_addressPrefix(result, min, prefixlen); ++ return make_addressPrefix(result, min, prefixlen, length); + + if ((aor = IPAddressOrRange_new()) == NULL) + return 0; +@@ -599,7 +601,9 @@ int X509v3_addr_add_prefix(IPAddrBlocks *addr, + { + IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi); + IPAddressOrRange *aor; +- if (aors == NULL || !make_addressPrefix(&aor, a, prefixlen)) ++ ++ if (aors == NULL ++ || !make_addressPrefix(&aor, a, prefixlen, length_from_afi(afi))) + return 0; + if (sk_IPAddressOrRange_push(aors, aor)) + return 1; +@@ -996,7 +1000,10 @@ static void *v2i_IPAddrBlocks(const struct v3_ext_method *method, + switch (delim) { + case '/': + prefixlen = (int)strtoul(s + i2, &t, 10); +- if (t == s + i2 || *t != '\0') { ++ if (t == s + i2 ++ || *t != '\0' ++ || prefixlen > (length * 8) ++ || prefixlen < 0) { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, + X509V3_R_EXTENSION_VALUE_ERROR); + X509V3_conf_err(val); +-- +2.17.1 + diff --git a/backport-Fix-ipv4_from_asc-behavior-on-invalid-Ip-addresses.patch b/backport-Fix-ipv4_from_asc-behavior-on-invalid-Ip-addresses.patch new file mode 100644 index 0000000000000000000000000000000000000000..fec39592c817a115ad5b1996e11d18f076d9137a --- /dev/null +++ b/backport-Fix-ipv4_from_asc-behavior-on-invalid-Ip-addresses.patch @@ -0,0 +1,45 @@ +From 65e30e7d56f01008d29e65c9ae7a42ce074def2f Mon Sep 17 00:00:00 2001 +From: Amir Mohammadi +Date: Wed, 4 Aug 2021 09:43:49 +0430 +Subject: [PATCH] Fix ipv4_from_asc behavior on invalid Ip addresses + +sscanf() call in ipv4_from_asc does not check that +the string is terminated immediately after the last digit. + +(cherry picked from commit 8b9a13b43ba3d71e441fca47a52e800ce79b3d2b) + +Reviewed-by: Tomas Mraz +Reviewed-by: Dmitry Belyavskiy +Reviewed-by: Hugo Landau +(Merged from https://github.com/openssl/openssl/pull/18847) +--- + crypto/x509v3/v3_utl.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/crypto/x509v3/v3_utl.c b/crypto/x509v3/v3_utl.c +index a7ff4b4fb4..eac78259fc 100644 +--- a/crypto/x509v3/v3_utl.c ++++ b/crypto/x509v3/v3_utl.c +@@ -1087,12 +1087,17 @@ int a2i_ipadd(unsigned char *ipout, const char *ipasc) + + static int ipv4_from_asc(unsigned char *v4, const char *in) + { +- int a0, a1, a2, a3; +- if (sscanf(in, "%d.%d.%d.%d", &a0, &a1, &a2, &a3) != 4) ++ const char *p; ++ int a0, a1, a2, a3, n; ++ ++ if (sscanf(in, "%d.%d.%d.%d%n", &a0, &a1, &a2, &a3, &n) != 4) + return 0; + if ((a0 < 0) || (a0 > 255) || (a1 < 0) || (a1 > 255) + || (a2 < 0) || (a2 > 255) || (a3 < 0) || (a3 > 255)) + return 0; ++ p = in + n; ++ if (!(*p == '\0' || ossl_isspace(*p))) ++ return 0; + v4[0] = a0; + v4[1] = a1; + v4[2] = a2; +-- +2.17.1 + diff --git a/backport-Fix-re-signing-certificates-with-different-key-sizes.patch b/backport-Fix-re-signing-certificates-with-different-key-sizes.patch new file mode 100644 index 0000000000000000000000000000000000000000..dc15494d3b25a7ee28514f3b74387460aaa2aafe --- /dev/null +++ b/backport-Fix-re-signing-certificates-with-different-key-sizes.patch @@ -0,0 +1,131 @@ +From 952fab01bebb15a8408c6ac27b59c28c979f7d49 Mon Sep 17 00:00:00 2001 +From: Todd Short +Date: Wed, 20 Jul 2022 16:42:50 -0400 +Subject: [PATCH] Fix re-signing certificates with different key sizes + +PR #18129 broke the scenario of signing a certificate (not CSR) with +different-sized key. This works in 3.0, so port the fix from 3.0 +(which is to only update the issuer for a request). + +Partially undo #18129, but keep setting the issuer only for a CSR + +Create two certs (a and ca) then sign a with c (into b): +``` +openssl req -x509 -newkey rsa:2048 -keyout a-key.pem -out a-cert.pem -days 365 -nodes -subj /CN=a.example.com +openssl req -x509 -newkey rsa:4096 -keyout ${HERE}/ca-key.pem -out ${HERE}/ca-cert.pem -days 3650 -nodes -subj /CN=ca.example.com +openssl x509 -in a-cert.pem -CA ca-cert.pem -CAkey ca-key.pem -set_serial '1234567890' -preserve_dates -sha256 -out b-cert.pem +``` +The above succeeds in 1.1.1n and 3.0, fails in 1.1.1o (which includes #18129) +The issue in #16080 is also fixed. + +Reviewed-by: Matt Caswell +Reviewed-by: Tomas Mraz +Reviewed-by: Ben Kaduk +(Merged from https://github.com/openssl/openssl/pull/18836) +--- + apps/x509.c | 4 ++- + test/recipes/25-test_x509.t | 61 ++++++++++++++++++++++++++++++++++++- + 2 files changed, 63 insertions(+), 2 deletions(-) + +diff --git a/apps/x509.c b/apps/x509.c +index 67a70e7fea..8d4bf71a03 100644 +--- a/apps/x509.c ++++ b/apps/x509.c +@@ -590,7 +590,7 @@ int x509_main(int argc, char **argv) + xca = load_cert(CAfile, CAformat, "CA Certificate"); + if (xca == NULL) + goto end; +- if (!X509_set_issuer_name(x, X509_get_subject_name(xca))) ++ if (reqfile && !X509_set_issuer_name(x, X509_get_subject_name(xca))) + goto end; + } + +@@ -993,6 +993,8 @@ static int x509_certify(X509_STORE *ctx, const char *CAfile, const EVP_MD *diges + goto end; + } + ++ if (!X509_set_issuer_name(x, X509_get_subject_name(xca))) ++ goto end; + if (!X509_set_serialNumber(x, bs)) + goto end; + +diff --git a/test/recipes/25-test_x509.t b/test/recipes/25-test_x509.t +index f5ef0f9963..73548145c8 100644 +--- a/test/recipes/25-test_x509.t ++++ b/test/recipes/25-test_x509.t +@@ -15,7 +15,11 @@ use OpenSSL::Test qw/:DEFAULT srctop_file/; + + setup("test_x509"); + +-plan tests => 9; ++plan tests => 16; ++ ++# Prevent MSys2 filename munging for arguments that look like file paths but ++# aren't ++$ENV{MSYS2_ARG_CONV_EXCL} = "/CN="; + + require_ok(srctop_file('test','recipes','tconversion.pl')); + +@@ -46,4 +50,59 @@ subtest 'x509 -- second x.509 v3 certificate' => sub { + + subtest 'x509 -- pathlen' => sub { + ok(run(test(["v3ext", srctop_file("test/certs", "pathlen.pem")]))); ++}; ++ ++# extracts issuer from a -text formatted-output ++sub get_issuer { ++ my $f = shift(@_); ++ my $issuer = ""; ++ open my $fh, $f or die; ++ while (my $line = <$fh>) { ++ if ($line =~ /Issuer:/) { ++ $issuer = $line; ++ } ++ } ++ close $fh; ++ return $issuer; + } ++ ++# Tests for signing certs (broken in 1.1.1o) ++my $a_key = "a-key.pem"; ++my $a_cert = "a-cert.pem"; ++my $a2_cert = "a2-cert.pem"; ++my $ca_key = "ca-key.pem"; ++my $ca_cert = "ca-cert.pem"; ++my $cnf = srctop_file('apps', 'openssl.cnf'); ++ ++# Create cert A ++ok(run(app(["openssl", "req", "-x509", "-newkey", "rsa:2048", ++ "-config", $cnf, ++ "-keyout", $a_key, "-out", $a_cert, "-days", "365", ++ "-nodes", "-subj", "/CN=test.example.com"]))); ++# Create cert CA - note key size ++ok(run(app(["openssl", "req", "-x509", "-newkey", "rsa:4096", ++ "-config", $cnf, ++ "-keyout", $ca_key, "-out", $ca_cert, "-days", "3650", ++ "-nodes", "-subj", "/CN=ca.example.com"]))); ++# Sign cert A with CA (errors on 1.1.1o) ++ok(run(app(["openssl", "x509", "-in", $a_cert, "-CA", $ca_cert, ++ "-CAkey", $ca_key, "-set_serial", "1234567890", ++ "-preserve_dates", "-sha256", "-text", "-out", $a2_cert]))); ++# verify issuer is CA ++ok (get_issuer($a2_cert) =~ /CN = ca.example.com/); ++ ++# Tests for issue #16080 (fixed in 1.1.1o) ++my $b_key = "b-key.pem"; ++my $b_csr = "b-cert.csr"; ++my $b_cert = "b-cert.pem"; ++# Create the CSR ++ok(run(app(["openssl", "req", "-new", "-newkey", "rsa:4096", ++ "-keyout", $b_key, "-out", $b_csr, "-nodes", ++ "-config", $cnf, ++ "-subj", "/CN=b.example.com"]))); ++# Sign it - position of "-text" matters! ++ok(run(app(["openssl", "x509", "-req", "-text", "-CAcreateserial", ++ "-CA", $ca_cert, "-CAkey", $ca_key, ++ "-in", $b_csr, "-out", $b_cert]))); ++# Verify issuer is CA ++ok(get_issuer($b_cert) =~ /CN = ca.example.com/); +-- +2.17.1 + diff --git a/backport-Fix-test-case-for-a2i_IPADDRESS.patch b/backport-Fix-test-case-for-a2i_IPADDRESS.patch new file mode 100644 index 0000000000000000000000000000000000000000..6fb1f30c64d2e200089a5d3fd58edd03f7302f4b --- /dev/null +++ b/backport-Fix-test-case-for-a2i_IPADDRESS.patch @@ -0,0 +1,42 @@ +From c3b0279bda7bf4f0f81a3dba952698fa68a51639 Mon Sep 17 00:00:00 2001 +From: Amir Mohammadi +Date: Wed, 4 Aug 2021 09:44:29 +0430 +Subject: [PATCH] Fix test case for a2i_IPADDRESS + +(cherry picked from commit 9b887d5d5a8ef9aa1c3ce6e54a82ddcba25b9415) + +Reviewed-by: Tomas Mraz +Reviewed-by: Dmitry Belyavskiy +Reviewed-by: Hugo Landau +(Merged from https://github.com/openssl/openssl/pull/18847) +--- + test/x509_internal_test.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/test/x509_internal_test.c b/test/x509_internal_test.c +index 3eec970352..63f350f74b 100644 +--- a/test/x509_internal_test.c ++++ b/test/x509_internal_test.c +@@ -61,7 +61,6 @@ typedef struct { + const char *ipasc; + const char *data; + int length; +- ASN1_OCTET_STRING ip; + } IP_TESTDATA; + + static IP_TESTDATA a2i_ipaddress_tests[] = { +@@ -81,8 +80,10 @@ static IP_TESTDATA a2i_ipaddress_tests[] = { + {"example.test", NULL, 0}, + {"", NULL, 0}, + ++ {"1.2.3.4 ", "\x01\x02\x03\x04", 4}, ++ {" 1.2.3.4", "\x01\x02\x03\x04", 4}, ++ {" 1.2.3.4 ", "\x01\x02\x03\x04", 4}, + {"1.2.3.4.example.test", NULL, 0}, +- {"1.2.3.4 ", NULL, 0}, + }; + + +-- +2.17.1 + diff --git a/backport-Fix-verify_callback-in-the-openssl-s_client-s_server.patch b/backport-Fix-verify_callback-in-the-openssl-s_client-s_server.patch new file mode 100644 index 0000000000000000000000000000000000000000..f5f70b4d29cd8fd50266d98e06dc803c51cede65 --- /dev/null +++ b/backport-Fix-verify_callback-in-the-openssl-s_client-s_server.patch @@ -0,0 +1,64 @@ +From 86945b10ccd84f685bd6215bbb00d1e700303e49 Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +Date: Thu, 14 Jul 2022 21:41:48 +0200 +Subject: [PATCH] Fix verify_callback in the openssl s_client/s_server app + +We need to check that error cert is available before printing its data + +Reviewed-by: Tomas Mraz +Reviewed-by: David von Oheimb +Reviewed-by: Viktor Dukhovni +Reviewed-by: Hugo Landau +(Merged from https://github.com/openssl/openssl/pull/18805) + +(cherry picked from commit fad0f80eff188ef938fed614245a56ed56110deb) +--- + apps/s_cb.c | 26 ++++++++++++++++---------- + 1 file changed, 16 insertions(+), 10 deletions(-) + +diff --git a/apps/s_cb.c b/apps/s_cb.c +index d066a423de..a4ff978908 100644 +--- a/apps/s_cb.c ++++ b/apps/s_cb.c +@@ -74,22 +74,28 @@ int verify_callback(int ok, X509_STORE_CTX *ctx) + } + switch (err) { + case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: +- BIO_puts(bio_err, "issuer= "); +- X509_NAME_print_ex(bio_err, X509_get_issuer_name(err_cert), +- 0, get_nameopt()); +- BIO_puts(bio_err, "\n"); ++ if (err_cert != NULL) { ++ BIO_puts(bio_err, "issuer= "); ++ X509_NAME_print_ex(bio_err, X509_get_issuer_name(err_cert), ++ 0, get_nameopt()); ++ BIO_puts(bio_err, "\n"); ++ } + break; + case X509_V_ERR_CERT_NOT_YET_VALID: + case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: +- BIO_printf(bio_err, "notBefore="); +- ASN1_TIME_print(bio_err, X509_get0_notBefore(err_cert)); +- BIO_printf(bio_err, "\n"); ++ if (err_cert != NULL) { ++ BIO_printf(bio_err, "notBefore="); ++ ASN1_TIME_print(bio_err, X509_get0_notBefore(err_cert)); ++ BIO_printf(bio_err, "\n"); ++ } + break; + case X509_V_ERR_CERT_HAS_EXPIRED: + case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: +- BIO_printf(bio_err, "notAfter="); +- ASN1_TIME_print(bio_err, X509_get0_notAfter(err_cert)); +- BIO_printf(bio_err, "\n"); ++ if (err_cert != NULL) { ++ BIO_printf(bio_err, "notAfter="); ++ ASN1_TIME_print(bio_err, X509_get0_notAfter(err_cert)); ++ BIO_printf(bio_err, "\n"); ++ } + break; + case X509_V_ERR_NO_EXPLICIT_POLICY: + if (!verify_args.quiet) +-- +2.17.1 + diff --git a/backport-Fixes-segfault-occurrence-in-PEM_write.patch b/backport-Fixes-segfault-occurrence-in-PEM_write.patch new file mode 100644 index 0000000000000000000000000000000000000000..4a3888b4cff8e72e23706ee446adee6454b25461 --- /dev/null +++ b/backport-Fixes-segfault-occurrence-in-PEM_write.patch @@ -0,0 +1,37 @@ +From 3b9082c844913d3a0efada9fac0bd2924ce1a8f2 Mon Sep 17 00:00:00 2001 +From: valdaarhun +Date: Mon, 25 Jul 2022 18:49:19 +0530 +Subject: [PATCH] Fixes segfault occurrence in PEM_write() + +Checks if header is NULL or not before calling strlen(). + +CLA: trivial + +Fixes #18825 + +Reviewed-by: Tomas Mraz +Reviewed-by: Ben Kaduk +Reviewed-by: Paul Dale +(Merged from https://github.com/openssl/openssl/pull/18865) + +(cherry picked from commit 205957405d08ef199e6ab654e333a627bbca9ccc) +--- + crypto/pem/pem_lib.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/crypto/pem/pem_lib.c b/crypto/pem/pem_lib.c +index 2de093595d..c2cf407931 100644 +--- a/crypto/pem/pem_lib.c ++++ b/crypto/pem/pem_lib.c +@@ -621,7 +621,7 @@ int PEM_write_bio(BIO *bp, const char *name, const char *header, + (BIO_write(bp, "-----\n", 6) != 6)) + goto err; + +- i = strlen(header); ++ i = header != NULL ? strlen(header) : 0; + if (i > 0) { + if ((BIO_write(bp, header, i) != i) || (BIO_write(bp, "\n", 1) != 1)) + goto err; +-- +2.17.1 + diff --git a/backport-Test-case-for-a2i_IPADDRESS.patch b/backport-Test-case-for-a2i_IPADDRESS.patch new file mode 100644 index 0000000000000000000000000000000000000000..e0c1a6a399afd18be5f74a019ac773e87bf6d9ee --- /dev/null +++ b/backport-Test-case-for-a2i_IPADDRESS.patch @@ -0,0 +1,91 @@ +From bd41b84bede84c1a5716be4eafddd1dd052faa72 Mon Sep 17 00:00:00 2001 +From: Christian Heimes +Date: Sat, 15 Aug 2020 20:01:49 +0200 +Subject: [PATCH] Test case for a2i_IPADDRESS + +Unit test to show that a2i_IPADDRESS("1.2.3.4.test.example") ignores +trailing data. + +See: https://github.com/openssl/openssl/issues/12649 +See: https://bugs.python.org/issue41556 + +(cherry picked from commit 1a9411a30b09a98498366979a1ea4898f70f6d19) + +Reviewed-by: Tomas Mraz +Reviewed-by: Dmitry Belyavskiy +Reviewed-by: Hugo Landau +(Merged from https://github.com/openssl/openssl/pull/18847) +--- + test/x509_internal_test.c | 54 +++++++++++++++++++++++++++++++++++++++ + 1 file changed, 54 insertions(+) + +diff --git a/test/x509_internal_test.c b/test/x509_internal_test.c +index d2f41d7085..3eec970352 100644 +--- a/test/x509_internal_test.c ++++ b/test/x509_internal_test.c +@@ -57,8 +57,62 @@ static int test_standard_exts(void) + return good; + } + ++typedef struct { ++ const char *ipasc; ++ const char *data; ++ int length; ++ ASN1_OCTET_STRING ip; ++} IP_TESTDATA; ++ ++static IP_TESTDATA a2i_ipaddress_tests[] = { ++ {"127.0.0.1", "\x7f\x00\x00\x01", 4}, ++ {"1.2.3.4", "\x01\x02\x03\x04", 4}, ++ {"1.2.3.255", "\x01\x02\x03\xff", 4}, ++ {"1.2.3", NULL, 0}, ++ {"1.2.3 .4", NULL, 0}, ++ ++ {"::1", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", 16}, ++ {"1:1:1:1:1:1:1:1", "\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01", 16}, ++ {"2001:db8::ff00:42:8329", "\x20\x01\x0d\xb8\x00\x00\x00\x00\x00\x00\xff\x00\x00\x42\x83\x29", 16}, ++ {"1:1:1:1:1:1:1:1.test", NULL, 0}, ++ {":::1", NULL, 0}, ++ {"2001::123g", NULL, 0}, ++ ++ {"example.test", NULL, 0}, ++ {"", NULL, 0}, ++ ++ {"1.2.3.4.example.test", NULL, 0}, ++ {"1.2.3.4 ", NULL, 0}, ++}; ++ ++ ++static int test_a2i_ipaddress(int idx) ++{ ++ int good = 1; ++ ASN1_OCTET_STRING *ip; ++ int len = a2i_ipaddress_tests[idx].length; ++ ++ ip = a2i_IPADDRESS(a2i_ipaddress_tests[idx].ipasc); ++ if (len == 0) { ++ if (!TEST_ptr_null(ip)) { ++ good = 0; ++ TEST_note("'%s' should not be parsed as IP address", a2i_ipaddress_tests[idx].ipasc); ++ } ++ } else { ++ if (!TEST_ptr(ip) ++ || !TEST_int_eq(ASN1_STRING_length(ip), len) ++ || !TEST_mem_eq(ASN1_STRING_get0_data(ip), len, ++ a2i_ipaddress_tests[idx].data, len)) { ++ good = 0; ++ } ++ } ++ ASN1_OCTET_STRING_free(ip); ++ return good; ++} ++ + int setup_tests(void) + { + ADD_TEST(test_standard_exts); ++ ADD_ALL_TESTS(test_a2i_ipaddress, OSSL_NELEM(a2i_ipaddress_tests)); + return 1; + } +-- +2.17.1 + diff --git a/backport-Test-that-swapping-the-first-app-data-record-with-Fi.patch b/backport-Test-that-swapping-the-first-app-data-record-with-Fi.patch new file mode 100644 index 0000000000000000000000000000000000000000..685668168c21b59e86537cdedfeb697cdbf2a08d --- /dev/null +++ b/backport-Test-that-swapping-the-first-app-data-record-with-Fi.patch @@ -0,0 +1,183 @@ +From d87e99df3162b2d56b8d44907fde88b67d7e3900 Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Mon, 25 Jul 2022 12:39:52 +0100 +Subject: [PATCH] Test that swapping the first app data record with Finished + msg works + +If the first app data record arrives before the Finished message we should +be able to buffer it and move on to the Finished message. + +Reviewed-by: Hugo Landau +Reviewed-by: Tomas Mraz +(Merged from https://github.com/openssl/openssl/pull/18976) +--- + test/dtlstest.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++ + test/ssltestlib.c | 33 ++++++++++++++++++ + test/ssltestlib.h | 1 + + 3 files changed, 122 insertions(+) + +diff --git a/test/dtlstest.c b/test/dtlstest.c +index 1d7b105fb6..f5c9dcfcd8 100644 +--- a/test/dtlstest.c ++++ b/test/dtlstest.c +@@ -328,6 +328,93 @@ static int test_dtls_duplicate_records(void) + return testresult; + } + ++/* ++ * Test that swapping an app data record so that it is received before the ++ * Finished message still works. ++ */ ++static int test_swap_app_data(void) ++{ ++ SSL_CTX *sctx = NULL, *cctx = NULL; ++ SSL *sssl = NULL, *cssl = NULL; ++ int testresult = 0; ++ BIO *bio; ++ char msg[] = { 0x00, 0x01, 0x02, 0x03 }; ++ char buf[10]; ++ ++ if (!TEST_true(create_ssl_ctx_pair(DTLS_server_method(), ++ DTLS_client_method(), ++ DTLS1_VERSION, 0, ++ &sctx, &cctx, cert, privkey))) ++ return 0; ++ ++#ifndef OPENSSL_NO_DTLS1_2 ++ if (!TEST_true(SSL_CTX_set_cipher_list(cctx, "AES128-SHA"))) ++ goto end; ++#else ++ /* Default sigalgs are SHA1 based in pkts); ++ ++ /* We need at least 2 packets to be able to swap them */ ++ if (numpkts <= 1) ++ return 0; ++ ++ /* Get the penultimate packet */ ++ thispkt = sk_MEMPACKET_value(ctx->pkts, numpkts - 2); ++ if (thispkt == NULL) ++ return 0; ++ ++ if (sk_MEMPACKET_delete(ctx->pkts, numpkts - 2) != thispkt) ++ return 0; ++ ++ /* Re-add it to the end of the list */ ++ thispkt->num++; ++ if (sk_MEMPACKET_insert(ctx->pkts, thispkt, numpkts - 1) <= 0) ++ return 0; ++ ++ /* We also have to adjust the packet number of the other packet */ ++ thispkt = sk_MEMPACKET_value(ctx->pkts, numpkts - 2); ++ if (thispkt == NULL) ++ return 0; ++ thispkt->num--; ++ ++ return 1; ++} ++ + int mempacket_test_inject(BIO *bio, const char *in, int inl, int pktnum, + int type) + { +diff --git a/test/ssltestlib.h b/test/ssltestlib.h +index 17b278219a..b47004f62e 100644 +--- a/test/ssltestlib.h ++++ b/test/ssltestlib.h +@@ -46,6 +46,7 @@ void bio_s_always_retry_free(void); + #define MEMPACKET_CTRL_GET_DROP_REC (3 << 15) + #define MEMPACKET_CTRL_SET_DUPLICATE_REC (4 << 15) + ++int mempacket_swap_recent(BIO *bio); + int mempacket_test_inject(BIO *bio, const char *in, int inl, int pktnum, + int type); + +-- +2.17.1 + diff --git a/backport-X509_REQ_get_extensions-Return-empty-stack-if-no-ext.patch b/backport-X509_REQ_get_extensions-Return-empty-stack-if-no-ext.patch new file mode 100644 index 0000000000000000000000000000000000000000..1bc0efd209ef1bbf5da015b845a66b53ff4aef7f --- /dev/null +++ b/backport-X509_REQ_get_extensions-Return-empty-stack-if-no-ext.patch @@ -0,0 +1,32 @@ +From 0b755cdfb52ff51830aa004799e1f78548423c00 Mon Sep 17 00:00:00 2001 +From: "Dr. David von Oheimb" +Date: Fri, 8 Jan 2021 08:27:17 +0100 +Subject: [PATCH] X509_REQ_get_extensions(): Return empty stack if no + extensions found + +Reviewed-by: Tomas Mraz +Reviewed-by: Todd Short +Reviewed-by: David von Oheimb +(Merged from https://github.com/openssl/openssl/pull/18926) +--- + crypto/x509/x509_req.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/crypto/x509/x509_req.c b/crypto/x509/x509_req.c +index dd674926dd..a69f9a723d 100644 +--- a/crypto/x509/x509_req.c ++++ b/crypto/x509/x509_req.c +@@ -167,7 +167,9 @@ STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req) + ext = X509_ATTRIBUTE_get0_type(attr, 0); + break; + } +- if (!ext || (ext->type != V_ASN1_SEQUENCE)) ++ if (ext == NULL) /* no extensions is not an error */ ++ return sk_X509_EXTENSION_new_null(); ++ if (ext->type != V_ASN1_SEQUENCE) + return NULL; + p = ext->value.sequence->data; + return (STACK_OF(X509_EXTENSION) *) +-- +2.17.1 + diff --git a/openssl.spec b/openssl.spec index cb5bffd11fb2525881b8d7d0031f97a50864359d..133062dad54ab194946132a19facf30dec7d4cae 100644 --- a/openssl.spec +++ b/openssl.spec @@ -2,7 +2,7 @@ Name: openssl Epoch: 1 Version: 1.1.1m -Release: 18 +Release: 19 Summary: Cryptography and SSL/TLS Toolkit License: OpenSSL and SSLeay URL: https://www.openssl.org/ @@ -77,6 +77,19 @@ Patch66: backport-Fix-a-memory-leak-in-tls13_generate_secret.patch Patch67: backport-Make-the-DRBG-seed-propagation-thread-safe.patch Patch68: backport-Fix-memory-leak-in-X509V3_add1_i2d-when-flag-is-X509.patch Patch69: fix-add-loongarch64-target.patch +Patch70: backport-APPS-x509-With-CA-but-both-CAserial-and-CAcreateseri.patch +Patch71: backport-Fix-verify_callback-in-the-openssl-s_client-s_server.patch +Patch72: backport-Fix-re-signing-certificates-with-different-key-sizes.patch +Patch73: backport-Fix-ipv4_from_asc-behavior-on-invalid-Ip-addresses.patch +Patch74: backport-Test-case-for-a2i_IPADDRESS.patch +Patch75: backport-Fix-test-case-for-a2i_IPADDRESS.patch +Patch76: backport-Fix-a-crash-in-v2i_IPAddrBlocks.patch +Patch77: backport-Fixes-segfault-occurrence-in-PEM_write.patch +Patch78: backport-X509_REQ_get_extensions-Return-empty-stack-if-no-ext.patch +Patch79: backport-Fix-EC_KEY_set_private_key-priv_key-regression.patch +Patch80: backport-Add-test-for-EC_KEY_set_private_key.patch +Patch81: backport-Fix-SSL_pending-and-SSL_has_pending-with-DTLS.patch +Patch82: backport-Test-that-swapping-the-first-app-data-record-with-Fi.patch BuildRequires: gcc perl make lksctp-tools-devel coreutils util-linux zlib-devel Requires: coreutils %{name}-libs%{?_isa} = %{epoch}:%{version}-%{release} @@ -282,6 +295,9 @@ make test || : %ldconfig_scriptlets libs %changelog +* Mon Nov 28 2022 zhujianwei001 - 1:1.1.1m-19 +- backport some patches + * Mon Nov 14 2022 zhaozhen - 1:1.1.1m-18 - Add loongarch support