1739 lines
70 KiB
Diff
1739 lines
70 KiB
Diff
commit 0f7122d4e98d6d3ba34492fd6eb517b0933f39bb
|
|
Author: Ingo Franzki <ifranzki@linux.ibm.com>
|
|
Date: Mon Mar 30 10:19:40 2026 +0200
|
|
|
|
COMMON: Fix possible out-of-bounds access in BER decode functions
|
|
|
|
When decoding BER encoded data the length of the BER encoded data as well as
|
|
any length fields inside the BER encoded data must be validated to not cause
|
|
an out-of-bounds access to data behind the BER encoded data.
|
|
|
|
Add length parameters to any of the BER decoder functions to allow validation
|
|
of the decoded length information.
|
|
|
|
Reported-by: Sebastián Alba <sebasjosue84@gmail.com>
|
|
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
|
|
|
|
diff --git a/usr/lib/cca_stdll/cca_specific.c b/usr/lib/cca_stdll/cca_specific.c
|
|
index 80369248..2e5ea877 100644
|
|
--- a/usr/lib/cca_stdll/cca_specific.c
|
|
+++ b/usr/lib/cca_stdll/cca_specific.c
|
|
@@ -8667,8 +8667,8 @@ static CK_RV import_ec_pubkey(STDLL_TokData_t *tokdata, TEMPLATE *pub_templ)
|
|
return rc;
|
|
}
|
|
|
|
- rc = ber_decode_OCTET_STRING(attr->pValue, &pubkey, &publen,
|
|
- &field_len);
|
|
+ rc = ber_decode_OCTET_STRING(attr->pValue, attr->ulValueLen,
|
|
+ &pubkey, &publen, &field_len);
|
|
if (rc != CKR_OK || attr->ulValueLen != field_len) {
|
|
TRACE_DEVEL("ber decoding of public key failed\n");
|
|
return CKR_ATTRIBUTE_VALUE_INVALID;
|
|
diff --git a/usr/lib/common/asn1.c b/usr/lib/common/asn1.c
|
|
index 631978ed..7a84d315 100644
|
|
--- a/usr/lib/common/asn1.c
|
|
+++ b/usr/lib/common/asn1.c
|
|
@@ -155,13 +155,13 @@ CK_ULONG ber_encode_INTEGER(CK_BBOOL length_only,
|
|
|
|
//
|
|
//
|
|
-CK_RV ber_decode_INTEGER(CK_BYTE *ber_int,
|
|
+CK_RV ber_decode_INTEGER(CK_BYTE *ber_int, CK_ULONG ber_int_len,
|
|
CK_BYTE **data, CK_ULONG *data_len,
|
|
CK_ULONG *field_len)
|
|
{
|
|
CK_ULONG len, length_octets;
|
|
|
|
- if (!ber_int) {
|
|
+ if (ber_int == NULL || ber_int_len < 2) {
|
|
TRACE_ERROR("Invalid function argument.\n");
|
|
return CKR_FUNCTION_FAILED;
|
|
}
|
|
@@ -181,9 +181,13 @@ CK_RV ber_decode_INTEGER(CK_BYTE *ber_int,
|
|
//
|
|
if ((ber_int[1] & 0x80) == 0) {
|
|
len = ber_int[1] & 0x7F;
|
|
+ if (1 + 1 + len > ber_int_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
*data = &ber_int[2];
|
|
*data_len = len;
|
|
- if (ber_int[2] == 0x00) {
|
|
+ if (len > 0 && ber_int[2] == 0x00) {
|
|
*data = &ber_int[3];
|
|
*data_len = len - 1;
|
|
}
|
|
@@ -192,12 +196,20 @@ CK_RV ber_decode_INTEGER(CK_BYTE *ber_int,
|
|
}
|
|
|
|
length_octets = ber_int[1] & 0x7F;
|
|
+ if (1 + 1 + length_octets > ber_int_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
|
|
if (length_octets == 1) {
|
|
len = ber_int[2];
|
|
+ if (1 + (1 + 1) + len > ber_int_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
*data = &ber_int[3];
|
|
*data_len = len;
|
|
- if (ber_int[3] == 0x00) {
|
|
+ if (len > 0 && ber_int[3] == 0x00) {
|
|
*data = &ber_int[4];
|
|
*data_len = len - 1;
|
|
}
|
|
@@ -209,9 +221,13 @@ CK_RV ber_decode_INTEGER(CK_BYTE *ber_int,
|
|
len = ber_int[2];
|
|
len = len << 8;
|
|
len |= ber_int[3];
|
|
+ if (1 + (1 + 2) + len > ber_int_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
*data = &ber_int[4];
|
|
*data_len = len;
|
|
- if (ber_int[4] == 0x00) {
|
|
+ if (len > 0 && ber_int[4] == 0x00) {
|
|
*data = &ber_int[5];
|
|
*data_len = len - 1;
|
|
}
|
|
@@ -225,9 +241,13 @@ CK_RV ber_decode_INTEGER(CK_BYTE *ber_int,
|
|
len |= ber_int[3];
|
|
len = len << 8;
|
|
len |= ber_int[4];
|
|
+ if (1 + (1 + 3) + len > ber_int_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
*data = &ber_int[5];
|
|
*data_len = len;
|
|
- if (ber_int[5] == 0x00) {
|
|
+ if (len > 0 && ber_int[5] == 0x00) {
|
|
*data = &ber_int[6];
|
|
*data_len = len - 1;
|
|
}
|
|
@@ -343,7 +363,7 @@ CK_RV ber_encode_OCTET_STRING(CK_BBOOL length_only,
|
|
|
|
//
|
|
//
|
|
-CK_RV ber_decode_OCTET_STRING(CK_BYTE *str,
|
|
+CK_RV ber_decode_OCTET_STRING(CK_BYTE *str, CK_ULONG str_len,
|
|
CK_BYTE **data,
|
|
CK_ULONG *data_len, CK_ULONG *field_len)
|
|
{
|
|
@@ -352,7 +372,7 @@ CK_RV ber_decode_OCTET_STRING(CK_BYTE *str,
|
|
// I only support decoding primitive OCTET STRINGS
|
|
//
|
|
|
|
- if (!str) {
|
|
+ if (!str || str_len < 2) {
|
|
TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
return CKR_FUNCTION_FAILED;
|
|
}
|
|
@@ -364,6 +384,10 @@ CK_RV ber_decode_OCTET_STRING(CK_BYTE *str,
|
|
//
|
|
if ((str[1] & 0x80) == 0) {
|
|
len = str[1] & 0x7F;
|
|
+ if (1 + 1 + len > str_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
|
|
*data = &str[2];
|
|
*data_len = len;
|
|
@@ -372,9 +396,17 @@ CK_RV ber_decode_OCTET_STRING(CK_BYTE *str,
|
|
}
|
|
|
|
length_octets = str[1] & 0x7F;
|
|
+ if (1 + 1 + length_octets > str_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
|
|
if (length_octets == 1) {
|
|
len = str[2];
|
|
+ if (1 + (1 + 1) + len > str_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
|
|
*data = &str[3];
|
|
*data_len = len;
|
|
@@ -386,6 +418,10 @@ CK_RV ber_decode_OCTET_STRING(CK_BYTE *str,
|
|
len = str[2];
|
|
len = len << 8;
|
|
len |= str[3];
|
|
+ if (1 + (1 + 2) + len > str_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
|
|
*data = &str[4];
|
|
*data_len = len;
|
|
@@ -399,6 +435,10 @@ CK_RV ber_decode_OCTET_STRING(CK_BYTE *str,
|
|
len |= str[3];
|
|
len = len << 8;
|
|
len |= str[4];
|
|
+ if (1 + (1 + 3) + len > str_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
|
|
*data = &str[5];
|
|
*data_len = len;
|
|
@@ -515,13 +555,13 @@ CK_ULONG ber_encode_BIT_STRING(CK_BBOOL length_only,
|
|
* The first byte of output parm *data is the number of unused bits and must
|
|
* be removed later by the calling function.
|
|
*/
|
|
-CK_RV ber_decode_BIT_STRING(CK_BYTE *str,
|
|
+CK_RV ber_decode_BIT_STRING(CK_BYTE *str, CK_ULONG str_len,
|
|
CK_BYTE **data,
|
|
CK_ULONG *data_len, CK_ULONG *field_len)
|
|
{
|
|
CK_ULONG len, length_octets;
|
|
|
|
- if (!str) {
|
|
+ if (!str || str_len < 2) {
|
|
TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
return CKR_FUNCTION_FAILED;
|
|
}
|
|
@@ -532,6 +572,15 @@ CK_RV ber_decode_BIT_STRING(CK_BYTE *str,
|
|
|
|
if ((str[1] & 0x80) == 0) {
|
|
len = str[1] & 0x7F;
|
|
+ if (1 + 1 + len > str_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
+ if (len < 1) {
|
|
+ TRACE_ERROR("BER length is too small to include the "
|
|
+ "unused-bits-byte\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
|
|
*data = &str[2];
|
|
*data_len = len;
|
|
@@ -540,9 +589,22 @@ CK_RV ber_decode_BIT_STRING(CK_BYTE *str,
|
|
}
|
|
|
|
length_octets = str[1] & 0x7F;
|
|
+ if (1 + 1 + length_octets > str_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
|
|
if (length_octets == 1) {
|
|
len = str[2];
|
|
+ if (1 + (1 + 1) + len > str_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
+ if (len < 1) {
|
|
+ TRACE_ERROR("BER length is too small to include the "
|
|
+ "unused-bits-byte\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
|
|
*data = &str[3];
|
|
*data_len = len;
|
|
@@ -554,6 +616,15 @@ CK_RV ber_decode_BIT_STRING(CK_BYTE *str,
|
|
len = str[2];
|
|
len = len << 8;
|
|
len |= str[3];
|
|
+ if (1 + (1 + 2) + len > str_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
+ if (len < 1) {
|
|
+ TRACE_ERROR("BER length is too small to include the "
|
|
+ "unused-bits-byte\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
|
|
*data = &str[4];
|
|
*data_len = len;
|
|
@@ -567,6 +638,15 @@ CK_RV ber_decode_BIT_STRING(CK_BYTE *str,
|
|
len |= str[3];
|
|
len = len << 8;
|
|
len |= str[4];
|
|
+ if (1 + (1 + 3) + len > str_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
+ if (len < 1) {
|
|
+ TRACE_ERROR("BER length is too small to include the "
|
|
+ "unused-bits-byte\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
|
|
*data = &str[5];
|
|
*data_len = len;
|
|
@@ -674,14 +754,14 @@ CK_RV ber_encode_SEQUENCE(CK_BBOOL length_only,
|
|
|
|
//
|
|
//
|
|
-CK_RV ber_decode_SEQUENCE(CK_BYTE *seq,
|
|
+CK_RV ber_decode_SEQUENCE(CK_BYTE *seq, CK_ULONG seq_len,
|
|
CK_BYTE **data, CK_ULONG *data_len,
|
|
CK_ULONG *field_len)
|
|
{
|
|
CK_ULONG len, length_octets;
|
|
|
|
|
|
- if (!seq) {
|
|
+ if (!seq || seq_len < 2) {
|
|
TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
return CKR_FUNCTION_FAILED;
|
|
}
|
|
@@ -693,6 +773,10 @@ CK_RV ber_decode_SEQUENCE(CK_BYTE *seq,
|
|
//
|
|
if ((seq[1] & 0x80) == 0) {
|
|
len = seq[1] & 0x7F;
|
|
+ if (1 + 1 + len > seq_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
|
|
*data = &seq[2];
|
|
*data_len = len;
|
|
@@ -701,9 +785,17 @@ CK_RV ber_decode_SEQUENCE(CK_BYTE *seq,
|
|
}
|
|
|
|
length_octets = seq[1] & 0x7F;
|
|
+ if (1 + 1 + length_octets > seq_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
|
|
if (length_octets == 1) {
|
|
len = seq[2];
|
|
+ if (1 + (1 + 1) + len > seq_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
|
|
*data = &seq[3];
|
|
*data_len = len;
|
|
@@ -715,6 +807,10 @@ CK_RV ber_decode_SEQUENCE(CK_BYTE *seq,
|
|
len = seq[2];
|
|
len = len << 8;
|
|
len |= seq[3];
|
|
+ if (1 + (1 + 2) + len > seq_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
|
|
*data = &seq[4];
|
|
*data_len = len;
|
|
@@ -728,6 +824,10 @@ CK_RV ber_decode_SEQUENCE(CK_BYTE *seq,
|
|
len |= seq[3];
|
|
len = len << 8;
|
|
len |= seq[4];
|
|
+ if (1 + (1 + 3) + len > seq_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
|
|
*data = &seq[5];
|
|
*data_len = len;
|
|
@@ -840,7 +940,7 @@ CK_RV ber_encode_CHOICE(CK_BBOOL length_only,
|
|
// attributes
|
|
// }
|
|
//
|
|
-CK_RV ber_decode_CHOICE(CK_BYTE *choice,
|
|
+CK_RV ber_decode_CHOICE(CK_BYTE *choice, CK_ULONG choice_len,
|
|
CK_BYTE **data,
|
|
CK_ULONG *data_len, CK_ULONG *field_len,
|
|
CK_ULONG *option)
|
|
@@ -848,7 +948,7 @@ CK_RV ber_decode_CHOICE(CK_BYTE *choice,
|
|
CK_ULONG len, length_octets;
|
|
|
|
|
|
- if (!choice) {
|
|
+ if (!choice || choice_len < 2) {
|
|
TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
return CKR_FUNCTION_FAILED;
|
|
}
|
|
@@ -864,6 +964,10 @@ CK_RV ber_decode_CHOICE(CK_BYTE *choice,
|
|
//
|
|
if ((choice[1] & 0x80) == 0) {
|
|
len = choice[1] & 0x7F;
|
|
+ if (1 + 1 + len > choice_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
*data = &choice[2];
|
|
*data_len = len;
|
|
*field_len = 1 + (1) + len;
|
|
@@ -871,9 +975,17 @@ CK_RV ber_decode_CHOICE(CK_BYTE *choice,
|
|
}
|
|
|
|
length_octets = choice[1] & 0x7F;
|
|
+ if (1 + 1 + length_octets > choice_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
|
|
if (length_octets == 1) {
|
|
len = choice[2];
|
|
+ if (1 + (1 + 1) + len > choice_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
*data = &choice[3];
|
|
*data_len = len;
|
|
*field_len = 1 + (1 + 1) + len;
|
|
@@ -884,6 +996,10 @@ CK_RV ber_decode_CHOICE(CK_BYTE *choice,
|
|
len = choice[2];
|
|
len = len << 8;
|
|
len |= choice[3];
|
|
+ if (1 + (1 + 2) + len > choice_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
*data = &choice[4];
|
|
*data_len = len;
|
|
*field_len = 1 + (1 + 2) + len;
|
|
@@ -896,6 +1012,10 @@ CK_RV ber_decode_CHOICE(CK_BYTE *choice,
|
|
len |= choice[3];
|
|
len = len << 8;
|
|
len |= choice[4];
|
|
+ if (1 + (1 + 3) + len > choice_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
*data = &choice[5];
|
|
*data_len = len;
|
|
*field_len = 1 + (1 + 3) + len;
|
|
@@ -1006,10 +1126,9 @@ error:
|
|
|
|
//
|
|
//
|
|
-CK_RV ber_decode_PrivateKeyInfo(CK_BYTE *data,
|
|
- CK_ULONG data_len,
|
|
- CK_BYTE **algorithm,
|
|
- CK_ULONG *alg_len, CK_BYTE **priv_key)
|
|
+CK_RV ber_decode_PrivateKeyInfo(CK_BYTE *data, CK_ULONG data_len,
|
|
+ CK_BYTE **algorithm, CK_ULONG *alg_len,
|
|
+ CK_BYTE **priv_key, CK_ULONG *priv_key_len)
|
|
{
|
|
CK_BYTE *buf = NULL;
|
|
CK_BYTE *alg = NULL;
|
|
@@ -1021,7 +1140,7 @@ CK_RV ber_decode_PrivateKeyInfo(CK_BYTE *data,
|
|
TRACE_ERROR("Invalid function arguments.\n");
|
|
return CKR_FUNCTION_FAILED;
|
|
}
|
|
- rc = ber_decode_SEQUENCE(data, &buf, &buf_len, &field_len);
|
|
+ rc = ber_decode_SEQUENCE(data, data_len, &buf, &buf_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SEQUENCE failed\n");
|
|
return rc;
|
|
@@ -1029,7 +1148,8 @@ CK_RV ber_decode_PrivateKeyInfo(CK_BYTE *data,
|
|
// version -- we just ignore this
|
|
//
|
|
offset = 0;
|
|
- rc = ber_decode_INTEGER(buf + offset, &ver, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &ver, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
return rc;
|
|
@@ -1038,15 +1158,18 @@ CK_RV ber_decode_PrivateKeyInfo(CK_BYTE *data,
|
|
|
|
// 'buf' is now pointing to the PrivateKeyAlgorithmIdentifier
|
|
//
|
|
- rc = ber_decode_SEQUENCE(buf + offset, &alg, &len, &field_len);
|
|
+ rc = ber_decode_SEQUENCE(buf + offset, buf_len - offset, &alg, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SEQUENCE failed\n");
|
|
return rc;
|
|
}
|
|
+ offset += field_len;
|
|
*algorithm = alg;
|
|
*alg_len = len;
|
|
|
|
- rc = ber_decode_OCTET_STRING(alg + len, priv_key, &buf_len, &field_len);
|
|
+ rc = ber_decode_OCTET_STRING(buf + offset, buf_len - offset,
|
|
+ priv_key, priv_key_len, &field_len);
|
|
if (rc != CKR_OK)
|
|
TRACE_DEVEL("ber_decode_OCTET_STRING failed\n");
|
|
|
|
@@ -1064,13 +1187,14 @@ CK_RV ber_decode_PrivateKeyInfo(CK_BYTE *data,
|
|
* parameters ANY DEFINED BY algorithm OPTIONAL
|
|
* }
|
|
*/
|
|
-CK_RV ber_decode_SPKI(CK_BYTE *spki, CK_BYTE **alg_oid, CK_ULONG *alg_oid_len,
|
|
+CK_RV ber_decode_SPKI(CK_BYTE *spki, CK_ULONG spki_len,
|
|
+ CK_BYTE **alg_oid, CK_ULONG *alg_oid_len,
|
|
CK_BYTE **param, CK_ULONG *param_len,
|
|
CK_BYTE **key, CK_ULONG *key_len)
|
|
{
|
|
CK_BYTE *out_seq, *id_seq, *bit_str;
|
|
CK_BYTE *data;
|
|
- CK_ULONG data_len;
|
|
+ CK_ULONG data_len, out_seq_len, id_seq_len, bit_str_len;
|
|
CK_ULONG field_len;
|
|
CK_RV rc;
|
|
|
|
@@ -1078,7 +1202,9 @@ CK_RV ber_decode_SPKI(CK_BYTE *spki, CK_BYTE **alg_oid, CK_ULONG *alg_oid_len,
|
|
*param_len = 0;
|
|
*key_len = 0;
|
|
out_seq = spki;
|
|
- rc = ber_decode_SEQUENCE(out_seq, &data, &data_len, &field_len);
|
|
+ out_seq_len = spki_len;
|
|
+ rc = ber_decode_SEQUENCE(out_seq, out_seq_len, &data, &data_len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_ERROR("%s ber_decode_SEQUENCE #1 failed rc=0x%lx\n",
|
|
__func__, rc);
|
|
@@ -1086,23 +1212,35 @@ CK_RV ber_decode_SPKI(CK_BYTE *spki, CK_BYTE **alg_oid, CK_ULONG *alg_oid_len,
|
|
}
|
|
|
|
id_seq = out_seq + field_len - data_len;
|
|
+ id_seq_len = out_seq_len - field_len + data_len;
|
|
/* get id seq */
|
|
- rc = ber_decode_SEQUENCE(id_seq, &data, &data_len, &field_len);
|
|
+ rc = ber_decode_SEQUENCE(id_seq, id_seq_len, &data, &data_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_ERROR("%s ber_decode_SEQUENCE #2 failed rc=0x%lx\n",
|
|
__func__, rc);
|
|
return rc;
|
|
}
|
|
|
|
+ if (data_len < 2) {
|
|
+ TRACE_ERROR("%s Length of id_seq is too short\n", __func__);
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
+
|
|
*alg_oid = data;
|
|
*alg_oid_len = data[1] + 2;
|
|
|
|
+ if (*alg_oid_len > data_len) {
|
|
+ TRACE_ERROR("%s Length of id_seq is too short\n", __func__);
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
+
|
|
*param = data + *alg_oid_len;
|
|
*param_len = data_len - *alg_oid_len;
|
|
|
|
bit_str = id_seq + field_len;
|
|
+ bit_str_len = id_seq_len - field_len;
|
|
/* get bitstring */
|
|
- rc = ber_decode_BIT_STRING(bit_str, key, key_len, &field_len);
|
|
+ rc = ber_decode_BIT_STRING(bit_str, bit_str_len, key, key_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_ERROR("%s ber_decode_BIT_STRING failed rc=0x%lx\n",
|
|
__func__, rc);
|
|
@@ -1369,10 +1507,11 @@ CK_RV ber_decode_RSAPrivateKey(CK_BYTE *data,
|
|
CK_BYTE *rsa_priv_key = NULL;
|
|
CK_BYTE *buf = NULL;
|
|
CK_BYTE *tmp = NULL;
|
|
- CK_ULONG offset, buf_len, field_len, len;
|
|
+ CK_ULONG offset, buf_len, field_len, len, rsa_priv_key_len;
|
|
CK_RV rc;
|
|
|
|
- rc = ber_decode_PrivateKeyInfo(data, data_len, &alg, &len, &rsa_priv_key);
|
|
+ rc = ber_decode_PrivateKeyInfo(data, data_len, &alg, &len,
|
|
+ &rsa_priv_key, &rsa_priv_key_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_PrivateKeyInfo failed\n");
|
|
return rc;
|
|
@@ -1384,7 +1523,8 @@ CK_RV ber_decode_RSAPrivateKey(CK_BYTE *data,
|
|
TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
return CKR_FUNCTION_FAILED;
|
|
}
|
|
- rc = ber_decode_SEQUENCE(rsa_priv_key, &buf, &buf_len, &field_len);
|
|
+ rc = ber_decode_SEQUENCE(rsa_priv_key, rsa_priv_key_len,
|
|
+ &buf, &buf_len, &field_len);
|
|
if (rc != CKR_OK)
|
|
return rc;
|
|
|
|
@@ -1394,7 +1534,8 @@ CK_RV ber_decode_RSAPrivateKey(CK_BYTE *data,
|
|
|
|
// Version
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -1403,7 +1544,8 @@ CK_RV ber_decode_RSAPrivateKey(CK_BYTE *data,
|
|
|
|
// modulus
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -1412,7 +1554,8 @@ CK_RV ber_decode_RSAPrivateKey(CK_BYTE *data,
|
|
|
|
// public exponent
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -1421,7 +1564,8 @@ CK_RV ber_decode_RSAPrivateKey(CK_BYTE *data,
|
|
|
|
// private exponent
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -1430,7 +1574,8 @@ CK_RV ber_decode_RSAPrivateKey(CK_BYTE *data,
|
|
|
|
// prime #1
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -1439,7 +1584,8 @@ CK_RV ber_decode_RSAPrivateKey(CK_BYTE *data,
|
|
|
|
// prime #2
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -1448,7 +1594,8 @@ CK_RV ber_decode_RSAPrivateKey(CK_BYTE *data,
|
|
|
|
// exponent #1
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -1457,7 +1604,8 @@ CK_RV ber_decode_RSAPrivateKey(CK_BYTE *data,
|
|
|
|
// exponent #2
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -1466,7 +1614,8 @@ CK_RV ber_decode_RSAPrivateKey(CK_BYTE *data,
|
|
|
|
// coefficient
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -1486,7 +1635,8 @@ CK_RV ber_decode_RSAPrivateKey(CK_BYTE *data,
|
|
|
|
// skip the version
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -1495,7 +1645,8 @@ CK_RV ber_decode_RSAPrivateKey(CK_BYTE *data,
|
|
|
|
// modulus
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -1510,7 +1661,8 @@ CK_RV ber_decode_RSAPrivateKey(CK_BYTE *data,
|
|
|
|
// public exponent
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -1525,7 +1677,8 @@ CK_RV ber_decode_RSAPrivateKey(CK_BYTE *data,
|
|
|
|
// private exponent
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -1540,7 +1693,8 @@ CK_RV ber_decode_RSAPrivateKey(CK_BYTE *data,
|
|
|
|
// prime #1
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -1555,7 +1709,8 @@ CK_RV ber_decode_RSAPrivateKey(CK_BYTE *data,
|
|
|
|
// prime #2
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -1570,7 +1725,8 @@ CK_RV ber_decode_RSAPrivateKey(CK_BYTE *data,
|
|
|
|
// exponent #1
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -1585,7 +1741,8 @@ CK_RV ber_decode_RSAPrivateKey(CK_BYTE *data,
|
|
|
|
// exponent #2
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -1600,7 +1757,8 @@ CK_RV ber_decode_RSAPrivateKey(CK_BYTE *data,
|
|
|
|
// coefficient
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -1788,9 +1946,7 @@ CK_RV ber_decode_RSAPublicKey(CK_BYTE *data,
|
|
CK_ULONG field_len, offset, len;
|
|
CK_RV rc;
|
|
|
|
- UNUSED(data_len); // XXX can this parameter be removed ?
|
|
-
|
|
- rc = ber_decode_SPKI(data, &algid, &algid_len, ¶m, ¶m_len,
|
|
+ rc = ber_decode_SPKI(data, data_len, &algid, &algid_len, ¶m, ¶m_len,
|
|
&val, &val_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SPKI failed\n");
|
|
@@ -1800,7 +1956,8 @@ CK_RV ber_decode_RSAPublicKey(CK_BYTE *data,
|
|
/*
|
|
* Make sure we're dealing with an DH key.
|
|
*/
|
|
- rc = ber_decode_SEQUENCE((CK_BYTE *)ber_AlgIdRSAEncryption, &algid_RSABase,
|
|
+ rc = ber_decode_SEQUENCE((CK_BYTE *)ber_AlgIdRSAEncryption,
|
|
+ ber_AlgIdRSAEncryptionLen, &algid_RSABase,
|
|
&len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SEQUENCE failed\n");
|
|
@@ -1812,20 +1969,21 @@ CK_RV ber_decode_RSAPublicKey(CK_BYTE *data,
|
|
return CKR_FUNCTION_FAILED;
|
|
}
|
|
|
|
- rc = ber_decode_SEQUENCE(val, &seq, &seq_len, &field_len);
|
|
+ rc = ber_decode_SEQUENCE(val, val_len, &seq, &seq_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SEQUENCE failed\n");
|
|
return rc;
|
|
}
|
|
|
|
- rc = ber_decode_INTEGER(seq, &mod, &mod_len, &field_len);
|
|
+ rc = ber_decode_INTEGER(seq, seq_len, &mod, &mod_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
return rc;
|
|
}
|
|
|
|
offset = field_len;
|
|
- rc = ber_decode_INTEGER(seq + offset, &exp, &exp_len, &field_len);
|
|
+ rc = ber_decode_INTEGER(seq + offset, seq_len - offset, &exp, &exp_len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
return rc;
|
|
@@ -2059,11 +2217,12 @@ CK_RV ber_decode_DSAPrivateKey(CK_BYTE *data,
|
|
CK_BYTE *buf = NULL;
|
|
CK_BYTE *dsakey = NULL;
|
|
CK_BYTE *tmp = NULL;
|
|
- CK_ULONG buf_len, field_len, len, offset;
|
|
+ CK_ULONG buf_len, field_len, len, dsakey_len, offset;
|
|
CK_RV rc;
|
|
|
|
|
|
- rc = ber_decode_PrivateKeyInfo(data, data_len, &alg, &len, &dsakey);
|
|
+ rc = ber_decode_PrivateKeyInfo(data, data_len, &alg, &len,
|
|
+ &dsakey, &dsakey_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_PrivateKeyInfo failed\n");
|
|
return rc;
|
|
@@ -2077,7 +2236,8 @@ CK_RV ber_decode_DSAPrivateKey(CK_BYTE *data,
|
|
}
|
|
// extract the parameter data into ATTRIBUTES
|
|
//
|
|
- rc = ber_decode_SEQUENCE(alg + ber_idDSALen, &buf, &buf_len, &field_len);
|
|
+ rc = ber_decode_SEQUENCE(alg + ber_idDSALen, len- ber_idDSALen,
|
|
+ &buf, &buf_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SEQUENCE failed\n");
|
|
return rc;
|
|
@@ -2086,7 +2246,8 @@ CK_RV ber_decode_DSAPrivateKey(CK_BYTE *data,
|
|
|
|
// prime
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -2095,7 +2256,8 @@ CK_RV ber_decode_DSAPrivateKey(CK_BYTE *data,
|
|
|
|
// subprime
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -2104,7 +2266,8 @@ CK_RV ber_decode_DSAPrivateKey(CK_BYTE *data,
|
|
|
|
// base
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -2123,7 +2286,8 @@ CK_RV ber_decode_DSAPrivateKey(CK_BYTE *data,
|
|
|
|
// prime
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -2138,7 +2302,8 @@ CK_RV ber_decode_DSAPrivateKey(CK_BYTE *data,
|
|
|
|
// subprime
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -2153,7 +2318,8 @@ CK_RV ber_decode_DSAPrivateKey(CK_BYTE *data,
|
|
|
|
// base
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -2168,7 +2334,7 @@ CK_RV ber_decode_DSAPrivateKey(CK_BYTE *data,
|
|
|
|
// now get the private key
|
|
//
|
|
- rc = ber_decode_INTEGER(dsakey, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(dsakey, dsakey_len, &tmp, &len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -2411,9 +2577,7 @@ CK_RV ber_decode_DSAPublicKey(CK_BYTE *data,
|
|
CK_ULONG field_len, offset;
|
|
CK_RV rc;
|
|
|
|
- UNUSED(data_len); // XXX can this parameter be removed ?
|
|
-
|
|
- rc = ber_decode_SPKI(data, &algid, &algid_len, ¶m, ¶m_len,
|
|
+ rc = ber_decode_SPKI(data, data_len, &algid, &algid_len, ¶m, ¶m_len,
|
|
&val, &val_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SPKI failed\n");
|
|
@@ -2428,27 +2592,29 @@ CK_RV ber_decode_DSAPublicKey(CK_BYTE *data,
|
|
return CKR_FUNCTION_FAILED;
|
|
}
|
|
|
|
- rc = ber_decode_SEQUENCE(param, &seq, &seq_len, &field_len);
|
|
+ rc = ber_decode_SEQUENCE(param, param_len, &seq, &seq_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SEQUENCE failed\n");
|
|
return rc;
|
|
}
|
|
|
|
- rc = ber_decode_INTEGER(seq, &p, &p_len, &field_len);
|
|
+ rc = ber_decode_INTEGER(seq, seq_len, &p, &p_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
return rc;
|
|
}
|
|
|
|
offset = field_len;
|
|
- rc = ber_decode_INTEGER(seq + offset, &sp, &sp_len, &field_len);
|
|
+ rc = ber_decode_INTEGER(seq + offset, seq_len - offset, &sp, &sp_len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
return rc;
|
|
}
|
|
|
|
offset += field_len;
|
|
- rc = ber_decode_INTEGER(seq + offset, &b, &b_len, &field_len);
|
|
+ rc = ber_decode_INTEGER(seq + offset, seq_len - offset, &b, &b_len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
return rc;
|
|
@@ -2547,8 +2713,8 @@ CK_RV der_encode_ECPrivateKey(CK_BBOOL length_only,
|
|
}
|
|
// public key bit string
|
|
if (pubkey && pubkey->pValue) {
|
|
- rc = ber_decode_OCTET_STRING(pubkey->pValue, &ecpoint, &ecpoint_len,
|
|
- &field_len);
|
|
+ rc = ber_decode_OCTET_STRING(pubkey->pValue, pubkey->ulValueLen,
|
|
+ &ecpoint, &ecpoint_len, &field_len);
|
|
if (rc != CKR_OK || pubkey->ulValueLen != field_len) {
|
|
TRACE_DEVEL("ber decoding of public key failed\n");
|
|
return CKR_ATTRIBUTE_VALUE_INVALID;
|
|
@@ -2630,8 +2796,8 @@ CK_RV der_encode_ECPrivateKey(CK_BBOOL length_only,
|
|
|
|
/* generate optional bit-string of public key */
|
|
if (pubkey && pubkey->pValue) {
|
|
- rc = ber_decode_OCTET_STRING(pubkey->pValue, &ecpoint, &ecpoint_len,
|
|
- &field_len);
|
|
+ rc = ber_decode_OCTET_STRING(pubkey->pValue, pubkey->ulValueLen,
|
|
+ &ecpoint, &ecpoint_len, &field_len);
|
|
if (rc != CKR_OK || pubkey->ulValueLen != field_len) {
|
|
TRACE_DEVEL("ber decoding of public key failed\n");
|
|
rc = CKR_ATTRIBUTE_VALUE_INVALID;
|
|
@@ -2723,7 +2889,7 @@ CK_RV der_decode_ECPrivateKey(CK_BYTE *data,
|
|
CK_BYTE *version = NULL;
|
|
CK_BYTE *choice = NULL;
|
|
CK_ULONG version_len, alg_len, priv_len, pub_len, parm_len, buf_len;
|
|
- CK_ULONG buf_offset, field_len, offset, choice_len, option;
|
|
+ CK_ULONG buf_offset, field_len, offset, choice_len, option, eckey_len;
|
|
CK_ULONG pubkey_available = 0;
|
|
CK_BYTE *ecpoint = NULL;
|
|
CK_ULONG ecpoint_len;
|
|
@@ -2737,7 +2903,7 @@ CK_RV der_decode_ECPrivateKey(CK_BYTE *data,
|
|
* know the actual length to be able to find out of the optional public key
|
|
* is present or not.
|
|
*/
|
|
- rc = ber_decode_SEQUENCE(data, &buf, &buf_len, &field_len);
|
|
+ rc = ber_decode_SEQUENCE(data, data_len, &buf, &buf_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SEQUENCE failed\n");
|
|
return rc;
|
|
@@ -2749,7 +2915,8 @@ CK_RV der_decode_ECPrivateKey(CK_BYTE *data,
|
|
data_len = field_len;
|
|
|
|
/* Decode PrivateKeyInfo into alg and eckey */
|
|
- rc = ber_decode_PrivateKeyInfo(data, data_len, &alg, &alg_len, &eckey);
|
|
+ rc = ber_decode_PrivateKeyInfo(data, data_len, &alg, &alg_len,
|
|
+ &eckey, &eckey_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_PrivateKeyInfo failed\n");
|
|
return rc;
|
|
@@ -2762,7 +2929,7 @@ CK_RV der_decode_ECPrivateKey(CK_BYTE *data,
|
|
}
|
|
|
|
/* Decode the ecdhkey into buf */
|
|
- rc = ber_decode_SEQUENCE(eckey, &buf, &buf_len, &field_len);
|
|
+ rc = ber_decode_SEQUENCE(eckey, eckey_len, &buf, &buf_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SEQUENCE failed\n");
|
|
return rc;
|
|
@@ -2770,7 +2937,8 @@ CK_RV der_decode_ECPrivateKey(CK_BYTE *data,
|
|
offset = 0;
|
|
|
|
/* Decode version (INTEGER) */
|
|
- rc = ber_decode_INTEGER(buf + offset, &version, &version_len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset,
|
|
+ &version, &version_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -2778,8 +2946,8 @@ CK_RV der_decode_ECPrivateKey(CK_BYTE *data,
|
|
offset += field_len;
|
|
|
|
/* Decode private key (OCTET_STRING) */
|
|
- rc = ber_decode_OCTET_STRING(buf + offset, &priv_buf, &priv_len,
|
|
- &field_len);
|
|
+ rc = ber_decode_OCTET_STRING(buf + offset, buf_len - offset,
|
|
+ &priv_buf, &priv_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_OCTET_STRING failed\n");
|
|
goto cleanup;
|
|
@@ -2791,8 +2959,8 @@ CK_RV der_decode_ECPrivateKey(CK_BYTE *data,
|
|
if (buf_offset + offset < data_len) {
|
|
|
|
/* Decode CHOICE */
|
|
- rc = ber_decode_CHOICE(buf + offset, &choice, &choice_len, &field_len,
|
|
- &option);
|
|
+ rc = ber_decode_CHOICE(buf + offset, buf_len - offset,
|
|
+ &choice, &choice_len, &field_len, &option);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_CHOICE failed\n");
|
|
goto cleanup;
|
|
@@ -2809,8 +2977,8 @@ CK_RV der_decode_ECPrivateKey(CK_BYTE *data,
|
|
break;
|
|
case 1:
|
|
/* publicKey [1] BIT STRING OPTIONAL */
|
|
- rc = ber_decode_BIT_STRING(buf + offset, &pub_buf, &pub_len,
|
|
- &field_len);
|
|
+ rc = ber_decode_BIT_STRING(buf + offset, buf_len - offset,
|
|
+ &pub_buf, &pub_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_BIT_STRING failed\n");
|
|
goto cleanup;
|
|
@@ -2893,7 +3061,8 @@ CK_RV ber_encode_ECPublicKey(CK_BBOOL length_only, CK_BYTE **data,
|
|
CK_ULONG ecpoint_len, field_len;
|
|
|
|
/* CKA_EC_POINT is an BER encoded OCTET STRING. Extract it. */
|
|
- rc = ber_decode_OCTET_STRING((CK_BYTE *)point->pValue, &ecpoint,
|
|
+ rc = ber_decode_OCTET_STRING((CK_BYTE *)point->pValue,
|
|
+ point->ulValueLen, &ecpoint,
|
|
&ecpoint_len, &field_len);
|
|
if (rc != CKR_OK || point->ulValueLen != field_len) {
|
|
TRACE_DEVEL("%s ber_decode_OCTET_STRING failed\n", __func__);
|
|
@@ -3024,9 +3193,7 @@ CK_RV der_decode_ECPublicKey(CK_BYTE *data,
|
|
CK_ULONG field_len, len;
|
|
CK_RV rc;
|
|
|
|
- UNUSED(data_len); // XXX can this parameter be removed ?
|
|
-
|
|
- rc = ber_decode_SPKI(data, &algid, &algid_len, ¶m, ¶m_len,
|
|
+ rc = ber_decode_SPKI(data, data_len, &algid, &algid_len, ¶m, ¶m_len,
|
|
&point, &point_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SPKI failed\n");
|
|
@@ -3038,8 +3205,9 @@ CK_RV der_decode_ECPublicKey(CK_BYTE *data,
|
|
* Extract base alg-id of DER encoded EC byte string
|
|
* and compare against the decoded alg-id from the inner sequence
|
|
*/
|
|
- rc = ber_decode_SEQUENCE((CK_BYTE *)der_AlgIdECBase, &algid_ECBase, &len,
|
|
- &field_len);
|
|
+ rc = ber_decode_SEQUENCE((CK_BYTE *)der_AlgIdECBase,
|
|
+ der_AlgIdECBaseLen, &algid_ECBase,
|
|
+ &len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SEQUENCE failed\n");
|
|
return rc;
|
|
@@ -3257,10 +3425,11 @@ CK_RV ber_decode_DHPrivateKey(CK_BYTE *data,
|
|
CK_BYTE *buf = NULL;
|
|
CK_BYTE *dhkey = NULL;
|
|
CK_BYTE *tmp = NULL;
|
|
- CK_ULONG buf_len, field_len, len, offset;
|
|
+ CK_ULONG buf_len, field_len, len, dhkey_len, offset;
|
|
CK_RV rc;
|
|
|
|
- rc = ber_decode_PrivateKeyInfo(data, data_len, &alg, &len, &dhkey);
|
|
+ rc = ber_decode_PrivateKeyInfo(data, data_len, &alg, &len,
|
|
+ &dhkey, &dhkey_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_PrivateKeyInfo failed\n");
|
|
return rc;
|
|
@@ -3273,7 +3442,8 @@ CK_RV ber_decode_DHPrivateKey(CK_BYTE *data,
|
|
}
|
|
// extract the parameter data into ATTRIBUTES
|
|
//
|
|
- rc = ber_decode_SEQUENCE(alg + ber_idDSALen, &buf, &buf_len, &field_len);
|
|
+ rc = ber_decode_SEQUENCE(alg + ber_idDHLen, len - ber_idDHLen,
|
|
+ &buf, &buf_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SEQUENCE failed\n");
|
|
return rc;
|
|
@@ -3281,7 +3451,8 @@ CK_RV ber_decode_DHPrivateKey(CK_BYTE *data,
|
|
offset = 0;
|
|
|
|
// prime
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset,
|
|
+ &tmp, &len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -3289,7 +3460,8 @@ CK_RV ber_decode_DHPrivateKey(CK_BYTE *data,
|
|
offset += field_len;
|
|
|
|
// base
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset,
|
|
+ &tmp, &len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -3305,7 +3477,8 @@ CK_RV ber_decode_DHPrivateKey(CK_BYTE *data,
|
|
offset = 0;
|
|
|
|
// prime
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset,
|
|
+ &tmp, &len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -3319,7 +3492,8 @@ CK_RV ber_decode_DHPrivateKey(CK_BYTE *data,
|
|
}
|
|
|
|
// base
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset,
|
|
+ &tmp, &len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -3333,7 +3507,7 @@ CK_RV ber_decode_DHPrivateKey(CK_BYTE *data,
|
|
}
|
|
|
|
// now get the private key
|
|
- rc = ber_decode_INTEGER(dhkey, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(dhkey, dhkey_len, &tmp, &len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -3555,9 +3729,7 @@ CK_RV ber_decode_DHPublicKey(CK_BYTE *data,
|
|
CK_ULONG field_len, offset;
|
|
CK_RV rc;
|
|
|
|
- UNUSED(data_len); // XXX can this parameter be removed ?
|
|
-
|
|
- rc = ber_decode_SPKI(data, &algid, &algid_len, ¶m, ¶m_len,
|
|
+ rc = ber_decode_SPKI(data, data_len, &algid, &algid_len, ¶m, ¶m_len,
|
|
&val, &val_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SPKI failed\n");
|
|
@@ -3572,20 +3744,21 @@ CK_RV ber_decode_DHPublicKey(CK_BYTE *data,
|
|
return CKR_FUNCTION_FAILED;
|
|
}
|
|
|
|
- rc = ber_decode_SEQUENCE(param, &seq, &seq_len, &field_len);
|
|
+ rc = ber_decode_SEQUENCE(param, param_len, &seq, &seq_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SEQUENCE failed\n");
|
|
return rc;
|
|
}
|
|
|
|
- rc = ber_decode_INTEGER(seq, &p, &p_len, &field_len);
|
|
+ rc = ber_decode_INTEGER(seq, seq_len, &p, &p_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
return rc;
|
|
}
|
|
|
|
offset = field_len;
|
|
- rc = ber_decode_INTEGER(seq + offset, &b, &b_len, &field_len);
|
|
+ rc = ber_decode_INTEGER(seq + offset, seq_len - offset, &b, &b_len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
return rc;
|
|
@@ -3826,10 +3999,8 @@ CK_RV ber_decode_IBM_DilithiumPublicKey(CK_BYTE *data,
|
|
CK_ULONG field_len, offset, raw_spki_len;
|
|
CK_RV rc;
|
|
|
|
- UNUSED(data_len); // XXX can this parameter be removed ?
|
|
-
|
|
- rc = ber_decode_SPKI(data, &algoid, &algoid_len, ¶m, ¶m_len,
|
|
- &val, &val_len);
|
|
+ rc = ber_decode_SPKI(data, data_len, &algoid, &algoid_len,
|
|
+ ¶m, ¶m_len, &val, &val_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SPKI failed\n");
|
|
return rc;
|
|
@@ -3846,14 +4017,14 @@ CK_RV ber_decode_IBM_DilithiumPublicKey(CK_BYTE *data,
|
|
* BIT STRING = rho
|
|
* BIT STRING = t1
|
|
*/
|
|
- rc = ber_decode_SEQUENCE(val, &seq, &seq_len, &field_len);
|
|
+ rc = ber_decode_SEQUENCE(val, val_len, &seq, &seq_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SEQUENCE failed\n");
|
|
return rc;
|
|
}
|
|
|
|
/* Decode rho */
|
|
- rc = ber_decode_BIT_STRING(seq, &rho, &rho_len, &field_len);
|
|
+ rc = ber_decode_BIT_STRING(seq, seq_len, &rho, &rho_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
return rc;
|
|
@@ -3863,7 +4034,8 @@ CK_RV ber_decode_IBM_DilithiumPublicKey(CK_BYTE *data,
|
|
|
|
/* Decode t1 */
|
|
offset = field_len;
|
|
- rc = ber_decode_BIT_STRING(seq + offset, &t1, &t1_len, &field_len);
|
|
+ rc = ber_decode_BIT_STRING(seq + offset, seq_len - offset, &t1, &t1_len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
return rc;
|
|
@@ -3886,7 +4058,7 @@ CK_RV ber_decode_IBM_DilithiumPublicKey(CK_BYTE *data,
|
|
}
|
|
|
|
/* Add raw SPKI as CKA_VALUE to public key (z/OS ICSF compatibility) */
|
|
- rc = ber_decode_SEQUENCE(data, &val, &val_len, &raw_spki_len);
|
|
+ rc = ber_decode_SEQUENCE(data, data_len, &val, &val_len, &raw_spki_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_ERROR("%s ber_decode_SEQUENCE failed with rc=0x%lx\n", __func__, rc);
|
|
goto cleanup;
|
|
@@ -4182,12 +4354,13 @@ CK_RV ber_decode_IBM_DilithiumPrivateKey(CK_BYTE *data,
|
|
CK_BYTE *dilithium_priv_key = NULL;
|
|
CK_BYTE *buf = NULL;
|
|
CK_BYTE *tmp = NULL;
|
|
- CK_ULONG offset, buf_len, field_len, len, option;
|
|
+ CK_ULONG offset, buf_len, field_len, len, dilithium_priv_key_len, option;
|
|
CK_RV rc;
|
|
|
|
/* Check if this is a Dilithium private key */
|
|
rc = ber_decode_PrivateKeyInfo(data, data_len, &algoid, &len,
|
|
- &dilithium_priv_key);
|
|
+ &dilithium_priv_key,
|
|
+ &dilithium_priv_key_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_PrivateKeyInfo failed\n");
|
|
return rc;
|
|
@@ -4206,7 +4379,8 @@ CK_RV ber_decode_IBM_DilithiumPrivateKey(CK_BYTE *data,
|
|
}
|
|
|
|
/* Decode private Dilithium key */
|
|
- rc = ber_decode_SEQUENCE(dilithium_priv_key, &buf, &buf_len, &field_len);
|
|
+ rc = ber_decode_SEQUENCE(dilithium_priv_key, dilithium_priv_key_len,
|
|
+ &buf, &buf_len, &field_len);
|
|
if (rc != CKR_OK)
|
|
return rc;
|
|
|
|
@@ -4214,7 +4388,8 @@ CK_RV ber_decode_IBM_DilithiumPrivateKey(CK_BYTE *data,
|
|
offset = 0;
|
|
|
|
/* Skip the version */
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -4222,7 +4397,8 @@ CK_RV ber_decode_IBM_DilithiumPrivateKey(CK_BYTE *data,
|
|
offset += field_len;
|
|
|
|
/* rho */
|
|
- rc = ber_decode_BIT_STRING(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_BIT_STRING(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_BIT_STRING of (rho) failed\n");
|
|
goto cleanup;
|
|
@@ -4238,7 +4414,8 @@ CK_RV ber_decode_IBM_DilithiumPrivateKey(CK_BYTE *data,
|
|
}
|
|
|
|
/* seed */
|
|
- rc = ber_decode_BIT_STRING(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_BIT_STRING(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_BIT_STRING of (seed) failed\n");
|
|
goto cleanup;
|
|
@@ -4254,7 +4431,8 @@ CK_RV ber_decode_IBM_DilithiumPrivateKey(CK_BYTE *data,
|
|
}
|
|
|
|
/* tr */
|
|
- rc = ber_decode_BIT_STRING(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_BIT_STRING(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_BIT_STRING of (tr) failed\n");
|
|
goto cleanup;
|
|
@@ -4270,7 +4448,8 @@ CK_RV ber_decode_IBM_DilithiumPrivateKey(CK_BYTE *data,
|
|
}
|
|
|
|
/* s1 */
|
|
- rc = ber_decode_BIT_STRING(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_BIT_STRING(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_BIT_STRING of (s1) failed\n");
|
|
goto cleanup;
|
|
@@ -4286,7 +4465,8 @@ CK_RV ber_decode_IBM_DilithiumPrivateKey(CK_BYTE *data,
|
|
}
|
|
|
|
/* s2 */
|
|
- rc = ber_decode_BIT_STRING(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_BIT_STRING(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_BIT_STRING of (s2) failed\n");
|
|
goto cleanup;
|
|
@@ -4302,7 +4482,8 @@ CK_RV ber_decode_IBM_DilithiumPrivateKey(CK_BYTE *data,
|
|
}
|
|
|
|
/* t0 */
|
|
- rc = ber_decode_BIT_STRING(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_BIT_STRING(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_BIT_STRING of (t0) failed\n");
|
|
goto cleanup;
|
|
@@ -4319,7 +4500,8 @@ CK_RV ber_decode_IBM_DilithiumPrivateKey(CK_BYTE *data,
|
|
|
|
/* t1 (optional, within choice) */
|
|
if (offset < buf_len) {
|
|
- rc = ber_decode_CHOICE(buf + offset, &tmp, &len, &field_len, &option);
|
|
+ rc = ber_decode_CHOICE(buf + offset, buf_len - offset,
|
|
+ &tmp, &len, &field_len, &option);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_BIT_STRING of (t1) failed\n");
|
|
goto cleanup;
|
|
@@ -4333,7 +4515,8 @@ CK_RV ber_decode_IBM_DilithiumPrivateKey(CK_BYTE *data,
|
|
|
|
offset += field_len - len;
|
|
|
|
- rc = ber_decode_BIT_STRING(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_BIT_STRING(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_BIT_STRING of (t1) failed\n");
|
|
goto cleanup;
|
|
@@ -4357,7 +4540,7 @@ CK_RV ber_decode_IBM_DilithiumPrivateKey(CK_BYTE *data,
|
|
}
|
|
|
|
/* Add private key as CKA_VALUE to public key (z/OS ICSF compatibility) */
|
|
- rc = ber_decode_SEQUENCE(data, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_SEQUENCE(data, data_len, &tmp, &len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_ERROR("%s ber_decode_SEQUENCE failed with rc=0x%lx\n", __func__, rc);
|
|
goto cleanup;
|
|
@@ -4579,10 +4762,8 @@ CK_RV ber_decode_IBM_KyberPublicKey(CK_BYTE *data,
|
|
CK_ULONG field_len, raw_spki_len;
|
|
CK_RV rc;
|
|
|
|
- UNUSED(data_len); // XXX can this parameter be removed ?
|
|
-
|
|
- rc = ber_decode_SPKI(data, &algoid, &algoid_len, ¶m, ¶m_len,
|
|
- &val, &val_len);
|
|
+ rc = ber_decode_SPKI(data, data_len, &algoid, &algoid_len,
|
|
+ ¶m, ¶m_len, &val, &val_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SPKI failed\n");
|
|
return rc;
|
|
@@ -4598,14 +4779,14 @@ CK_RV ber_decode_IBM_KyberPublicKey(CK_BYTE *data,
|
|
* SEQUENCE (1 elem)
|
|
* BIT STRING = pk
|
|
*/
|
|
- rc = ber_decode_SEQUENCE(val, &seq, &seq_len, &field_len);
|
|
+ rc = ber_decode_SEQUENCE(val, val_len, &seq, &seq_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SEQUENCE failed\n");
|
|
return rc;
|
|
}
|
|
|
|
/* Decode pk */
|
|
- rc = ber_decode_BIT_STRING(seq, &pk, &pk_len, &field_len);
|
|
+ rc = ber_decode_BIT_STRING(seq, seq_len, &pk, &pk_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
return rc;
|
|
@@ -4621,7 +4802,7 @@ CK_RV ber_decode_IBM_KyberPublicKey(CK_BYTE *data,
|
|
}
|
|
|
|
/* Add raw SPKI as CKA_VALUE to public key (z/OS ICSF compatibility) */
|
|
- rc = ber_decode_SEQUENCE(data, &val, &val_len, &raw_spki_len);
|
|
+ rc = ber_decode_SEQUENCE(data, data_len, &val, &val_len, &raw_spki_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_ERROR("%s ber_decode_SEQUENCE failed with rc=0x%lx\n", __func__, rc);
|
|
goto cleanup;
|
|
@@ -4837,12 +5018,12 @@ CK_RV ber_decode_IBM_KyberPrivateKey(CK_BYTE *data,
|
|
CK_BYTE *kyber_priv_key = NULL;
|
|
CK_BYTE *buf = NULL;
|
|
CK_BYTE *tmp = NULL;
|
|
- CK_ULONG offset, buf_len, field_len, len, option;
|
|
+ CK_ULONG offset, buf_len, field_len, len, kyber_priv_key_len, option;
|
|
CK_RV rc;
|
|
|
|
/* Check if this is a Kyber private key */
|
|
rc = ber_decode_PrivateKeyInfo(data, data_len, &algoid, &len,
|
|
- &kyber_priv_key);
|
|
+ &kyber_priv_key, &kyber_priv_key_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_PrivateKeyInfo failed\n");
|
|
return rc;
|
|
@@ -4861,7 +5042,8 @@ CK_RV ber_decode_IBM_KyberPrivateKey(CK_BYTE *data,
|
|
}
|
|
|
|
/* Decode private Kyber key */
|
|
- rc = ber_decode_SEQUENCE(kyber_priv_key, &buf, &buf_len, &field_len);
|
|
+ rc = ber_decode_SEQUENCE(kyber_priv_key, kyber_priv_key_len,
|
|
+ &buf, &buf_len, &field_len);
|
|
if (rc != CKR_OK)
|
|
return rc;
|
|
|
|
@@ -4869,7 +5051,8 @@ CK_RV ber_decode_IBM_KyberPrivateKey(CK_BYTE *data,
|
|
offset = 0;
|
|
|
|
/* Skip the version */
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -4877,7 +5060,8 @@ CK_RV ber_decode_IBM_KyberPrivateKey(CK_BYTE *data,
|
|
offset += field_len;
|
|
|
|
/* sk */
|
|
- rc = ber_decode_BIT_STRING(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_BIT_STRING(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_BIT_STRING of (sk) failed\n");
|
|
goto cleanup;
|
|
@@ -4894,7 +5078,8 @@ CK_RV ber_decode_IBM_KyberPrivateKey(CK_BYTE *data,
|
|
|
|
/* pk (optional, within choice) */
|
|
if (offset < buf_len) {
|
|
- rc = ber_decode_CHOICE(buf + offset, &tmp, &len, &field_len, &option);
|
|
+ rc = ber_decode_CHOICE(buf + offset, buf_len - offset,
|
|
+ &tmp, &len, &field_len, &option);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_BIT_STRING of (t1) failed\n");
|
|
goto cleanup;
|
|
@@ -4908,7 +5093,8 @@ CK_RV ber_decode_IBM_KyberPrivateKey(CK_BYTE *data,
|
|
|
|
offset += field_len - len;
|
|
|
|
- rc = ber_decode_BIT_STRING(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_BIT_STRING(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_BIT_STRING of (pk) failed\n");
|
|
goto cleanup;
|
|
@@ -4935,7 +5121,7 @@ CK_RV ber_decode_IBM_KyberPrivateKey(CK_BYTE *data,
|
|
}
|
|
|
|
/* Add private key as CKA_VALUE to public key (z/OS ICSF compatibility) */
|
|
- rc = ber_decode_SEQUENCE(data, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_SEQUENCE(data, data_len, &tmp, &len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_ERROR("%s ber_decode_SEQUENCE failed with rc=0x%lx\n", __func__, rc);
|
|
goto cleanup;
|
|
diff --git a/usr/lib/common/h_extern.h b/usr/lib/common/h_extern.h
|
|
index a88b57d0..b77a0c61 100644
|
|
--- a/usr/lib/common/h_extern.h
|
|
+++ b/usr/lib/common/h_extern.h
|
|
@@ -2750,11 +2750,11 @@ CK_ULONG ber_encode_INTEGER(CK_BBOOL length_only,
|
|
CK_ULONG *ber_int_len,
|
|
CK_BYTE *data, CK_ULONG data_len);
|
|
|
|
-CK_RV ber_decode_INTEGER(CK_BYTE *ber_int,
|
|
+CK_RV ber_decode_INTEGER(CK_BYTE *ber_int, CK_ULONG ber_int_len,
|
|
CK_BYTE **data,
|
|
CK_ULONG *data_len, CK_ULONG *field_len);
|
|
|
|
-CK_RV ber_decode_BIT_STRING(CK_BYTE *str,
|
|
+CK_RV ber_decode_BIT_STRING(CK_BYTE *str, CK_ULONG str_len,
|
|
CK_BYTE **data,
|
|
CK_ULONG *data_len, CK_ULONG *field_len);
|
|
|
|
@@ -2763,7 +2763,7 @@ CK_RV ber_encode_OCTET_STRING(CK_BBOOL length_only,
|
|
CK_ULONG *str_len,
|
|
CK_BYTE *data, CK_ULONG data_len);
|
|
|
|
-CK_RV ber_decode_OCTET_STRING(CK_BYTE *str,
|
|
+CK_RV ber_decode_OCTET_STRING(CK_BYTE *str, CK_ULONG str_len,
|
|
CK_BYTE **data,
|
|
CK_ULONG *data_len, CK_ULONG *field_len);
|
|
|
|
@@ -2772,7 +2772,7 @@ CK_RV ber_encode_SEQUENCE(CK_BBOOL length_only,
|
|
CK_ULONG *seq_len,
|
|
CK_BYTE *data, CK_ULONG data_len);
|
|
|
|
-CK_RV ber_decode_SEQUENCE(CK_BYTE *seq,
|
|
+CK_RV ber_decode_SEQUENCE(CK_BYTE *seq, CK_ULONG seq_len,
|
|
CK_BYTE **data,
|
|
CK_ULONG *data_len, CK_ULONG *field_len);
|
|
|
|
@@ -2783,12 +2783,12 @@ CK_RV ber_encode_PrivateKeyInfo(CK_BBOOL length_only,
|
|
const CK_ULONG algorithm_id_len,
|
|
CK_BYTE *priv_key, CK_ULONG priv_key_len);
|
|
|
|
-CK_RV ber_decode_PrivateKeyInfo(CK_BYTE *data,
|
|
- CK_ULONG data_len,
|
|
- CK_BYTE **algorithm_id,
|
|
- CK_ULONG *alg_len, CK_BYTE **priv_key);
|
|
+CK_RV ber_decode_PrivateKeyInfo(CK_BYTE *data, CK_ULONG data_len,
|
|
+ CK_BYTE **algorithm_id, CK_ULONG *alg_len,
|
|
+ CK_BYTE **priv_key, CK_ULONG *priv_key_len);
|
|
|
|
-CK_RV ber_decode_SPKI(CK_BYTE *spki, CK_BYTE **alg_oid, CK_ULONG *alg_oid_len,
|
|
+CK_RV ber_decode_SPKI(CK_BYTE *spki, CK_ULONG spki_len,
|
|
+ CK_BYTE **alg_oid, CK_ULONG *alg_oid_len,
|
|
CK_BYTE **param, CK_ULONG *param_len,
|
|
CK_BYTE **key, CK_ULONG *key_len);
|
|
|
|
diff --git a/usr/lib/common/key_mgr.c b/usr/lib/common/key_mgr.c
|
|
index cd34aa73..cafc3eb8 100644
|
|
--- a/usr/lib/common/key_mgr.c
|
|
+++ b/usr/lib/common/key_mgr.c
|
|
@@ -1385,10 +1385,11 @@ CK_RV key_mgr_get_private_key_type(CK_BYTE *keydata,
|
|
{
|
|
CK_BYTE *alg = NULL;
|
|
CK_BYTE *priv_key = NULL;
|
|
- CK_ULONG alg_len, i;
|
|
+ CK_ULONG alg_len, priv_key_len, i;
|
|
CK_RV rc;
|
|
|
|
- rc = ber_decode_PrivateKeyInfo(keydata, keylen, &alg, &alg_len, &priv_key);
|
|
+ rc = ber_decode_PrivateKeyInfo(keydata, keylen, &alg, &alg_len,
|
|
+ &priv_key, &priv_key_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_PrivateKeyInfo failed.\n");
|
|
return rc;
|
|
diff --git a/usr/lib/common/mech_ec.c b/usr/lib/common/mech_ec.c
|
|
index 4fb4db10..cf9ccebf 100644
|
|
--- a/usr/lib/common/mech_ec.c
|
|
+++ b/usr/lib/common/mech_ec.c
|
|
@@ -1449,7 +1449,7 @@ int ec_point_from_public_data(const CK_BYTE *data, CK_ULONG data_len,
|
|
|
|
check_encoded:
|
|
/* If we reach here, try to BER decode it as OCTET-STRING */
|
|
- rc = ber_decode_OCTET_STRING((CK_BYTE *)data, &value, &value_len,
|
|
+ rc = ber_decode_OCTET_STRING((CK_BYTE *)data, data_len, &value, &value_len,
|
|
&field_len);
|
|
if (rc == CKR_OK && field_len == data_len && value_len <= data_len - 2) {
|
|
/* Looks like a BER encoded EC Point */
|
|
diff --git a/usr/lib/common/pkey_utils.c b/usr/lib/common/pkey_utils.c
|
|
index bd381ca4..3eaca774 100644
|
|
--- a/usr/lib/common/pkey_utils.c
|
|
+++ b/usr/lib/common/pkey_utils.c
|
|
@@ -1299,8 +1299,8 @@ struct { \
|
|
}
|
|
|
|
/* CKA_EC_POINT is an BER encoded OCTET STRING. Extract it. */
|
|
- rc = ber_decode_OCTET_STRING(pub_attr->pValue, &ecpoint,
|
|
- &ecpoint_len, &field_len);
|
|
+ rc = ber_decode_OCTET_STRING(pub_attr->pValue, pub_attr->ulValueLen,
|
|
+ &ecpoint, &ecpoint_len, &field_len);
|
|
if (rc != CKR_OK || pub_attr->ulValueLen != field_len) {
|
|
TRACE_ERROR("%s: ber_decode_OCTET_STRING failed\n", __func__);
|
|
ret = CKR_ATTRIBUTE_VALUE_INVALID;
|
|
@@ -1417,8 +1417,8 @@ struct { \
|
|
}
|
|
|
|
/* CKA_EC_POINT is an BER encoded OCTET STRING. Extract it. */
|
|
- rc = ber_decode_OCTET_STRING(pub_attr->pValue, &ecpoint,
|
|
- &ecpoint_len, &field_len);
|
|
+ rc = ber_decode_OCTET_STRING(pub_attr->pValue, pub_attr->ulValueLen,
|
|
+ &ecpoint, &ecpoint_len, &field_len);
|
|
if (rc != CKR_OK || pub_attr->ulValueLen != field_len) {
|
|
TRACE_ERROR("%s: ber_decode_OCTET_STRING failed\n", __func__);
|
|
ret = CKR_ATTRIBUTE_VALUE_INVALID;
|
|
diff --git a/usr/lib/ep11_stdll/ep11_mkchange.c b/usr/lib/ep11_stdll/ep11_mkchange.c
|
|
index e7b37a0e..53737089 100644
|
|
--- a/usr/lib/ep11_stdll/ep11_mkchange.c
|
|
+++ b/usr/lib/ep11_stdll/ep11_mkchange.c
|
|
@@ -45,15 +45,16 @@ CK_BBOOL ep11tok_is_blob_new_wkid(STDLL_TokData_t *tokdata,
|
|
* denoted by 0x30 followed by the DER encoded length of the SPKI.
|
|
*/
|
|
if (blob_len > 5 && blob[0] == 0x30 &&
|
|
- ber_decode_SEQUENCE(blob, &data, &data_len, &spki_len) == CKR_OK) {
|
|
+ ber_decode_SEQUENCE(blob, blob_len, &data, &data_len, &spki_len) ==
|
|
+ CKR_OK) {
|
|
/* Its a SPKI, WKID follows as OCTET STRING right after SPKI data */
|
|
if (blob_len < spki_len + 2 + XCP_WKID_BYTES) {
|
|
TRACE_ERROR("MACed SPKI is too small\n");
|
|
return CK_FALSE;
|
|
}
|
|
|
|
- rc = ber_decode_OCTET_STRING(blob + spki_len, &data, &data_len,
|
|
- &wkid_len);
|
|
+ rc = ber_decode_OCTET_STRING(blob + spki_len, blob_len - spki_len,
|
|
+ &data, &data_len, &wkid_len);
|
|
if (rc != CKR_OK || data_len != XCP_WKID_BYTES) {
|
|
TRACE_ERROR("Invalid MACed SPKI encoding\n");
|
|
return CK_FALSE;
|
|
diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c
|
|
index 073b349f..b45cdb20 100644
|
|
--- a/usr/lib/ep11_stdll/ep11_specific.c
|
|
+++ b/usr/lib/ep11_stdll/ep11_specific.c
|
|
@@ -3310,8 +3310,9 @@ static CK_RV import_EC_key(STDLL_TokData_t *tokdata, SESSION *sess,
|
|
}
|
|
|
|
/* CKA_EC_POINT is an BER encoded OCTET STRING. Extract it. */
|
|
- rc = ber_decode_OCTET_STRING((CK_BYTE *)ec_point_attr->pValue, &ecpoint,
|
|
- &ecpoint_len, &field_len);
|
|
+ rc = ber_decode_OCTET_STRING((CK_BYTE *)ec_point_attr->pValue,
|
|
+ ec_point_attr->ulValueLen,
|
|
+ &ecpoint, &ecpoint_len, &field_len);
|
|
if (rc != CKR_OK || ec_point_attr->ulValueLen != field_len) {
|
|
TRACE_DEVEL("%s ber_decode_OCTET_STRING failed\n", __func__);
|
|
rc = CKR_ATTRIBUTE_VALUE_INVALID;
|
|
@@ -4381,7 +4382,7 @@ CK_RV token_specific_object_add(STDLL_TokData_t * tokdata, SESSION * sess,
|
|
|
|
if (spkisize > 0 && (class == CKO_PRIVATE_KEY || class == CKO_PUBLIC_KEY)) {
|
|
/* spki may be a MACed SPKI, get length of SPKI part only */
|
|
- rc = ber_decode_SEQUENCE(spki, &temp, &temp_len, &spkisize);
|
|
+ rc = ber_decode_SEQUENCE(spki, spkisize, &temp, &temp_len, &spkisize);
|
|
if (rc != CKR_OK) {
|
|
TRACE_ERROR("%s ber_decode_SEQUENCE failed rc=0x%lx\n",
|
|
__func__, rc);
|
|
@@ -6281,8 +6282,10 @@ CK_RV ep11tok_derive_key(STDLL_TokData_t *tokdata, SESSION *session,
|
|
goto error;
|
|
}
|
|
} else {
|
|
- rc = ber_decode_OCTET_STRING(ecdh1_parms->pPublicData, &ecpoint,
|
|
- &ecpoint_len, &field_len);
|
|
+ rc = ber_decode_OCTET_STRING(ecdh1_parms->pPublicData,
|
|
+ ecdh1_parms->ulPublicDataLen,
|
|
+ &ecpoint, &ecpoint_len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK || field_len != ecdh1_parms->ulPublicDataLen ||
|
|
ecpoint_len > ecdh1_parms->ulPublicDataLen - 2) {
|
|
/* no valid BER OCTET STRING encoding, assume raw */
|
|
@@ -6946,15 +6949,15 @@ static CK_RV dh_generate_keypair(STDLL_TokData_t *tokdata,
|
|
#endif
|
|
|
|
/* CKA_VALUE of the public key must hold 'y' */
|
|
- rc = ber_decode_SPKI(publblob, &oid, &oid_len, &parm, &parm_len,
|
|
- &y_start, &bit_str_len);
|
|
+ rc = ber_decode_SPKI(publblob, publblobsize, &oid, &oid_len,
|
|
+ &parm, &parm_len, &y_start, &bit_str_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_ERROR("%s ber_decode SKPI failed rc=0x%lx\n", __func__, rc);
|
|
goto dh_generate_keypair_end;
|
|
}
|
|
|
|
/* DHPublicKey ::= INTEGER -- public key, y = g^x mod p */
|
|
- rc = ber_decode_INTEGER(y_start, &data, &data_len, &field_len);
|
|
+ rc = ber_decode_INTEGER(y_start, bit_str_len, &data, &data_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_ERROR("%s ber_decode_INTEGER failed rc=0x%lx\n", __func__, rc);
|
|
goto dh_generate_keypair_end;
|
|
@@ -7325,15 +7328,15 @@ static CK_RV dsa_generate_keypair(STDLL_TokData_t *tokdata,
|
|
}
|
|
|
|
/* set CKA_VALUE of the public key, first get key from SPKI */
|
|
- rc = ber_decode_SPKI(publblob, &oid, &oid_len, &parm, &parm_len,
|
|
- &key, &bit_str_len);
|
|
+ rc = ber_decode_SPKI(publblob, publblobsize, &oid, &oid_len,
|
|
+ &parm, &parm_len, &key, &bit_str_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_ERROR("%s reading DSA SPKI failed with rc=0x%lx\n", __func__, rc);
|
|
goto dsa_generate_keypair_end;
|
|
}
|
|
|
|
/* key must be an integer */
|
|
- rc = ber_decode_INTEGER(key, &data, &data_len, &field_len);
|
|
+ rc = ber_decode_INTEGER(key, bit_str_len, &data, &data_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_ERROR("%s reading DSA public key failed with rc=0x%lx\n",
|
|
__func__, rc);
|
|
@@ -7575,7 +7578,7 @@ static CK_RV rsa_ec_generate_keypair(STDLL_TokData_t *tokdata,
|
|
TRACE_DEBUG("%s ec_generate_keypair spki:\n", __func__);
|
|
TRACE_DEBUG_DUMP(" ", spki, spki_len);
|
|
#endif
|
|
- rc = ber_decode_SPKI(spki, &oid, &oid_len, &parm, &parm_len,
|
|
+ rc = ber_decode_SPKI(spki, spki_len, &oid, &oid_len, &parm, &parm_len,
|
|
&key, &bit_str_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_ERROR("%s read key from SPKI failed with rc=0x%lx\n",
|
|
@@ -7671,8 +7674,9 @@ static CK_RV rsa_ec_generate_keypair(STDLL_TokData_t *tokdata,
|
|
* already built SPKI (in CKA_IBM_OPAQUE of the public key).
|
|
*/
|
|
CK_BYTE *modulus, *publ_exp;
|
|
+ CK_ULONG modulus_len, publ_exp_len;
|
|
|
|
- rc = ber_decode_SPKI(spki, &oid, &oid_len, &parm, &parm_len,
|
|
+ rc = ber_decode_SPKI(spki, spki_len, &oid, &oid_len, &parm, &parm_len,
|
|
&key, &bit_str_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_ERROR("%s read key from SPKI failed with rc=0x%lx\n",
|
|
@@ -7683,7 +7687,8 @@ static CK_RV rsa_ec_generate_keypair(STDLL_TokData_t *tokdata,
|
|
/* key must be a sequence holding two integers,
|
|
* modulus and public exponent
|
|
*/
|
|
- rc = ber_decode_SEQUENCE(key, &data, &data_len, &field_len);
|
|
+ rc = ber_decode_SEQUENCE(key, bit_str_len, &data, &data_len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_ERROR("%s read sequence failed with rc=0x%lx\n",
|
|
__func__, rc);
|
|
@@ -7691,7 +7696,9 @@ static CK_RV rsa_ec_generate_keypair(STDLL_TokData_t *tokdata,
|
|
}
|
|
|
|
modulus = key + field_len - data_len;
|
|
- rc = ber_decode_INTEGER(modulus, &data, &data_len, &field_len);
|
|
+ modulus_len = bit_str_len - field_len + data_len;
|
|
+ rc = ber_decode_INTEGER(modulus, modulus_len, &data, &data_len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_ERROR("%s read modulus failed with rc=0x%lx\n", __func__, rc);
|
|
goto error;
|
|
@@ -7718,7 +7725,9 @@ static CK_RV rsa_ec_generate_keypair(STDLL_TokData_t *tokdata,
|
|
|
|
/* read public exponent */
|
|
publ_exp = modulus + field_len;
|
|
- rc = ber_decode_INTEGER(publ_exp, &data, &data_len, &field_len);
|
|
+ publ_exp_len = bit_str_len - field_len;
|
|
+ rc = ber_decode_INTEGER(publ_exp, publ_exp_len, &data, &data_len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_ERROR("%s read public exponent failed with rc=0x%lx\n",
|
|
__func__, rc);
|
|
@@ -10833,7 +10842,7 @@ CK_RV ep11tok_unwrap_key(STDLL_TokData_t * tokdata, SESSION * session,
|
|
}
|
|
|
|
/* csum is a MACed SPKI, get length of SPKI part only */
|
|
- rc = ber_decode_SEQUENCE(csum, &temp, &temp_len, &cslen);
|
|
+ rc = ber_decode_SEQUENCE(csum, cslen, &temp, &temp_len, &cslen);
|
|
if (rc != CKR_OK) {
|
|
TRACE_ERROR("%s ber_decode_SEQUENCE failed rc=0x%lx\n",
|
|
__func__, rc);
|
|
diff --git a/usr/lib/ica_s390_stdll/ica_specific.c b/usr/lib/ica_s390_stdll/ica_specific.c
|
|
index d69a32c5..266142c0 100644
|
|
--- a/usr/lib/ica_s390_stdll/ica_specific.c
|
|
+++ b/usr/lib/ica_s390_stdll/ica_specific.c
|
|
@@ -5400,8 +5400,8 @@ static CK_RV ica_build_ec_pub_key(OBJECT *key_obj, ICA_EC_KEY **eckey,
|
|
}
|
|
|
|
/* CKA_EC_POINT contains the EC point as OCTET STRING */
|
|
- ret = ber_decode_OCTET_STRING(attr->pValue, &ecpoint, &ecpoint_len,
|
|
- &field_len);
|
|
+ ret = ber_decode_OCTET_STRING(attr->pValue, attr->ulValueLen,
|
|
+ &ecpoint, &ecpoint_len, &field_len);
|
|
if (ret != CKR_OK || field_len != attr->ulValueLen) {
|
|
TRACE_DEVEL("ber_decode_OCTET_STRING failed\n");
|
|
ret = CKR_ATTRIBUTE_VALUE_INVALID;
|