doc/website/static/security/patches/SA-15:06/openssl-1.0.1.patch
Sergio Carlavilla Delgado 989d921f5d Migrate doc to Hugo/AsciiDoctor
I'm very pleased to announce the release of
our new website and documentation using
the new toolchain with Hugo and AsciiDoctor.

To get more information about the new toolchain
please read the FreeBSD Documentation Project Primer[1],
Hugo docs[2] and AsciiDoctor docs[3].

Acknowledgment:
Benedict Reuschling <bcr@>
Glen Barber <gjb@>
Hiroki Sato <hrs@>
Li-Wen Hsu <lwhsu@>
Sean Chittenden <seanc@>
The FreeBSD Foundation

[1] https://docs.FreeBSD.org/en/books/fdp-primer/
[2] https://gohugo.io/documentation/
[3] https://docs.asciidoctor.org/home/

Approved by:    doceng, core
2021-01-26 00:31:29 +01:00

428 lines
15 KiB
Diff

Index: crypto/openssl/crypto/asn1/a_type.c
===================================================================
--- crypto/openssl/crypto/asn1/a_type.c (revision 280181)
+++ crypto/openssl/crypto/asn1/a_type.c (working copy)
@@ -124,6 +124,9 @@ int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_T
case V_ASN1_OBJECT:
result = OBJ_cmp(a->value.object, b->value.object);
break;
+ case V_ASN1_BOOLEAN:
+ result = a->value.boolean - b->value.boolean;
+ break;
case V_ASN1_NULL:
result = 0; /* They do not have content. */
break;
Index: crypto/openssl/crypto/asn1/tasn_dec.c
===================================================================
--- crypto/openssl/crypto/asn1/tasn_dec.c (revision 280181)
+++ crypto/openssl/crypto/asn1/tasn_dec.c (working copy)
@@ -127,16 +127,22 @@ unsigned long ASN1_tag2bit(int tag)
ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval,
const unsigned char **in, long len, const ASN1_ITEM *it)
- {
+{
ASN1_TLC c;
ASN1_VALUE *ptmpval = NULL;
- if (!pval)
- pval = &ptmpval;
asn1_tlc_clear_nc(&c);
- if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0)
- return *pval;
+ if (pval && *pval && it->itype == ASN1_ITYPE_PRIMITIVE)
+ ptmpval = *pval;
+ if (ASN1_item_ex_d2i(&ptmpval, in, len, it, -1, 0, 0, &c) > 0) {
+ if (pval && it->itype != ASN1_ITYPE_PRIMITIVE) {
+ if (*pval)
+ ASN1_item_free(*pval, it);
+ *pval = ptmpval;
+ }
+ return ptmpval;
+ }
return NULL;
- }
+}
int ASN1_template_d2i(ASN1_VALUE **pval,
const unsigned char **in, long len, const ASN1_TEMPLATE *tt)
@@ -311,13 +317,20 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsi
if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
goto auxerr;
- /* Allocate structure */
- if (!*pval && !ASN1_item_ex_new(pval, it))
- {
+ if (*pval) {
+ /* Free up and zero CHOICE value if initialised */
+ i = asn1_get_choice_selector(pval, it);
+ if ((i >= 0) && (i < it->tcount)) {
+ tt = it->templates + i;
+ pchptr = asn1_get_field_ptr(pval, tt);
+ ASN1_template_free(pchptr, tt);
+ asn1_set_choice_selector(pval, -1, it);
+ }
+ } else if (!ASN1_item_ex_new(pval, it)) {
ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
ERR_R_NESTED_ASN1_ERROR);
goto err;
- }
+ }
/* CHOICE type, try each possibility in turn */
p = *in;
for (i = 0, tt=it->templates; i < it->tcount; i++, tt++)
@@ -407,6 +420,17 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsi
if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
goto auxerr;
+ /* Free up and zero any ADB found */
+ for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
+ if (tt->flags & ASN1_TFLG_ADB_MASK) {
+ const ASN1_TEMPLATE *seqtt;
+ ASN1_VALUE **pseqval;
+ seqtt = asn1_do_adb(pval, tt, 1);
+ pseqval = asn1_get_field_ptr(pval, seqtt);
+ ASN1_template_free(pseqval, seqtt);
+ }
+ }
+
/* Get each field entry */
for (i = 0, tt = it->templates; i < it->tcount; i++, tt++)
{
Index: crypto/openssl/crypto/pkcs7/pk7_doit.c
===================================================================
--- crypto/openssl/crypto/pkcs7/pk7_doit.c (revision 280181)
+++ crypto/openssl/crypto/pkcs7/pk7_doit.c (working copy)
@@ -272,6 +272,25 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
PKCS7_RECIP_INFO *ri=NULL;
ASN1_OCTET_STRING *os=NULL;
+ if (p7 == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_INVALID_NULL_POINTER);
+ return NULL;
+ }
+ /*
+ * The content field in the PKCS7 ContentInfo is optional, but that really
+ * only applies to inner content (precisely, detached signatures).
+ *
+ * When reading content, missing outer content is therefore treated as an
+ * error.
+ *
+ * When creating content, PKCS7_content_new() must be called before
+ * calling this method, so a NULL p7->d is always an error.
+ */
+ if (p7->d.ptr == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_NO_CONTENT);
+ return NULL;
+ }
+
i=OBJ_obj2nid(p7->type);
p7->state=PKCS7_S_HEADER;
@@ -433,6 +452,16 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, B
unsigned char *ek = NULL, *tkey = NULL;
int eklen = 0, tkeylen = 0;
+ if (p7 == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_INVALID_NULL_POINTER);
+ return NULL;
+ }
+
+ if (p7->d.ptr == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT);
+ return NULL;
+ }
+
i=OBJ_obj2nid(p7->type);
p7->state=PKCS7_S_HEADER;
@@ -752,6 +781,16 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
STACK_OF(PKCS7_SIGNER_INFO) *si_sk=NULL;
ASN1_OCTET_STRING *os=NULL;
+ if (p7 == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_INVALID_NULL_POINTER);
+ return 0;
+ }
+
+ if (p7->d.ptr == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_NO_CONTENT);
+ return 0;
+ }
+
EVP_MD_CTX_init(&ctx_tmp);
i=OBJ_obj2nid(p7->type);
p7->state=PKCS7_S_HEADER;
@@ -796,6 +835,7 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
/* If detached data then the content is excluded */
if(PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) {
M_ASN1_OCTET_STRING_free(os);
+ os = NULL;
p7->d.sign->contents->d.data = NULL;
}
break;
@@ -806,6 +846,7 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
if(PKCS7_type_is_data(p7->d.digest->contents) && p7->detached)
{
M_ASN1_OCTET_STRING_free(os);
+ os = NULL;
p7->d.digest->contents->d.data = NULL;
}
break;
@@ -866,8 +907,7 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
}
}
}
- else if (i == NID_pkcs7_digest)
- {
+ else if (i == NID_pkcs7_digest) {
unsigned char md_data[EVP_MAX_MD_SIZE];
unsigned int md_len;
if (!PKCS7_find_digest(&mdc, bio,
@@ -878,24 +918,31 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len);
}
- if (!PKCS7_is_detached(p7) && !(os->flags & ASN1_STRING_FLAG_NDEF))
- {
- char *cont;
- long contlen;
- btmp=BIO_find_type(bio,BIO_TYPE_MEM);
- if (btmp == NULL)
- {
- PKCS7err(PKCS7_F_PKCS7_DATAFINAL,PKCS7_R_UNABLE_TO_FIND_MEM_BIO);
- goto err;
+ if (!PKCS7_is_detached(p7)) {
+ /*
+ * NOTE(emilia): I think we only reach os == NULL here because detached
+ * digested data support is broken.
+ */
+ if (os == NULL)
+ goto err;
+ if (!(os->flags & ASN1_STRING_FLAG_NDEF)) {
+ char *cont;
+ long contlen;
+ btmp = BIO_find_type(bio, BIO_TYPE_MEM);
+ if (btmp == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_UNABLE_TO_FIND_MEM_BIO);
+ goto err;
}
- contlen = BIO_get_mem_data(btmp, &cont);
- /* Mark the BIO read only then we can use its copy of the data
- * instead of making an extra copy.
- */
- BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY);
- BIO_set_mem_eof_return(btmp, 0);
- ASN1_STRING_set0(os, (unsigned char *)cont, contlen);
+ contlen = BIO_get_mem_data(btmp, &cont);
+ /*
+ * Mark the BIO read only then we can use its copy of the data
+ * instead of making an extra copy.
+ */
+ BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY);
+ BIO_set_mem_eof_return(btmp, 0);
+ ASN1_STRING_set0(os, (unsigned char *)cont, contlen);
}
+ }
ret=1;
err:
EVP_MD_CTX_cleanup(&ctx_tmp);
@@ -971,6 +1018,16 @@ int PKCS7_dataVerify(X509_STORE *cert_store, X509_
STACK_OF(X509) *cert;
X509 *x509;
+ if (p7 == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_INVALID_NULL_POINTER);
+ return 0;
+ }
+
+ if (p7->d.ptr == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_NO_CONTENT);
+ return 0;
+ }
+
if (PKCS7_type_is_signed(p7))
{
cert=p7->d.sign->cert;
Index: crypto/openssl/crypto/pkcs7/pk7_lib.c
===================================================================
--- crypto/openssl/crypto/pkcs7/pk7_lib.c (revision 280181)
+++ crypto/openssl/crypto/pkcs7/pk7_lib.c (working copy)
@@ -71,6 +71,7 @@ long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, cha
switch (cmd)
{
+ /* NOTE(emilia): does not support detached digested data. */
case PKCS7_OP_SET_DETACHED_SIGNATURE:
if (nid == NID_pkcs7_signed)
{
@@ -459,6 +460,8 @@ int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md)
STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7)
{
+ if (p7 == NULL || p7->d.ptr == NULL)
+ return NULL;
if (PKCS7_type_is_signed(p7))
{
return(p7->d.sign->signer_info);
Index: crypto/openssl/doc/crypto/d2i_X509.pod
===================================================================
--- crypto/openssl/doc/crypto/d2i_X509.pod (revision 280181)
+++ crypto/openssl/doc/crypto/d2i_X509.pod (working copy)
@@ -199,6 +199,12 @@ B<*px> is valid is broken and some parts of the re
persist if they are not present in the new one. As a result the use
of this "reuse" behaviour is strongly discouraged.
+Current versions of OpenSSL will not modify B<*px> if an error occurs.
+If parsing succeeds then B<*px> is freed (if it is not NULL) and then
+set to the value of the newly decoded structure. As a result B<*px>
+B<must not> be allocated on the stack or an attempt will be made to
+free an invalid pointer.
+
i2d_X509() will not return an error in many versions of OpenSSL,
if mandatory fields are not initialized due to a programming error
then the encoded structure may contain invalid data or omit the
@@ -210,7 +216,9 @@ always succeed.
d2i_X509(), d2i_X509_bio() and d2i_X509_fp() return a valid B<X509> structure
or B<NULL> if an error occurs. The error code that can be obtained by
-L<ERR_get_error(3)|ERR_get_error(3)>.
+L<ERR_get_error(3)|ERR_get_error(3)>. If the "reuse" capability has been used
+with a valid X509 structure being passed in via B<px> then the object is not
+modified in the event of error.
i2d_X509() returns the number of bytes successfully encoded or a negative
value if an error occurs. The error code can be obtained by
Index: crypto/openssl/ssl/s2_lib.c
===================================================================
--- crypto/openssl/ssl/s2_lib.c (revision 280181)
+++ crypto/openssl/ssl/s2_lib.c (working copy)
@@ -488,7 +488,7 @@ int ssl2_generate_key_material(SSL *s)
OPENSSL_assert(s->session->master_key_length >= 0
&& s->session->master_key_length
- < (int)sizeof(s->session->master_key));
+ <= (int)sizeof(s->session->master_key));
EVP_DigestUpdate(&ctx,s->session->master_key,s->session->master_key_length);
EVP_DigestUpdate(&ctx,&c,1);
c++;
Index: crypto/openssl/ssl/s2_srvr.c
===================================================================
--- crypto/openssl/ssl/s2_srvr.c (revision 280181)
+++ crypto/openssl/ssl/s2_srvr.c (working copy)
@@ -454,9 +454,6 @@ static int get_client_master_key(SSL *s)
SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_NO_PRIVATEKEY);
return(-1);
}
- i=ssl_rsa_private_decrypt(s->cert,s->s2->tmp.enc,
- &(p[s->s2->tmp.clear]),&(p[s->s2->tmp.clear]),
- (s->s2->ssl2_rollback)?RSA_SSLV23_PADDING:RSA_PKCS1_PADDING);
is_export=SSL_C_IS_EXPORT(s->session->cipher);
@@ -475,23 +472,61 @@ static int get_client_master_key(SSL *s)
else
ek=5;
+ /*
+ * The format of the CLIENT-MASTER-KEY message is
+ * 1 byte message type
+ * 3 bytes cipher
+ * 2-byte clear key length (stored in s->s2->tmp.clear)
+ * 2-byte encrypted key length (stored in s->s2->tmp.enc)
+ * 2-byte key args length (IV etc)
+ * clear key
+ * encrypted key
+ * key args
+ *
+ * If the cipher is an export cipher, then the encrypted key bytes
+ * are a fixed portion of the total key (5 or 8 bytes). The size of
+ * this portion is in |ek|. If the cipher is not an export cipher,
+ * then the entire key material is encrypted (i.e., clear key length
+ * must be zero).
+ */
+ if ((!is_export && s->s2->tmp.clear != 0) ||
+ (is_export && s->s2->tmp.clear + ek != EVP_CIPHER_key_length(c))) {
+ ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
+ SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_BAD_LENGTH);
+ return -1;
+ }
+ /*
+ * The encrypted blob must decrypt to the encrypted portion of the key.
+ * Decryption can't be expanding, so if we don't have enough encrypted
+ * bytes to fit the key in the buffer, stop now.
+ */
+ if ((is_export && s->s2->tmp.enc < ek) ||
+ (!is_export && s->s2->tmp.enc < EVP_CIPHER_key_length(c))) {
+ ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+ SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_LENGTH_TOO_SHORT);
+ return -1;
+ }
+
+ i = ssl_rsa_private_decrypt(s->cert, s->s2->tmp.enc,
+ &(p[s->s2->tmp.clear]),
+ &(p[s->s2->tmp.clear]),
+ (s->s2->ssl2_rollback) ? RSA_SSLV23_PADDING :
+ RSA_PKCS1_PADDING);
+
/* bad decrypt */
#if 1
/* If a bad decrypt, continue with protocol but with a
* random master secret (Bleichenbacher attack) */
- if ((i < 0) ||
- ((!is_export && (i != EVP_CIPHER_key_length(c)))
- || (is_export && ((i != ek) || (s->s2->tmp.clear+(unsigned int)i !=
- (unsigned int)EVP_CIPHER_key_length(c))))))
- {
+ if ((i < 0) || ((!is_export && i != EVP_CIPHER_key_length(c))
+ || (is_export && i != ek))) {
ERR_clear_error();
if (is_export)
i=ek;
else
i=EVP_CIPHER_key_length(c);
- if (RAND_pseudo_bytes(p,i) <= 0)
+ if (RAND_pseudo_bytes(&p[s->s2->tmp.clear], i) <= 0)
return 0;
- }
+ }
#else
if (i < 0)
{
@@ -513,7 +548,8 @@ static int get_client_master_key(SSL *s)
}
#endif
- if (is_export) i+=s->s2->tmp.clear;
+ if (is_export)
+ i = EVP_CIPHER_key_length(c);
if (i > SSL_MAX_MASTER_KEY_LENGTH)
{
Index: secure/lib/libcrypto/man/d2i_X509.3
===================================================================
--- secure/lib/libcrypto/man/d2i_X509.3 (revision 280181)
+++ secure/lib/libcrypto/man/d2i_X509.3 (working copy)
@@ -342,6 +342,12 @@ In some versions of OpenSSL the \*(L"reuse\*(R" be
persist if they are not present in the new one. As a result the use
of this \*(L"reuse\*(R" behaviour is strongly discouraged.
.PP
+Current versions of OpenSSL will not modify \fB*px\fR if an error occurs.
+If parsing succeeds then \fB*px\fR is freed (if it is not \s-1NULL\s0) and then
+set to the value of the newly decoded structure. As a result \fB*px\fR
+\&\fBmust not\fR be allocated on the stack or an attempt will be made to
+free an invalid pointer.
+.PP
\&\fIi2d_X509()\fR will not return an error in many versions of OpenSSL,
if mandatory fields are not initialized due to a programming error
then the encoded structure may contain invalid data or omit the
@@ -352,7 +358,9 @@ always succeed.
.IX Header "RETURN VALUES"
\&\fId2i_X509()\fR, \fId2i_X509_bio()\fR and \fId2i_X509_fp()\fR return a valid \fBX509\fR structure
or \fB\s-1NULL\s0\fR if an error occurs. The error code that can be obtained by
-\&\fIERR_get_error\fR\|(3).
+\&\fIERR_get_error\fR\|(3). If the \*(L"reuse\*(R" capability has been used
+with a valid X509 structure being passed in via \fBpx\fR then the object is not
+modified in the event of error.
.PP
\&\fIi2d_X509()\fR returns the number of bytes successfully encoded or a negative
value if an error occurs. The error code can be obtained by