[openssl] master update
Dr. Paul Dale
pauli at openssl.org
Mon Jul 15 22:31:43 UTC 2019
The branch master has been updated
via 0d03acea7aa45e94903fb12186ed6cc324eb1b03 (commit)
via b8805834756434bfc6ee3840e7097e6e1a877905 (commit)
via 15cb0f095878092a625219f58bd915bdf1acc973 (commit)
via 8ae173bb57819a23717fd3c8e7c51cb62f4268d0 (commit)
via 0d345f0e10b14392925479fc61b6c9072a9605a3 (commit)
via 54846b7c6ef5718f507def9d192628133f97fe20 (commit)
from 35e264c03232c7843733caa80f8e16bef7e2e829 (commit)
- Log -----------------------------------------------------------------
commit 0d03acea7aa45e94903fb12186ed6cc324eb1b03
Author: Pauli <paul.dale at oracle.com>
Date: Fri Jul 12 06:27:19 2019 +1000
remove end of line whitespace
Reviewed-by: Matt Caswell <matt at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/9111)
commit b8805834756434bfc6ee3840e7097e6e1a877905
Author: Matt Caswell <matt at openssl.org>
Date: Mon Jun 10 17:52:15 2019 +0100
Convert asn1_dsa.c to use the WPACKET API instead
Reviewed-by: Paul Dale <paul.dale at oracle.com>
(Merged from https://github.com/openssl/openssl/pull/9111)
commit 15cb0f095878092a625219f58bd915bdf1acc973
Author: Matt Caswell <matt at openssl.org>
Date: Mon Jun 10 17:48:26 2019 +0100
Give WPACKET the ability to have a NULL buffer underneath it
This means the WPACKET API can be used for calculating the number of
bytes that would have been written if a non-NULL buffer had been used.
This enables us to calculate the number of length bytes required when
encoding ASN.1
Reviewed-by: Paul Dale <paul.dale at oracle.com>
(Merged from https://github.com/openssl/openssl/pull/9111)
commit 8ae173bb57819a23717fd3c8e7c51cb62f4268d0
Author: Matt Caswell <matt at openssl.org>
Date: Fri Jun 7 17:40:21 2019 +0100
Convert asn1_dsa.c to use the PACKET API instead
Reviewed-by: Paul Dale <paul.dale at oracle.com>
(Merged from https://github.com/openssl/openssl/pull/9111)
commit 0d345f0e10b14392925479fc61b6c9072a9605a3
Author: Matt Caswell <matt at openssl.org>
Date: Fri Jun 7 16:32:49 2019 +0100
Make the PACKET/WPACKET code available to both libcrypto and libssl
Reviewed-by: Paul Dale <paul.dale at oracle.com>
(Merged from https://github.com/openssl/openssl/pull/9111)
commit 54846b7c6ef5718f507def9d192628133f97fe20
Author: David Makepeace <david.p.makepeace at oracle.com>
Date: Mon Jun 3 14:58:54 2019 +1000
Add simple ASN.1 utils for DSA signature DER.
Adds simple utility functions to allow both the default and fips providers to
encode and decode DSA-Sig-Value and ECDSA-Sig-Value (DSA_SIG and ECDSA_SIG
structures) to/from ASN.1 DER without requiring those providers to have a
dependency on the asn1 module.
Reviewed-by: Paul Dale <paul.dale at oracle.com>
Reviewed-by: Matt Caswell <matt at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/9111)
-----------------------------------------------------------------------
Summary of changes:
crypto/asn1_dsa.c | 253 +++++++++++++++++++++
crypto/build.info | 3 +-
crypto/dsa/dsa_asn1.c | 76 ++++++-
crypto/ec/ec_asn1.c | 75 +++++-
crypto/include/internal/asn1_dsa.h | 23 ++
{ssl => crypto}/packet.c | 56 ++++-
ssl/packet_locl.h => include/internal/packet.h | 10 +
ssl/build.info | 6 +-
ssl/record/rec_layer_d1.c | 2 +-
ssl/record/rec_layer_s3.c | 2 +-
ssl/ssl_locl.h | 2 +-
ssl/ssl_rsa.c | 2 +-
test/asn1_dsa_internal_test.c | 184 +++++++++++++++
test/asynciotest.c | 2 +-
test/bad_dtls_test.c | 2 +-
test/build.info | 9 +-
test/clienthellotest.c | 2 +-
test/packettest.c | 2 +-
...ernal_namemap.t => 03-test_internal_asn1_dsa.t} | 4 +-
test/servername_test.c | 2 +-
test/sslbuffertest.c | 2 +-
test/tls13ccstest.c | 2 +-
test/wpackettest.c | 2 +-
23 files changed, 679 insertions(+), 44 deletions(-)
create mode 100644 crypto/asn1_dsa.c
create mode 100644 crypto/include/internal/asn1_dsa.h
rename {ssl => crypto}/packet.c (89%)
rename ssl/packet_locl.h => include/internal/packet.h (98%)
create mode 100644 test/asn1_dsa_internal_test.c
copy test/recipes/{03-test_internal_namemap.t => 03-test_internal_asn1_dsa.t} (82%)
diff --git a/crypto/asn1_dsa.c b/crypto/asn1_dsa.c
new file mode 100644
index 0000000..8423ff8
--- /dev/null
+++ b/crypto/asn1_dsa.c
@@ -0,0 +1,253 @@
+/*
+ * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (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
+ */
+
+/*
+ * A simple ASN.1 DER encoder/decoder for DSA-Sig-Value and ECDSA-Sig-Value.
+ *
+ * DSA-Sig-Value ::= SEQUENCE {
+ * r INTEGER,
+ * s INTEGER
+ * }
+ *
+ * ECDSA-Sig-Value ::= SEQUENCE {
+ * r INTEGER,
+ * s INTEGER
+ * }
+ */
+
+#include <openssl/crypto.h>
+#include <openssl/bn.h>
+#include "internal/asn1_dsa.h"
+#include "internal/packet.h"
+
+#define ID_SEQUENCE 0x30
+#define ID_INTEGER 0x02
+
+/*
+ * Outputs the encoding of the length octets for a DER value with a content
+ * length of cont_len bytes to pkt. The maximum supported content length is
+ * 65535 (0xffff) bytes.
+ *
+ * Returns 1 on success or 0 on error.
+ */
+int encode_der_length(WPACKET *pkt, size_t cont_len)
+{
+ if (cont_len > 0xffff)
+ return 0; /* Too large for supported length encodings */
+
+ if (cont_len > 0xff) {
+ if (!WPACKET_put_bytes_u8(pkt, 0x82)
+ || !WPACKET_put_bytes_u16(pkt, cont_len))
+ return 0;
+ } else {
+ if (cont_len > 0x7f
+ && !WPACKET_put_bytes_u8(pkt, 0x81))
+ return 0;
+ if (!WPACKET_put_bytes_u8(pkt, cont_len))
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
+ * Outputs the DER encoding of a positive ASN.1 INTEGER to pkt.
+ *
+ * Results in an error if n is negative or too large.
+ *
+ * Returns 1 on success or 0 on error.
+ */
+int encode_der_integer(WPACKET *pkt, const BIGNUM *n)
+{
+ unsigned char *bnbytes;
+ size_t cont_len;
+
+ if (BN_is_negative(n))
+ return 0;
+
+ /*
+ * Calculate the ASN.1 INTEGER DER content length for n.
+ * This is the number of whole bytes required to represent n (i.e. rounded
+ * down), plus one.
+ * If n is zero then the content is a single zero byte (length = 1).
+ * If the number of bits of n is a multiple of 8 then an extra zero padding
+ * byte is included to ensure that the value is still treated as positive
+ * in the INTEGER two's complement representation.
+ */
+ cont_len = BN_num_bits(n) / 8 + 1;
+
+ if (!WPACKET_start_sub_packet(pkt)
+ || !WPACKET_put_bytes_u8(pkt, ID_INTEGER)
+ || !encode_der_length(pkt, cont_len)
+ || !WPACKET_allocate_bytes(pkt, cont_len, &bnbytes)
+ || !WPACKET_close(pkt))
+ return 0;
+
+ if (bnbytes != NULL
+ && BN_bn2binpad(n, bnbytes, (int)cont_len) != (int)cont_len)
+ return 0;
+
+ return 1;
+}
+
+/*
+ * Outputs the DER encoding of a DSA-Sig-Value or ECDSA-Sig-Value to pkt. pkt
+ * may be initialised with a NULL buffer which enables pkt to be used to
+ * calulate how many bytes would be needed.
+ *
+ * Returns 1 on success or 0 on error.
+ */
+int encode_der_dsa_sig(WPACKET *pkt, const BIGNUM *r, const BIGNUM *s)
+{
+ WPACKET tmppkt, *dummypkt;
+ size_t cont_len;
+ int isnull = WPACKET_is_null_buf(pkt);
+
+ if (!WPACKET_start_sub_packet(pkt))
+ return 0;
+
+ if (!isnull) {
+ if (!WPACKET_init_null(&tmppkt, 0))
+ return 0;
+ dummypkt = &tmppkt;
+ } else {
+ /* If the input packet has a NULL buffer, we don't need a dummy packet */
+ dummypkt = pkt;
+ }
+
+ /* Calculate the content length */
+ if (!encode_der_integer(dummypkt, r)
+ || !encode_der_integer(dummypkt, s)
+ || !WPACKET_get_length(dummypkt, &cont_len)
+ || (!isnull && !WPACKET_finish(dummypkt))) {
+ if (!isnull)
+ WPACKET_cleanup(dummypkt);
+ return 0;
+ }
+
+ /* Add the tag and length bytes */
+ if (!WPACKET_put_bytes_u8(pkt, ID_SEQUENCE)
+ || !encode_der_length(pkt, cont_len)
+ /*
+ * Really encode the integers. We already wrote to the main pkt
+ * if it had a NULL buffer, so don't do it again
+ */
+ || (!isnull && !encode_der_integer(pkt, r))
+ || (!isnull && !encode_der_integer(pkt, s))
+ || !WPACKET_close(pkt))
+ return 0;
+
+ return 1;
+}
+
+/*
+ * Decodes the DER length octets in pkt and initialises subpkt with the
+ * following bytes of that length.
+ *
+ * Returns 1 on success or 0 on failure.
+ */
+int decode_der_length(PACKET *pkt, PACKET *subpkt)
+{
+ unsigned int byte;
+
+ if (!PACKET_get_1(pkt, &byte))
+ return 0;
+
+ if (byte < 0x80)
+ return PACKET_get_sub_packet(pkt, subpkt, (size_t)byte);
+ if (byte == 0x81)
+ return PACKET_get_length_prefixed_1(pkt, subpkt);
+ if (byte == 0x82)
+ return PACKET_get_length_prefixed_2(pkt, subpkt);
+
+ /* Too large, invalid, or not DER. */
+ return 0;
+}
+
+/*
+ * Decodes a single ASN.1 INTEGER value from pkt, which must be DER encoded,
+ * and updates n with the decoded value.
+ *
+ * The BIGNUM, n, must have already been allocated by calling BN_new().
+ * pkt must not be NULL.
+ *
+ * An attempt to consume more than len bytes results in an error.
+ * Returns 1 on success or 0 on error.
+ *
+ * If the PACKET is supposed to only contain a single INTEGER value with no
+ * trailing garbage then it is up to the caller to verify that all bytes
+ * were consumed.
+ */
+int decode_der_integer(PACKET *pkt, BIGNUM *n)
+{
+ PACKET contpkt, tmppkt;
+ unsigned int tag, tmp;
+
+ /* Check we have an integer and get the content bytes */
+ if (!PACKET_get_1(pkt, &tag)
+ || tag != ID_INTEGER
+ || !decode_der_length(pkt, &contpkt))
+ return 0;
+
+ /* Peek ahead at the first bytes to check for proper encoding */
+ tmppkt = contpkt;
+ /* The INTEGER must be positive */
+ if (!PACKET_get_1(&tmppkt, &tmp)
+ || (tmp & 0x80) != 0)
+ return 0;
+ /* If there a zero padding byte the next byte must have the msb set */
+ if (PACKET_remaining(&tmppkt) > 0 && tmp == 0) {
+ if (!PACKET_get_1(&tmppkt, &tmp)
+ || (tmp & 0x80) == 0)
+ return 0;
+ }
+
+ if (BN_bin2bn(PACKET_data(&contpkt),
+ (int)PACKET_remaining(&contpkt), n) == NULL)
+ return 0;
+
+ return 1;
+}
+
+/*
+ * Decodes a single DSA-Sig-Value or ECDSA-Sig-Value from *ppin, which must be
+ * DER encoded, updates r and s with the decoded values, and increments *ppin
+ * past the data that was consumed.
+ *
+ * The BIGNUMs, r and s, must have already been allocated by calls to BN_new().
+ * ppin and *ppin must not be NULL.
+ *
+ * An attempt to consume more than len bytes results in an error.
+ * Returns the number of bytes of input consumed or 0 if an error occurs.
+ *
+ * If the buffer is supposed to only contain a single [EC]DSA-Sig-Value with no
+ * trailing garbage then it is up to the caller to verify that all bytes
+ * were consumed.
+ */
+size_t decode_der_dsa_sig(BIGNUM *r, BIGNUM *s, const unsigned char **ppin,
+ size_t len)
+{
+ size_t consumed;
+ PACKET pkt, contpkt;
+ unsigned int tag;
+
+ if (!PACKET_buf_init(&pkt, *ppin, len)
+ || !PACKET_get_1(&pkt, &tag)
+ || tag != ID_SEQUENCE
+ || !decode_der_length(&pkt, &contpkt)
+ || !decode_der_integer(&contpkt, r)
+ || !decode_der_integer(&contpkt, s)
+ || PACKET_remaining(&contpkt) != 0)
+ return 0;
+
+ consumed = PACKET_data(&pkt) - *ppin;
+ *ppin += consumed;
+ return consumed;
+}
+
diff --git a/crypto/build.info b/crypto/build.info
index fccca08..90ccbc8 100644
--- a/crypto/build.info
+++ b/crypto/build.info
@@ -75,11 +75,10 @@ SOURCE[../libcrypto]=$UTIL_COMMON \
mem.c mem_sec.c mem_str.c mem_dbg.c \
cversion.c info.c cpt_err.c ebcdic.c uid.c o_time.c o_dir.c \
o_fopen.c getenv.c o_init.c o_fips.c init.c trace.c provider.c \
- $UPLINKSRC
+ asn1_dsa.c packet.c $UPLINKSRC
DEFINE[../libcrypto]=$UTIL_DEFINE $UPLINKDEF
SOURCE[../providers/fips]=$UTIL_COMMON
DEFINE[../providers/fips]=$UTIL_DEFINE
-
DEPEND[cversion.o]=buildinf.h
diff --git a/crypto/dsa/dsa_asn1.c b/crypto/dsa/dsa_asn1.c
index acf80c6..eddcc11 100644
--- a/crypto/dsa/dsa_asn1.c
+++ b/crypto/dsa/dsa_asn1.c
@@ -13,13 +13,7 @@
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/rand.h>
-
-ASN1_SEQUENCE(DSA_SIG) = {
- ASN1_SIMPLE(DSA_SIG, r, CBIGNUM),
- ASN1_SIMPLE(DSA_SIG, s, CBIGNUM)
-} static_ASN1_SEQUENCE_END(DSA_SIG)
-
-IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(DSA_SIG, DSA_SIG, DSA_SIG)
+#include "internal/asn1_dsa.h"
DSA_SIG *DSA_SIG_new(void)
{
@@ -38,6 +32,74 @@ void DSA_SIG_free(DSA_SIG *sig)
OPENSSL_free(sig);
}
+DSA_SIG *d2i_DSA_SIG(DSA_SIG **psig, const unsigned char **ppin, long len)
+{
+ DSA_SIG *sig;
+
+ if (len < 0)
+ return NULL;
+ if (psig != NULL && *psig != NULL) {
+ sig = *psig;
+ } else {
+ sig = DSA_SIG_new();
+ if (sig == NULL)
+ return NULL;
+ }
+ if (sig->r == NULL)
+ sig->r = BN_new();
+ if (sig->s == NULL)
+ sig->s = BN_new();
+ if (decode_der_dsa_sig(sig->r, sig->s, ppin, (size_t)len) == 0) {
+ if (psig == NULL || *psig == NULL)
+ DSA_SIG_free(sig);
+ return NULL;
+ }
+ if (psig != NULL && *psig == NULL)
+ *psig = sig;
+ return sig;
+}
+
+int i2d_DSA_SIG(const DSA_SIG *sig, unsigned char **ppout)
+{
+ BUF_MEM *buf = NULL;
+ size_t encoded_len;
+ WPACKET pkt;
+
+ if (ppout == NULL) {
+ if (!WPACKET_init_null(&pkt, 0))
+ return -1;
+ } else if (*ppout == NULL) {
+ if ((buf = BUF_MEM_new()) == NULL
+ || !WPACKET_init_len(&pkt, buf, 0)) {
+ BUF_MEM_free(buf);
+ return -1;
+ }
+ } else {
+ if (!WPACKET_init_static_len(&pkt, *ppout, SIZE_MAX, 0))
+ return -1;
+ }
+
+ if (!encode_der_dsa_sig(&pkt, sig->r, sig->s)
+ || !WPACKET_get_total_written(&pkt, &encoded_len)
+ || !WPACKET_finish(&pkt)) {
+ BUF_MEM_free(buf);
+ WPACKET_cleanup(&pkt);
+ return -1;
+ }
+
+ if (ppout != NULL) {
+ if (*ppout == NULL) {
+ *ppout = (unsigned char *)buf->data;
+ buf->data = NULL;
+ BUF_MEM_free(buf);
+ } else {
+ *ppout += encoded_len;
+ }
+ }
+
+ return (int)encoded_len;
+}
+
void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
{
if (pr != NULL)
diff --git a/crypto/ec/ec_asn1.c b/crypto/ec/ec_asn1.c
index 35ff948..c2f9679 100644
--- a/crypto/ec/ec_asn1.c
+++ b/crypto/ec/ec_asn1.c
@@ -13,6 +13,7 @@
#include <openssl/asn1t.h>
#include <openssl/objects.h>
#include "internal/nelem.h"
+#include "internal/asn1_dsa.h"
int EC_GROUP_get_basis_type(const EC_GROUP *group)
{
@@ -1137,14 +1138,8 @@ int i2o_ECPublicKey(const EC_KEY *a, unsigned char **out)
return buf_len;
}
-ASN1_SEQUENCE(ECDSA_SIG) = {
- ASN1_SIMPLE(ECDSA_SIG, r, CBIGNUM),
- ASN1_SIMPLE(ECDSA_SIG, s, CBIGNUM)
-} static_ASN1_SEQUENCE_END(ECDSA_SIG)
-
DECLARE_ASN1_FUNCTIONS(ECDSA_SIG)
DECLARE_ASN1_ENCODE_FUNCTIONS_name(ECDSA_SIG, ECDSA_SIG)
-IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(ECDSA_SIG, ECDSA_SIG, ECDSA_SIG)
ECDSA_SIG *ECDSA_SIG_new(void)
{
@@ -1163,6 +1158,74 @@ void ECDSA_SIG_free(ECDSA_SIG *sig)
OPENSSL_free(sig);
}
+ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **psig, const unsigned char **ppin, long len)
+{
+ ECDSA_SIG *sig;
+
+ if (len < 0)
+ return NULL;
+ if (psig != NULL && *psig != NULL) {
+ sig = *psig;
+ } else {
+ sig = ECDSA_SIG_new();
+ if (sig == NULL)
+ return NULL;
+ }
+ if (sig->r == NULL)
+ sig->r = BN_new();
+ if (sig->s == NULL)
+ sig->s = BN_new();
+ if (decode_der_dsa_sig(sig->r, sig->s, ppin, (size_t)len) == 0) {
+ if (psig == NULL || *psig == NULL)
+ ECDSA_SIG_free(sig);
+ return NULL;
+ }
+ if (psig != NULL && *psig == NULL)
+ *psig = sig;
+ return sig;
+}
+
+int i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **ppout)
+{
+ BUF_MEM *buf = NULL;
+ size_t encoded_len;
+ WPACKET pkt;
+
+ if (ppout == NULL) {
+ if (!WPACKET_init_null(&pkt, 0))
+ return -1;
+ } else if (*ppout == NULL) {
+ if ((buf = BUF_MEM_new()) == NULL
+ || !WPACKET_init_len(&pkt, buf, 0)) {
+ BUF_MEM_free(buf);
+ return -1;
+ }
+ } else {
+ if (!WPACKET_init_static_len(&pkt, *ppout, SIZE_MAX, 0))
+ return -1;
+ }
+
+ if (!encode_der_dsa_sig(&pkt, sig->r, sig->s)
+ || !WPACKET_get_total_written(&pkt, &encoded_len)
+ || !WPACKET_finish(&pkt)) {
+ BUF_MEM_free(buf);
+ WPACKET_cleanup(&pkt);
+ return -1;
+ }
+
+ if (ppout != NULL) {
+ if (*ppout == NULL) {
+ *ppout = (unsigned char *)buf->data;
+ buf->data = NULL;
+ BUF_MEM_free(buf);
+ } else {
+ *ppout += encoded_len;
+ }
+ }
+
+ return (int)encoded_len;
+}
+
void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
{
if (pr != NULL)
diff --git a/crypto/include/internal/asn1_dsa.h b/crypto/include/internal/asn1_dsa.h
new file mode 100644
index 0000000..d257051
--- /dev/null
+++ b/crypto/include/internal/asn1_dsa.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (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
+ */
+
+#ifndef HEADER_ASN1_DSA_H
+# define HEADER_ASN1_DSA_H
+
+#include "internal/packet.h"
+
+int encode_der_length(WPACKET *pkt, size_t cont_len);
+int encode_der_integer(WPACKET *pkt, const BIGNUM *n);
+int encode_der_dsa_sig(WPACKET *pkt, const BIGNUM *r, const BIGNUM *s);
+int decode_der_length(PACKET *pkt, PACKET *subpkt);
+int decode_der_integer(PACKET *pkt, BIGNUM *n);
+size_t decode_der_dsa_sig(BIGNUM *r, BIGNUM *s, const unsigned char **ppin,
+ size_t len);
+
+#endif
diff --git a/ssl/packet.c b/crypto/packet.c
similarity index 89%
rename from ssl/packet.c
rename to crypto/packet.c
index 26cf1eb..75a0317 100644
--- a/ssl/packet.c
+++ b/crypto/packet.c
@@ -8,7 +8,7 @@
*/
#include "internal/cryptlib.h"
-#include "packet_locl.h"
+#include "internal/packet.h"
#include <openssl/sslerr.h>
#define DEFAULT_BUF_SIZE 256
@@ -35,7 +35,10 @@ int WPACKET_sub_allocate_bytes__(WPACKET *pkt, size_t len,
}
#define GETBUF(p) (((p)->staticbuf != NULL) \
- ? (p)->staticbuf : (unsigned char *)(p)->buf->data)
+ ? (p)->staticbuf \
+ : ((p)->buf != NULL \
+ ? (unsigned char *)(p)->buf->data \
+ : NULL))
int WPACKET_reserve_bytes(WPACKET *pkt, size_t len, unsigned char **allocbytes)
{
@@ -46,7 +49,7 @@ int WPACKET_reserve_bytes(WPACKET *pkt, size_t len, unsigned char **allocbytes)
if (pkt->maxsize - pkt->written < len)
return 0;
- if (pkt->staticbuf == NULL && (pkt->buf->length - pkt->written < len)) {
+ if (pkt->buf != NULL && (pkt->buf->length - pkt->written < len)) {
size_t newlen;
size_t reflen;
@@ -74,7 +77,8 @@ int WPACKET_sub_reserve_bytes__(WPACKET *pkt, size_t len,
if (!WPACKET_reserve_bytes(pkt, lenbytes + len, allocbytes))
return 0;
- *allocbytes += lenbytes;
+ if (*allocbytes != NULL)
+ *allocbytes += lenbytes;
return 1;
}
@@ -110,7 +114,7 @@ static int wpacket_intern_init_len(WPACKET *pkt, size_t lenbytes)
pkt->subs = NULL;
return 0;
}
- pkt->subs->packet_len = lenchars - GETBUF(pkt);
+ pkt->subs->packet_len = 0;
return 1;
}
@@ -149,6 +153,15 @@ int WPACKET_init(WPACKET *pkt, BUF_MEM *buf)
return WPACKET_init_len(pkt, buf, 0);
}
+int WPACKET_init_null(WPACKET *pkt, size_t lenbytes)
+{
+ pkt->staticbuf = NULL;
+ pkt->buf = NULL;
+ pkt->maxsize = maxmaxsize(lenbytes);
+
+ return wpacket_intern_init_len(pkt, 0);
+}
+
int WPACKET_set_flags(WPACKET *pkt, unsigned int flags)
{
/* Internal API, so should not fail */
@@ -163,6 +176,9 @@ int WPACKET_set_flags(WPACKET *pkt, unsigned int flags)
/* Store the |value| of length |len| at location |data| */
static int put_value(unsigned char *data, size_t value, size_t len)
{
+ if (data == NULL)
+ return 1;
+
for (data += len - 1; len > 0; len--) {
*data = (unsigned char)(value & 0xff);
data--;
@@ -209,10 +225,14 @@ static int wpacket_intern_close(WPACKET *pkt, WPACKET_SUB *sub, int doclose)
}
/* Write out the WPACKET length if needed */
- if (sub->lenbytes > 0
- && !put_value(&GETBUF(pkt)[sub->packet_len], packlen,
+ if (sub->lenbytes > 0) {
+ unsigned char *buf = GETBUF(pkt);
+
+ if (buf != NULL
+ && !put_value(&buf[sub->packet_len], packlen,
sub->lenbytes))
return 0;
+ }
if (doclose) {
pkt->subs = sub->parent;
@@ -293,10 +313,10 @@ int WPACKET_start_sub_packet_len__(WPACKET *pkt, size_t lenbytes)
return 1;
}
+ sub->packet_len = pkt->written;
+
if (!WPACKET_allocate_bytes(pkt, lenbytes, &lenchars))
return 0;
- /* Convert to an offset in case the underlying BUF_MEM gets realloc'd */
- sub->packet_len = lenchars - GETBUF(pkt);
return 1;
}
@@ -354,7 +374,8 @@ int WPACKET_memset(WPACKET *pkt, int ch, size_t len)
if (!WPACKET_allocate_bytes(pkt, len, &dest))
return 0;
- memset(dest, ch, len);
+ if (dest != NULL)
+ memset(dest, ch, len);
return 1;
}
@@ -369,7 +390,8 @@ int WPACKET_memcpy(WPACKET *pkt, const void *src, size_t len)
if (!WPACKET_allocate_bytes(pkt, len, &dest))
return 0;
- memcpy(dest, src, len);
+ if (dest != NULL)
+ memcpy(dest, src, len);
return 1;
}
@@ -409,7 +431,17 @@ int WPACKET_get_length(WPACKET *pkt, size_t *len)
unsigned char *WPACKET_get_curr(WPACKET *pkt)
{
- return GETBUF(pkt) + pkt->curr;
+ unsigned char *buf = GETBUF(pkt);
+
+ if (buf == NULL)
+ return NULL;
+
+ return buf + pkt->curr;
+}
+
+int WPACKET_is_null_buf(WPACKET *pkt)
+{
+ return pkt->buf == NULL && pkt->staticbuf == NULL;
}
void WPACKET_cleanup(WPACKET *pkt)
diff --git a/ssl/packet_locl.h b/include/internal/packet.h
similarity index 98%
rename from ssl/packet_locl.h
rename to include/internal/packet.h
index 9f8a098..69a6bd1 100644
--- a/ssl/packet_locl.h
+++ b/include/internal/packet.h
@@ -670,6 +670,13 @@ int WPACKET_init_len(WPACKET *pkt, BUF_MEM *buf, size_t lenbytes);
int WPACKET_init(WPACKET *pkt, BUF_MEM *buf);
/*
+ * Same as WPACKET_init_len except there is no underlying buffer. No data is
+ * ever actually written. We just keep track of how much data would have been
+ * written if a buffer was there.
+ */
+int WPACKET_init_null(WPACKET *pkt, size_t lenbytes);
+
+/*
* Same as WPACKET_init_len except we do not use a growable BUF_MEM structure.
* A fixed buffer of memory |buf| of size |len| is used instead. A failure will
* occur if you attempt to write beyond the end of the buffer
@@ -868,6 +875,9 @@ int WPACKET_get_length(WPACKET *pkt, size_t *len);
*/
unsigned char *WPACKET_get_curr(WPACKET *pkt);
+/* Returns true if the underlying buffer is actually NULL */
+int WPACKET_is_null_buf(WPACKET *pkt);
+
/* Release resources in a WPACKET if a failure has occurred. */
void WPACKET_cleanup(WPACKET *pkt);
diff --git a/ssl/build.info b/ssl/build.info
index bb2f1de..152810b 100644
--- a/ssl/build.info
+++ b/ssl/build.info
@@ -1,6 +1,10 @@
LIBS=../libssl
+#TODO: For now we just include the libcrypto packet.c in libssl as well. We
+# could either continue to do it like this, or export all the WPACKET
+# symbols so that libssl can use them like any other. Probably would do
+# this privately so it does not become part of the public API.
SOURCE[../libssl]=\
- pqueue.c packet.c \
+ pqueue.c ../crypto/packet.c \
statem/statem_srvr.c statem/statem_clnt.c s3_lib.c s3_enc.c record/rec_layer_s3.c \
statem/statem_lib.c statem/extensions.c statem/extensions_srvr.c \
statem/extensions_clnt.c statem/extensions_cust.c s3_cbc.c s3_msg.c \
diff --git a/ssl/record/rec_layer_d1.c b/ssl/record/rec_layer_d1.c
index 821c9cc..1256f9e 100644
--- a/ssl/record/rec_layer_d1.c
+++ b/ssl/record/rec_layer_d1.c
@@ -13,7 +13,7 @@
#include <openssl/evp.h>
#include <openssl/buffer.h>
#include "record_locl.h"
-#include "../packet_locl.h"
+#include "internal/packet.h"
#include "internal/cryptlib.h"
int DTLS_RECORD_LAYER_new(RECORD_LAYER *rl)
diff --git a/ssl/record/rec_layer_s3.c b/ssl/record/rec_layer_s3.c
index a991132..9efaf54 100644
--- a/ssl/record/rec_layer_s3.c
+++ b/ssl/record/rec_layer_s3.c
@@ -15,7 +15,7 @@
#include <openssl/buffer.h>
#include <openssl/rand.h>
#include "record_locl.h"
-#include "../packet_locl.h"
+#include "internal/packet.h"
#if defined(OPENSSL_SMALL_FOOTPRINT) || \
!( defined(AES_ASM) && ( \
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index 269f542..a4278b2 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -30,7 +30,7 @@
# include <openssl/ct.h>
# include "record/record.h"
# include "statem/statem.h"
-# include "packet_locl.h"
+# include "internal/packet.h"
# include "internal/dane.h"
# include "internal/refcount.h"
# include "internal/tsan_assist.h"
diff --git a/ssl/ssl_rsa.c b/ssl/ssl_rsa.c
index 897c8f2..2c447ee 100644
--- a/ssl/ssl_rsa.c
+++ b/ssl/ssl_rsa.c
@@ -9,7 +9,7 @@
#include <stdio.h>
#include "ssl_locl.h"
-#include "packet_locl.h"
+#include "internal/packet.h"
#include <openssl/bio.h>
#include <openssl/objects.h>
#include <openssl/evp.h>
diff --git a/test/asn1_dsa_internal_test.c b/test/asn1_dsa_internal_test.c
new file mode 100644
index 0000000..a62f5e4
--- /dev/null
+++ b/test/asn1_dsa_internal_test.c
@@ -0,0 +1,184 @@
+/*
+ * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (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 <string.h>
+
+#include <openssl/bn.h>
+#include "internal/asn1_dsa.h"
+#include "testutil.h"
+
+static unsigned char t_dsa_sig[] = {
+ 0x30, 0x06, /* SEQUENCE tag + length */
+ 0x02, 0x01, 0x01, /* INTEGER tag + length + content */
+ 0x02, 0x01, 0x02 /* INTEGER tag + length + content */
+};
+
+static unsigned char t_dsa_sig_extra[] = {
+ 0x30, 0x06, /* SEQUENCE tag + length */
+ 0x02, 0x01, 0x01, /* INTEGER tag + length + content */
+ 0x02, 0x01, 0x02, /* INTEGER tag + length + content */
+ 0x05, 0x00 /* NULL tag + length */
+};
+
+static unsigned char t_dsa_sig_msb[] = {
+ 0x30, 0x08, /* SEQUENCE tag + length */
+ 0x02, 0x02, 0x00, 0x81, /* INTEGER tag + length + content */
+ 0x02, 0x02, 0x00, 0x82 /* INTEGER tag + length + content */
+};
+
+static unsigned char t_dsa_sig_two[] = {
+ 0x30, 0x08, /* SEQUENCE tag + length */
+ 0x02, 0x02, 0x01, 0x00, /* INTEGER tag + length + content */
+ 0x02, 0x02, 0x02, 0x00 /* INTEGER tag + length + content */
+};
+
+/*
+ * Badly coded ASN.1 INTEGER zero wrapped in a sequence along with another
+ * (valid) INTEGER.
+ */
+static unsigned char t_invalid_int_zero[] = {
+ 0x30, 0x05, /* SEQUENCE tag + length */
+ 0x02, 0x00, /* INTEGER tag + length */
+ 0x02, 0x01, 0x2a /* INTEGER tag + length */
+};
+
+/*
+ * Badly coded ASN.1 INTEGER (with leading zeros) wrapped in a sequence along
+ * with another (valid) INTEGER.
+ */
+static unsigned char t_invalid_int[] = {
+ 0x30, 0x07, /* SEQUENCE tag + length */
+ 0x02, 0x02, 0x00, 0x7f, /* INTEGER tag + length */
+ 0x02, 0x01, 0x2a /* INTEGER tag + length */
+};
+
+/*
+ * Negative ASN.1 INTEGER wrapped in a sequence along with another
+ * (valid) INTEGER.
+ */
+static unsigned char t_neg_int[] = {
+ 0x30, 0x06, /* SEQUENCE tag + length */
+ 0x02, 0x01, 0xaa, /* INTEGER tag + length */
+ 0x02, 0x01, 0x2a /* INTEGER tag + length */
+};
+
+static unsigned char t_trunc_der[] = {
+ 0x30, 0x08, /* SEQUENCE tag + length */
+ 0x02, 0x02, 0x00, 0x81, /* INTEGER tag + length */
+ 0x02, 0x02, 0x00 /* INTEGER tag + length */
+};
+
+static unsigned char t_trunc_seq[] = {
+ 0x30, 0x07, /* SEQUENCE tag + length */
+ 0x02, 0x02, 0x00, 0x81, /* INTEGER tag + length */
+ 0x02, 0x02, 0x00, 0x82 /* INTEGER tag + length */
+};
+
+static int test_decode(void)
+{
+ int rv = 0;
+ BIGNUM *r;
+ BIGNUM *s;
+ const unsigned char *pder;
+
+ r = BN_new();
+ s = BN_new();
+
+ /* Positive tests */
+ pder = t_dsa_sig;
+ if (decode_der_dsa_sig(r, s, &pder, sizeof(t_dsa_sig)) == 0
+ || !TEST_ptr_eq(pder, (t_dsa_sig + sizeof(t_dsa_sig)))
+ || !TEST_BN_eq_word(r, 1) || !TEST_BN_eq_word(s, 2)) {
+ TEST_info("asn1_dsa test_decode: t_dsa_sig failed");
+ goto fail;
+ }
+
+ BN_clear(r);
+ BN_clear(s);
+ pder = t_dsa_sig_extra;
+ if (decode_der_dsa_sig(r, s, &pder, sizeof(t_dsa_sig_extra)) == 0
+ || !TEST_ptr_eq(pder,
+ (t_dsa_sig_extra + sizeof(t_dsa_sig_extra) - 2))
+ || !TEST_BN_eq_word(r, 1) || !TEST_BN_eq_word(s, 2)) {
+ TEST_info("asn1_dsa test_decode: t_dsa_sig_extra failed");
+ goto fail;
+ }
+
+ BN_clear(r);
+ BN_clear(s);
+ pder = t_dsa_sig_msb;
+ if (decode_der_dsa_sig(r, s, &pder, sizeof(t_dsa_sig_msb)) == 0
+ || !TEST_ptr_eq(pder, (t_dsa_sig_msb + sizeof(t_dsa_sig_msb)))
+ || !TEST_BN_eq_word(r, 0x81) || !TEST_BN_eq_word(s, 0x82)) {
+ TEST_info("asn1_dsa test_decode: t_dsa_sig_msb failed");
+ goto fail;
+ }
+
+ BN_clear(r);
+ BN_clear(s);
+ pder = t_dsa_sig_two;
+ if (decode_der_dsa_sig(r, s, &pder, sizeof(t_dsa_sig_two)) == 0
+ || !TEST_ptr_eq(pder, (t_dsa_sig_two + sizeof(t_dsa_sig_two)))
+ || !TEST_BN_eq_word(r, 0x100) || !TEST_BN_eq_word(s, 0x200)) {
+ TEST_info("asn1_dsa test_decode: t_dsa_sig_two failed");
+ goto fail;
+ }
+
+ /* Negative tests */
+ pder = t_invalid_int_zero;
+ if (decode_der_dsa_sig(r, s, &pder, sizeof(t_invalid_int_zero)) != 0) {
+ TEST_info("asn1_dsa test_decode: Expected t_invalid_int_zero to fail");
+ goto fail;
+ }
+
+ BN_clear(r);
+ BN_clear(s);
+ pder = t_invalid_int;
+ if (decode_der_dsa_sig(r, s, &pder, sizeof(t_invalid_int)) != 0) {
+ TEST_info("asn1_dsa test_decode: Expected t_invalid_int to fail");
+ goto fail;
+ }
+
+ BN_clear(r);
+ BN_clear(s);
+ pder = t_neg_int;
+ if (decode_der_dsa_sig(r, s, &pder, sizeof(t_neg_int)) != 0) {
+ TEST_info("asn1_dsa test_decode: Expected t_neg_int to fail");
+ goto fail;
+ }
+
+ BN_clear(r);
+ BN_clear(s);
+ pder = t_trunc_der;
+ if (decode_der_dsa_sig(r, s, &pder, sizeof(t_trunc_der)) != 0) {
+ TEST_info("asn1_dsa test_decode: Expected fail t_trunc_der");
+ goto fail;
+ }
+
+ BN_clear(r);
+ BN_clear(s);
+ pder = t_trunc_seq;
+ if (decode_der_dsa_sig(r, s, &pder, sizeof(t_trunc_seq)) != 0) {
+ TEST_info("asn1_dsa test_decode: Expected fail t_trunc_seq");
+ goto fail;
+ }
+
+ rv = 1;
+fail:
+ BN_free(r);
+ BN_free(s);
+ return rv;
+}
+
+int setup_tests(void)
+{
+ ADD_TEST(test_decode);
+ return 1;
+}
diff --git a/test/asynciotest.c b/test/asynciotest.c
index 3bba098..bf0a205 100644
--- a/test/asynciotest.c
+++ b/test/asynciotest.c
@@ -13,7 +13,7 @@
#include <openssl/bio.h>
#include <openssl/err.h>
-#include "../ssl/packet_locl.h"
+#include "internal/packet.h"
#include "ssltestlib.h"
#include "testutil.h"
diff --git a/test/bad_dtls_test.c b/test/bad_dtls_test.c
index 5f6b6a9..66b5e1d 100644
--- a/test/bad_dtls_test.c
+++ b/test/bad_dtls_test.c
@@ -37,7 +37,7 @@
#include <openssl/err.h>
#include <openssl/rand.h>
#include <openssl/kdf.h>
-#include "../ssl/packet_locl.h"
+#include "internal/packet.h"
#include "internal/nelem.h"
#include "testutil.h"
diff --git a/test/build.info b/test/build.info
index f5b802d..e38f142 100644
--- a/test/build.info
+++ b/test/build.info
@@ -469,7 +469,8 @@ IF[{- !$disabled{tests} -}]
PROGRAMS{noinst}=asn1_internal_test modes_internal_test x509_internal_test \
tls13encryptiontest wpackettest ctype_internal_test \
rdrand_sanitytest property_test \
- rsa_sp800_56b_test bn_internal_test
+ rsa_sp800_56b_test bn_internal_test \
+ asn1_dsa_internal_test
IF[{- !$disabled{poly1305} -}]
PROGRAMS{noinst}=poly1305_internal_test
@@ -561,6 +562,10 @@ IF[{- !$disabled{tests} -}]
SOURCE[bn_internal_test]=bn_internal_test.c
INCLUDE[bn_internal_test]=.. ../include ../crypto/include ../crypto/bn ../apps/include
DEPEND[bn_internal_test]=../libcrypto.a libtestutil.a
+
+ SOURCE[asn1_dsa_internal_test]=asn1_dsa_internal_test.c
+ INCLUDE[asn1_dsa_internal_test]=.. ../include ../apps/include ../crypto/include
+ DEPEND[asn1_dsa_internal_test]=../libcrypto.a libtestutil.a
ENDIF
IF[{- !$disabled{mdc2} -}]
@@ -582,7 +587,7 @@ IF[{- !$disabled{tests} -}]
IF[{- !$disabled{shared} -}]
PROGRAMS{noinst}=tls13secretstest
SOURCE[tls13secretstest]=tls13secretstest.c
- SOURCE[tls13secretstest]= ../ssl/tls13_enc.c ../ssl/packet.c
+ SOURCE[tls13secretstest]= ../ssl/tls13_enc.c ../crypto/packet.c
INCLUDE[tls13secretstest]=.. ../include ../apps/include
DEPEND[tls13secretstest]=../libcrypto ../libssl libtestutil.a
ENDIF
diff --git a/test/clienthellotest.c b/test/clienthellotest.c
index 0afad6d..03b8745 100644
--- a/test/clienthellotest.c
+++ b/test/clienthellotest.c
@@ -17,7 +17,7 @@
#include <openssl/err.h>
#include <time.h>
-#include "../ssl/packet_locl.h"
+#include "internal/packet.h"
#include "testutil.h"
diff --git a/test/packettest.c b/test/packettest.c
index 41d938a..2d6c2a6 100644
--- a/test/packettest.c
+++ b/test/packettest.c
@@ -7,7 +7,7 @@
* https://www.openssl.org/source/license.html
*/
-#include "../ssl/packet_locl.h"
+#include "internal/packet.h"
#include "testutil.h"
#define BUF_LEN 255
diff --git a/test/recipes/03-test_internal_namemap.t b/test/recipes/03-test_internal_asn1_dsa.t
similarity index 82%
copy from test/recipes/03-test_internal_namemap.t
copy to test/recipes/03-test_internal_asn1_dsa.t
index 9214242..ecacac7 100644
--- a/test/recipes/03-test_internal_namemap.t
+++ b/test/recipes/03-test_internal_asn1_dsa.t
@@ -11,6 +11,6 @@ use OpenSSL::Test; # get 'plan'
use OpenSSL::Test::Simple;
use OpenSSL::Test::Utils;
-setup("test_internal_namemap");
+setup("test_internal_asn1_dsa");
-simple_test("test_internal_namemap", "namemap_internal_test");
+simple_test("test_internal_asn1_dsa", "asn1_dsa_internal_test");
diff --git a/test/servername_test.c b/test/servername_test.c
index 86d261f..3d19265 100644
--- a/test/servername_test.c
+++ b/test/servername_test.c
@@ -18,7 +18,7 @@
#include <openssl/err.h>
#include <time.h>
-#include "../ssl/packet_locl.h"
+#include "internal/packet.h"
#include "testutil.h"
#include "internal/nelem.h"
diff --git a/test/sslbuffertest.c b/test/sslbuffertest.c
index 9a5ec2b..e8293f7 100644
--- a/test/sslbuffertest.c
+++ b/test/sslbuffertest.c
@@ -13,7 +13,7 @@
#include <openssl/bio.h>
#include <openssl/err.h>
-#include "../ssl/packet_locl.h"
+#include "internal/packet.h"
#include "ssltestlib.h"
#include "testutil.h"
diff --git a/test/tls13ccstest.c b/test/tls13ccstest.c
index 1d0a268..999ca57 100644
--- a/test/tls13ccstest.c
+++ b/test/tls13ccstest.c
@@ -11,7 +11,7 @@
#include <string.h>
#include "ssltestlib.h"
#include "testutil.h"
-#include "../ssl/packet_locl.h"
+#include "internal/packet.h"
static char *cert = NULL;
static char *privkey = NULL;
diff --git a/test/wpackettest.c b/test/wpackettest.c
index 0a27c63..abb001e 100644
--- a/test/wpackettest.c
+++ b/test/wpackettest.c
@@ -9,7 +9,7 @@
#include <string.h>
#include <openssl/buffer.h>
-#include "../ssl/packet_locl.h"
+#include "internal/packet.h"
#include "testutil.h"
static const unsigned char simple1[] = { 0xff };
More information about the openssl-commits
mailing list