mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-08-14 10:03:43 +08:00
More tests
This commit is contained in:
81
src/asn1.c
81
src/asn1.c
@@ -313,34 +313,37 @@ int asn1_header_to_der(int tag, size_t len, uint8_t **out, size_t *outlen)
|
||||
|
||||
// If data == NULL, out should not be NULL
|
||||
// 这个实现是不支持OPTIONAL的
|
||||
int asn1_type_to_der(int tag, const uint8_t *data, size_t datalen, uint8_t **out, size_t *outlen)
|
||||
int asn1_type_to_der(int tag, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen)
|
||||
{
|
||||
// 针对IMPLICIT, OPTIONAL
|
||||
if (data == NULL && datalen == 0) {
|
||||
if (!d) {
|
||||
if (dlen) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// FIXME: asn1_tag,length,data_to_der这几个函数增加错误检查
|
||||
// 检查这几个函数的返回值
|
||||
asn1_tag_to_der(tag, out, outlen);
|
||||
asn1_length_to_der(datalen, out, outlen);
|
||||
asn1_data_to_der(data, datalen, out, outlen);
|
||||
if (asn1_tag_to_der(tag, out, outlen) != 1
|
||||
|| asn1_length_to_der(dlen, out, outlen) != 1
|
||||
|| asn1_data_to_der(d, dlen, out, outlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int asn1_type_from_der(int tag, const uint8_t **data, size_t *datalen, const uint8_t **in, size_t *inlen)
|
||||
int asn1_type_from_der(int tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen)
|
||||
{
|
||||
int ret;
|
||||
*data = NULL;
|
||||
*datalen = 0;
|
||||
if ((ret = asn1_tag_from_der(tag, in, inlen)) != 1) {
|
||||
if (ret < 0) error_print();
|
||||
//if (ret == 0) error_print();
|
||||
else {
|
||||
*d = NULL;
|
||||
*dlen = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
if (asn1_length_from_der(datalen, in, inlen) != 1
|
||||
|| asn1_data_from_der(data, *datalen, in, inlen) != 1) {
|
||||
if (asn1_length_from_der(dlen, in, inlen) != 1
|
||||
|| asn1_data_from_der(d, *dlen, in, inlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
@@ -402,11 +405,38 @@ int asn1_any_from_der(const uint8_t **tlv, size_t *tlvlen, const uint8_t **in, s
|
||||
#define ASN1_TRUE 0xff
|
||||
#define ASN1_FALSE 0x00
|
||||
|
||||
const char *asn1_boolean_name(int val)
|
||||
{
|
||||
switch (val) {
|
||||
case 1: return "true";
|
||||
case 0: return "false";
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int asn1_boolean_from_name(int *val, const char *name)
|
||||
{
|
||||
if (strcmp(name, "true") == 0) {
|
||||
*val = 1;
|
||||
return 1;
|
||||
} else if (strcmp(name, "false") == 0) {
|
||||
*val = 0;
|
||||
return 1;
|
||||
}
|
||||
*val = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int asn1_boolean_to_der_ex(int tag, int val, uint8_t **out, size_t *outlen)
|
||||
{
|
||||
if ((out && !(*out)) || !outlen) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (val < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (out) {
|
||||
*(*out)++ = tag;
|
||||
*(*out)++ = 0x01;
|
||||
@@ -523,6 +553,11 @@ int asn1_bits_to_der_ex(int tag, int bits, uint8_t **out, size_t *outlen)
|
||||
return asn1_bit_string_to_der_ex(tag, buf, nbits, out, outlen);
|
||||
}
|
||||
|
||||
const char *asn1_null_name(void)
|
||||
{
|
||||
return "null";
|
||||
}
|
||||
|
||||
int asn1_null_to_der(uint8_t **out, size_t *outlen)
|
||||
{
|
||||
if ((out && !(*out)) || !outlen) {
|
||||
@@ -591,7 +626,7 @@ static int asn1_oid_node_from_base128(uint32_t *a, const uint8_t **in, size_t *i
|
||||
return 1;
|
||||
}
|
||||
|
||||
int asn1_oid_nodes_to_octets(const uint32_t *nodes, size_t nodes_cnt, uint8_t *out, size_t *outlen)
|
||||
int asn1_object_identifier_to_octets(const uint32_t *nodes, size_t nodes_cnt, uint8_t *out, size_t *outlen)
|
||||
{
|
||||
if (nodes_cnt < 2 || nodes_cnt > 32) {
|
||||
return -1;
|
||||
@@ -667,7 +702,7 @@ int asn1_object_identifier_to_der_ex(int tag, const uint32_t *nodes, size_t node
|
||||
*(*out)++ = tag;
|
||||
(*outlen)++;
|
||||
|
||||
asn1_oid_nodes_to_octets(nodes, nodes_cnt, octets, &octetslen);
|
||||
asn1_object_identifier_to_octets(nodes, nodes_cnt, octets, &octetslen);
|
||||
|
||||
asn1_length_to_der(octetslen, out, outlen);
|
||||
|
||||
@@ -865,6 +900,7 @@ int asn1_boolean_from_der_ex(int tag, int *val, const uint8_t **in, size_t *inle
|
||||
}
|
||||
|
||||
if (*inlen <= 0 || **in != tag) {
|
||||
*val = -1;
|
||||
return 0;
|
||||
}
|
||||
if (*inlen < 3
|
||||
@@ -1242,12 +1278,11 @@ int asn1_length_le(size_t len1, size_t len2)
|
||||
|
||||
int asn1_object_identifier_equ(const uint32_t *a, size_t a_cnt, const uint32_t *b, size_t b_cnt)
|
||||
{
|
||||
if (a_cnt != b_cnt
|
||||
|| memcmp(a, b, b_cnt * sizeof(uint32_t)) != 0) {
|
||||
error_print();
|
||||
return 0;
|
||||
if (a_cnt == b_cnt
|
||||
&& memcmp(a, b, b_cnt * sizeof(uint32_t)) == 0) {
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
16
src/cms.c
16
src/cms.c
@@ -78,7 +78,7 @@ static uint32_t oid_cms_key_agreement_info[] = { oid_sm2_cms,6 };
|
||||
static const ASN1_OID_INFO cms_content_types[] = {
|
||||
{ OID_cms_data, "data", oid_cms_data, OID_CMS_CONUNT },
|
||||
{ OID_cms_signed_data, "signedData", oid_cms_signed_data, OID_CMS_CONUNT },
|
||||
{ OID_cms_enveloped_data, "envelopedData", oid_cms_signed_data, OID_CMS_CONUNT },
|
||||
{ OID_cms_enveloped_data, "envelopedData", oid_cms_enveloped_data, OID_CMS_CONUNT },
|
||||
{ OID_cms_signed_and_enveloped_data, "signedAndEnvelopedData", oid_cms_signed_and_enveloped_data, OID_CMS_CONUNT },
|
||||
{ OID_cms_encrypted_data, "encryptedData", oid_cms_encrypted_data, OID_CMS_CONUNT },
|
||||
{ OID_cms_key_agreement_info, "keyAgreementInfo", oid_cms_key_agreement_info, OID_CMS_CONUNT }
|
||||
@@ -346,11 +346,11 @@ int cms_enced_content_info_print(FILE *fp, int fmt, int ind, const char *label,
|
||||
if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err;
|
||||
x509_encryption_algor_print(fp, fmt, ind, "contentEncryptionAlgorithm", p, len);
|
||||
if ((ret = asn1_implicit_octet_string_from_der(0, &p, &len, &d, &dlen)) < 0) goto err;
|
||||
if (ret) format_bytes(fp, fmt, ind, "encryptedContent", d, dlen);
|
||||
if (ret) format_bytes(fp, fmt, ind, "encryptedContent", p, len);
|
||||
if ((ret = asn1_implicit_octet_string_from_der(1, &p, &len, &d, &dlen)) < 0) goto err;
|
||||
if (ret) format_bytes(fp, fmt, ind, "sharedInfo1", d, dlen);
|
||||
if (ret) format_bytes(fp, fmt, ind, "sharedInfo1", p, len);
|
||||
if ((ret = asn1_implicit_octet_string_from_der(2, &p, &len, &d, &dlen)) < 0) goto err;
|
||||
if (ret) format_bytes(fp, fmt, ind, "sharedInfo2", d, dlen);
|
||||
if (ret) format_bytes(fp, fmt, ind, "sharedInfo2", p, len);
|
||||
if (asn1_length_is_zero(dlen) != 1) goto err;
|
||||
return 1;
|
||||
err:
|
||||
@@ -658,6 +658,7 @@ int cms_signer_info_to_der(
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (asn1_int_to_der(version, NULL, &len) != 1
|
||||
|| cms_issuer_and_serial_number_to_der(
|
||||
issuer, issuer_len,
|
||||
@@ -732,13 +733,13 @@ int cms_signer_info_print(FILE *fp, int fmt, int ind, const char *label, const u
|
||||
cms_issuer_and_serial_number_print(fp, fmt, ind, "issuerAndSerialNumber", p, len);
|
||||
if (x509_digest_algor_from_der(&val, &d, &dlen) != 1) goto err;
|
||||
format_print(fp, fmt, ind, "digestAlgorithm: %s\n", x509_digest_algor_name(val));
|
||||
if ((ret = asn1_implicit_set_from_der(0, &p, &len, &d, &dlen)) != 1) goto err;
|
||||
if ((ret = asn1_implicit_set_from_der(0, &p, &len, &d, &dlen)) < 0) goto err;
|
||||
if (ret) x509_attributes_print(fp, fmt, ind, "authenticatedAttributes", p, len);
|
||||
if (x509_signature_algor_from_der(&val, &d, &dlen) != 1) goto err;
|
||||
format_print(fp, fmt, ind, "digestEncryptionAlgorithm: %s\n", x509_signature_algor_name(val));
|
||||
if (asn1_octet_string_from_der(&p, &len, &d, &dlen) != 1) goto err;
|
||||
format_bytes(fp, fmt, ind, "encryptedDigest", p, len);
|
||||
if ((ret = asn1_implicit_set_from_der(1, &p, &len, &d, &dlen)) != 1) goto err;
|
||||
if ((ret = asn1_implicit_set_from_der(1, &p, &len, &d, &dlen)) < 0) goto err;
|
||||
if (ret) x509_attributes_print(fp, fmt, ind, "unauthenticatedAttributes", p, len);
|
||||
if (asn1_length_is_zero(dlen) != 1) goto err;
|
||||
return 1;
|
||||
@@ -834,6 +835,7 @@ int cms_signer_infos_add_signer_info(
|
||||
const uint8_t *unauthed_attrs, size_t unauthed_attrs_len)
|
||||
{
|
||||
size_t len = *dlen;
|
||||
d += *dlen;
|
||||
if (cms_signer_info_sign_to_der(sm3_ctx, sign_key,
|
||||
issuer, issuer_len, serial_number, serial_number_len,
|
||||
authed_attrs, authed_attrs_len,
|
||||
@@ -1290,7 +1292,7 @@ int cms_recipient_info_encrypt_to_der(
|
||||
uint8_t **out, size_t *outlen)
|
||||
{
|
||||
int pke_algor = OID_sm2encrypt;
|
||||
uint8_t enced_key[SM2_CIPHERTEXT_SIZE(inlen)];
|
||||
uint8_t enced_key[SM2_MAX_CIPHERTEXT_SIZE];
|
||||
size_t enced_key_len;
|
||||
|
||||
if (pke_algor != OID_sm2encrypt) {
|
||||
|
||||
178
src/ec.c
Normal file
178
src/ec.c
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright (c) 2014 - 2020 The GmSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project.
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* 4. The name "GmSSL Project" must not be used to endorse or promote
|
||||
* products derived from this software without prior written
|
||||
* permission. For written permission, please contact
|
||||
* guanzhi1980@gmail.com.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "GmSSL"
|
||||
* nor may "GmSSL" appear in their names without prior written
|
||||
* permission of the GmSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <gmssl/ec.h>
|
||||
#include <gmssl/error.h>
|
||||
|
||||
|
||||
#define oid_sm_scheme 1,2,156,10197,1
|
||||
static uint32_t oid_sm2[] = { oid_sm_scheme,301 };
|
||||
|
||||
#define oid_x9_62_curves oid_x9_62,3
|
||||
#define oid_x9_62_prime_curves oid_x9_62_curves,1
|
||||
static uint32_t oid_prime192v1[] = { oid_x9_62_prime_curves,1 };
|
||||
static uint32_t oid_prime256v1[] = { oid_x9_62_prime_curves,7 }; // NIST P-256
|
||||
|
||||
#define oid_secg_curve 1,3,132,0
|
||||
static uint32_t oid_secp256k1[] = { oid_secg_curve,10 };
|
||||
static uint32_t oid_secp384r1[] = { oid_secg_curve,34 }; // NIST P-384
|
||||
static uint32_t oid_secp521r1[] = { oid_secg_curve,35 }; // NIST P-521
|
||||
|
||||
|
||||
static const ASN1_OID_INFO ec_named_curves[] = {
|
||||
{ OID_sm2, "sm2p256v1", oid_sm2, sizeof(oid_sm2)/sizeof(int), 0, "SM2" },
|
||||
{ OID_prime192v1, "prime192v1", oid_prime192v1, sizeof(oid_prime192v1)/sizeof(int), 0, },
|
||||
{ OID_prime256v1, "prime256v1", oid_prime256v1, sizeof(oid_prime256v1)/sizeof(int), 0, "NIST P-256" },
|
||||
{ OID_secp256k1, "secp256k1", oid_secp256k1, sizeof(oid_secp256k1)/sizeof(int) },
|
||||
{ OID_secp384r1, "secp384r1", oid_secp384r1, sizeof(oid_secp384r1)/sizeof(int), 0, "NIST P-384" },
|
||||
{ OID_secp521r1, "secp521r1", oid_secp521r1, sizeof(oid_secp521r1)/sizeof(int), 0, "NIST P-521" }
|
||||
};
|
||||
|
||||
static const int ec_named_curves_count =
|
||||
sizeof(ec_named_curves)/sizeof(ec_named_curves[0]);
|
||||
|
||||
const char *ec_named_curve_name(int oid)
|
||||
{
|
||||
const ASN1_OID_INFO *info;
|
||||
if (!(info = asn1_oid_info_from_oid(ec_named_curves, ec_named_curves_count, oid))) {
|
||||
error_print();
|
||||
return NULL;
|
||||
}
|
||||
return info->name;
|
||||
}
|
||||
|
||||
int ec_named_curve_from_name(const char *name)
|
||||
{
|
||||
const ASN1_OID_INFO *info;
|
||||
if (!(info = asn1_oid_info_from_name(ec_named_curves, ec_named_curves_count, name))) {
|
||||
error_print();
|
||||
return OID_undef;
|
||||
}
|
||||
return info->oid;
|
||||
}
|
||||
|
||||
int ec_named_curve_to_der(int oid, uint8_t **out, size_t *outlen)
|
||||
{
|
||||
const ASN1_OID_INFO *info;
|
||||
if (!(info = asn1_oid_info_from_oid(ec_named_curves, ec_named_curves_count, oid))) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, out, outlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ec_named_curve_from_der(int *oid, const uint8_t **in, size_t *inlen)
|
||||
{
|
||||
int ret;
|
||||
const ASN1_OID_INFO *info;
|
||||
if ((ret = asn1_oid_info_from_der(&info, ec_named_curves, ec_named_curves_count, in, inlen)) != 1) {
|
||||
if (ret < 0) error_print();
|
||||
else *oid = -1;
|
||||
return ret;
|
||||
}
|
||||
*oid = info->oid;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ec_point_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
|
||||
{
|
||||
const uint8_t *p;
|
||||
size_t len;
|
||||
|
||||
if (asn1_octet_string_from_der(&p, &len, &d, &dlen) != 1) goto err;
|
||||
format_bytes(fp, fmt, ind, label, p, len);
|
||||
if (asn1_length_is_zero(dlen) != 1) goto err;
|
||||
return 1;
|
||||
err:
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ec_private_key_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
|
||||
{
|
||||
int ret;
|
||||
const uint8_t *a;
|
||||
size_t alen;
|
||||
const uint8_t *p;
|
||||
size_t len;
|
||||
int val;
|
||||
|
||||
format_print(fp, fmt, ind, "%s\n", label);
|
||||
ind += 4;
|
||||
|
||||
if (asn1_int_from_der(&val, &d, &dlen) != 1) goto err;
|
||||
format_print(fp, fmt, ind, "version: %d\n", val);
|
||||
if (asn1_octet_string_from_der(&p, &len, &d, &dlen) != 1) goto err;
|
||||
format_bytes(fp, fmt, ind, "privateKey", p, len);
|
||||
if ((ret = asn1_explicit_from_der(0, &a, &alen, &d, &dlen)) < 0) goto err;
|
||||
else if (ret) {
|
||||
if (ec_named_curve_from_der(&val, &a, &alen) != 1) goto err;
|
||||
format_print(fp, fmt, ind, "parameters: %s\n", ec_named_curve_name(val));
|
||||
if (asn1_length_is_zero(alen) != 1) goto err;
|
||||
}
|
||||
format_print(fp, fmt, ind, "publicKey\n");
|
||||
ind += 4;
|
||||
if ((ret = asn1_explicit_from_der(1, &a, &alen, &d, &dlen)) < 0) goto err;
|
||||
else if (ret) {
|
||||
if (asn1_bit_octets_from_der(&p, &len, &a, &alen) != 1) goto err;
|
||||
format_bytes(fp, fmt, ind, "ECPoint", p, len);
|
||||
if (asn1_length_is_zero(alen) != 1) goto err;
|
||||
}
|
||||
if (asn1_length_is_zero(dlen) != 1) goto err;
|
||||
return 1;
|
||||
err:
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
@@ -173,3 +173,12 @@ int pbkdf2_genkey(const DIGEST *digest,
|
||||
memset(tmp_block, 0, sizeof(key_block));
|
||||
return 1;
|
||||
}
|
||||
|
||||
int pbkdf2_hmac_sm3_genkey(
|
||||
const char *pass, size_t passlen,
|
||||
const uint8_t *salt, size_t saltlen, size_t count,
|
||||
size_t outlen, uint8_t *out)
|
||||
{
|
||||
return pbkdf2_genkey(DIGEST_sm3(), pass, passlen, salt, saltlen, count, outlen, out);
|
||||
}
|
||||
|
||||
|
||||
80
src/rsa.c
Normal file
80
src/rsa.c
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) 2014 - 2021 The GmSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project.
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* 4. The name "GmSSL Project" must not be used to endorse or promote
|
||||
* products derived from this software without prior written
|
||||
* permission. For written permission, please contact
|
||||
* guanzhi1980@gmail.com.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "GmSSL"
|
||||
* nor may "GmSSL" appear in their names without prior written
|
||||
* permission of the GmSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <gmssl/rsa.h>
|
||||
#include <gmssl/asn1.h>
|
||||
#include <gmssl/error.h>
|
||||
|
||||
|
||||
int rsa_public_key_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen)
|
||||
{
|
||||
const uint8_t *d;
|
||||
size_t dlen;
|
||||
const uint8_t *p;
|
||||
size_t len;
|
||||
int val;
|
||||
|
||||
format_print(fp, fmt, ind, "%s\n", label);
|
||||
ind += 4;
|
||||
if (asn1_sequence_from_der(&d, &dlen, &a, &alen) != 1) goto err;
|
||||
if (asn1_integer_from_der(&p, &len, &d, &dlen) != 1) goto err;
|
||||
format_bytes(fp, fmt, ind, "modulus", p, len);
|
||||
if (asn1_int_from_der(&val, &d, &dlen) != 1) goto err;
|
||||
format_print(fp, fmt, ind, "publicExponent: %d\n",val);
|
||||
if (asn1_length_is_zero(dlen) != 1) goto err;
|
||||
if (asn1_length_is_zero(alen) != 1) goto err;
|
||||
return 1;
|
||||
err:
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
@@ -1267,6 +1267,8 @@ int sm2_key_generate(SM2_KEY *key)
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(key, 0, sizeof(SM2_KEY));
|
||||
|
||||
do {
|
||||
bn_rand_range(x, SM2_N);
|
||||
} while (bn_is_zero(x));
|
||||
|
||||
383
src/sm2_asn1.c
383
src/sm2_asn1.c
@@ -56,8 +56,8 @@
|
||||
#include <gmssl/pbkdf2.h>
|
||||
#include <gmssl/pkcs8.h>
|
||||
#include <gmssl/error.h>
|
||||
|
||||
// sm2 curve 1.2.156.10197.1.301
|
||||
#include <gmssl/ec.h>
|
||||
#include <gmssl/x509_alg.h>
|
||||
|
||||
|
||||
void sm2_point_to_compressed_octets(const SM2_POINT *P, uint8_t out[33])
|
||||
@@ -93,11 +93,12 @@ int sm2_point_from_octets(SM2_POINT *P, const uint8_t *in, size_t inlen)
|
||||
|
||||
int sm2_point_to_der(const SM2_POINT *P, uint8_t **out, size_t *outlen)
|
||||
{
|
||||
uint8_t buf[65];
|
||||
if (!P)
|
||||
uint8_t octets[65];
|
||||
if (!P) {
|
||||
return 0;
|
||||
sm2_point_to_uncompressed_octets(P, buf);
|
||||
if (asn1_octet_string_to_der(buf, sizeof(buf), out, outlen) != 1) {
|
||||
}
|
||||
sm2_point_to_uncompressed_octets(P, octets);
|
||||
if (asn1_octet_string_to_der(octets, sizeof(octets), out, outlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
@@ -114,6 +115,10 @@ int sm2_point_from_der(SM2_POINT *P, const uint8_t **in, size_t *inlen)
|
||||
if (ret < 0) error_print();
|
||||
return ret;
|
||||
}
|
||||
if (dlen != 65) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (sm2_point_from_octets(P, d, dlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
@@ -124,8 +129,9 @@ int sm2_point_from_der(SM2_POINT *P, const uint8_t **in, size_t *inlen)
|
||||
int sm2_signature_to_der(const SM2_SIGNATURE *sig, uint8_t **out, size_t *outlen)
|
||||
{
|
||||
size_t len = 0;
|
||||
if (!sig)
|
||||
if (!sig) {
|
||||
return 0;
|
||||
}
|
||||
if (asn1_integer_to_der(sig->r, 32, NULL, &len) != 1
|
||||
|| asn1_integer_to_der(sig->s, 32, NULL, &len) != 1
|
||||
|| asn1_sequence_header_to_der(len, out, outlen) != 1
|
||||
@@ -160,31 +166,34 @@ int sm2_signature_from_der(SM2_SIGNATURE *sig, const uint8_t **in, size_t *inlen
|
||||
return -1;
|
||||
}
|
||||
memset(sig, 0, sizeof(*sig));
|
||||
memcpy(sig->r, r, rlen);
|
||||
memcpy(sig->s, s, slen);
|
||||
memcpy(sig->r + 32 - rlen, r, rlen); // 需要测试当r, s是比较小的整数时
|
||||
memcpy(sig->s + 32 - slen, s, slen);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
int sm2_ciphertext_size(size_t inlen, size_t *outlen)
|
||||
{
|
||||
*outlen = sizeof(SM2_CIPHERTEXT)-1+inlen;
|
||||
return 1;
|
||||
}
|
||||
*/
|
||||
|
||||
int sm2_ciphertext_to_der(const SM2_CIPHERTEXT *c, uint8_t **out, size_t *outlen)
|
||||
int sm2_ciphertext_to_der(const SM2_CIPHERTEXT *C, uint8_t **out, size_t *outlen)
|
||||
{
|
||||
size_t len = 0;
|
||||
if (!c)
|
||||
if (!C) {
|
||||
return 0;
|
||||
if (asn1_integer_to_der(c->point.x, 32, NULL, &len) != 1
|
||||
|| asn1_integer_to_der(c->point.y, 32, NULL, &len) != 1
|
||||
|| asn1_octet_string_to_der(c->hash, 32, NULL, &len) != 1
|
||||
|| asn1_octet_string_to_der(c->ciphertext, c->ciphertext_size, NULL, &len) != 1
|
||||
}
|
||||
if (asn1_integer_to_der(C->point.x, 32, NULL, &len) != 1
|
||||
|| asn1_integer_to_der(C->point.y, 32, NULL, &len) != 1
|
||||
|| asn1_octet_string_to_der(C->hash, 32, NULL, &len) != 1
|
||||
|| asn1_octet_string_to_der(C->ciphertext, C->ciphertext_size, NULL, &len) != 1
|
||||
|| asn1_sequence_header_to_der(len, out, outlen) != 1
|
||||
|| asn1_integer_to_der(c->point.x, 32, out, outlen) != 1
|
||||
|| asn1_integer_to_der(c->point.y, 32, out, outlen) != 1
|
||||
|| asn1_octet_string_to_der(c->hash, 32, out, outlen) != 1
|
||||
|| asn1_octet_string_to_der(c->ciphertext, c->ciphertext_size, out, outlen) != 1) {
|
||||
|| asn1_integer_to_der(C->point.x, 32, out, outlen) != 1
|
||||
|| asn1_integer_to_der(C->point.y, 32, out, outlen) != 1
|
||||
|| asn1_octet_string_to_der(C->hash, 32, out, outlen) != 1
|
||||
|| asn1_octet_string_to_der(C->ciphertext, C->ciphertext_size, out, outlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
@@ -200,7 +209,7 @@ int sm2_ciphertext_from_der(SM2_CIPHERTEXT *C, const uint8_t **in, size_t *inlen
|
||||
const uint8_t *y;
|
||||
const uint8_t *hash;
|
||||
const uint8_t *c;
|
||||
size_t datalen, xlen, ylen, hashlen, clen;
|
||||
size_t xlen, ylen, hashlen, clen;
|
||||
|
||||
if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
|
||||
if (ret < 0) error_print();
|
||||
@@ -223,130 +232,155 @@ int sm2_ciphertext_from_der(SM2_CIPHERTEXT *C, const uint8_t **in, size_t *inlen
|
||||
memcpy(C->point.y, y, ylen);
|
||||
memcpy(C->hash, hash, hashlen);
|
||||
memcpy(C->ciphertext, c, clen);
|
||||
C->ciphertext_size = (uint32_t)clen;
|
||||
C->ciphertext_size = (uint8_t)clen;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// TODO: sm2, ecPublicKey 这些公用的OID应该提取到一个地方
|
||||
static const uint32_t oid_sm2[] = { 1,2,156,10197,1,301 };
|
||||
static const size_t oid_sm2_count = sizeof(oid_sm2)/sizeof(oid_sm2[0]);
|
||||
// BIT STRING wrapping of uncompressed point
|
||||
int sm2_public_key_to_der(const SM2_KEY *key, uint8_t **out, size_t *outlen)
|
||||
{
|
||||
uint8_t buf[65];
|
||||
size_t len = 0;
|
||||
|
||||
if (!key) {
|
||||
return 0;
|
||||
}
|
||||
sm2_point_to_uncompressed_octets(&key->public_key, buf);
|
||||
if (asn1_bit_octets_to_der(buf, sizeof(buf), out, outlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int sm2_public_key_from_der(SM2_KEY *key, const uint8_t **in, size_t *inlen)
|
||||
{
|
||||
int ret;
|
||||
const uint8_t *d;
|
||||
size_t dlen;
|
||||
SM2_POINT P;
|
||||
|
||||
if ((ret = asn1_bit_octets_from_der(&d, &dlen, in, inlen)) != 1) {
|
||||
if (ret < 0) error_print();
|
||||
return ret;
|
||||
}
|
||||
if (dlen != 65) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (sm2_point_from_octets(&P, d, dlen) != 1
|
||||
|| sm2_key_set_public_key(key, &P) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
int sm2_public_key_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen)
|
||||
{
|
||||
const uint8_t *d;
|
||||
size_t dlen;
|
||||
|
||||
format_print(fp, fmt, ind, "%s\n", label);
|
||||
ind += 4;
|
||||
|
||||
if (asn1_bit_octets_from_der(&d, &dlen, &a, &alen) != 1) goto err;
|
||||
format_bytes(fp, fmt, ind, "", d, dlen);
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
*/
|
||||
|
||||
int sm2_private_key_to_der(const SM2_KEY *key, uint8_t **out, size_t *outlen)
|
||||
{
|
||||
int version = 1;
|
||||
uint8_t public_key[65];
|
||||
size_t len = 0;
|
||||
uint8_t params[64];
|
||||
uint8_t pubkey[128];
|
||||
uint8_t *params_ptr = params;
|
||||
uint8_t *pubkey_ptr = pubkey;
|
||||
size_t params_len = 0;
|
||||
size_t pubkey_len = 0;
|
||||
|
||||
sm2_point_to_uncompressed_octets(&key->public_key, public_key);
|
||||
|
||||
asn1_int_to_der(version, NULL, &len);
|
||||
asn1_octet_string_to_der(key->private_key, 32, NULL, &len);
|
||||
asn1_object_identifier_to_der(oid_sm2, oid_sm2_count, NULL, ¶ms_len);
|
||||
asn1_explicit_to_der(0, NULL, params_len, NULL, &len);
|
||||
asn1_bit_string_to_der(public_key, sizeof(public_key) * 8, NULL, &pubkey_len);
|
||||
asn1_explicit_to_der(1, NULL, pubkey_len, NULL, &len);
|
||||
|
||||
asn1_sequence_header_to_der(len, out, outlen);
|
||||
asn1_int_to_der(version, out, outlen);
|
||||
asn1_octet_string_to_der(key->private_key, 32, out, outlen);
|
||||
asn1_explicit_header_to_der(0, params_len, out, outlen);
|
||||
asn1_object_identifier_to_der(oid_sm2, oid_sm2_count, out, outlen);
|
||||
asn1_explicit_header_to_der(1, pubkey_len, out, outlen);
|
||||
asn1_bit_string_to_der(public_key, sizeof(public_key) * 8, out, outlen);
|
||||
|
||||
if (ec_named_curve_to_der(OID_sm2, ¶ms_ptr, ¶ms_len) != 1
|
||||
|| sm2_public_key_to_der(key, &pubkey_ptr, &pubkey_len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (asn1_int_to_der(EC_private_key_version, NULL, &len) != 1
|
||||
|| asn1_octet_string_to_der(key->private_key, 32, NULL, &len) != 1
|
||||
|| asn1_explicit_to_der(0, params, params_len, NULL, &len) != 1
|
||||
|| asn1_explicit_to_der(1, pubkey, pubkey_len, NULL, &len) != 1
|
||||
|| asn1_sequence_header_to_der(len, out, outlen) != 1
|
||||
|| asn1_int_to_der(EC_private_key_version, out, outlen) != 1
|
||||
|| asn1_octet_string_to_der(key->private_key, 32, out, outlen) != 1
|
||||
|| asn1_explicit_to_der(0, params, params_len, out, outlen) != 1
|
||||
|| asn1_explicit_to_der(1, pubkey, pubkey_len, out, outlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int sm2_private_key_from_der(SM2_KEY *key, const uint8_t **in, size_t *inlen)
|
||||
{
|
||||
int ret;
|
||||
const uint8_t *data;
|
||||
size_t datalen;
|
||||
int version;
|
||||
const uint8_t *d;
|
||||
size_t dlen;
|
||||
int ver;
|
||||
const uint8_t *prikey;
|
||||
const uint8_t *params;
|
||||
const uint8_t *pubkey;
|
||||
size_t prikey_len;
|
||||
size_t params_len;
|
||||
size_t pubkey_len;
|
||||
size_t prikey_len, params_len, pubkey_len;
|
||||
|
||||
memset(key, 0, sizeof(SM2_KEY));
|
||||
|
||||
if ((ret = asn1_sequence_from_der(&data, &datalen, in, inlen)) != 1) {
|
||||
if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
|
||||
if (ret < 0) error_print();
|
||||
return ret;
|
||||
}
|
||||
if (asn1_int_from_der(&version, &data, &datalen) != 1
|
||||
|| asn1_octet_string_from_der(&prikey, &prikey_len, &data, &datalen) != 1
|
||||
|| asn1_explicit_from_der(0, ¶ms, ¶ms_len, &data, &datalen) < 0
|
||||
|| asn1_explicit_from_der(1, &pubkey, &pubkey_len, &data, &datalen) < 0
|
||||
|| datalen > 0) {
|
||||
return -1;
|
||||
}
|
||||
if (version != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (prikey_len != 32) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (sm2_key_set_private_key(key, prikey) != 1) {
|
||||
if (asn1_int_from_der(&ver, &d, &dlen) != 1
|
||||
|| asn1_octet_string_from_der(&prikey, &prikey_len, &d, &dlen) != 1
|
||||
|| asn1_explicit_from_der(0, ¶ms, ¶ms_len, &d, &dlen) != 1
|
||||
|| asn1_explicit_from_der(1, &pubkey, &pubkey_len, &d, &dlen) != 1
|
||||
|| asn1_check(ver == EC_private_key_version) != 1
|
||||
|| asn1_length_is_zero(dlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (params) {
|
||||
uint32_t nodes[16]; // FIXME: 这个长度不对啊!
|
||||
size_t nodes_count;
|
||||
|
||||
if (asn1_object_identifier_from_der(nodes, &nodes_count, ¶ms, ¶ms_len) != 1
|
||||
|| params_len > 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (nodes_count != oid_sm2_count
|
||||
|| memcmp(nodes, oid_sm2, sizeof(oid_sm2)) != 0) {
|
||||
int curve;
|
||||
if (ec_named_curve_from_der(&curve, ¶ms, ¶ms_len) != 1
|
||||
|| asn1_check(curve == OID_sm2) != 1
|
||||
|| asn1_length_is_zero(params_len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (asn1_check(prikey_len == 32) != 1
|
||||
|| sm2_key_set_private_key(key, prikey) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (pubkey) {
|
||||
const uint8_t *bits;
|
||||
size_t nbits;
|
||||
|
||||
if (asn1_bit_string_from_der(&bits, &nbits, &pubkey, &pubkey_len) != 1
|
||||
|| pubkey_len > 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (nbits % 8) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (sm2_point_from_octets(&key->public_key, bits, nbits/8) != 1) {
|
||||
if (sm2_public_key_from_der(key, &pubkey, &pubkey_len) != 1
|
||||
|| asn1_length_is_zero(pubkey_len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int sm2_private_key_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
|
||||
{
|
||||
return ec_private_key_print(fp, fmt, ind, label, d, dlen);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const uint32_t oid_ec_public_key[] = { 1,2,840,10045,2,1 };
|
||||
static const size_t oid_ec_public_key_count = sizeof(oid_ec_public_key)/sizeof(oid_ec_public_key[0]);
|
||||
|
||||
int sm2_public_key_algor_to_der(uint8_t **out, size_t *outlen)
|
||||
{
|
||||
size_t len = 0;
|
||||
if (asn1_object_identifier_to_der(oid_ec_public_key, oid_ec_public_key_count, NULL, &len) != 1
|
||||
|| asn1_object_identifier_to_der(oid_sm2, oid_sm2_count, NULL, &len) != 1
|
||||
|| asn1_sequence_header_to_der(len, out, outlen) != 1
|
||||
|| asn1_object_identifier_to_der(oid_ec_public_key, oid_ec_public_key_count, out, outlen) != 1
|
||||
|| asn1_object_identifier_to_der(oid_sm2, oid_sm2_count, out, outlen) != 1) {
|
||||
if (x509_public_key_algor_to_der(OID_ec_public_key, OID_sm2, out, outlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
@@ -356,36 +390,31 @@ int sm2_public_key_algor_to_der(uint8_t **out, size_t *outlen)
|
||||
int sm2_public_key_algor_from_der(const uint8_t **in, size_t *inlen)
|
||||
{
|
||||
int ret;
|
||||
const uint8_t *data;
|
||||
size_t datalen;
|
||||
uint32_t nodes[ASN1_OID_MAX_NODES];
|
||||
size_t nodes_count;
|
||||
int oid;
|
||||
int curve;
|
||||
|
||||
if ((ret = asn1_sequence_from_der(&data, &datalen, in, inlen)) != 1) {
|
||||
if ((ret = x509_public_key_algor_from_der(&oid, &curve, in, inlen)) != 1) {
|
||||
if (ret < 0) error_print();
|
||||
return ret;
|
||||
}
|
||||
if (asn1_object_identifier_from_der(nodes, &nodes_count, &data, &datalen) != 1
|
||||
|| asn1_object_identifier_equ(nodes, nodes_count, oid_ec_public_key, oid_ec_public_key_count) != 1) {
|
||||
if (oid != OID_ec_public_key) {
|
||||
printf("%s %d: oid = %d\n", __FILE__, __LINE__, oid);
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (asn1_object_identifier_from_der(nodes, &nodes_count, &data, &datalen) != 1
|
||||
|| asn1_object_identifier_equ(nodes, nodes_count, oid_sm2, oid_sm2_count) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (datalen) {
|
||||
if (curve != OID_sm2) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define SM2_PRIVATE_KEY_MAX_SIZE 512 // 需要测试这个buffer的最大值
|
||||
|
||||
int sm2_private_key_info_to_der(const SM2_KEY *sm2_key, uint8_t **out, size_t *outlen)
|
||||
{
|
||||
size_t len = 0;
|
||||
uint8_t prikey[512];
|
||||
uint8_t prikey[SM2_PRIVATE_KEY_MAX_SIZE];
|
||||
uint8_t *p = prikey;
|
||||
size_t prikey_len = 0;
|
||||
|
||||
@@ -393,11 +422,11 @@ int sm2_private_key_info_to_der(const SM2_KEY *sm2_key, uint8_t **out, size_t *o
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (asn1_int_to_der(0, NULL, &len) != 1
|
||||
if (asn1_int_to_der(PKCS8_private_key_info_version, NULL, &len) != 1
|
||||
|| sm2_public_key_algor_to_der(NULL, &len) != 1
|
||||
|| asn1_octet_string_to_der(prikey, prikey_len, NULL, &len) != 1
|
||||
|| asn1_sequence_header_to_der(len, out, outlen) != 1
|
||||
|| asn1_int_to_der(0, out, outlen) != 1
|
||||
|| asn1_int_to_der(PKCS8_private_key_info_version, out, outlen) != 1
|
||||
|| sm2_public_key_algor_to_der(out, outlen) != 1
|
||||
|| asn1_octet_string_to_der(prikey, prikey_len, out, outlen) != 1) {
|
||||
memset(prikey, 0, sizeof(prikey));
|
||||
@@ -416,7 +445,7 @@ int sm2_private_key_info_from_der(SM2_KEY *sm2_key, const uint8_t **attrs, size_
|
||||
size_t dlen;
|
||||
int version;
|
||||
const uint8_t *prikey;
|
||||
size_t prikeylen;
|
||||
size_t prikey_len;
|
||||
|
||||
if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
|
||||
if (ret < 0) error_print();
|
||||
@@ -424,24 +453,56 @@ int sm2_private_key_info_from_der(SM2_KEY *sm2_key, const uint8_t **attrs, size_
|
||||
}
|
||||
if (asn1_int_from_der(&version, &d, &dlen) != 1
|
||||
|| sm2_public_key_algor_from_der(&d, &dlen) != 1
|
||||
|| asn1_octet_string_from_der(&prikey, &prikeylen, &d, &dlen) != 1
|
||||
|| asn1_octet_string_from_der(&prikey, &prikey_len, &d, &dlen) != 1
|
||||
|| asn1_implicit_set_from_der(0, attrs, attrslen, &d, &dlen) < 0
|
||||
|| asn1_check(version == 0) != 1
|
||||
|| asn1_length_is_zero(dlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (sm2_private_key_from_der(sm2_key, &prikey, &prikeylen) != 1
|
||||
|| asn1_length_is_zero(prikeylen) != 1) {
|
||||
if (asn1_check(version == PKCS8_private_key_info_version) != 1
|
||||
|| sm2_private_key_from_der(sm2_key, &prikey, &prikey_len) != 1
|
||||
|| asn1_length_is_zero(prikey_len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int sm2_private_key_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
|
||||
{
|
||||
int ret;
|
||||
const uint8_t *p;
|
||||
size_t len;
|
||||
int val;
|
||||
const uint8_t *prikey;
|
||||
size_t prikey_len;
|
||||
|
||||
format_print(fp, fmt, ind, "%s\n", label);
|
||||
ind += 4;
|
||||
|
||||
if (asn1_int_from_der(&val, &d, &dlen) != 1) goto err;
|
||||
format_print(fp, fmt, ind, "version: %d\n", val);
|
||||
if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err;
|
||||
x509_public_key_algor_print(fp, fmt, ind, "privateKeyAlgorithm", p, len);
|
||||
if (asn1_octet_string_from_der(&p, &len, &d, &dlen) != 1) goto err;
|
||||
if (asn1_sequence_from_der(&prikey, &prikey_len, &p, &len) != 1) goto err;
|
||||
ec_private_key_print(fp, fmt, ind + 4, "privateKey", prikey, prikey_len);
|
||||
if (asn1_length_is_zero(len) != 1) goto err;
|
||||
if ((ret = asn1_implicit_set_from_der(0, &p, &len, &d, &dlen)) < 0) goto err;
|
||||
else if (ret) format_bytes(fp, fmt, ind, "attributes", p, len);
|
||||
if (asn1_length_is_zero(dlen) != 1) goto err;
|
||||
return 1;
|
||||
err:
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
#define SM2_PRIVATE_KEY_INFO_MAX_SIZE 512 // 计算长度
|
||||
|
||||
int sm2_private_key_info_to_pem(const SM2_KEY *key, FILE *fp)
|
||||
{
|
||||
uint8_t buf[512];
|
||||
uint8_t buf[SM2_PRIVATE_KEY_INFO_MAX_SIZE];
|
||||
uint8_t *p = buf;
|
||||
size_t len = 0;
|
||||
|
||||
@@ -457,7 +518,7 @@ int sm2_private_key_info_to_pem(const SM2_KEY *key, FILE *fp)
|
||||
|
||||
int sm2_private_key_info_from_pem(SM2_KEY *sm2_key, const uint8_t **attrs, size_t *attrslen, FILE *fp)
|
||||
{
|
||||
uint8_t buf[512];
|
||||
uint8_t buf[512]; // 这个可能是不够用的,因为attributes可能很长
|
||||
const uint8_t *cp = buf;
|
||||
size_t len;
|
||||
|
||||
@@ -471,51 +532,35 @@ int sm2_private_key_info_from_pem(SM2_KEY *sm2_key, const uint8_t **attrs, size_
|
||||
}
|
||||
|
||||
|
||||
int sm2_public_key_info_to_der(const SM2_KEY *a, uint8_t **out, size_t *outlen)
|
||||
#define SM2_POINT_MAX_SIZE (2 + 65)
|
||||
|
||||
int sm2_public_key_info_to_der(const SM2_KEY *pub_key, uint8_t **out, size_t *outlen)
|
||||
{
|
||||
size_t len = 0;
|
||||
uint8_t bits[65];
|
||||
|
||||
sm2_point_to_uncompressed_octets(&a->public_key, bits);
|
||||
|
||||
sm2_public_key_algor_to_der(NULL, &len);
|
||||
asn1_bit_string_to_der(bits, sizeof(bits)*8, NULL, &len);
|
||||
asn1_sequence_header_to_der(len, out, outlen);
|
||||
sm2_public_key_algor_to_der(out, outlen);
|
||||
asn1_bit_string_to_der(bits, sizeof(bits)*8, out, outlen);
|
||||
if (sm2_public_key_algor_to_der(NULL, &len) != 1
|
||||
|| sm2_public_key_to_der(pub_key, NULL, &len) != 1
|
||||
|| asn1_sequence_header_to_der(len, out, outlen) != 1
|
||||
|| sm2_public_key_algor_to_der(out, outlen) != 1
|
||||
|| sm2_public_key_to_der(pub_key, out, outlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int sm2_public_key_info_from_der(SM2_KEY *a, const uint8_t **in, size_t *inlen)
|
||||
int sm2_public_key_info_from_der(SM2_KEY *pub_key, const uint8_t **in, size_t *inlen)
|
||||
{
|
||||
int ret;
|
||||
const uint8_t *data;
|
||||
size_t datalen;
|
||||
const uint8_t *bits;
|
||||
size_t nbits;
|
||||
SM2_POINT point;
|
||||
const uint8_t *d;
|
||||
size_t dlen;
|
||||
|
||||
if ((ret = asn1_sequence_from_der(&data, &datalen, in, inlen)) != 1) {
|
||||
if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
|
||||
if (ret < 0) error_print();
|
||||
return ret;
|
||||
}
|
||||
if (sm2_public_key_algor_from_der(&data, &datalen) != 1
|
||||
|| asn1_bit_string_from_der(&bits, &nbits, &data, &datalen) != 1
|
||||
|| datalen > 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (nbits % 8) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (sm2_point_from_octets(&point, bits, nbits/8) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
memset(a, 0, sizeof(SM2_KEY));
|
||||
if (sm2_key_set_public_key(a, &point) != 1) {
|
||||
if (sm2_public_key_algor_from_der(&d, &dlen) != 1
|
||||
|| sm2_public_key_from_der(pub_key, &d, &dlen) != 1
|
||||
|| asn1_length_is_zero(dlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
@@ -591,6 +636,14 @@ int sm2_public_key_info_from_pem(SM2_KEY *a, FILE *fp)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int sm2_public_key_equ(const SM2_KEY *sm2_key, const SM2_KEY *pub_key)
|
||||
{
|
||||
if (memcmp(sm2_key, pub_key, sizeof(SM2_POINT)) == 0) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sm2_public_key_copy(SM2_KEY *sm2_key, const SM2_KEY *pub_key)
|
||||
{
|
||||
return sm2_key_set_public_key(sm2_key, &pub_key->public_key);
|
||||
@@ -687,6 +740,12 @@ int sm2_private_key_info_decrypt_from_der(SM2_KEY *sm2,
|
||||
|| sm2_private_key_info_from_der(sm2, attrs, attrs_len, &cp, &pkey_info_len) != 1
|
||||
|| asn1_length_is_zero(pkey_info_len) != 1) {
|
||||
error_print();
|
||||
|
||||
if (pkey_info_len) {
|
||||
format_bytes(stderr, 0, 0, "700", cp, pkey_info_len);
|
||||
}
|
||||
|
||||
|
||||
goto end;
|
||||
}
|
||||
ret = 1;
|
||||
@@ -723,8 +782,12 @@ int sm2_private_key_info_decrypt_from_pem(SM2_KEY *key, const char *pass, FILE *
|
||||
size_t attrs_len;
|
||||
|
||||
if (pem_read(fp, "ENCRYPTED PRIVATE KEY", buf, &len, sizeof(buf)) != 1
|
||||
|| sm2_private_key_info_decrypt_from_der(key, &attrs, &attrs_len, pass, &cp, &len) != 1
|
||||
|| asn1_length_is_zero(len) != 1) {
|
||||
|| sm2_private_key_info_decrypt_from_der(key, &attrs, &attrs_len, pass, &cp, &len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (asn1_length_is_zero(len) != 1) {
|
||||
format_bytes(stderr, 0, 0, "", cp, len);
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -209,7 +209,7 @@ int sm2_compute_z(uint8_t z[32], const SM2_POINT *pub, const char *id, size_t id
|
||||
int sm2_sign_init(SM2_SIGN_CTX *ctx, const SM2_KEY *key, const char *id, size_t idlen)
|
||||
{
|
||||
uint8_t z[32];
|
||||
if (!ctx || !key || !id || idlen > SM2_MAX_ID_SIZE) {
|
||||
if (!ctx || !key || !id || idlen > SM2_MAX_ID_LENGTH) {
|
||||
return -1;
|
||||
}
|
||||
sm2_compute_z(z, &key->public_key, id, idlen);
|
||||
@@ -242,7 +242,7 @@ int sm2_sign_resume(SM2_SIGN_CTX *ctx)
|
||||
int sm2_verify_init(SM2_SIGN_CTX *ctx, const SM2_KEY *key, const char *id, size_t idlen)
|
||||
{
|
||||
uint8_t z[32];
|
||||
if (!ctx || !key || !id || idlen > SM2_MAX_ID_SIZE) {
|
||||
if (!ctx || !key || !id || idlen > SM2_MAX_ID_LENGTH) {
|
||||
return -1;
|
||||
}
|
||||
sm2_compute_z(z, &key->public_key, id, idlen);
|
||||
|
||||
51
src/tlcp.c
51
src/tlcp.c
@@ -132,31 +132,35 @@ int tlcp_certificate_chain_verify(const uint8_t *data, size_t datalen, FILE *ca_
|
||||
{
|
||||
const uint8_t *certs;
|
||||
size_t certslen;
|
||||
const uint8_t *der;
|
||||
size_t derlen;
|
||||
X509_CERTIFICATE sign_cert;
|
||||
X509_CERTIFICATE enc_cert;
|
||||
X509_CERTIFICATE ca_cert;
|
||||
|
||||
const uint8_t *sign_cert;
|
||||
size_t sign_cert_len;
|
||||
const uint8_t *enc_cert;
|
||||
size_t enc_cert_len;
|
||||
const uint8_t *ca_cert;
|
||||
size_t ca_cert_len;
|
||||
const uint8_t *sign_issuer;
|
||||
size_t sign_issuer_len;
|
||||
const uint8_t *enc_issuer;
|
||||
size_t enc_issuer_len;
|
||||
|
||||
if (tls_uint24array_from_bytes(&certs, &certslen, &data, &datalen) != 1
|
||||
|| datalen > 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (tls_uint24array_from_bytes(&der, &derlen, &certs, &certslen) != 1
|
||||
|| x509_certificate_from_der(&sign_cert, &der, &derlen) != 1
|
||||
|| derlen > 0) {
|
||||
if (tls_uint24array_from_bytes(&sign_cert, &sign_cert_len, &certs, &certslen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (tls_uint24array_from_bytes(&der, &derlen, &certs, &certslen) != 1
|
||||
|| x509_certificate_from_der(&enc_cert, &der, &derlen) != 1
|
||||
|| derlen > 0) {
|
||||
if (tls_uint24array_from_bytes(&enc_cert, &enc_cert_len, &certs, &certslen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (x509_name_equ(&sign_cert.tbs_certificate.issuer,
|
||||
&enc_cert.tbs_certificate.issuer) != 1) {
|
||||
if (x509_cert_get_issuer(sign_cert, sign_cert_len, &sign_issuer, &sign_issuer_len) != 1
|
||||
|| x509_cert_get_issuer(enc_cert, enc_cert_len, &enc_issuer, &enc_issuer_len) != 1
|
||||
|| asn1_check(sign_issuer_len == enc_issuer_len) != 1
|
||||
|| asn1_check(memcmp(sign_issuer, enc_issuer, enc_issuer_len) == 0) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
@@ -164,14 +168,12 @@ int tlcp_certificate_chain_verify(const uint8_t *data, size_t datalen, FILE *ca_
|
||||
if (certslen) {
|
||||
const uint8_t *chain = certs;
|
||||
size_t chainlen = certslen;
|
||||
if (tls_uint24array_from_bytes(&der, &derlen, &certs, &certslen) != 1
|
||||
|| x509_certificate_from_der(&ca_cert, &der, &derlen) != 1
|
||||
|| derlen > 0) {
|
||||
if (tls_uint24array_from_bytes(&ca_cert, &ca_cert_len, &certs, &certslen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (x509_certificate_verify_by_certificate(&sign_cert, &ca_cert) != 1
|
||||
|| x509_certificate_verify_by_certificate(&enc_cert, &ca_cert) != 1) {
|
||||
if (x509_cert_verify_by_ca_cert(sign_cert, sign_cert_len, ca_cert, ca_cert_len, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1
|
||||
|| x509_cert_verify_by_ca_cert(enc_cert, enc_cert_len, ca_cert, ca_cert_len, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
@@ -180,7 +182,9 @@ int tlcp_certificate_chain_verify(const uint8_t *data, size_t datalen, FILE *ca_
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (x509_certificate_from_pem_by_name(&ca_cert, ca_certs_fp, &sign_cert.tbs_certificate.issuer) != 1
|
||||
|
||||
/*
|
||||
if (x509_cert_from_pem_by_subject(&ca_cert, ca_certs_fp, &sign_cert.tbs_certificate.issuer) != 1
|
||||
|| x509_certificate_verify_by_certificate(&sign_cert, &ca_cert) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
@@ -190,6 +194,7 @@ int tlcp_certificate_chain_verify(const uint8_t *data, size_t datalen, FILE *ca_
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
*/
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -241,7 +246,7 @@ int tlcp_connect(TLS_CONNECT *conn, const char *hostname, int port,
|
||||
|
||||
sm3_init(&sm3_ctx);
|
||||
if (client_sign_key)
|
||||
sm2_sign_init(&sign_ctx, client_sign_key, SM2_DEFAULT_ID);
|
||||
sm2_sign_init(&sign_ctx, client_sign_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH);
|
||||
tls_record_set_version(record, TLS_version_tlcp);
|
||||
tls_record_set_version(finished, TLS_version_tlcp);
|
||||
|
||||
@@ -333,7 +338,7 @@ int tlcp_connect(TLS_CONNECT *conn, const char *hostname, int port,
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (sm2_verify_init(&verify_ctx, &server_sign_key, SM2_DEFAULT_ID) != 1
|
||||
if (sm2_verify_init(&verify_ctx, &server_sign_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1
|
||||
|| sm2_verify_update(&verify_ctx, client_random, 32) != 1
|
||||
|| sm2_verify_update(&verify_ctx, server_random, 32) != 1
|
||||
|| sm2_verify_update(&verify_ctx, server_enc_cert, server_enc_cert_len) != 1) {
|
||||
@@ -692,7 +697,7 @@ int tlcp_accept(TLS_CONNECT *conn, int port,
|
||||
}
|
||||
|
||||
tls_trace(">>>> ServerKeyExchange\n");
|
||||
if (sm2_sign_init(&sign_ctx, server_sign_key, SM2_DEFAULT_ID) != 1
|
||||
if (sm2_sign_init(&sign_ctx, server_sign_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1
|
||||
|| sm2_sign_update(&sign_ctx, client_random, 32) != 1
|
||||
|| sm2_sign_update(&sign_ctx, server_random, 32) != 1
|
||||
|| sm2_sign_update(&sign_ctx, server_enc_cert, server_enc_certlen) != 1
|
||||
@@ -820,7 +825,7 @@ int tlcp_accept(TLS_CONNECT *conn, int port,
|
||||
return -1;
|
||||
}
|
||||
sm3_update(&sm3_ctx, record + 5, recordlen - 5);
|
||||
sm2_verify_init(&sign_ctx, &client_sign_key, SM2_DEFAULT_ID);
|
||||
sm2_verify_init(&sign_ctx, &client_sign_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH);
|
||||
sm2_verify_update(&sign_ctx, handshakes_buf, handshakeslen);
|
||||
if (sm2_verify_finish(&sign_ctx, sig, siglen) != 1) {
|
||||
error_print();
|
||||
|
||||
98
src/tls.c
98
src/tls.c
@@ -583,7 +583,7 @@ int tls_sign_server_ecdh_params(const SM2_KEY *server_sign_key,
|
||||
server_ecdh_params[3] = 65;
|
||||
sm2_point_to_uncompressed_octets(point, server_ecdh_params + 4);
|
||||
|
||||
sm2_sign_init(&sign_ctx, server_sign_key, SM2_DEFAULT_ID);
|
||||
sm2_sign_init(&sign_ctx, server_sign_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH);
|
||||
sm2_sign_update(&sign_ctx, client_random, 32);
|
||||
sm2_sign_update(&sign_ctx, server_random, 32);
|
||||
sm2_sign_update(&sign_ctx, server_ecdh_params, 69);
|
||||
@@ -612,7 +612,7 @@ int tls_verify_server_ecdh_params(const SM2_KEY *server_sign_key,
|
||||
server_ecdh_params[3] = 65;
|
||||
sm2_point_to_uncompressed_octets(point, server_ecdh_params + 4);
|
||||
|
||||
sm2_verify_init(&verify_ctx, server_sign_key, SM2_DEFAULT_ID);
|
||||
sm2_verify_init(&verify_ctx, server_sign_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH);
|
||||
sm2_verify_update(&verify_ctx, client_random, 32);
|
||||
sm2_verify_update(&verify_ctx, server_random, 32);
|
||||
sm2_verify_update(&verify_ctx, server_ecdh_params, 69);
|
||||
@@ -951,24 +951,16 @@ int tls_record_set_handshake_certificate_from_pem(uint8_t *record, size_t *recor
|
||||
|
||||
for (;;) {
|
||||
int ret;
|
||||
X509_CERTIFICATE cert;
|
||||
uint8_t der[1024];
|
||||
const uint8_t *cp = der;
|
||||
size_t derlen;
|
||||
uint8_t cert[1024];
|
||||
size_t certlen;
|
||||
|
||||
if ((ret = pem_read(fp, "CERTIFICATE", der, &derlen)) < 0) {
|
||||
if ((ret = x509_cert_from_pem(cert, &certlen, sizeof(cert), fp)) < 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
} else if (ret == 0) {
|
||||
} else if (!ret) {
|
||||
break;
|
||||
}
|
||||
tls_uint24array_to_bytes(der, derlen, &certs, &certslen);
|
||||
if (x509_certificate_from_der(&cert, &cp, &derlen) != 1
|
||||
|| derlen > 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
//x509_certificate_print(stderr, &cert, 0, 0);
|
||||
tls_uint24array_to_bytes(cert, certlen, &certs, &certslen);
|
||||
}
|
||||
datalen = certslen;
|
||||
tls_uint24_to_bytes((uint24_t)certslen, &data, &datalen);
|
||||
@@ -996,25 +988,22 @@ int tls_record_get_handshake_certificate(const uint8_t *record, uint8_t *data, s
|
||||
int tls_certificate_get_subject_names(const uint8_t *certs, size_t certslen, uint8_t *names, size_t *nameslen)
|
||||
{
|
||||
*nameslen = 0;
|
||||
const uint8_t *der;
|
||||
size_t derlen;
|
||||
const uint8_t *cert;
|
||||
size_t certlen;
|
||||
|
||||
while (certslen > 0) {
|
||||
X509_CERTIFICATE cert;
|
||||
const uint8_t *subject;
|
||||
size_t subject_len;
|
||||
|
||||
if (tls_uint24array_from_bytes(&der, &derlen, &certs, &certslen) != 1) {
|
||||
if (tls_uint24array_from_bytes(&cert, &certlen, &certs, &certslen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (x509_certificate_from_der(&cert, &der, &derlen) != 1) {
|
||||
if (x509_cert_get_subject(cert, certlen, &subject, &subject_len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (derlen > 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (x509_name_to_der(&cert.tbs_certificate.subject, &names, nameslen) != 1) {
|
||||
if (asn1_sequence_to_der(subject, subject_len, &names, nameslen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
@@ -1056,7 +1045,6 @@ int tls_certificate_get_second(const uint8_t *data, size_t datalen, const uint8_
|
||||
int tls_certificate_get_public_keys(const uint8_t *data, size_t datalen,
|
||||
SM2_KEY *sign_key, SM2_KEY *enc_key)
|
||||
{
|
||||
X509_CERTIFICATE x509;
|
||||
const uint8_t *cert;
|
||||
const uint8_t *der;
|
||||
size_t certlen, derlen;
|
||||
@@ -1067,23 +1055,26 @@ int tls_certificate_get_public_keys(const uint8_t *data, size_t datalen,
|
||||
}
|
||||
if (tls_certificate_get_first(data, datalen, &cert, &certlen) != 1
|
||||
|| tls_uint24array_from_bytes(&der, &derlen, &cert, &certlen) != 1
|
||||
|| certlen > 0
|
||||
|| x509_certificate_from_der(&x509, &der, &derlen) != 1
|
||||
|| derlen > 0) {
|
||||
|| certlen > 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
memcpy(sign_key, &x509.tbs_certificate.subject_public_key_info.sm2_key, sizeof(SM2_KEY));
|
||||
if (x509_cert_get_subject_public_key(der, derlen, sign_key) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (enc_key) {
|
||||
if (tls_certificate_get_second(data, datalen, &cert, &certlen) != 1
|
||||
|| tls_uint24array_from_bytes(&der, &derlen, &cert, &certlen) != 1
|
||||
|| certlen > 0
|
||||
|| x509_certificate_from_der(&x509, &der, &derlen) != 1
|
||||
|| derlen > 0) {
|
||||
|| certlen > 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (x509_cert_get_subject_public_key(der, derlen, enc_key) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
memcpy(enc_key, &x509.tbs_certificate.subject_public_key_info.sm2_key, sizeof(SM2_KEY));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -1092,41 +1083,44 @@ int tls_certificate_get_public_keys(const uint8_t *data, size_t datalen,
|
||||
|
||||
int tls_certificate_chain_verify(const uint8_t *certs, size_t certslen, FILE *ca_certs_fp, int depth)
|
||||
{
|
||||
X509_CERTIFICATE cert;
|
||||
X509_CERTIFICATE cacert;
|
||||
const uint8_t *der;
|
||||
size_t derlen;
|
||||
if (tls_uint24array_from_bytes(&der, &derlen, &certs, &certslen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (x509_certificate_from_der(&cert, &der, &derlen) != 1
|
||||
|| derlen > 0) {
|
||||
const uint8_t *cert;
|
||||
size_t certlen;
|
||||
const uint8_t *cacert;
|
||||
size_t cacertlen;
|
||||
const uint8_t *subject;
|
||||
size_t subject_len;
|
||||
uint8_t rootcacert[1024];
|
||||
size_t rootcacertlen;
|
||||
const char *signer_id = SM2_DEFAULT_ID;
|
||||
|
||||
if (tls_uint24array_from_bytes(&cert, &certlen, &certs, &certslen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
while (certslen > 0) {
|
||||
if (tls_uint24array_from_bytes(&der, &derlen, &certs, &certslen) != 1
|
||||
|| x509_certificate_from_der(&cacert, &der, &derlen) != 1
|
||||
|| derlen > 0) {
|
||||
if (tls_uint24array_from_bytes(&cacert, &cacertlen, &certs, &certslen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (x509_certificate_verify_by_certificate(&cert, &cacert) != 1) {
|
||||
if (x509_cert_verify_by_ca_cert(cert, certlen, cacert, cacertlen, signer_id, strlen(signer_id)) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
memcpy(&cert, &cacert, sizeof(X509_CERTIFICATE));
|
||||
cert = cacert;
|
||||
certlen = cacertlen;
|
||||
}
|
||||
if (x509_certificate_from_pem_by_name(&cacert, ca_certs_fp, &cert.tbs_certificate.issuer) != 1
|
||||
|| x509_certificate_verify_by_certificate(&cert, &cacert) != 1) {
|
||||
if (x509_cert_get_subject(cacert, cacertlen, &subject, &subject_len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (x509_cert_from_pem_by_subject(rootcacert, &rootcacertlen, sizeof(rootcacert), subject, subject_len, ca_certs_fp) != 1
|
||||
|| x509_cert_verify_by_ca_cert(cert, certlen, cacert, cacertlen, signer_id, strlen(signer_id)) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int tls_record_set_handshake_certificate_request(uint8_t *record, size_t *recordlen,
|
||||
const int *cert_types, size_t cert_types_count,
|
||||
const uint8_t *ca_names, size_t ca_names_len)
|
||||
|
||||
@@ -264,7 +264,7 @@ int tls12_connect(TLS_CONNECT *conn, const char *hostname, int port,
|
||||
|
||||
sm3_init(&sm3_ctx);
|
||||
if (client_sign_key)
|
||||
sm2_sign_init(&sign_ctx, client_sign_key, SM2_DEFAULT_ID);
|
||||
sm2_sign_init(&sign_ctx, client_sign_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH);
|
||||
tls_record_set_version(record, TLS_version_tls1);
|
||||
tls_record_set_version(finished, TLS_version_tls12);
|
||||
|
||||
@@ -378,7 +378,7 @@ int tls12_connect(TLS_CONNECT *conn, const char *hostname, int port,
|
||||
}
|
||||
|
||||
tls_trace("++++ generate secrets\n");
|
||||
sm2_keygen(&client_ecdh);
|
||||
sm2_key_generate(&client_ecdh);
|
||||
sm2_ecdh(&client_ecdh, &server_ecdh_public, &server_ecdh_public);
|
||||
memcpy(pre_master_secret, &server_ecdh_public, 32);
|
||||
|
||||
@@ -732,7 +732,7 @@ int tls12_accept(TLS_CONNECT *conn, int port,
|
||||
}
|
||||
|
||||
tls_trace(">>>> ServerKeyExchange\n");
|
||||
sm2_keygen(&server_ecdh);
|
||||
sm2_key_generate(&server_ecdh);
|
||||
if (tls_sign_server_ecdh_params(server_sign_key,
|
||||
client_random, server_random,
|
||||
TLS_curve_sm2p256v1, &server_ecdh.public_key, sig, &siglen) != 1) {
|
||||
@@ -887,7 +887,7 @@ int tls12_accept(TLS_CONNECT *conn, int port,
|
||||
return -1;
|
||||
}
|
||||
sm3_update(&sm3_ctx, record + 5, recordlen - 5);
|
||||
sm2_verify_init(&sign_ctx, &client_sign_key, SM2_DEFAULT_ID);
|
||||
sm2_verify_init(&sign_ctx, &client_sign_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH);
|
||||
sm2_verify_update(&sign_ctx, handshakes_buf, handshakeslen);
|
||||
if (sm2_verify_finish(&sign_ctx, sig, siglen) != 1) {
|
||||
error_print();
|
||||
|
||||
28
src/tls13.c
28
src/tls13.c
@@ -387,7 +387,7 @@ int tls13_sign(const SM2_KEY *key, const DIGEST_CTX *dgst_ctx, uint8_t *sig, siz
|
||||
temp_dgst_ctx = *dgst_ctx;
|
||||
digest_finish(&temp_dgst_ctx, dgst, &dgstlen);
|
||||
|
||||
sm2_sign_init(&sm2_ctx, key, SM2_DEFAULT_ID);
|
||||
sm2_sign_init(&sm2_ctx, key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH);
|
||||
sm2_sign_update(&sm2_ctx, prefix, 64);
|
||||
sm2_sign_update(&sm2_ctx, context_str, context_str_len);
|
||||
sm2_sign_update(&sm2_ctx, dgst, dgstlen);
|
||||
@@ -412,7 +412,7 @@ int tls13_verify(const SM2_KEY *key, const DIGEST_CTX *dgst_ctx, const uint8_t *
|
||||
temp_dgst_ctx = *dgst_ctx;
|
||||
digest_finish(&temp_dgst_ctx, dgst, &dgstlen);
|
||||
|
||||
sm2_verify_init(&sm2_ctx, key, SM2_DEFAULT_ID);
|
||||
sm2_verify_init(&sm2_ctx, key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH);
|
||||
sm2_verify_update(&sm2_ctx, prefix, 64);
|
||||
sm2_verify_update(&sm2_ctx, is_server ? server_context_str : client_context_str, sizeof(server_context_str));
|
||||
sm2_verify_update(&sm2_ctx, dgst, dgstlen);
|
||||
@@ -1013,24 +1013,18 @@ int tls13_record_set_handshake_certificate_from_pem(uint8_t *record, size_t *rec
|
||||
|
||||
for (;;) {
|
||||
int ret;
|
||||
X509_CERTIFICATE cert;
|
||||
uint8_t der[1024];
|
||||
const uint8_t *cp = der;
|
||||
size_t derlen;
|
||||
uint8_t cert[1024];
|
||||
size_t certlen;
|
||||
|
||||
if ((ret = pem_read(fp, "CERTIFICATE", der, &derlen)) < 0) {
|
||||
if (x509_cert_from_pem(cert, &certlen, sizeof(cert), fp) < 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
} else if (ret == 0) {
|
||||
} else if (!ret) {
|
||||
break;
|
||||
}
|
||||
tls_uint24array_to_bytes(der, derlen, &certs, &certslen);
|
||||
if (x509_certificate_from_der(&cert, &cp, &derlen) != 1
|
||||
|| derlen > 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
//x509_certificate_print(stderr, &cert, 0, 0);
|
||||
|
||||
tls_uint24array_to_bytes(cert, certlen, &certs, &certslen);
|
||||
x509_cert_print(stderr, 0, 0, "Certificate", cert, certlen);
|
||||
}
|
||||
datalen = certslen;
|
||||
tls_uint24_to_bytes((uint24_t)certslen, &data, &datalen);
|
||||
@@ -1312,7 +1306,7 @@ int tls13_connect(TLS_CONNECT *conn, const char *hostname, int port, FILE *serve
|
||||
tls_record_set_version(record, TLS_version_tls12);
|
||||
rand_bytes(client_random, 32);
|
||||
rand_bytes(session_id, 32);
|
||||
sm2_keygen(&client_ecdhe);
|
||||
sm2_key_generate(&client_ecdhe);
|
||||
tls13_client_hello_extensions_set(exts, &extslen, &(client_ecdhe.public_key));
|
||||
tls_record_set_handshake_client_hello(record, &recordlen,
|
||||
TLS_version_tls12, client_random, session_id, 32,
|
||||
@@ -1772,7 +1766,7 @@ int tls13_accept(TLS_CONNECT *conn, int port,
|
||||
tls_trace("<<<< ServerHello\n");
|
||||
|
||||
rand_bytes(server_random, 32);
|
||||
sm2_keygen(&server_ecdhe);
|
||||
sm2_key_generate(&server_ecdhe);
|
||||
tls13_server_hello_extensions_set(exts, &extslen, &(server_ecdhe.public_key), NULL);
|
||||
|
||||
if (tls_record_set_handshake_server_hello(enced_record, &enced_recordlen,
|
||||
|
||||
@@ -570,21 +570,12 @@ int tls_certificate_print(FILE *fp, const uint8_t *data, size_t datalen, int for
|
||||
return -1;
|
||||
}
|
||||
while (certslen > 0) {
|
||||
X509_CERTIFICATE cert;
|
||||
if (tls_uint24array_from_bytes(&der, &derlen, &certs, &certslen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (x509_certificate_from_der(&cert, &der, &derlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (derlen > 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
(void)x509_certificate_print(fp, &cert, format, indent);
|
||||
(void)x509_certificate_to_pem(&cert, fp);
|
||||
(void)x509_cert_print(fp, format, indent, "Certificate", der, derlen);
|
||||
(void)x509_cert_to_pem(der, derlen, fp);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ int gmssl_version_num(void)
|
||||
return GMSSL_VERSION_NUM;
|
||||
}
|
||||
|
||||
const char *gmssl_version(void)
|
||||
const char *gmssl_version_str(void)
|
||||
{
|
||||
return GMSSL_VERSION_STR;
|
||||
}
|
||||
|
||||
137
src/x509_alg.c
137
src/x509_alg.c
@@ -49,12 +49,12 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <gmssl/ec.h>
|
||||
#include <gmssl/oid.h>
|
||||
#include <gmssl/asn1.h>
|
||||
#include <gmssl/error.h>
|
||||
|
||||
|
||||
#define oid_x9_62 1,2,840,10045
|
||||
|
||||
|
||||
static uint32_t oid_sm3[] = { 1,2,156,10197,1,401 };
|
||||
@@ -489,50 +489,7 @@ err:
|
||||
}
|
||||
|
||||
|
||||
#define oid_sm_scheme 1,2,156,10197,1
|
||||
static uint32_t oid_sm2[] = { oid_sm_scheme,301 };
|
||||
|
||||
#define oid_x9_62_curves oid_x9_62,3
|
||||
#define oid_x9_62_prime_curves oid_x9_62_curves,1
|
||||
static uint32_t oid_prime192v1[] = { oid_x9_62_prime_curves,1 };
|
||||
static uint32_t oid_prime256v1[] = { oid_x9_62_prime_curves,7 }; // NIST P-256
|
||||
|
||||
#define oid_secg_curve 1,3,132,0
|
||||
static uint32_t oid_secp256k1[] = { oid_secg_curve,10 };
|
||||
static uint32_t oid_secp384r1[] = { oid_secg_curve,34 }; // NIST P-384
|
||||
static uint32_t oid_secp521r1[] = { oid_secg_curve,35 }; // NIST P-521
|
||||
|
||||
|
||||
static const ASN1_OID_INFO ec_curves[] = {
|
||||
{ OID_sm2, "sm2", oid_sm2, sizeof(oid_sm2)/sizeof(int), 0, "SM2" },
|
||||
{ OID_prime192v1, "prime192v1", oid_prime192v1, sizeof(oid_prime192v1)/sizeof(int), 0, },
|
||||
{ OID_prime256v1, "prime256v1", oid_prime256v1, sizeof(oid_prime256v1)/sizeof(int), 0, "NIST P-256" },
|
||||
{ OID_secp256k1, "secp256k1", oid_secp256k1, sizeof(oid_secp256k1)/sizeof(int) },
|
||||
{ OID_secp384r1, "secp384r1", oid_secp384r1, sizeof(oid_secp384r1)/sizeof(int), 0, "NIST P-384" },
|
||||
{ OID_secp521r1, "secp521r1", oid_secp521r1, sizeof(oid_secp521r1)/sizeof(int), 0, "NIST P-521" }
|
||||
};
|
||||
|
||||
static const int ec_curves_count = sizeof(ec_curves)/sizeof(ec_curves[0]);
|
||||
|
||||
const char *ec_curve_name(int oid)
|
||||
{
|
||||
const ASN1_OID_INFO *info;
|
||||
if (!(info = asn1_oid_info_from_oid(ec_curves, ec_curves_count, oid))) {
|
||||
error_print();
|
||||
return NULL;
|
||||
}
|
||||
return info->name;
|
||||
}
|
||||
|
||||
int ec_curve_from_name(const char *name)
|
||||
{
|
||||
const ASN1_OID_INFO *info;
|
||||
if (!(info = asn1_oid_info_from_name(ec_curves, ec_curves_count, name))) {
|
||||
error_print();
|
||||
return OID_undef;
|
||||
}
|
||||
return info->oid;
|
||||
}
|
||||
|
||||
|
||||
static uint32_t oid_ec_public_key[] = { oid_x9_62,2,1 };
|
||||
@@ -566,66 +523,102 @@ int x509_public_key_algor_from_name(const char *name)
|
||||
return info->oid;
|
||||
}
|
||||
|
||||
int x509_ec_public_key_algor_to_der(int curve_oid, uint8_t **out, size_t *outlen)
|
||||
int x509_public_key_algor_to_der(int oid, int curve_or_null, uint8_t **out, size_t *outlen)
|
||||
{
|
||||
const ASN1_OID_INFO *info;
|
||||
size_t len = 0;
|
||||
|
||||
if (!(info = asn1_oid_info_from_oid(ec_curves, ec_curves_count, curve_oid))) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (asn1_object_identifier_to_der(oid_ec_public_key, sizeof(oid_ec_public_key)/sizeof(int), NULL, &len) != 1
|
||||
|| asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, NULL, &len) != 1
|
||||
|| asn1_sequence_header_to_der(len, out, outlen) != 1
|
||||
|| asn1_object_identifier_to_der(oid_ec_public_key, sizeof(oid_ec_public_key)/sizeof(int), out, outlen) != 1
|
||||
|| asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, out, outlen) != 1) {
|
||||
switch (oid) {
|
||||
case OID_ec_public_key:
|
||||
if (asn1_object_identifier_to_der(oid_ec_public_key, sizeof(oid_ec_public_key)/sizeof(int), NULL, &len) != 1
|
||||
|| ec_named_curve_to_der(curve_or_null, NULL, &len) != 1
|
||||
|| asn1_sequence_header_to_der(len, out, outlen) != 1
|
||||
|| asn1_object_identifier_to_der(oid_ec_public_key, sizeof(oid_ec_public_key)/sizeof(int), out, outlen) != 1
|
||||
|| ec_named_curve_to_der(curve_or_null, out, outlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case OID_rsa_encryption:
|
||||
if (asn1_object_identifier_to_der(oid_rsa_encryption, sizeof(oid_rsa_encryption)/sizeof(int), NULL, &len) != 1
|
||||
|| asn1_null_to_der(NULL, &len) != 1
|
||||
|| asn1_sequence_header_to_der(len, out, outlen) != 1
|
||||
|| asn1_object_identifier_to_der(oid_rsa_encryption, sizeof(oid_rsa_encryption)/sizeof(int), out, outlen) != 1
|
||||
|| asn1_null_to_der(out, outlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int x509_ec_public_key_algor_from_der(int *curve_oid, const uint8_t **in, size_t *inlen)
|
||||
int x509_public_key_algor_from_der(int *oid , int *curve_or_null, const uint8_t **in, size_t *inlen)
|
||||
{
|
||||
int ret;
|
||||
const uint8_t *p;
|
||||
size_t len;
|
||||
const uint8_t *d;
|
||||
size_t dlen;
|
||||
const ASN1_OID_INFO *info;
|
||||
|
||||
*curve_oid = OID_undef;
|
||||
if ((ret = asn1_sequence_from_der(&p, &len, in, inlen)) != 1) {
|
||||
if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
|
||||
if (ret < 0) error_print();
|
||||
return ret;
|
||||
}
|
||||
if (asn1_oid_info_from_der(&info, x509_public_key_algors, x509_public_key_algors_count, &p, &len) != 1) {
|
||||
|
||||
if (asn1_oid_info_from_der(&info, x509_public_key_algors, x509_public_key_algors_count, &d, &dlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (info->oid != OID_ec_public_key) {
|
||||
*oid = info->oid;
|
||||
|
||||
switch (*oid) {
|
||||
case OID_ec_public_key:
|
||||
if (ec_named_curve_from_der(curve_or_null, &d, &dlen) != 1
|
||||
|| asn1_length_is_zero(dlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case OID_rsa_encryption:
|
||||
if ((*curve_or_null = asn1_null_from_der(&d, &dlen)) < 0
|
||||
|| asn1_length_is_zero(dlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (asn1_oid_info_from_der(&info, ec_curves, ec_curves_count, &p, &len) != 1
|
||||
|| asn1_length_is_zero(len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
*curve_oid = info->oid;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int x509_public_key_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
|
||||
{
|
||||
const ASN1_OID_INFO *info;
|
||||
int val;
|
||||
|
||||
format_print(fp, fmt, ind, "%s\n", label);
|
||||
ind += 4;
|
||||
|
||||
if (asn1_oid_info_from_der(&info, x509_public_key_algors, x509_public_key_algors_count, &d, &dlen) != 1) goto err;
|
||||
format_print(fp, fmt, ind, "algorithm: %s\n", info->description);
|
||||
if (info->oid != OID_ec_public_key) goto err;
|
||||
if (asn1_oid_info_from_der(&info, ec_curves, ec_curves_count, &d, &dlen) != 1) goto err;
|
||||
format_print(fp, fmt, ind, "namedCurve: %s\n", info->name);
|
||||
format_print(fp, fmt, ind, "algorithm: %s\n", info->name);
|
||||
|
||||
switch (info->oid) {
|
||||
case OID_ec_public_key:
|
||||
if (ec_named_curve_from_der(&val, &d, &dlen) != 1) goto err;
|
||||
format_print(fp, fmt, ind, "namedCurve: %s\n", ec_named_curve_name(val));
|
||||
break;
|
||||
case OID_rsa_encryption:
|
||||
if ((val = asn1_null_from_der(&d, &dlen)) < 0) goto err;
|
||||
else if (val) format_print(fp, fmt, ind, "parameters: %s\n", asn1_null_name());
|
||||
break;
|
||||
default:
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (asn1_length_is_zero(dlen) != 1) goto err;
|
||||
return 1;
|
||||
err:
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
#include <gmssl/oid.h>
|
||||
#include <gmssl/pem.h>
|
||||
#include <gmssl/asn1.h>
|
||||
#include <gmssl/rsa.h>
|
||||
#include <gmssl/x509_oid.h>
|
||||
#include <gmssl/x509_str.h>
|
||||
#include <gmssl/x509_alg.h>
|
||||
@@ -500,6 +501,7 @@ int x509_name_set(uint8_t *d, size_t *dlen, size_t maxlen,
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
*dlen = 0;
|
||||
if (x509_name_add_country_name(d, dlen, maxlen, country) < 0
|
||||
|| x509_name_add_state_or_province_name(d, dlen, maxlen, tag, (uint8_t *)state, _strlen(state)) < 0
|
||||
|| x509_name_add_locality_name(d, dlen, maxlen, tag, (uint8_t *)locality, _strlen(locality)) < 0
|
||||
@@ -551,16 +553,30 @@ int x509_name_get_common_name(const uint8_t *d, size_t dlen, int *tag, const uin
|
||||
|
||||
int x509_public_key_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
|
||||
{
|
||||
const uint8_t *p;
|
||||
size_t len;
|
||||
const uint8_t *p = d;
|
||||
size_t len = dlen;
|
||||
int alg;
|
||||
int params;
|
||||
|
||||
format_print(fp, fmt, ind, "%s\n", label);
|
||||
ind += 4;
|
||||
|
||||
if (x509_public_key_algor_from_der(&alg, ¶ms, &p, &len) != 1) goto err;
|
||||
if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err;
|
||||
x509_public_key_algor_print(fp, fmt, ind, "algorithm", p, len);
|
||||
format_print(fp, fmt, ind, "subjectPublicKey\n");
|
||||
ind += 4;
|
||||
if (asn1_bit_octets_from_der(&p, &len, &d, &dlen) != 1) goto err;
|
||||
format_bytes(fp, fmt, ind, "subjectPublicKey", p, len);
|
||||
switch (alg) {
|
||||
case OID_ec_public_key:
|
||||
format_bytes(fp, fmt, ind, "ECPoint", p, len);
|
||||
break;
|
||||
case OID_rsa_encryption:
|
||||
rsa_public_key_print(fp, fmt, ind, "RSAPublicKey", p, len);
|
||||
break;
|
||||
default:
|
||||
format_bytes(fp, fmt, ind, "raw_data", p, len);
|
||||
}
|
||||
if (asn1_length_is_zero(dlen) != 1) goto err;
|
||||
return 1;
|
||||
err:
|
||||
@@ -627,12 +643,12 @@ int x509_ext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t
|
||||
if (x509_ext_id_from_der(&oid, nodes, &nodes_cnt, &d, &dlen) != 1) goto err;
|
||||
asn1_object_identifier_print(fp, fmt, ind, "extnID", x509_ext_id_name(oid), nodes, nodes_cnt);
|
||||
if ((ret = asn1_boolean_from_der(&critical, &d, &dlen)) < 0) goto err;
|
||||
if (ret) format_print(fp, fmt, ind, "critical: %s\n", critical ? "True" : "False");
|
||||
if (ret) format_print(fp, fmt, ind, "critical: %s\n", asn1_boolean_name(critical));
|
||||
if (asn1_octet_string_from_der(&val, &vlen, &d, &dlen) != 1) goto err;
|
||||
|
||||
switch (oid) {
|
||||
case OID_ce_subject_key_identifier:
|
||||
if (asn1_octet_string_from_der(&p, &len, &val, &vlen)) {
|
||||
if (asn1_octet_string_from_der(&p, &len, &val, &vlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
@@ -649,6 +665,8 @@ int x509_ext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case OID_netscape_cert_comment:
|
||||
case OID_ct_precertificate_scts:
|
||||
case OID_undef:
|
||||
p = val;
|
||||
len = vlen;
|
||||
@@ -683,6 +701,7 @@ int x509_ext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t
|
||||
case OID_ce_crl_distribution_points: return x509_crl_distribution_points_print(fp, fmt, ind, name, p, len);
|
||||
case OID_ce_inhibit_any_policy: format_print(fp, fmt, ind, "%s: %d\n", name, ival);
|
||||
case OID_ce_freshest_crl: return x509_freshest_crl_print(fp, fmt, ind, name, p, len);
|
||||
case OID_netscape_cert_comment: return format_string(fp, fmt, ind, name, p, len);
|
||||
default: format_bytes(fp, fmt, ind, "extnValue", p, len);
|
||||
}
|
||||
return 1;
|
||||
@@ -1257,7 +1276,22 @@ int x509_cert_get_subject(const uint8_t *a, size_t alen, const uint8_t **d, size
|
||||
NULL, NULL); // signature
|
||||
}
|
||||
|
||||
|
||||
int x509_cert_get_issuer(const uint8_t *a, size_t alen, const uint8_t **d, size_t *dlen)
|
||||
{
|
||||
return x509_cert_get_details(a, alen,
|
||||
NULL, // version
|
||||
NULL, NULL, // serial
|
||||
NULL, // signature_algor
|
||||
d, dlen, // issuer
|
||||
NULL, NULL, // validity
|
||||
NULL, NULL, // subject
|
||||
NULL, // subject_public_key
|
||||
NULL, NULL, // issuer_unique_id
|
||||
NULL, NULL, // subject_unique_id
|
||||
NULL, NULL, // extensions
|
||||
NULL, // signature_algor
|
||||
NULL, NULL); // signature
|
||||
}
|
||||
|
||||
int x509_certs_to_pem(const uint8_t *d, size_t dlen, FILE *fp)
|
||||
{
|
||||
@@ -1330,6 +1364,7 @@ int x509_certs_get_cert_by_issuer_and_serial_number(
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int x509_certs_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
|
||||
{
|
||||
const uint8_t *p;
|
||||
|
||||
183
src/x509_ext.c
183
src/x509_ext.c
@@ -71,6 +71,7 @@ int x509_exts_add_sequence(uint8_t *exts, size_t *extslen, size_t maxlen,
|
||||
size_t curlen = *extslen;
|
||||
size_t vlen = 0;
|
||||
|
||||
exts += *extslen;
|
||||
if (asn1_sequence_to_der(d, dlen, &p, &vlen) != 1
|
||||
|| x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1
|
||||
|| asn1_length_le(curlen, maxlen) != 1
|
||||
@@ -94,6 +95,7 @@ int x509_exts_add_authority_key_identifier(uint8_t *exts, size_t *extslen, size_
|
||||
size_t vlen = 0;
|
||||
size_t len = 0;
|
||||
|
||||
exts += *extslen;
|
||||
if (x509_authority_key_identifier_to_der(
|
||||
keyid, keyid_len,
|
||||
issuer, issuer_len,
|
||||
@@ -128,6 +130,8 @@ int x509_exts_add_subject_key_identifier(uint8_t *exts, size_t *extslen, size_t
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
exts += *extslen;
|
||||
if (asn1_octet_string_to_der(d, dlen, &p, &vlen) != 1
|
||||
|| x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1
|
||||
|| asn1_length_le(curlen, maxlen) != 1
|
||||
@@ -146,6 +150,7 @@ int x509_exts_add_key_usage(uint8_t *exts, size_t *extslen, size_t maxlen, int c
|
||||
uint8_t *p = val;
|
||||
size_t vlen = 0;
|
||||
|
||||
exts += *extslen;
|
||||
if (asn1_bits_to_der(bits, &p, &vlen) != 1
|
||||
|| x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1
|
||||
|| asn1_length_le(curlen, maxlen) != 1
|
||||
@@ -203,6 +208,7 @@ int x509_exts_add_name_constraints(uint8_t *exts, size_t *extslen, size_t maxlen
|
||||
size_t vlen = 0;
|
||||
size_t len = 0;
|
||||
|
||||
exts += *extslen;
|
||||
if (x509_name_constraints_to_der(
|
||||
permitted_subtrees, permitted_subtrees_len,
|
||||
excluded_subtrees, excluded_subtrees_len,
|
||||
@@ -230,6 +236,7 @@ int x509_exts_add_policy_constraints(uint8_t *exts, size_t *extslen, size_t maxl
|
||||
uint8_t *p = val;
|
||||
size_t vlen = 0;
|
||||
|
||||
exts += *extslen;
|
||||
if (x509_policy_constraints_to_der(
|
||||
require_explicit_policy,
|
||||
inhibit_policy_mapping,
|
||||
@@ -252,6 +259,7 @@ int x509_exts_add_basic_constraints(uint8_t *exts, size_t *extslen, size_t maxle
|
||||
uint8_t *p = val;
|
||||
size_t vlen = 0;
|
||||
|
||||
exts += *extslen;
|
||||
if (x509_basic_constraints_to_der(ca, path_len_constraint, &p, &vlen) != 1
|
||||
|| x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1
|
||||
|| asn1_length_le(curlen, maxlen) != 1
|
||||
@@ -272,6 +280,7 @@ int x509_exts_add_ext_key_usage(uint8_t *exts, size_t *extslen, size_t maxlen,
|
||||
size_t vlen = 0;
|
||||
size_t len = 0;
|
||||
|
||||
exts += *extslen;
|
||||
if (x509_ext_key_usage_to_der(key_purposes, key_purposes_cnt, NULL, &len) != 1
|
||||
|| asn1_length_le(len, sizeof(val)) != 1
|
||||
|| x509_ext_key_usage_to_der(key_purposes, key_purposes_cnt, &p, &vlen) != 1
|
||||
@@ -300,6 +309,7 @@ int x509_exts_add_inhibit_any_policy(uint8_t *exts, size_t *extslen, size_t maxl
|
||||
uint8_t *p = val;
|
||||
size_t vlen = 0;
|
||||
|
||||
exts += *extslen;
|
||||
if (x509_inhibit_any_policy_to_der(skip_certs, &p, &vlen) != 1
|
||||
|| x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1
|
||||
|| asn1_length_le(curlen, maxlen) != 1
|
||||
@@ -505,6 +515,17 @@ int x509_general_names_add_general_name(uint8_t *gns, size_t *gnslen, size_t max
|
||||
{
|
||||
size_t len = 0;
|
||||
uint8_t *p = gns + *gnslen;
|
||||
|
||||
switch (choice) {
|
||||
case X509_gn_rfc822_name:
|
||||
case X509_gn_dns_name:
|
||||
case X509_gn_uniform_resource_identifier:
|
||||
if (asn1_ia5_string_check((char *)d, dlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (x509_general_name_to_der(choice, d, dlen, NULL, &len) != 1
|
||||
|| asn1_length_le(*gnslen + len, maxlen) != 1
|
||||
|| x509_general_name_to_der(choice, d, dlen, &p, gnslen) != 1) {
|
||||
@@ -514,6 +535,66 @@ int x509_general_names_add_general_name(uint8_t *gns, size_t *gnslen, size_t max
|
||||
return 1;
|
||||
}
|
||||
|
||||
int x509_general_names_add_other_name(uint8_t *gns, size_t *gnslen, size_t maxlen,
|
||||
const uint32_t *nodes, size_t nodes_cnt,
|
||||
const uint8_t *value, size_t value_len)
|
||||
{
|
||||
int choice = X509_gn_other_name;
|
||||
uint8_t buf[128];
|
||||
uint8_t *p = buf;
|
||||
const uint8_t *cp = buf;
|
||||
size_t len = 0;
|
||||
const uint8_t *d;
|
||||
size_t dlen;
|
||||
|
||||
if (x509_other_name_to_der(nodes, nodes_cnt, value, value_len, &p, &len) != 1
|
||||
|| asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1
|
||||
|| x509_general_names_add_general_name(gns, gnslen, maxlen, choice, d, dlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int x509_general_names_add_edi_party_name(uint8_t *gns, size_t *gnslen, size_t maxlen,
|
||||
int assigner_tag, const uint8_t *assigner, size_t assigner_len,
|
||||
int party_name_tag, const uint8_t *party_name, size_t party_name_len)
|
||||
{
|
||||
int choice = X509_gn_edi_party_name;
|
||||
uint8_t buf[128];
|
||||
uint8_t *p = buf;
|
||||
const uint8_t *cp = buf;
|
||||
size_t len = 0;
|
||||
const uint8_t *d;
|
||||
size_t dlen;
|
||||
|
||||
if (x509_edi_party_name_to_der(
|
||||
assigner_tag, assigner, assigner_len,
|
||||
party_name_tag, party_name, party_name_len,
|
||||
&p, &len) != 1
|
||||
|| asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1
|
||||
|| x509_general_names_add_general_name(gns, gnslen, maxlen, choice, d, dlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int x509_general_names_add_registered_id(uint8_t *gns, size_t *gnslen, size_t maxlen,
|
||||
const uint32_t *nodes, size_t nodes_cnt)
|
||||
{
|
||||
int choice = X509_gn_registered_id;
|
||||
uint8_t d[128];
|
||||
size_t dlen;
|
||||
|
||||
if (asn1_object_identifier_to_octets(nodes, nodes_cnt, d, &dlen) != 1
|
||||
|| x509_general_names_add_general_name(gns, gnslen, maxlen, choice, d, dlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int x509_general_names_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
|
||||
{
|
||||
int choice;
|
||||
@@ -614,6 +695,37 @@ static const char *x509_key_usages[] = {
|
||||
static size_t x509_key_usages_count =
|
||||
sizeof(x509_key_usages)/sizeof(x509_key_usages[0]);
|
||||
|
||||
const char *x509_key_usage_name(int flag)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < x509_key_usages_count; i++) {
|
||||
if (flag & 1) {
|
||||
if (flag >> 1) {
|
||||
error_print();
|
||||
return NULL;
|
||||
}
|
||||
return x509_key_usages[i];
|
||||
}
|
||||
flag >>= 1;
|
||||
}
|
||||
error_print();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int x509_key_usage_from_name(int *flag, const char *name)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < x509_key_usages_count; i++) {
|
||||
if (strcmp(name, x509_key_usages[i]) == 0) {
|
||||
*flag = i;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
*flag = 0;
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
int x509_key_usage_print(FILE *fp, int fmt, int ind, const char *label, int bits)
|
||||
{
|
||||
return asn1_bits_print(fp, fmt, ind, label, x509_key_usages, x509_key_usages_count, bits);
|
||||
@@ -647,6 +759,7 @@ int x509_notice_reference_from_der(
|
||||
|
||||
if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
|
||||
if (ret < 0) error_print();
|
||||
else error_print();
|
||||
return ret;
|
||||
}
|
||||
if (x509_display_text_from_der(org_tag, org, org_len, &d, &dlen) != 1
|
||||
@@ -655,7 +768,7 @@ int x509_notice_reference_from_der(
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int x509_notice_reference_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
|
||||
@@ -747,6 +860,7 @@ err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 是否要针对oid = cps的IA5String做一个方便的接口呢?毕竟oid 只有两个可选项
|
||||
int x509_policy_qualifier_info_to_der(
|
||||
int oid,
|
||||
const uint8_t *qualifier, size_t qualifier_len,
|
||||
@@ -1097,18 +1211,20 @@ int x509_basic_constraints_from_der(int *ca, int *path_len_cons, const uint8_t *
|
||||
|
||||
if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
|
||||
if (ret < 0) error_print();
|
||||
else {
|
||||
*ca = -1;
|
||||
*path_len_cons = -1;
|
||||
};
|
||||
return ret;
|
||||
}
|
||||
|
||||
*ca = 0;
|
||||
*path_len_cons = 0; // FIXME: 默认值应该设置为多少?
|
||||
|
||||
if (asn1_boolean_from_der(ca, &d, &dlen) < 0
|
||||
|| asn1_int_from_der(path_len_cons, &d, &dlen) < 0
|
||||
|| asn1_check(ca >= 0 || path_len_cons >= 0) != 1
|
||||
|| asn1_length_is_zero(dlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (*ca < 0) *ca = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1120,7 +1236,7 @@ int x509_basic_constraints_print(FILE *fp, int fmt, int ind, const char *label,
|
||||
ind += 4;
|
||||
|
||||
if ((ret = asn1_boolean_from_der(&val, &d, &dlen)) < 0) goto err;
|
||||
if (ret) format_print(fp, fmt, ind, "cA: %s\n", val ? "True" : "False");
|
||||
if (ret) format_print(fp, fmt, ind, "cA: %s\n", asn1_boolean_name(val));
|
||||
if ((ret = asn1_int_from_der(&val, &d, &dlen)) < 0) goto err;
|
||||
if (ret) format_print(fp, fmt, ind, "pathLenConstraint: %d\n", val);
|
||||
if (asn1_length_is_zero(dlen) != 1) goto err;
|
||||
@@ -1164,15 +1280,14 @@ int x509_general_subtree_from_der(
|
||||
if (ret < 0) error_print();
|
||||
return ret;
|
||||
}
|
||||
*minimum = 0;
|
||||
*maximum = -1;
|
||||
if (x509_general_name_from_der(base_choice, base, base_len, &d, &dlen) != 1
|
||||
|| asn1_int_from_der(minimum, &d, &dlen) < 0
|
||||
|| asn1_int_from_der(maximum, &d, &dlen) < 0
|
||||
|| asn1_implicit_int_from_der(0, minimum, &d, &dlen) < 0
|
||||
|| asn1_implicit_int_from_der(1, maximum, &d, &dlen) < 0
|
||||
|| asn1_length_is_zero(dlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (*minimum < 0) *minimum = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1187,9 +1302,9 @@ int x509_general_subtree_print(FILE *fp, int fmt, int ind, const char *label, co
|
||||
|
||||
if (x509_general_name_from_der(&choice, &p, &len, &d, &dlen) != 1) goto err;
|
||||
x509_general_name_print(fp, fmt, ind, "base", choice, p, len);
|
||||
if ((ret = asn1_int_from_der(&val, &d, &dlen)) < 0) goto err;
|
||||
if ((ret = asn1_implicit_int_from_der(0, &val, &d, &dlen)) < 0) goto err;
|
||||
if (ret) format_print(fp, fmt, ind, "minimum: %d\n", val);
|
||||
if ((ret = asn1_int_from_der(&val, &d, &dlen)) < 0) goto err;
|
||||
if ((ret = asn1_implicit_int_from_der(1, &val, &d, &dlen)) < 0) goto err;
|
||||
if (ret) format_print(fp, fmt, ind, "maximum: %d\n", val);
|
||||
if (asn1_length_is_zero(dlen) != 1) goto err;
|
||||
return 1;
|
||||
@@ -1337,7 +1452,7 @@ int x509_policy_constraints_print(FILE *fp, int fmt, int ind, const char *label,
|
||||
|
||||
if ((ret = asn1_implicit_int_from_der(0, &val, &d, &dlen)) < 0) goto err;
|
||||
if (ret) format_print(fp, fmt, ind, "requireExplicitPolicy: %d\n", val);
|
||||
if ((ret = asn1_implicit_int_from_der(0, &val, &d, &dlen)) < 0) goto err;
|
||||
if ((ret = asn1_implicit_int_from_der(1, &val, &d, &dlen)) < 0) goto err;
|
||||
if (ret) format_print(fp, fmt, ind, "inhibitPolicyMapping: %d\n", val);
|
||||
if (asn1_length_is_zero(dlen) != 1) goto err;
|
||||
return 1;
|
||||
@@ -1403,15 +1518,16 @@ int x509_ext_key_usage_from_der(int *oids, size_t *oids_cnt, size_t max_cnt, con
|
||||
int x509_ext_key_usage_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
|
||||
{
|
||||
int oid;
|
||||
format_print(fp, fmt, ind, "%s: ", label);
|
||||
format_print(fp, fmt, ind, "%s\n", label);
|
||||
ind += 4;
|
||||
|
||||
while (dlen) {
|
||||
if (x509_key_purpose_from_der(&oid, &d, &dlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
fprintf(fp, "%s%s", x509_key_purpose_name(oid), dlen ? ", " : "");
|
||||
format_print(fp, fmt, ind, "%s\n", x509_key_purpose_name(oid));
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1430,6 +1546,36 @@ static const char *x509_revoke_reasons[] = {
|
||||
static size_t x509_revoke_reasons_count =
|
||||
sizeof(x509_revoke_reasons)/sizeof(x509_revoke_reasons[0]);
|
||||
|
||||
const char *x509_revoke_reason_name(int flag)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < x509_revoke_reasons_count; i++) {
|
||||
if (flag & 1) {
|
||||
if (flag >> 1) {
|
||||
error_print();
|
||||
return NULL;
|
||||
}
|
||||
return x509_revoke_reasons[i];
|
||||
}
|
||||
flag >>= 1;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int x509_revoke_reason_from_name(int *flag, const char *name)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < x509_revoke_reasons_count; i++) {
|
||||
if (strcmp(name, x509_revoke_reasons[i]) == 0) {
|
||||
*flag = 1 << i;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
*flag = 0;
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
int x509_revoke_reasons_print(FILE *fp, int fmt, int ind, const char *label, int bits)
|
||||
{
|
||||
return asn1_bits_print(fp, fmt, ind, label, x509_revoke_reasons, x509_revoke_reasons_count, bits);
|
||||
@@ -1548,7 +1694,10 @@ int x509_distribution_point_print(FILE *fp, int fmt, int ind, const char *label,
|
||||
format_print(fp, fmt, ind, "%s\n", label);
|
||||
ind += 4;
|
||||
|
||||
format_bytes(stderr, 0, 0, "1697", d, dlen);
|
||||
|
||||
if ((ret = asn1_explicit_from_der(0, &p, &len, &d, &dlen)) < 0) goto err;
|
||||
/*
|
||||
if (ret) {
|
||||
int choice;
|
||||
const uint8_t *name;
|
||||
@@ -1558,11 +1707,13 @@ int x509_distribution_point_print(FILE *fp, int fmt, int ind, const char *label,
|
||||
x509_distribution_point_name_print(fp, fmt, ind, "DistributionPointName", choice, name, namelen);
|
||||
if (asn1_length_is_zero(len) != 1) goto err;
|
||||
}
|
||||
|
||||
if ((ret = asn1_implicit_bits_from_der(1, &bits, &d, &dlen)) < 0) goto err;
|
||||
if (ret) x509_revoke_reasons_print(fp, fmt, ind, "reasons", bits);
|
||||
if ((ret = asn1_implicit_sequence_from_der(2, &p, &len, &d, &dlen)) < 0) goto err;
|
||||
if (ret) x509_general_names_print(fp, fmt, ind, "cRLIssuer", p, len);
|
||||
if (asn1_length_is_zero(dlen) != 1) goto err;
|
||||
*/
|
||||
return 1;
|
||||
err:
|
||||
error_print();
|
||||
|
||||
@@ -75,6 +75,7 @@ static uint32_t oid_at_country_name[] = { oid_at,6 };
|
||||
static uint32_t oid_at_serial_number[] = { oid_at,5 };
|
||||
static uint32_t oid_at_pseudonym[] = { oid_at,65 };
|
||||
static uint32_t oid_domain_component[] = { 0,9,2342,19200300,100,1,25 };
|
||||
|
||||
static const size_t oid_at_cnt = sizeof(oid_at_name)/sizeof(int);
|
||||
|
||||
static const ASN1_OID_INFO x509_name_types[] = {
|
||||
@@ -165,6 +166,10 @@ static uint32_t oid_ce_freshest_crl[] = { oid_ce,46 };
|
||||
static uint32_t oid_ce_inhibit_any_policy[] = { oid_ce,54 };
|
||||
static const size_t oid_ce_cnt = sizeof(oid_ce_subject_directory_attributes)/sizeof(int);
|
||||
|
||||
static uint32_t oid_netscape_cert_comment[] = { 2,16,840,1,113730,1,13 };
|
||||
static uint32_t oid_cert_authority_info_access[] = { 1,3,6,1,5,5,7,1,1 };
|
||||
static uint32_t oid_ct_precertificate_scts[] = { 1,3,6,1,4,1,11129,2,4,2 };
|
||||
|
||||
static const ASN1_OID_INFO x509_ext_ids[] = {
|
||||
{ OID_ce_authority_key_identifier, "AuthorityKeyIdentifier", oid_ce_authority_key_identifier, oid_ce_cnt },
|
||||
{ OID_ce_subject_key_identifier, "SubjectKeyIdentifier", oid_ce_subject_key_identifier, oid_ce_cnt },
|
||||
@@ -181,6 +186,9 @@ static const ASN1_OID_INFO x509_ext_ids[] = {
|
||||
{ OID_ce_crl_distribution_points, "CRLDistributionPoints", oid_ce_crl_distribution_points, oid_ce_cnt },
|
||||
{ OID_ce_inhibit_any_policy, "InhibitAnyPolicy", oid_ce_inhibit_any_policy, oid_ce_cnt },
|
||||
{ OID_ce_freshest_crl, "FreshestCRL", oid_ce_freshest_crl, oid_ce_cnt },
|
||||
{ OID_netscape_cert_comment, "NetscapeCertComment", oid_netscape_cert_comment, sizeof(oid_netscape_cert_comment)/sizeof(int) },
|
||||
{ OID_cert_authority_info_access, "CertificateAuthorityInformationAccess", oid_cert_authority_info_access, sizeof(oid_cert_authority_info_access)/sizeof(int) },
|
||||
{ OID_ct_precertificate_scts, "CT-PrecertificateSCTs", oid_ct_precertificate_scts, sizeof(oid_ct_precertificate_scts)/sizeof(int) },
|
||||
};
|
||||
|
||||
static const int x509_ext_ids_count =
|
||||
@@ -189,6 +197,9 @@ static const int x509_ext_ids_count =
|
||||
const char *x509_ext_id_name(int oid)
|
||||
{
|
||||
const ASN1_OID_INFO *info;
|
||||
if (oid == 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (!(info = asn1_oid_info_from_oid(x509_ext_ids, x509_ext_ids_count, oid))) {
|
||||
error_print();
|
||||
return NULL;
|
||||
@@ -340,13 +351,12 @@ int x509_cert_policy_id_from_der(int *oid, uint32_t *nodes, size_t *nodes_cnt, c
|
||||
int ret;
|
||||
if ((ret = asn1_object_identifier_from_der(nodes, nodes_cnt, in, inlen)) != 1) {
|
||||
if (ret < 0) error_print();
|
||||
*oid = -1;
|
||||
else *oid = -1;
|
||||
return ret;
|
||||
}
|
||||
if (*nodes_cnt == sizeof(oid_any_policy)/sizeof(int)
|
||||
&& memcmp(nodes, oid_any_policy, sizeof(oid_any_policy))) {
|
||||
if (asn1_object_identifier_equ(nodes, *nodes_cnt, oid_any_policy, oid_cnt(oid_any_policy)))
|
||||
*oid = OID_any_policy;
|
||||
}
|
||||
else *oid = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -424,7 +434,7 @@ int x509_key_purpose_from_der(int *oid, const uint8_t **in, size_t *inlen)
|
||||
const ASN1_OID_INFO *info;
|
||||
if ((ret = asn1_oid_info_from_der(&info, x509_key_purposes, x509_key_purposes_count, in, inlen)) != 1) {
|
||||
if (ret < 0) error_print();
|
||||
else *oid = 0;
|
||||
else *oid = -1;
|
||||
return ret;
|
||||
}
|
||||
*oid = info->oid;
|
||||
|
||||
Reference in New Issue
Block a user