/*
- * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2002-2018 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
{
int ok = 0, nid;
BIGNUM *tmp_1 = NULL, *tmp_2 = NULL;
- unsigned char *buffer_1 = NULL, *buffer_2 = NULL,
- *a_buf = NULL, *b_buf = NULL;
- size_t len_1, len_2;
- unsigned char char_zero = 0;
+ unsigned char *a_buf = NULL, *b_buf = NULL;
+ size_t len;
if (!group || !curve || !curve->a || !curve->b)
return 0;
}
}
#endif
- len_1 = (size_t)BN_num_bytes(tmp_1);
- len_2 = (size_t)BN_num_bytes(tmp_2);
-
- if (len_1 == 0) {
- /* len_1 == 0 => a == 0 */
- a_buf = &char_zero;
- len_1 = 1;
- } else {
- if ((buffer_1 = OPENSSL_malloc(len_1)) == NULL) {
- ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- if ((len_1 = BN_bn2bin(tmp_1, buffer_1)) == 0) {
- ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB);
- goto err;
- }
- a_buf = buffer_1;
+ /*
+ * Per SEC 1, the curve coefficients must be padded up to size. See C.2's
+ * definition of Curve, C.1's definition of FieldElement, and 2.3.5's
+ * definition of how to encode the field elements.
+ */
+ len = ((size_t)EC_GROUP_get_degree(group) + 7) / 8;
+ if ((a_buf = OPENSSL_malloc(len)) == NULL
+ || (b_buf = OPENSSL_malloc(len)) == NULL) {
+ ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
+ goto err;
}
-
- if (len_2 == 0) {
- /* len_2 == 0 => b == 0 */
- b_buf = &char_zero;
- len_2 = 1;
- } else {
- if ((buffer_2 = OPENSSL_malloc(len_2)) == NULL) {
- ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- if ((len_2 = BN_bn2bin(tmp_2, buffer_2)) == 0) {
- ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB);
- goto err;
- }
- b_buf = buffer_2;
+ if (BN_bn2binpad(tmp_1, a_buf, len) < 0
+ || BN_bn2binpad(tmp_2, b_buf, len) < 0) {
+ ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB);
+ goto err;
}
/* set a and b */
- if (!ASN1_OCTET_STRING_set(curve->a, a_buf, len_1) ||
- !ASN1_OCTET_STRING_set(curve->b, b_buf, len_2)) {
+ if (!ASN1_OCTET_STRING_set(curve->a, a_buf, len)
+ || !ASN1_OCTET_STRING_set(curve->b, b_buf, len)) {
ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB);
goto err;
}
ok = 1;
err:
- OPENSSL_free(buffer_1);
- OPENSSL_free(buffer_2);
+ OPENSSL_free(a_buf);
+ OPENSSL_free(b_buf);
BN_free(tmp_1);
BN_free(tmp_2);
return ok;
goto err;
}
- /* now extract the curve parameters a and b */
+ /*
+ * Now extract the curve parameters a and b. Note that, although SEC 1
+ * specifies the length of their encodings, historical versions of OpenSSL
+ * encoded them incorrectly, so we must accept any length for backwards
+ * compatibility.
+ */
if (!params->curve || !params->curve->a ||
!params->curve->a->data || !params->curve->b ||
!params->curve->b->data) {
ECerr(EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS, ERR_R_EC_LIB);
return NULL;
}
- EC_GROUP_set_asn1_flag(ret, 0x0);
+ EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_EXPLICIT_CURVE);
} else if (params->type == 2) { /* implicitlyCA */
return NULL;
} else {
*ps = sig->s;
}
+const BIGNUM *ECDSA_SIG_get0_r(const ECDSA_SIG *sig)
+{
+ return sig->r;
+}
+
+const BIGNUM *ECDSA_SIG_get0_s(const ECDSA_SIG *sig)
+{
+ return sig->s;
+}
+
int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s)
{
if (r == NULL || s == NULL)