diff --git a/CMakeLists.txt b/CMakeLists.txt index f5b576d3..b9dc02fe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -123,6 +123,12 @@ add_executable( tools/certparse.c tools/certverify.c tools/crlparse.c + tools/crlverify.c + tools/cmssign.c + tools/cmsverify.c + tools/cmsencrypt.c + tools/cmsdecrypt.c + tools/cmsparse.c tools/pbkdf2.c tools/reqgen.c tools/reqparse.c diff --git a/certs/ca/Ant Financial Certification Authority S1.pem b/certs/ca/Ant Financial Certification Authority S1.pem new file mode 100644 index 00000000..5c7326b4 --- /dev/null +++ b/certs/ca/Ant Financial Certification Authority S1.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIICzjCCAnKgAwIBAgIQZMsSZdRKbxEiVT+tvsQxfzAMBggqgRzPVQGDdQUAMC4x +CzAJBgNVBAYTAkNOMQ4wDAYDVQQKDAVOUkNBQzEPMA0GA1UEAwwGUk9PVENBMB4X +DTE4MDMwNTA3MDEwOFoXDTM4MDIyODA3MDEwOFowejELMAkGA1UEBhMCQ04xFjAU +BgNVBAoMDUFudCBGaW5hbmNpYWwxIDAeBgNVBAsMF0NlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MTEwLwYDVQQDDChBbnQgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5IFMxMFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEGmfMCs2ZerI5lvrO +bxfY8HJyIcTwfMtXb3R1KgqJmUTmsdlb3g13lkvkp2GwqGOpptUOxE09hZAeF4tY +QzSkSaOCASIwggEeMB8GA1UdIwQYMBaAFEwysZfZMxvEpgXBxuWLYlvwl3ZYMA8G +A1UdEwEB/wQFMAMBAf8wgboGA1UdHwSBsjCBrzBBoD+gPaQ7MDkxCzAJBgNVBAYT +AkNOMQ4wDAYDVQQKDAVOUkNBQzEMMAoGA1UECwwDQVJMMQwwCgYDVQQDDANhcmww +KqAooCaGJGh0dHA6Ly93d3cucm9vdGNhLmdvdi5jbi9hcmwvYXJsLmNybDA+oDyg +OoY4bGRhcDovL2xkYXAucm9vdGNhLmdvdi5jbjozODkvQ049YXJsLE9VPUFSTCxP +PU5SQ0FDLEM9Q04wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBQ3NFyrGaAF5BAy +72g+BP4NTGdGEzAMBggqgRzPVQGDdQUAA0gAMEUCIQCXq5uO1PaKFI764ak1Ah5R +5vc7E6WGBsO7Jv8+GM8xFgIgbCi8GfqKKiAAhJ3grv5vbQy5kPeC5I/8X3igW4k5 +1Tc= +-----END CERTIFICATE----- diff --git a/certs/ca/TJCA.pem b/certs/ca/TJCA.pem new file mode 100644 index 00000000..cdf512a5 --- /dev/null +++ b/certs/ca/TJCA.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC7jCCApKgAwIBAgIQS66cxft/wk8MdWCL2qSImjAMBggqgRzPVQGDdQUAMDox +CzAJBgNVBAYTAkNOMQ4wDAYDVQQKDAVOUkNBQzEbMBkGA1UEAwwSQ2l2aWwgU2Vy +dmFudCBST09UMB4XDTE3MTIwNjAyNTczMFoXDTM3MTIwMTAyNTczMFowVjELMAkG +A1UEBhMCQ04xEjAQBgNVBAgMCeWkqea0peW4gjEkMCIGA1UECgwb5aSp5rSl5biC +55S15a2Q6K6k6K+B5Lit5b+DMQ0wCwYDVQQDDARUSkNBMFkwEwYHKoZIzj0CAQYI +KoEcz1UBgi0DQgAE2GJUeLtgaq271GSkgvmvBHJVxrg6K8Nx6AogQxNB/qoQjup4 +YDw9odBrYiqdTbOgYL5I+iiPCXJg+6xKL3VA6aOCAVowggFWMB8GA1UdIwQYMBaA +FJ/cX1elCW5m8PJ1du0BYnAE/PpUMA8GA1UdEwEB/wQFMAMBAf8wgfIGA1UdHwSB +6jCB5zBPoE2gS6RJMEcxCzAJBgNVBAYTAkNOMQ4wDAYDVQQKDAVOUkNBQzEMMAoG +A1UECwwDQVJMMRowGAYDVQQDDBFDaXZpbF9TZXJ2YW50X0FSTDBGoESgQoZAaHR0 +cDovL3d3dy5yb290Y2EuZ292LmNuL0NpdmlsX1NlcnZhbnRfYXJsL0NpdmlsX1Nl +cnZhbnRfQVJMLmNybDBMoEqgSIZGbGRhcDovL2xkYXAucm9vdGNhLmdvdi5jbjoz +OTAvQ049Q2l2aWxfU2VydmFudF9BUkwsT1U9QVJMLE89TlJDQUMsQz1DTjAOBgNV +HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFE6BR1+l7EDGRDMxpkHLpByil04oMAwGCCqB +HM9VAYN1BQADSAAwRQIgC79X9bYZNHi88AOzS1mcL8iMOTnuOhISxkw6Hbou9bIC +IQCGFTlCuEYGX3Qc+HlufzqyKjyYyUCTb0FkfhOfhcEU+g== +-----END CERTIFICATE----- diff --git a/certs/ca/Taier CA.pem b/certs/ca/Taier CA.pem new file mode 100644 index 00000000..40ed0965 --- /dev/null +++ b/certs/ca/Taier CA.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIIChDCCAiigAwIBAgIQLXrZ9QK+bZE4WSoVyuo7GzAMBggqgRzPVQGDdQUAMC4x +CzAJBgNVBAYTAkNOMQ4wDAYDVQQKDAVOUkNBQzEPMA0GA1UEAwwGUk9PVENBMB4X +DTE2MDcxMzA4MjQ1NFoXDTM2MDcwODA4MjQ1NFowMDELMAkGA1UEBhMCQ04xDjAM +BgNVBAoMBUNBSUNUMREwDwYDVQQDDAhUYWllciBDQTBZMBMGByqGSM49AgEGCCqB +HM9VAYItA0IABAxbfsHfqwv8GmfhJYnj0R+fFFqkegyvdZgzRtnnnEDmoy4GNwQa +kVNElUTsMFIJDOEbXTfYazvOghVNsR1UFRujggEiMIIBHjAfBgNVHSMEGDAWgBRM +MrGX2TMbxKYFwcbli2Jb8Jd2WDAPBgNVHRMBAf8EBTADAQH/MIG6BgNVHR8EgbIw +ga8wQaA/oD2kOzA5MQswCQYDVQQGEwJDTjEOMAwGA1UECgwFTlJDQUMxDDAKBgNV +BAsMA0FSTDEMMAoGA1UEAwwDYXJsMCqgKKAmhiRodHRwOi8vd3d3LnJvb3RjYS5n +b3YuY24vYXJsL2FybC5jcmwwPqA8oDqGOGxkYXA6Ly9sZGFwLnJvb3RjYS5nb3Yu +Y246Mzg5L0NOPWFybCxPVT1BUkwsTz1OUkNBQyxDPUNOMA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUi2kQa6VC3y6m96DZs4ykCLs9UDkwDAYIKoEcz1UBg3UFAANI +ADBFAiAnOTxqRKjk7+RlMuu6dRIoncmZPPkmVytXeGkvxmN8zAIhAI4zYqRtqy4e +754IdYX8fZDRQi9Mf2ZIkEEgIy9o1+Gf +-----END CERTIFICATE----- diff --git a/certs/crl/Civil Servant ROOT.crl b/certs/crl/Civil Servant ROOT.crl new file mode 100644 index 00000000..a713b437 Binary files /dev/null and b/certs/crl/Civil Servant ROOT.crl differ diff --git a/certs/crl/Device ROOT.crl b/certs/crl/Device ROOT.crl new file mode 100644 index 00000000..0384dfd7 Binary files /dev/null and b/certs/crl/Device ROOT.crl differ diff --git a/certs/crl/ROOTCA.crl b/certs/crl/ROOTCA.crl new file mode 100644 index 00000000..8200bc0e Binary files /dev/null and b/certs/crl/ROOTCA.crl differ diff --git a/certs/rootca/Civil Servant ROOT.pem b/certs/rootca/Civil Servant ROOT.pem new file mode 100644 index 00000000..eff2c5ed --- /dev/null +++ b/certs/rootca/Civil Servant ROOT.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIB0jCCAXegAwIBAgIQEdZMMEt/UB6aBlClCPrHdDAMBggqgRzPVQGDdQUAMDox +CzAJBgNVBAYTAkNOMQ4wDAYDVQQKDAVOUkNBQzEbMBkGA1UEAwwSQ2l2aWwgU2Vy +dmFudCBST09UMB4XDTE0MDcxNTA2NDg1NloXDTQ0MDcwNzA2NDg1NlowOjELMAkG +A1UEBhMCQ04xDjAMBgNVBAoMBU5SQ0FDMRswGQYDVQQDDBJDaXZpbCBTZXJ2YW50 +IFJPT1QwWTATBgcqhkjOPQIBBggqgRzPVQGCLQNCAAR1whSysIMDakj11nL+KgJ1 +J+HtXJU2D/EhV+QC1b+/yDXWdcZay7X79wC/g4vJdUIAdyZfLVy3lYYFc3aJ2smr +o10wWzAfBgNVHSMEGDAWgBSf3F9XpQluZvDydXbtAWJwBPz6VDAMBgNVHRMEBTAD +AQH/MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUn9xfV6UJbmbw8nV27QFicAT8+lQw +DAYIKoEcz1UBg3UFAANHADBEAiAkrV4rtXx+4fdJBIVSxHFKh2znz2vnSgk/eBIl +gNQK7AIgNVusahBBOxafSdIB1cX8zJCnq+OcCNLRezYSbXQ45Jg= +-----END CERTIFICATE----- diff --git a/certs/rootca/Device ROOT.pem b/certs/rootca/Device ROOT.pem new file mode 100644 index 00000000..101e4acc --- /dev/null +++ b/certs/rootca/Device ROOT.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIBxjCCAWmgAwIBAgIQVWEAYiD7bkTypcG5eLcUIzAMBggqgRzPVQGDdQUAMDMx +CzAJBgNVBAYTAkNOMQ4wDAYDVQQKDAVOUkNBQzEUMBIGA1UEAwwLRGV2aWNlIFJP +T1QwHhcNMTQwNzE1MDY0OTE0WhcNNDQwNzA3MDY0OTE0WjAzMQswCQYDVQQGEwJD +TjEOMAwGA1UECgwFTlJDQUMxFDASBgNVBAMMC0RldmljZSBST09UMFkwEwYHKoZI +zj0CAQYIKoEcz1UBgi0DQgAErrT3rKewd5fIH38K5dUcB6dxxYcFCqHlklxWnwiU +n39eP3O8D3h7gncGBJoxX5XToyqwy4saICZq3MEIBf6XKqNdMFswHwYDVR0jBBgw +FoAUodkX9LXKzt+c9s0ZP86nFwz5gPUwDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMC +AQYwHQYDVR0OBBYEFKHZF/S1ys7fnPbNGT/OpxcM+YD1MAwGCCqBHM9VAYN1BQAD +SQAwRgIhAO6XHWXfSyMUt/fn6yB5vPH9bHofYkylecmwqbN7jNlBAiEA2b8vR1TR +u1rh597JnGgp8tdjAiBbPWYjHcJDRBGcljA= +-----END CERTIFICATE----- diff --git a/certs/rootca/ROOTCA.pem b/certs/rootca/ROOTCA.pem new file mode 100644 index 00000000..ae04bf53 --- /dev/null +++ b/certs/rootca/ROOTCA.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIBszCCAVegAwIBAgIIaeL+wBcKxnswDAYIKoEcz1UBg3UFADAuMQswCQYDVQQG +EwJDTjEOMAwGA1UECgwFTlJDQUMxDzANBgNVBAMMBlJPT1RDQTAeFw0xMjA3MTQw +MzExNTlaFw00MjA3MDcwMzExNTlaMC4xCzAJBgNVBAYTAkNOMQ4wDAYDVQQKDAVO +UkNBQzEPMA0GA1UEAwwGUk9PVENBMFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE +MPCca6pmgcchsTf2UnBeL9rtp4nw+itk1Kzrmbnqo05lUwkwlWK+4OIrtFdAqnRT +V7Q9v1htkv42TsIutzd126NdMFswHwYDVR0jBBgwFoAUTDKxl9kzG8SmBcHG5Yti +W/CXdlgwDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFEwysZfZ +MxvEpgXBxuWLYlvwl3ZYMAwGCCqBHM9VAYN1BQADSAAwRQIgG1bSLeOXp3oB8H7b +53W+CKOPl2PknmWEq/lMhtn25HkCIQDaHDgWxWFtnCrBjH16/W3Ezn7/U/Vjo5xI +pDoiVhsLwg== +-----END CERTIFICATE----- diff --git a/demos/cademo.sh b/demos/cademo.sh new file mode 100755 index 00000000..f3dae83d --- /dev/null +++ b/demos/cademo.sh @@ -0,0 +1,22 @@ +#!/bin/bash + + +gmssl sm2keygen -pass 1234 -out rootcakey.pem +gmssl certgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN ROOTCA -days 3650 -key rootcakey.pem -pass 1234 -out rootcacert.pem -key_usage keyCertSign -key_usage cRLSign +gmssl certparse -in rootcacert.pem + +gmssl sm2keygen -pass 1234 -out cakey.pem +gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN "Sub CA" -days 3650 -key cakey.pem -pass 1234 -out careq.pem +gmssl reqsign -in careq.pem -days 365 -key_usage keyCertSign -path_len_constraint 0 -cacert rootcacert.pem -key rootcakey.pem -pass 1234 -out cacert.pem +gmssl certparse -in cacert.pem + +gmssl sm2keygen -pass 1234 -out enckey.pem +gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN localhost -days 365 -key enckey.pem -pass 1234 -out encreq.pem +gmssl reqsign -in encreq.pem -days 365 -key_usage keyEncipherment -cacert cacert.pem -key cakey.pem -pass 1234 -out enccert.pem +gmssl certparse -in enccert.pem + +cat enccert.pem > certs.pem +cat cacert.pem >> certs.pem + +#sudo gmssl tlcp_server -cert cert.pem -key signkey.pem -pass 1234 -ex_key enckey.pem -ex_pass 1234 # -cacert cacert.pem + diff --git a/include/gmssl/oid.h b/include/gmssl/oid.h index 842e9f03..29cfd84a 100644 --- a/include/gmssl/oid.h +++ b/include/gmssl/oid.h @@ -190,6 +190,7 @@ enum { OID_ecdsa_with_sha384, OID_ecdsa_with_sha512, + OID_rsasign_with_md5, OID_rsasign_with_sha1, OID_rsasign_with_sha224, OID_rsasign_with_sha256, diff --git a/include/gmssl/x509.h b/include/gmssl/x509.h index 2cdbe45e..dcb92891 100644 --- a/include/gmssl/x509.h +++ b/include/gmssl/x509.h @@ -117,7 +117,7 @@ Validity ::= SEQUENCE { notAfter Time } */ #define X509_VALIDITY_MIN_DAYS 1 -#define X509_VALIDITY_MAX_DAYS (365 * 3) +#define X509_VALIDITY_MAX_DAYS (365 * 10) // ROOTCA, CA需要更长的时间! int x509_validity_add_days(time_t *not_after, time_t not_before, int days); int x509_validity_to_der(time_t not_before, time_t not_after, uint8_t **out, size_t *outlen); int x509_validity_from_der(time_t *not_before, time_t *not_after, const uint8_t **in, size_t *inlen); diff --git a/include/gmssl/x509_crl.h b/include/gmssl/x509_crl.h index 75eb6d64..137f42cd 100644 --- a/include/gmssl/x509_crl.h +++ b/include/gmssl/x509_crl.h @@ -268,8 +268,8 @@ int x509_crl_to_der(const uint8_t *a, size_t alen, uint8_t **out, size_t *outlen int x509_crl_from_der(const uint8_t **a, size_t *alen, const uint8_t **in, size_t *inlen); int x509_crl_to_pem(const uint8_t *a, size_t alen, FILE *fp); int x509_crl_from_pem(uint8_t *a, size_t *alen, size_t maxlen, FILE *fp); -int x509_crl_to_fp(const uint8_t *a, size_t alen, FILE *fp); -int x509_crl_from_fp(uint8_t *a, size_t *alen, size_t maxlen, FILE *fp); +int x509_crl_to_fp(const uint8_t *a, size_t alen, FILE *fp); // 去掉这个函数 +int x509_crl_from_fp(uint8_t *a, size_t *alen, size_t maxlen, FILE *fp); // 去掉这个函数 int x509_crl_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen); @@ -285,6 +285,8 @@ int x509_crl_sign(uint8_t *crl, size_t *crl_len, const SM2_KEY *sign_key, const char *signer_id, size_t signer_id_len); int x509_crl_verify(const uint8_t *a, size_t alen, const SM2_KEY *sign_pub_key, const char *signer_id, size_t signer_id_len); +int x509_crl_verify_by_ca_cert(const uint8_t *a, size_t alen, const uint8_t *cacert, size_t cacertlen, + const char *signer_id, size_t signer_id_len); int x509_crl_get_details(const uint8_t *crl, size_t crl_len, int *version, @@ -295,10 +297,15 @@ int x509_crl_get_details(const uint8_t *crl, size_t crl_len, const uint8_t **exts, size_t *exts_len, int *signature_algor, const uint8_t **sig, size_t *siglen); +int x509_crl_get_issuer(const uint8_t *crl, size_t crl_len, + const uint8_t **issuer, size_t *issuer_len); + int x509_crl_find_revoked_cert_by_serial_number(const uint8_t *a, size_t alen, const uint8_t *serial, size_t serial_len, time_t *revoke_date, const uint8_t **entry_exts, size_t *entry_exts_len); + + int x509_crls_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); #ifdef __cplusplus diff --git a/include/gmssl/x509_ext.h b/include/gmssl/x509_ext.h index 934afba9..338f314e 100644 --- a/include/gmssl/x509_ext.h +++ b/include/gmssl/x509_ext.h @@ -86,6 +86,8 @@ int x509_exts_add_authority_key_identifier(uint8_t *exts, size_t *extslen, size_ const uint8_t *keyid, size_t keyid_len, const uint8_t *issuer, size_t issuer_len, const uint8_t *serial, size_t serial_len); +int x509_exts_add_default_authority_key_identifier(uint8_t *exts, size_t *extslen, size_t maxlen, + const SM2_KEY *public_key); int x509_exts_add_subject_key_identifier(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const uint8_t *d, size_t dlen); int x509_exts_add_key_usage(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, int bits); int x509_exts_add_certificate_policies(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const uint8_t *d, size_t dlen); @@ -500,7 +502,7 @@ DistributionPointName ::= CHOICE { */ int x509_distribution_point_name_to_der(int choice, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen); int x509_distribution_point_name_from_der(int *choice, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen); -int x509_distribution_point_name_print(FILE *fp, int fmt, int ind, const char *label, int choice, const uint8_t *d, size_t dlen); +int x509_distribution_point_name_print(FILE *fp, int fmt, int ind, const char *label,const uint8_t *a, size_t alen); int x509_explicit_distribution_point_name_to_der(int index, int choice, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen); int x509_explicit_distribution_point_name_from_der(int index, int *choice, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen); diff --git a/src/asn1.c b/src/asn1.c index de4980d3..674f933f 100644 --- a/src/asn1.c +++ b/src/asn1.c @@ -448,11 +448,21 @@ int asn1_boolean_to_der_ex(int tag, int val, uint8_t **out, size_t *outlen) int asn1_integer_to_der_ex(int tag, const uint8_t *a, size_t alen, uint8_t **out, size_t *outlen) { - if (!a || alen <= 0 || alen > INT_MAX || (out && !(*out)) || !outlen) { + if (!a) { + return 0; + } + + + + if (alen <= 0 || alen > INT_MAX || (out && !(*out)) || !outlen) { error_print(); return -1; } + + + + if (out) *(*out)++ = tag; (*outlen)++; diff --git a/src/sm2_lib.c b/src/sm2_lib.c index 2487b6d3..193450fd 100644 --- a/src/sm2_lib.c +++ b/src/sm2_lib.c @@ -306,40 +306,18 @@ extern void sm3_compress_blocks(uint32_t digest[8], const uint8_t *data, size_t int sm2_compute_z(uint8_t z[32], const SM2_POINT *pub, const char *id, size_t idlen) { - uint8_t zin[] = { + SM3_CTX ctx; + uint8_t zin[18 + 32 * 6] = { 0x00, 0x80, - 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, - 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, - 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, - 0x28, 0xE9, 0xFA, 0x9E, 0x9D, 0x9F, 0x5E, 0x34, - 0x4D, 0x5A, 0x9E, 0x4B, 0xCF, 0x65, 0x09, 0xA7, - 0xF3, 0x97, 0x89, 0xF5, 0x15, 0xAB, 0x8F, 0x92, - 0xDD, 0xBC, 0xBD, 0x41, 0x4D, 0x94, 0x0E, 0x93, - 0x32, 0xC4, 0xAE, 0x2C, 0x1F, 0x19, 0x81, 0x19, - 0x5F, 0x99, 0x04, 0x46, 0x6A, 0x39, 0xC9, 0x94, - 0x8F, 0xE3, 0x0B, 0xBF, 0xF2, 0x66, 0x0B, 0xE1, - 0x71, 0x5A, 0x45, 0x89, 0x33, 0x4C, 0x74, 0xC7, - 0xBC, 0x37, 0x36, 0xA2, 0xF4, 0xF6, 0x77, 0x9C, - 0x59, 0xBD, 0xCE, 0xE3, 0x6B, 0x69, 0x21, 0x53, - 0xD0, 0xA9, 0x87, 0x7C, 0xC6, 0x2A, 0x47, 0x40, - 0x02, 0xDF, 0x32, 0xE5, 0x21, 0x39, 0xF0, 0xA0, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x06, 0x90, + 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, + 0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFC, + 0x28,0xE9,0xFA,0x9E,0x9D,0x9F,0x5E,0x34,0x4D,0x5A,0x9E,0x4B,0xCF,0x65,0x09,0xA7, + 0xF3,0x97,0x89,0xF5,0x15,0xAB,0x8F,0x92,0xDD,0xBC,0xBD,0x41,0x4D,0x94,0x0E,0x93, + 0x32,0xC4,0xAE,0x2C,0x1F,0x19,0x81,0x19,0x5F,0x99,0x04,0x46,0x6A,0x39,0xC9,0x94, + 0x8F,0xE3,0x0B,0xBF,0xF2,0x66,0x0B,0xE1,0x71,0x5A,0x45,0x89,0x33,0x4C,0x74,0xC7, + 0xBC,0x37,0x36,0xA2,0xF4,0xF6,0x77,0x9C,0x59,0xBD,0xCE,0xE3,0x6B,0x69,0x21,0x53, + 0xD0,0xA9,0x87,0x7C,0xC6,0x2A,0x47,0x40,0x02,0xDF,0x32,0xE5,0x21,0x39,0xF0,0xA0, }; if (!z || !pub || !id) { @@ -347,40 +325,21 @@ int sm2_compute_z(uint8_t z[32], const SM2_POINT *pub, const char *id, size_t id return -1; } + memcpy(&zin[18 + 32 * 4], pub->x, 32); + memcpy(&zin[18 + 32 * 5], pub->y, 32); - if (strcmp(id, "1234567812345678") == 0) { - uint32_t digest[8] = { - 0xadadedb5U, 0x0446043fU, 0x08a87aceU, 0xe86d2243U, - 0x8e232383U, 0xbfc81fe2U, 0xcf9117c8U, 0x4707011dU, - }; - memcpy(&zin[128], pub->x, 32); - memcpy(&zin[160], pub->y, 32); - sm3_compress_blocks(digest, zin, 2); - PUTU32(z , digest[0]); - PUTU32(z + 4, digest[1]); - PUTU32(z + 8, digest[2]); - PUTU32(z + 12, digest[3]); - PUTU32(z + 16, digest[4]); - PUTU32(z + 20, digest[5]); - PUTU32(z + 24, digest[6]); - PUTU32(z + 28, digest[7]); - + sm3_init(&ctx); + if (strcmp(id, SM2_DEFAULT_ID) == 0) { + sm3_update(&ctx, zin, sizeof(zin)); } else { - SM3_CTX ctx; uint8_t idbits[2]; - idbits[0] = (uint8_t)(idlen >> 5); idbits[1] = (uint8_t)(idlen << 3); - - sm3_init(&ctx); sm3_update(&ctx, idbits, 2); sm3_update(&ctx, (uint8_t *)id, idlen); - sm3_update(&ctx, zin + 18, 128); - sm3_update(&ctx, pub->x, 32); - sm3_update(&ctx, pub->y, 32); - sm3_finish(&ctx, z); + sm3_update(&ctx, zin + 18, 32 * 6); } - + sm3_finish(&ctx, z); return 1; } @@ -492,11 +451,6 @@ int sm2_kdf(const uint8_t *in, size_t inlen, size_t outlen, uint8_t *out) uint32_t counter = 1; size_t len; - /* - size_t i; fprintf(stderr, "kdf input : "); - for (i = 0; i < inlen; i++) fprintf(stderr, "%02x", in[i]); fprintf(stderr, "\n"); - */ - while (outlen) { PUTU32(counter_be, counter); counter++; diff --git a/src/sm3.c b/src/sm3.c index 720ff5fe..0ea38a09 100644 --- a/src/sm3.c +++ b/src/sm3.c @@ -49,6 +49,7 @@ #include #include #include +#include #ifdef SM3_SSE3 @@ -345,103 +346,11 @@ void sm3_init(SM3_CTX *ctx) ctx->digest[7] = 0xB0FB0E4E; } - - - -#if 0 -void sm3_compute_id_digest(uint8_t z[32], const char *id, - const uint8_t x[32], const uint8_t y[32]) -{ - uint8_t zin[] = { - 0x00, 0x80, - 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, - 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, - 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, - 0x28, 0xE9, 0xFA, 0x9E, 0x9D, 0x9F, 0x5E, 0x34, - 0x4D, 0x5A, 0x9E, 0x4B, 0xCF, 0x65, 0x09, 0xA7, - 0xF3, 0x97, 0x89, 0xF5, 0x15, 0xAB, 0x8F, 0x92, - 0xDD, 0xBC, 0xBD, 0x41, 0x4D, 0x94, 0x0E, 0x93, - 0x32, 0xC4, 0xAE, 0x2C, 0x1F, 0x19, 0x81, 0x19, - 0x5F, 0x99, 0x04, 0x46, 0x6A, 0x39, 0xC9, 0x94, - 0x8F, 0xE3, 0x0B, 0xBF, 0xF2, 0x66, 0x0B, 0xE1, - 0x71, 0x5A, 0x45, 0x89, 0x33, 0x4C, 0x74, 0xC7, - 0xBC, 0x37, 0x36, 0xA2, 0xF4, 0xF6, 0x77, 0x9C, - 0x59, 0xBD, 0xCE, 0xE3, 0x6B, 0x69, 0x21, 0x53, - 0xD0, 0xA9, 0x87, 0x7C, 0xC6, 0x2A, 0x47, 0x40, - 0x02, 0xDF, 0x32, 0xE5, 0x21, 0x39, 0xF0, 0xA0, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x06, 0x90, - }; - - if (!id || strcmp(id, "1234567812345678")) { - unsigned int digest[8] = { - 0xadadedb5U, 0x0446043fU, 0x08a87aceU, 0xe86d2243U, - 0x8e232383U, 0xbfc81fe2U, 0xcf9117c8U, 0x4707011dU, - }; - memcpy(&zin[128], x, 32); - memcpy(&zin[160], y, 32); - sm3_compress_blocks(digest, zin, 2); - PUTU32(z , digest[0]); - PUTU32(z + 4, digest[1]); - PUTU32(z + 8, digest[2]); - PUTU32(z + 12, digest[3]); - PUTU32(z + 16, digest[4]); - PUTU32(z + 20, digest[5]); - PUTU32(z + 24, digest[6]); - PUTU32(z + 28, digest[7]); - - } else { - SM3_CTX ctx; - uint8_t idbits[2]; - size_t len; - - len = strlen(id); - idbits[0] = (uint8_t)(len >> 5); - idbits[1] = (uint8_t)(len << 3); - - sm3_init(&ctx); - sm3_update(&ctx, idbits, 2); - sm3_update(&ctx, (uint8_t *)id, len); - sm3_update(&ctx, zin + 18, 128); - sm3_update(&ctx, x, 32); - sm3_update(&ctx, y, 32); - sm3_finish(&ctx, z); - } -} - -int sm3_sm2_init(SM3_CTX *ctx, const char *id, - const uint8_t *x, const uint8_t *y) -{ - uint8_t z[32]; - if ((id && strlen(id) > 65535/8) || !x || !y) { - return 0; - } - sm3_compute_id_digest(z, id, x, y); - sm3_init(ctx); - sm3_update(ctx, z, 32); - return 1; -} -#endif - void sm3_update(SM3_CTX *ctx, const uint8_t *data, size_t data_len) { size_t blocks; + ctx->num &= 0x3f; if (ctx->num) { unsigned int left = SM3_BLOCK_SIZE - ctx->num; diff --git a/src/tlcp.c b/src/tlcp.c index 4929a9d8..a32c58b9 100644 --- a/src/tlcp.c +++ b/src/tlcp.c @@ -86,6 +86,7 @@ int tlcp_record_set_handshake_server_key_exchange_pke(uint8_t *record, size_t *r error_print(); return -1; } + tls_uint16_to_bytes(siglen, &p, &hslen); tls_array_to_bytes(sig, siglen, &p, &hslen); tls_record_set_handshake(record, recordlen, type, NULL, hslen); return 1; @@ -115,16 +116,11 @@ int tlcp_record_get_handshake_server_key_exchange_pke(const uint8_t *record, error_print(); return -1; } - /* if (tls_uint16array_copy_from_bytes(sig, siglen, *siglen, &p, &len) != 1 || len > 0) { error_print(); return -1; } - */ - // FIXME: check *siglen >= len - memcpy(sig, p, len); - *siglen = len; return 1; } @@ -250,7 +246,7 @@ int tlcp_connect(TLS_CONNECT *conn, const char *hostname, int port, tls_record_set_version(record, TLS_version_tlcp); tls_record_set_version(finished, TLS_version_tlcp); - tls_trace(">>>> ClientHello\n"); + tls_trace("send ClientHello\n"); tls_random_generate(client_random); if (tls_record_set_handshake_client_hello(record, &recordlen, TLS_version_tlcp, client_random, NULL, 0, @@ -267,7 +263,7 @@ int tlcp_connect(TLS_CONNECT *conn, const char *hostname, int port, if (client_sign_key) sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); - tls_trace("<<<< ServerHello\n"); + tls_trace("recv ServerHello\n"); if (tls_record_recv(record, &recordlen, conn->sock) != 1 || tls_record_version(record) != TLS_version_tlcp) { error_print(); @@ -292,7 +288,7 @@ int tlcp_connect(TLS_CONNECT *conn, const char *hostname, int port, if (client_sign_key) sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); - tls_trace("<<<< ServerCertificate\n"); + tls_trace("recv ServerCertificate\n"); if (tls_record_recv(record, &recordlen, conn->sock) != 1 || tls_record_version(record) != TLS_version_tlcp) { error_print(); @@ -317,7 +313,7 @@ int tlcp_connect(TLS_CONNECT *conn, const char *hostname, int port, if (client_sign_key) sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); - tls_trace("<<<< ServerKeyExchange\n"); + tls_trace("recv ServerKeyExchange\n"); if (tls_record_recv(record, &recordlen, conn->sock) != 1 || tls_record_version(record) != TLS_version_tlcp) { error_print(); @@ -332,7 +328,7 @@ int tlcp_connect(TLS_CONNECT *conn, const char *hostname, int port, if (client_sign_key) sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); - tls_trace("++++ process ServerKeyExchange\n"); + tls_trace("process ServerKeyExchange\n"); if (tls_certificate_get_second(conn->server_certs, conn->server_certs_len, &server_enc_cert, &server_enc_cert_len) != 1) { error_print(); @@ -357,7 +353,7 @@ int tlcp_connect(TLS_CONNECT *conn, const char *hostname, int port, return -1; } if (type == TLS_handshake_certificate_request) { - tls_trace("<<<< CertificateRequest\n"); + tls_trace("recv CertificateRequest\n"); int cert_types[TLS_MAX_CERTIFICATE_TYPES]; size_t cert_types_count;; uint8_t ca_names[TLS_MAX_CA_NAMES_SIZE]; @@ -382,7 +378,7 @@ int tlcp_connect(TLS_CONNECT *conn, const char *hostname, int port, memset(&sign_ctx, 0, sizeof(SM2_SIGN_CTX)); client_sign_key = NULL; } - tls_trace("<<<< ServerHelloDone\n"); + tls_trace("recv ServerHelloDone\n"); tls_record_print(stderr, record, recordlen, 0, 0); if (tls_record_get_handshake_server_hello_done(record) != 1) { error_print(); @@ -392,7 +388,7 @@ int tlcp_connect(TLS_CONNECT *conn, const char *hostname, int port, if (client_sign_key) { sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); - tls_trace(">>>> ClientCertificate\n"); + tls_trace("send ClientCertificate\n"); if (tls_record_set_handshake_certificate_from_pem(record, &recordlen, client_certs_fp) != 1) { error_print(); return -1; @@ -406,7 +402,7 @@ int tlcp_connect(TLS_CONNECT *conn, const char *hostname, int port, sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); } - tls_trace("++++ generate secrets\n"); + tls_trace("generate secrets\n"); if (tls_pre_master_secret_generate(pre_master_secret, TLS_version_tlcp) != 1 || tls_prf(pre_master_secret, 48, "master secret", client_random, 32, server_random, 32, @@ -421,15 +417,15 @@ int tlcp_connect(TLS_CONNECT *conn, const char *hostname, int port, sm3_hmac_init(&conn->server_write_mac_ctx, conn->key_block + 32, 32); sm4_set_encrypt_key(&conn->client_write_enc_key, conn->key_block + 64); sm4_set_decrypt_key(&conn->server_write_enc_key, conn->key_block + 80); - format_bytes(stderr, 0, 0, "pre_master_secret : ", pre_master_secret, 48); - format_bytes(stderr, 0, 0, "master_secret : ", conn->master_secret, 48); - format_bytes(stderr, 0, 0, "client_write_mac_key : ", conn->key_block, 32); - format_bytes(stderr, 0, 0, "server_write_mac_key : ", conn->key_block + 32, 32); - format_bytes(stderr, 0, 0, "client_write_enc_key : ", conn->key_block + 64, 16); - format_bytes(stderr, 0, 0, "server_write_enc_key : ", conn->key_block + 80, 16); + format_bytes(stderr, 0, 4, "PRE_MASTER_SECRET", pre_master_secret, 48); + format_bytes(stderr, 0, 4, "MASTER_SECRET", conn->master_secret, 48); + format_bytes(stderr, 0, 4, "CLIENT_WRITE_MAC_KEY", conn->key_block, 32); + format_bytes(stderr, 0, 4, "SERVER_WRITE_MAC_KEY", conn->key_block + 32, 32); + format_bytes(stderr, 0, 4, "CLIENT_WRITE_ENC_KEY", conn->key_block + 64, 16); + format_bytes(stderr, 0, 4, "SERVER_WRITE_ENC_KEY", conn->key_block + 80, 16); format_print(stderr, 0, 0, "\n"); - tls_trace(">>>> ClientKeyExchange\n"); + tls_trace("send ClientKeyExchange\n"); if (sm2_encrypt(&server_enc_key, pre_master_secret, 48, enced_pre_master_secret, &enced_pre_master_secret_len) != 1) { error_print(); @@ -450,7 +446,7 @@ int tlcp_connect(TLS_CONNECT *conn, const char *hostname, int port, sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); if (client_sign_key) { - tls_trace(">>>> CertificateVerify\n"); + tls_trace("send CertificateVerify\n"); sm2_sign_finish(&sign_ctx, sig, &siglen); if (tls_record_set_handshake_certificate_verify(record, &recordlen, sig, siglen) != 1) { error_print(); @@ -464,7 +460,7 @@ int tlcp_connect(TLS_CONNECT *conn, const char *hostname, int port, sm3_update(&sm3_ctx, record + 5, recordlen - 5); } - tls_trace(">>>> [ChangeCipherSpec]\n"); + tls_trace("send [ChangeCipherSpec]\n"); if (tls_record_set_change_cipher_spec(record, &recordlen) !=1) { error_print(); return -1; @@ -475,7 +471,7 @@ int tlcp_connect(TLS_CONNECT *conn, const char *hostname, int port, } tls_record_print(stderr, record, recordlen, 0, 0); - tls_trace(">>>> Finished\n"); + tls_trace("send Finished\n"); memcpy(&tmp_sm3_ctx, &sm3_ctx, sizeof(sm3_ctx)); sm3_finish(&tmp_sm3_ctx, sm3_hash); @@ -503,7 +499,7 @@ int tlcp_connect(TLS_CONNECT *conn, const char *hostname, int port, return -1; } - tls_trace("<<<< [ChangeCipherSpec]\n"); + tls_trace("recv [ChangeCipherSpec]\n"); if (tls_record_recv(record, &recordlen, conn->sock) != 1 || tls_record_version(record) != TLS_version_tlcp) { error_print(); @@ -515,7 +511,7 @@ int tlcp_connect(TLS_CONNECT *conn, const char *hostname, int port, } tls_record_print(stderr, record, recordlen, 0, 0); - tls_trace("<<<< Finished\n"); + tls_trace("recv Finished\n"); if (tls_record_recv(record, &recordlen, conn->sock) != 1 || tls_record_version(record) != TLS_version_tlcp) { error_print(); @@ -600,7 +596,7 @@ int tlcp_accept(TLS_CONNECT *conn, int port, return -1; } - error_puts("start listen ..."); + error_puts("start listen ...\n"); listen(sock, 5); memset(conn, 0, sizeof(*conn)); @@ -619,7 +615,7 @@ int tlcp_accept(TLS_CONNECT *conn, int port, sm3_init(&sm3_ctx); - tls_trace("<<<< ClientHello\n"); + tls_trace("recv ClientHello\n"); if (tls_record_recv(record, &recordlen, conn->sock) != 1 || tls_record_version(record) != TLS_version_tlcp) { error_print(); @@ -653,7 +649,7 @@ int tlcp_accept(TLS_CONNECT *conn, int port, handshakeslen += recordlen - 5; } - tls_trace(">>>> ServerHello\n"); + tls_trace("send ServerHello\n"); tls_random_generate(server_random); if (tls_record_set_handshake_server_hello(record, &recordlen, TLS_version_tlcp, server_random, NULL, 0, @@ -673,7 +669,7 @@ int tlcp_accept(TLS_CONNECT *conn, int port, handshakeslen += recordlen - 5; } - tls_trace(">>>> ServerCertificate\n"); + tls_trace("send ServerCertificate\n"); if (tls_record_set_handshake_certificate_from_pem(record, &recordlen, certs_fp) != 1) { error_print(); return -1; @@ -696,7 +692,8 @@ int tlcp_accept(TLS_CONNECT *conn, int port, handshakeslen += recordlen - 5; } - tls_trace(">>>> ServerKeyExchange\n"); + tls_trace("send ServerKeyExchange\n"); + 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 @@ -705,6 +702,7 @@ int tlcp_accept(TLS_CONNECT *conn, int port, error_print(); return -1; } + if (tlcp_record_set_handshake_server_key_exchange_pke(record, &recordlen, sig, siglen) != 1) { error_print(); return -1; @@ -722,11 +720,16 @@ int tlcp_accept(TLS_CONNECT *conn, int port, } if (client_cacerts_fp) { - tls_trace(">>>> CertificateRequest\n"); + tls_trace("send CertificateRequest\n"); const int cert_types[] = { TLS_cert_type_ecdsa_sign, }; uint8_t ca_names[TLS_MAX_CA_NAMES_SIZE] = {0}; size_t cert_types_count = sizeof(cert_types)/sizeof(cert_types[0]); size_t ca_names_len = 0; + + //TODO : read CAnames + + + if (tls_record_set_handshake_certificate_request(record, &recordlen, cert_types, cert_types_count, ca_names, ca_names_len) != 1) { @@ -747,7 +750,7 @@ int tlcp_accept(TLS_CONNECT *conn, int port, } } - tls_trace(">>>> ServerHelloDone\n"); + tls_trace("send ServerHelloDone\n"); if (tls_record_set_handshake_server_hello_done(record, &recordlen) != 1) { error_print(); return -1; @@ -765,7 +768,7 @@ int tlcp_accept(TLS_CONNECT *conn, int port, } if (client_cacerts_fp) { - tls_trace("<<<< ClientCertificate\n"); + tls_trace("recv ClientCertificate\n"); if (tls_record_recv(record, &recordlen, conn->sock) != 1 || tls_record_version(record) != TLS_version_tlcp) { error_print(); @@ -789,7 +792,7 @@ int tlcp_accept(TLS_CONNECT *conn, int port, handshakeslen += recordlen - 5; } - tls_trace("<<<< ClientKeyExchange\n"); + tls_trace("recv ClientKeyExchange\n"); if (tls_record_recv(record, &recordlen, conn->sock) != 1 || tls_record_version(record) != TLS_version_tlcp) { error_print(); @@ -813,7 +816,7 @@ int tlcp_accept(TLS_CONNECT *conn, int port, } if (client_cacerts_fp) { - tls_trace("<<<< CertificateVerify\n"); + tls_trace("recv CertificateVerify\n"); if (tls_record_recv(record, &recordlen, conn->sock) != 1 || tls_record_version(record) != TLS_version_tlcp) { error_print(); @@ -833,7 +836,7 @@ int tlcp_accept(TLS_CONNECT *conn, int port, } } - tls_trace("++++ generate secrets\n"); + tls_trace("generate secrets\n"); if (tls_prf(pre_master_secret, 48, "master secret", client_random, 32, server_random, 32, 48, conn->master_secret) != 1) { @@ -850,16 +853,16 @@ int tlcp_accept(TLS_CONNECT *conn, int port, sm3_hmac_init(&conn->server_write_mac_ctx, conn->key_block + 32, 32); sm4_set_decrypt_key(&conn->client_write_enc_key, conn->key_block + 64); sm4_set_encrypt_key(&conn->server_write_enc_key, conn->key_block + 80); - format_bytes(stderr, 0, 0, "pre_master_secret : ", pre_master_secret, 48); - format_bytes(stderr, 0, 0, "master_secret : ", conn->master_secret, 48); - format_bytes(stderr, 0, 0, "client_write_mac_key : ", conn->key_block, 32); - format_bytes(stderr, 0, 0, "server_write_mac_key : ", conn->key_block + 32, 32); - format_bytes(stderr, 0, 0, "client_write_enc_key : ", conn->key_block + 64, 16); - format_bytes(stderr, 0, 0, "server_write_enc_key : ", conn->key_block + 80, 16); + format_bytes(stderr, 0, 4, "PRE_MASTER_SECRET", pre_master_secret, 48); + format_bytes(stderr, 0, 4, "MASTER_SECRET", conn->master_secret, 48); + format_bytes(stderr, 0, 4, "CLIENT_WRITE_MAC_KEY", conn->key_block, 32); + format_bytes(stderr, 0, 4, "SERVER_WRITE_MAC_KEY", conn->key_block + 32, 32); + format_bytes(stderr, 0, 4, "CLIENT_WRITE_ENC_KEY", conn->key_block + 64, 16); + format_bytes(stderr, 0, 4, "SERVER_WRITE_ENC_KEY", conn->key_block + 80, 16); format_print(stderr, 0, 0, "\n"); - tls_trace("<<<< [ChangeCipherSpec]\n"); + tls_trace("recv [ChangeCipherSpec]\n"); if (tls_record_recv(record, &recordlen, conn->sock) != 1 || tls_record_version(record) != TLS_version_tlcp) { error_print(); @@ -871,7 +874,7 @@ int tlcp_accept(TLS_CONNECT *conn, int port, return -1; } - tls_trace("<<<< ClientFinished\n"); + tls_trace("recv ClientFinished\n"); if (tls_record_recv(record, &recordlen, conn->sock) != 1 || tls_record_version(record) != TLS_version_tlcp) { error_print(); @@ -902,7 +905,7 @@ int tlcp_accept(TLS_CONNECT *conn, int port, return -1; } - tls_trace(">>>> [ChangeCipherSpec]\n"); + tls_trace("send [ChangeCipherSpec]\n"); if (tls_record_set_change_cipher_spec(record, &recordlen) != 1) { error_print(); return -1; @@ -913,7 +916,7 @@ int tlcp_accept(TLS_CONNECT *conn, int port, return -1; } - tls_trace(">>>> ServerFinished\n"); + tls_trace("send ServerFinished\n"); sm3_finish(&sm3_ctx, sm3_hash); if (tls_prf(conn->master_secret, 48, "server finished", sm3_hash, 32, NULL, 0, 12, verify_data) != 1) { diff --git a/src/tls.c b/src/tls.c index a3b1d043..67243ee2 100644 --- a/src/tls.c +++ b/src/tls.c @@ -783,18 +783,19 @@ int tls_record_get_handshake_client_hello(const uint8_t *record, (*cipher_suites_count)++; } if (len > 0) { + /* + // OpenSSL 即使在TLCP时仍然会发出扩展 if (*version < TLS_version_tls12) { error_print(); return -1; } - if (!exts) { - error_print(); - return -1; - } - if (tls_uint16array_copy_from_bytes(exts, exts_len, TLS_MAX_EXTENSIONS_SIZE, &p, &len) != 1 - || len > 0) { - error_print(); - return -1; + */ + if (exts) { + if (tls_uint16array_copy_from_bytes(exts, exts_len, TLS_MAX_EXTENSIONS_SIZE, &p, &len) != 1 + || len > 0) { + error_print(); + return -1; + } } } return 1; @@ -1482,10 +1483,16 @@ int tls_record_recv(uint8_t *record, size_t *recordlen, int sock) int type; size_t len; +retry: if ((r = recv(sock, record, 5, 0)) < 0) { error_print(); return -1; } else if (r != 5) { + sleep(1); + goto retry; + + format_bytes(stderr, 0, 0, "record", record, r); + // FIXME: 如果对方已经中断连接,那么我们要判断这个错误吗? error_print(); perror(""); // 否则打印ioctl错误 diff --git a/src/x509_alg.c b/src/x509_alg.c index 4f36b414..ab3f1063 100644 --- a/src/x509_alg.c +++ b/src/x509_alg.c @@ -264,6 +264,7 @@ static uint32_t oid_ecdsa_with_sha224[] = { 1,2,840,10045,4,3,1 }; static uint32_t oid_ecdsa_with_sha256[] = { 1,2,840,10045,4,3,2 }; static uint32_t oid_ecdsa_with_sha384[] = { 1,2,840,10045,4,3,3 }; static uint32_t oid_ecdsa_with_sha512[] = { 1,2,840,10045,4,3,4 }; +static uint32_t oid_rsasign_with_md5[] = { 1,2,840,113549,1,1,4 }; static uint32_t oid_rsasign_with_sha1[] = { 1,2,840,113549,1,1,5 }; static uint32_t oid_rsasign_with_sha224[] = { 1,2,840,113549,1,1,14 }; static uint32_t oid_rsasign_with_sha256[] = { 1,2,840,113549,1,1,11 }; @@ -279,6 +280,7 @@ static const ASN1_OID_INFO x509_sign_algors[] = { { OID_ecdsa_with_sha256, "ecdsa-with-sha256", oid_ecdsa_with_sha256, sizeof(oid_ecdsa_with_sha256)/sizeof(int), X509_ALGOR_ALLOW_EC_NULL_PARAM }, { OID_ecdsa_with_sha384, "ecdsa-with-sha384", oid_ecdsa_with_sha384, sizeof(oid_ecdsa_with_sha384)/sizeof(int), X509_ALGOR_ALLOW_EC_NULL_PARAM }, { OID_ecdsa_with_sha512, "ecdsa-with-sha512", oid_ecdsa_with_sha512, sizeof(oid_ecdsa_with_sha512)/sizeof(int), X509_ALGOR_ALLOW_EC_NULL_PARAM }, + { OID_rsasign_with_md5, "md5WithRSAEncryption", oid_rsasign_with_md5, sizeof(oid_rsasign_with_md5)/sizeof(int), X509_ALGOR_ALLOW_EC_NULL_PARAM }, { OID_rsasign_with_sha1, "sha1WithRSAEncryption", oid_rsasign_with_sha1, sizeof(oid_rsasign_with_sha1)/sizeof(int), X509_ALGOR_ALLOW_EC_NULL_PARAM }, { OID_rsasign_with_sha224, "sha224WithRSAEncryption", oid_rsasign_with_sha224, sizeof(oid_rsasign_with_sha224)/sizeof(int), 1 }, { OID_rsasign_with_sha256, "sha256WithRSAEncryption", oid_rsasign_with_sha256, sizeof(oid_rsasign_with_sha256)/sizeof(int), 1 }, diff --git a/src/x509_cer.c b/src/x509_cer.c index 4e8b361f..96292fbb 100644 --- a/src/x509_cer.c +++ b/src/x509_cer.c @@ -628,7 +628,7 @@ int x509_ext_to_der(int oid, int critical, const uint8_t *val, size_t vlen, uint || asn1_octet_string_to_der(val, vlen, NULL, &len) != 1 || asn1_sequence_header_to_der(len, out, outlen) != 1 || x509_ext_id_to_der(oid, out, outlen) != 1 - || asn1_boolean_to_der(critical, out, outlen) != 1 + || asn1_boolean_to_der(critical, out, outlen) < 0 || asn1_octet_string_to_der(val, vlen, out, outlen) != 1) { error_print(); return -1; @@ -1150,20 +1150,23 @@ int x509_cert_from_pem_by_index(uint8_t *a, size_t *alen, size_t maxlen, int ind int x509_cert_from_pem_by_subject(uint8_t *a, size_t *alen, size_t maxlen, const uint8_t *name, size_t namelen, FILE *fp) { + int ret; const uint8_t *d; size_t dlen; for (;;) { - if (x509_cert_from_pem(a, alen, maxlen, fp) != 1) { + if ((ret = x509_cert_from_pem(a, alen, maxlen, fp)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (x509_cert_get_subject(a, *alen, &d, &dlen) != 1) { error_print(); return -1; } - x509_cert_get_subject(a, *alen, &d, &dlen); if (dlen == namelen && memcmp(name, d, dlen) == 0) { return 1; } - } return 0; } diff --git a/src/x509_crl.c b/src/x509_crl.c index f5c7e6be..0aac4bc4 100644 --- a/src/x509_crl.c +++ b/src/x509_crl.c @@ -110,6 +110,11 @@ int x509_crl_reason_from_der(int *reason, const uint8_t **in, size_t *inlen) return asn1_enumerated_from_der(reason, in, inlen); } +int x509_implicit_crl_reason_from_der(int index, int *reason, const uint8_t **in, size_t *inlen) +{ + return asn1_implicit_enumerated_from_der(index, reason, in, inlen); +} + static uint32_t oid_ce_crl_reasons[] = { oid_ce,21 }; static uint32_t oid_ce_invalidity_date[] = { oid_ce,24 }; @@ -612,12 +617,32 @@ int x509_issuing_distribution_point_from_der( int x509_issuing_distribution_point_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) { + int ret, val; const uint8_t *p; size_t len; format_print(fp, fmt, ind, "%s\n", label); ind += 4; + if ((ret = asn1_explicit_from_der(0, &p, &len, &d, &dlen)) < 0) goto end; + if (ret) x509_distribution_point_name_print(fp, fmt, ind, "distributionPoint", p, len); + if ((ret = asn1_implicit_boolean_from_der(1, &val, &d, &dlen)) < 0) goto end; + if (!ret) val = 0; + format_print(fp, fmt, ind, "onlyContainsUserCerts: %s\n", asn1_boolean_name(val)); + if ((ret = asn1_implicit_boolean_from_der(2, &val, &d, &dlen)) < 0) goto end; + if (!ret) val = 0; + format_print(fp, fmt, ind, "onlyContainsCACerts: %s\n", asn1_boolean_name(val)); + if ((ret = x509_implicit_crl_reason_from_der(3, &val, &d, &dlen)) < 0) goto end; + if (ret) format_print(fp, fmt, ind, "onlySomeReasons: %s\n", x509_crl_reason_name(val)); + if ((ret = asn1_implicit_boolean_from_der(4, &val, &d, &dlen)) < 0) goto end; + if (!ret) val = 0; + format_print(fp, fmt, ind, "indirectCRL: %s\n", asn1_boolean_name(val)); + if ((ret = asn1_implicit_boolean_from_der(5, &val, &d, &dlen)) < 0) goto end; + if (!ret) val = 0; + format_print(fp, fmt, ind, "onlyContainsAttributeCerts: %s\n", asn1_boolean_name(val)); + if (asn1_length_is_zero(dlen) != 1) goto end; + return 1; +end: error_print(); return -1; } @@ -758,6 +783,7 @@ int x509_tbs_crl_from_der( if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { if (ret < 0) error_print(); + else error_print(); return ret; } if (asn1_int_from_der(version, &d, &dlen) < 0 @@ -1024,6 +1050,8 @@ int x509_crl_verify(const uint8_t *a, size_t alen, const SM2_KEY *pub_key, const char *signer_id, size_t signer_id_len) { int ret; + const uint8_t *d; + size_t dlen; const uint8_t *tbs; size_t tbslen; int sig_alg; @@ -1031,8 +1059,15 @@ int x509_crl_verify(const uint8_t *a, size_t alen, size_t siglen; SM2_SIGN_CTX verify_ctx; - if (x509_cert_list_from_der(&tbs, &tbslen, &sig_alg, &sig, &siglen, &a, &alen) != 1 - || asn1_length_is_zero(alen) != 1) { + if ((ret = asn1_sequence_from_der(&d, &dlen, &a, &alen)) != 1) { + if (ret < 0) error_print(); + else error_print(); + return -1; + } + if (asn1_any_from_der(&tbs, &tbslen, &d, &dlen) != 1 + || x509_signature_algor_from_der(&sig_alg, &d, &dlen) != 1 + || asn1_bit_octets_from_der(&sig, &siglen, &d, &dlen) != 1 + || asn1_length_is_zero(dlen) != 1) { error_print(); return -1; } @@ -1041,8 +1076,26 @@ int x509_crl_verify(const uint8_t *a, size_t alen, return -1; } if (sm2_verify_init(&verify_ctx, pub_key, signer_id, signer_id_len) != 1 - || sm2_verify_update(&verify_ctx, tbs, tbslen) != 1 - || (ret = sm2_verify_finish(&verify_ctx, sig, siglen)) < 0) { + || sm2_verify_update(&verify_ctx, tbs, tbslen) != 1) { + error_print(); + return -1; + } + if ((ret = sm2_verify_finish(&verify_ctx, sig, siglen)) != 1) { + if (ret < 0) error_print(); + else error_print(); + return -1; + } + return 1; +} + +int x509_crl_verify_by_ca_cert(const uint8_t *a, size_t alen, const uint8_t *cacert, size_t cacertlen, + const char *signer_id, size_t signer_id_len) +{ + int ret; + SM2_KEY public_key; + + if (x509_cert_get_subject_public_key(cacert, cacertlen, &public_key) != 1 + || (ret = x509_crl_verify(a, alen, &public_key, signer_id, signer_id_len)) < 0) { error_print(); return -1; } @@ -1050,7 +1103,7 @@ int x509_crl_verify(const uint8_t *a, size_t alen, return ret; } -int x509_crl_get_details(const uint8_t *crl, size_t crl_len, +int x509_crl_get_details(const uint8_t *a, size_t alen, int *opt_version, const uint8_t **opt_issuer, size_t *opt_issuer_len, time_t *opt_this_update, @@ -1060,15 +1113,35 @@ int x509_crl_get_details(const uint8_t *crl, size_t crl_len, int *opt_signature_algor, const uint8_t **opt_sig, size_t *opt_siglen) { + int ret; + const uint8_t *d; + size_t dlen; const uint8_t *tbs; size_t tbs_len; int signature_algor; const uint8_t *sig; size_t siglen; + int version; + int sig_alg; + const uint8_t *issuer; + size_t issuer_len; + time_t this_update; + time_t next_update; + const uint8_t *revoked_certs; + size_t revoked_certs_len; + const uint8_t *exts; + size_t exts_len; - if (x509_cert_list_from_der(&tbs, &tbs_len, &signature_algor, &sig, &siglen, &crl, &crl_len) != 1 - || asn1_length_is_zero(crl_len) != 1) { + if ((ret = asn1_sequence_from_der(&d, &dlen, &a, &alen)) != 1) { + if (ret < 0) error_print(); + else error_print(); + return -1; + } + if (asn1_any_from_der(&tbs, &tbs_len, &d, &dlen) != 1 + || x509_signature_algor_from_der(&sig_alg, &d, &dlen) != 1 + || asn1_bit_octets_from_der(&sig, &siglen, &d, &dlen) != 1 + || asn1_length_is_zero(dlen) != 1) { error_print(); return -1; } @@ -1076,49 +1149,40 @@ int x509_crl_get_details(const uint8_t *crl, size_t crl_len, if (opt_sig) *opt_sig = sig; if (opt_siglen) *opt_siglen = siglen; - if (opt_version - || opt_issuer || opt_issuer_len - || opt_this_update - || opt_next_update - || opt_revoked_certs || opt_revoked_certs_len) { + if (x509_tbs_crl_from_der(&version, &sig_alg, &issuer, &issuer_len, + &this_update, &next_update, &revoked_certs, &revoked_certs_len, + &exts, &exts_len, &tbs, &tbs_len) != 1 + || asn1_length_is_zero(tbs_len) != 1) { + error_print(); + return -1; + } - int version; - int sig_alg; - const uint8_t *issuer; - size_t issuer_len; - time_t this_update; - time_t next_update; - const uint8_t *revoked_certs; - size_t revoked_certs_len; - const uint8_t *exts; - size_t exts_len; + if (opt_version) *opt_version = version; + if (opt_issuer) *opt_issuer = issuer; + if (opt_issuer_len) *opt_issuer_len = issuer_len; + if (opt_this_update) *opt_this_update = this_update; + if (opt_next_update) *opt_next_update = next_update; + if (opt_revoked_certs) *opt_revoked_certs = revoked_certs; + if (opt_revoked_certs_len) *opt_revoked_certs_len = revoked_certs_len; + if (opt_exts) *opt_exts = exts; + if (opt_exts_len) *opt_exts_len = exts_len; + return 1; +} - if (x509_tbs_crl_from_der( - &version, - &sig_alg, - &issuer, &issuer_len, - &this_update, - &next_update, - &revoked_certs, &revoked_certs_len, - &exts, &exts_len, - &tbs, &tbs_len) != 1 - || asn1_length_is_zero(tbs_len) != 1) { - error_print(); - return -1; - } - if (sig_alg != signature_algor) { - error_print(); - return -1; - } - if (opt_version) *opt_version = version; - if (opt_issuer) *opt_issuer = issuer; - if (opt_issuer_len) *opt_issuer_len = issuer_len; - if (opt_this_update) *opt_this_update = this_update; - if (opt_next_update) *opt_next_update = next_update; - if (opt_revoked_certs) *opt_revoked_certs = revoked_certs; - if (opt_revoked_certs_len) *opt_revoked_certs_len = revoked_certs_len; - if (opt_exts) *opt_exts = exts; - if (opt_exts_len) *opt_exts_len = exts_len; +int x509_crl_get_issuer(const uint8_t *crl, size_t crl_len, + const uint8_t **issuer, size_t *issuer_len) +{ + if (x509_crl_get_details(crl, crl_len, + NULL, // version + issuer, issuer_len, + NULL, NULL, // this_udpate, next_update + NULL, NULL, // revoked_certs, revoked_certs_len + NULL, NULL, // exts, exts_len, + NULL, // signature_algor + NULL, NULL // sig, siglen + ) != 1) { + error_print(); + return -1; } return 1; } diff --git a/src/x509_ext.c b/src/x509_ext.c index d0645fe0..ecc76a4a 100644 --- a/src/x509_ext.c +++ b/src/x509_ext.c @@ -116,6 +116,24 @@ int x509_exts_add_authority_key_identifier(uint8_t *exts, size_t *extslen, size_ return 1; } +int x509_exts_add_default_authority_key_identifier(uint8_t *exts, size_t *extslen, size_t maxlen, + const SM2_KEY *public_key) +{ + uint8_t buf[65]; + uint8_t id[32]; + int critical = -1; + + sm2_point_to_uncompressed_octets(&public_key->public_key, buf); + sm3_digest(buf, sizeof(buf), id); + + if (x509_exts_add_authority_key_identifier(exts, extslen, maxlen, critical, + id, sizeof(id), NULL, 0, NULL, 0) != 1) { + error_print(); + return -1; + } + return 1; +} + int x509_exts_add_subject_key_identifier(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const uint8_t *d, size_t dlen) { @@ -150,6 +168,12 @@ 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; + if (!bits) { + // TODO: 检查是否在合法范围内 + error_print(); + return -1; + } + exts += *extslen; if (asn1_bits_to_der(bits, &p, &vlen) != 1 || x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1 @@ -1646,18 +1670,27 @@ int x509_explicit_distribution_point_name_from_der(int index, int *choice, const return -1; } -int x509_distribution_point_name_print(FILE *fp, int fmt, int ind, const char *label, int choice, const uint8_t *d, size_t dlen) +int x509_distribution_point_name_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen) { + int tag; + const uint8_t *d; + size_t dlen; + format_print(fp, fmt, ind, "%s\n", label); ind += 4; - switch (choice) { - case 0: return x509_general_names_print(fp, fmt, ind, "fullName", d, dlen); - case 1: return x509_rdn_print(fp, fmt, ind, "nameRelativeToCRLIssuer", d, dlen); + if (asn1_any_type_from_der(&tag, &d, &dlen, &a, &alen) != 1) { + error_print(); + return -1; + } + switch (tag) { + case ASN1_TAG_EXPLICIT(0): return x509_general_names_print(fp, fmt, ind, "fullName", d, dlen); + case ASN1_TAG_IMPLICIT(1): return x509_rdn_print(fp, fmt, ind, "nameRelativeToCRLIssuer", d, dlen); default: error_print(); return -1; } + return 1; } int x509_distribution_point_to_der( @@ -1712,32 +1745,41 @@ 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; - size_t namelen; - - if (x509_distribution_point_name_from_der(&choice, &name, &namelen, &p, &len) != 1) goto err; - x509_distribution_point_name_print(fp, fmt, ind, "DistributionPointName", choice, name, namelen); - if (asn1_length_is_zero(len) != 1) goto err; - } + if (ret) x509_distribution_point_name_print(fp, fmt, ind, "distributionPoint", p, len); 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(); return -1; } +/* + extnID: CRLDistributionPoints (2.5.29.31) + DistributionPoint + distributionPoint + fullName + GeneralName + URI: http://www.rootca.gov.cn/Civil_Servant_arl/Civil_Servant_ARL.crl + DistributionPoint + distributionPoint + fullName + GeneralName + URI: ldap://ldap.rootca.gov.cn:390/CN=Civil_Servant_ARL,OU=ARL,O=NRCAC,C=CN + +*/ + +int x509_distribution_points_add_url(uint8_t *d, size_t *dlen, size_t maxlen, const char *url) +{ + return 0; +} + int x509_distribution_points_add_distribution_point(uint8_t *d, size_t *dlen, size_t maxlen, int dist_point_choice, const uint8_t *dist_point, size_t dist_point_len, int reasons, const uint8_t *crl_issuer, size_t crl_issuer_len) diff --git a/tools/certgen.c b/tools/certgen.c index a3d7a477..850024fe 100644 --- a/tools/certgen.c +++ b/tools/certgen.c @@ -144,9 +144,11 @@ int certgen_main(int argc, char **argv) goto end; } } else if (!strcmp(*argv, "-key_usage")) { + char *usage; if (--argc < 1) goto bad; - if (ext_key_usage_set(&key_usage, *(++argv)) != 1) { - fprintf(stderr, "%s: invalid -key_usage value\n", prog); + usage = *(++argv); + if (ext_key_usage_set(&key_usage, usage) != 1) { + fprintf(stderr, "%s: invalid -key_usage value '%s'\n", prog, usage); goto end; } } else if (!strcmp(*argv, "-key")) { @@ -194,17 +196,28 @@ bad: fprintf(stderr, "%s: '-pass' option required\n", prog); goto end; } + if (!key_usage) { + fprintf(stderr, "%s: '-key_usage' option required\n", prog); + goto end; + } if (sm2_private_key_info_decrypt_from_pem(&sm2_key, pass, keyfp) != 1) { fprintf(stderr, "%s: load private key failed\n", prog); goto end; } + + if (x509_exts_add_key_usage(exts, &extslen, sizeof(exts), 1, key_usage) != 1 + || x509_exts_add_basic_constraints(exts, &extslen, sizeof(exts), 1, 1, -1) != 1 + || x509_exts_add_default_authority_key_identifier(exts, &extslen, sizeof(exts), &sm2_key) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + time(¬_before); if (rand_bytes(serial, sizeof(serial)) != 1 || x509_name_set(name, &namelen, sizeof(name), country, state, locality, org, org_unit, common_name) != 1 || x509_validity_add_days(¬_after, not_before, days) != 1 - || x509_exts_add_key_usage(exts, &extslen, sizeof(exts), 1, key_usage) != 1 || x509_cert_sign( cert, &certlen, sizeof(cert), X509_version_v3, diff --git a/tools/certverify.c b/tools/certverify.c index 550bca64..ea008b2f 100644 --- a/tools/certverify.c +++ b/tools/certverify.c @@ -53,7 +53,30 @@ #include -static const char *options = "[-in pem] -cacert pem (-id str)\n"; +// 这里面我们想支持证书链的验证 +// 首先输入的应该是一个证书链 +// 需要兼容TLCP的双证书证书链 +// 验证完之后,最后一个证书需要由一个ROOTCA证书来验证 + +/* + +首先从证书链中读取第一个证书,如果没有读取到证书就失败了 + +从证书链中尝试读取一个证书,如果没有读取到,这个就结束了 +如果读取到,存放在CA证书中 +验证证书 +将CA证书copy到被验证证书缓冲中 + +从证书链中读取一个证书,如果没有读取到,就技术了 +如果读取到,存在在CA证书中 +验证证书 +将CA证书copy到被验证证书缓冲中 + +*/ + + + +static const char *options = "[-in pem] -cacert pem\n"; int certverify_main(int argc, char **argv) { @@ -65,8 +88,8 @@ int certverify_main(int argc, char **argv) FILE *cacertfp = NULL; uint8_t cert[1024]; size_t certlen; - const uint8_t *issuer; - size_t issuer_len; + const uint8_t *subject; + size_t subject_len; uint8_t cacert[1024]; size_t cacertlen; char *signer_id = SM2_DEFAULT_ID; @@ -85,7 +108,7 @@ int certverify_main(int argc, char **argv) printf("usage: %s %s\n", prog, options); ret = 0; goto end; - } else if (!strcmp(*argv, "-cert")) { + } else if (!strcmp(*argv, "-in")) { if (--argc < 1) goto bad; infile = *(++argv); if (!(infp = fopen(infile, "r"))) { @@ -123,15 +146,42 @@ bad: fprintf(stderr, "%s: read certificate failure\n", prog); goto end; } - if (x509_cert_get_subject(cert, certlen, &issuer, &issuer_len) != 1) { + if (x509_cert_get_subject(cert, certlen, &subject, &subject_len) != 1) { + goto end; + } + x509_name_print(stdout, 0, 0, "Certificate", subject, subject_len); + + for (;;) { + if ((rv = x509_cert_from_pem(cacert, &cacertlen, sizeof(cacert), infp)) != 1) { + if (rv < 0) goto end; + goto final; + } + if (x509_cert_get_subject(cacert, cacertlen, &subject, &subject_len) != 1) { + goto end; + } + x509_name_print(stdout, 0, 0, "Signed by", subject, subject_len); + + if ((rv = x509_cert_verify_by_ca_cert(cert, certlen, cacert, cacertlen, SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID))) < 0) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + printf("Verification %s\n", rv ? "success" : "failure"); + + memcpy(cert, cacert, cacertlen); + certlen = cacertlen; + } + +final: + if (x509_cert_get_issuer(cert, certlen, &subject, &subject_len) != 1) { fprintf(stderr, "%s: parse certificate error\n", prog); goto end; } - if (x509_cert_from_pem_by_subject(cacert, &cacertlen, sizeof(cacert), issuer, issuer_len, cacertfp) != 1) { + if (x509_cert_from_pem_by_subject(cacert, &cacertlen, sizeof(cacert), subject, subject_len, cacertfp) != 1) { fprintf(stderr, "%s: load CA certificate failure\n", prog); goto end; } - if ((rv = x509_cert_verify_by_ca_cert(cert, certlen, cacert, cacertlen, signer_id, strlen(signer_id))) < 0) { + x509_name_print(stdout, 0, 0, "Signed by", subject, subject_len); + if ((rv = x509_cert_verify_by_ca_cert(cert, certlen, cacert, cacertlen, SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID))) < 0) { fprintf(stderr, "%s: inner error\n", prog); goto end; } diff --git a/tools/crlparse.c b/tools/crlparse.c index bbae4748..5a2f3c5f 100644 --- a/tools/crlparse.c +++ b/tools/crlparse.c @@ -50,11 +50,12 @@ #include #include #include +#include #include #include -static const char *options = "[-in file] [-out file]"; +static const char *options = "-in file [-out file]"; int crlparse_main(int argc, char **argv) { @@ -64,12 +65,21 @@ int crlparse_main(int argc, char **argv) char *outfile = NULL; FILE *infp = stdin; FILE *outfp = stdout; - uint8_t crl[64 * 1024]; + struct stat st; + uint8_t *in = NULL; + size_t inlen; + const uint8_t *pin; + const uint8_t *crl = NULL; size_t crllen; argc--; argv++; + if (argc < 1) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + while (argc > 0) { if (!strcmp(*argv, "-help")) { printf("usage: %s %s\n", prog, options); @@ -100,23 +110,37 @@ bad: argv++; } - for (;;) { - int rv; - - if ((rv = x509_crl_from_fp(crl, &crllen, sizeof(crl), infp)) != 1) { - if (rv < 0) fprintf(stderr, "%s: read CRL failure\n", prog); - else ret = 0; - goto end; - } - x509_crl_print(outfp, 0, 0, "CRL", crl, crllen); - if (x509_crl_to_pem(crl, crllen, outfp) != 1) { - fprintf(stderr, "%s: output CRL failure\n", prog); - goto end; - } + if (!infile) { + fprintf(stderr, "%s: '-in' option required\n", prog); + goto end; } + if (fstat(fileno(infp), &st) < 0) { + fprintf(stderr, "%s: access file error : %s\n", prog, strerror(errno)); + goto end; + } + if ((inlen = st.st_size) <= 0) { + fprintf(stderr, "%s: invalid input length\n", prog); + goto end; + } + if (!(in = malloc(inlen))) { + fprintf(stderr, "%s: malloc failure\n", prog); + goto end; + } + if (fread(in, 1, inlen, infp) != inlen) { + fprintf(stderr, "%s: read file error : %s\n", prog, strerror(errno)); + goto end; + } + pin = in; + if (x509_crl_from_der(&crl, &crllen, &pin, &inlen) != 1 + || asn1_length_is_zero(inlen) != 1) { + fprintf(stderr, "%s: read CRL failure\n", prog); + goto end; + } + x509_crl_print(outfp, 0, 0, "CRL", crl, crllen); end: if (infile && infp) fclose(infp); if (outfile && outfp) fclose(outfp); + if (in) free(in); return ret; } diff --git a/tools/crlverify.c b/tools/crlverify.c new file mode 100644 index 00000000..cc0af88b --- /dev/null +++ b/tools/crlverify.c @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2021 - 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 +#include +#include +#include +#include +#include +#include + + +static const char *options = "-in file -cacert file\n"; + +int crlverify_main(int argc, char **argv) +{ + int ret = 1; + char *prog = argv[0]; + char *infile = NULL; + char *cacertfile = NULL; + FILE *infp = NULL; + FILE *cacertfp = NULL; + uint8_t *in = NULL; + size_t inlen; + struct stat st; + const uint8_t *pin; + const uint8_t *crl = NULL; + size_t crllen; + const uint8_t *subject; + size_t subject_len; + uint8_t cacert[1024]; + size_t cacertlen; + int rv; + + argc--; + argv++; + + if (argc < 1) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + + while (argc > 0) { + if (!strcmp(*argv, "-help")) { + printf("usage: %s %s\n", prog, options); + ret = 0; + goto end; + } else if (!strcmp(*argv, "-in")) { + if (--argc < 1) goto bad; + infile = *(++argv); + if (!(infp = fopen(infile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); + goto end; + } + } else if (!strcmp(*argv, "-cacert")) { + if (--argc < 1) goto bad; + cacertfile = *(++argv); + if (!(cacertfp = fopen(cacertfile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, cacertfile, strerror(errno)); + goto end; + } + } else { + fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); + goto end; +bad: + fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); + goto end; + } + + argc--; + argv++; + } + + if (!infile) { + fprintf(stderr, "%s: '-in' option required\n", prog); + goto end; + } + if (!cacertfile) { + fprintf(stderr, "%s: '-cacert' option required\n", prog); + goto end; + } + + + if (fstat(fileno(infp), &st) < 0) { + fprintf(stderr, "%s: access file error : %s\n", prog, strerror(errno)); + goto end; + } + if ((inlen = st.st_size) <= 0) { + fprintf(stderr, "%s: invalid input length\n", prog); + goto end; + } + if (!(in = malloc(inlen))) { + fprintf(stderr, "%s: malloc failure\n", prog); + goto end; + } + if (fread(in, 1, inlen, infp) != inlen) { + fprintf(stderr, "%s: read file error : %s\n", prog, strerror(errno)); + goto end; + } + pin = in; + if (x509_crl_from_der(&crl, &crllen, &pin, &inlen) != 1 + || asn1_length_is_zero(inlen) != 1) { + fprintf(stderr, "%s: read CRL failure\n", prog); + goto end; + } + + if (x509_crl_get_issuer(crl, crllen, &subject, &subject_len) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + if (x509_cert_from_pem_by_subject(cacert, &cacertlen, sizeof(cacert), subject, subject_len, cacertfp) != 1) { + fprintf(stderr, "%s: read certificate failure\n", prog); + goto end; + } + if ((rv = x509_crl_verify_by_ca_cert(crl, crllen, cacert, cacertlen, SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID))) < 0) { + fprintf(stderr, "%s: verification inner error\n", prog); + goto end; + } + + printf("Verification %s\n", rv ? "success" : "failure"); + if (rv == 1) ret = 0; + +end: + if (infile && infp) fclose(infp); + if (cacertfp) fclose(cacertfp); + if (in) free(in); + return ret; +} + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/gmssl.c b/tools/gmssl.c index 67004a5c..d000acf8 100644 --- a/tools/gmssl.c +++ b/tools/gmssl.c @@ -57,6 +57,7 @@ extern int certgen_main(int argc, char **argv); extern int certparse_main(int argc, char **argv); extern int certverify_main(int argc, char **argv); extern int crlparse_main(int argc, char **argv); +extern int crlverify_main(int argc, char **argv); extern int pbkdf2_main(int argc, char **argv); extern int reqgen_main(int argc, char **argv); extern int reqparse_main(int argc, char **argv); @@ -117,7 +118,8 @@ static const char *options = " reqgen Generate certificate signing request (CSR)\n" " reqsign Generate certificate from CSR\n" " reqparse Parse and print a CSR\n" - " crlparse Parse and print CRL\n" + " crlparse Verify a CRL with certificate\n" + " crlverify Parse and print CRL\n" " certgen Generate a self-signed certificate\n" " certparse Parse and print certificates\n" " certverify Verify certificate chain\n" @@ -166,6 +168,8 @@ int main(int argc, char **argv) return certverify_main(argc, argv); } else if (!strcmp(*argv, "crlparse")) { return crlparse_main(argc, argv); + } else if (!strcmp(*argv, "crlverify")) { + return crlverify_main(argc, argv); } else if (!strcmp(*argv, "reqgen")) { return reqgen_main(argc, argv); } else if (!strcmp(*argv, "reqparse")) { diff --git a/tools/reqsign.c b/tools/reqsign.c index 5e64b177..fe87056b 100644 --- a/tools/reqsign.c +++ b/tools/reqsign.c @@ -57,7 +57,8 @@ #include -static const char *options = "[-in pem] -days num -cacert pem -key pem [-pass str] [-out pem]\n"; +static const char *options = "[-in pem] -days num -cacert pem -key pem [-pass str] [-out pem] " + "-key_usage oid -path_len_constraint num -crl_url url\n"; static int ext_key_usage_set(int *usages, const char *usage_name) { @@ -105,6 +106,7 @@ int reqsign_main(int argc, char **argv) uint8_t exts[512]; size_t extslen = 0; int key_usage = 0; + int path_len_constraint = -1; argc--; argv++; @@ -139,6 +141,16 @@ int reqsign_main(int argc, char **argv) fprintf(stderr, "%s: set KeyUsage extenstion failure\n", prog); goto end; } + } else if (!strcmp(*argv, "-path_len_constraint")) { + if (--argc < 1) goto bad; + path_len_constraint = atoi(*(++argv)); + if (path_len_constraint < 0) { + fprintf(stderr, "%s: invalid value for '-path_len_constraint'\n", prog); + goto end; + } + } else if (!strcmp(*argv, "-crl_url")) { + if (--argc < 1) goto bad; + //crl_url = *(++argv); } else if (!strcmp(*argv, "-cacert")) { if (--argc < 1) goto bad; cacertfile = *(++argv); @@ -223,16 +235,31 @@ bad: } time(¬_before); + + if (x509_exts_add_key_usage(exts, &extslen, sizeof(exts), 1, key_usage) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + if (path_len_constraint >= 0) { + if (x509_exts_add_basic_constraints(exts, &extslen, sizeof(exts), 1, 1, path_len_constraint) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + } + if (x509_exts_add_default_authority_key_identifier(exts, &extslen, sizeof(exts), &sm2_key) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + if (x509_validity_add_days(¬_after, not_before, days) != 1 - || x509_exts_add_key_usage(exts, &extslen, sizeof(exts), 1, key_usage) != 1 || x509_cert_sign( cert, &certlen, sizeof(cert), X509_version_v3, serial, sizeof(serial), OID_sm2sign_with_sm3, - subject, subject_len, - not_before, not_after, issuer, issuer_len, + not_before, not_after, + subject, subject_len, &subject_public_key, NULL, 0, NULL, 0, diff --git a/tools/tlcp_server.c b/tools/tlcp_server.c index a9cf60db..5990534e 100644 --- a/tools/tlcp_server.c +++ b/tools/tlcp_server.c @@ -47,48 +47,51 @@ */ #include +#include #include #include -#include +#include #include #include -#include - static const char *options = "[-port num] -cert file -key file [-pass str] -ex_key file [-ex_pass str] [-cacert file]"; int tlcp_server_main(int argc , char **argv) { - int ret = -1; + int ret = 1; char *prog = argv[0]; int port = 443; - char *file = NULL; + char *certfile = NULL; + char *signkeyfile = NULL; + char *signpass = NULL; + char *enckeyfile = NULL; + char *encpass = NULL; + char *cacertfile = NULL; FILE *certfp = NULL; FILE *signkeyfp = NULL; FILE *enckeyfp = NULL; + FILE *cacertfp = NULL; SM2_KEY signkey; SM2_KEY enckey; - char *pass = NULL; - char *ex_pass = NULL; - uint8_t verify_buf[4096]; - TLS_CONNECT conn; char buf[1600] = {0}; size_t len = sizeof(buf); - if (argc < 2) { + + argc--; + argv++; + + if (argc < 1) { fprintf(stderr, "usage: %s %s\n", prog, options); return 1; } - argc--; - argv++; - while (argc >= 1) { + while (argc > 0) { if (!strcmp(*argv, "-help")) { printf("usage: %s %s\n", prog, options); return 0; @@ -97,31 +100,38 @@ int tlcp_server_main(int argc , char **argv) port = atoi(*(++argv)); } else if (!strcmp(*argv, "-cert")) { if (--argc < 1) goto bad; - file = *(++argv); - if (!(certfp = fopen(file, "r"))) { - error_print(); - return -1; + certfile = *(++argv); + if (!(certfp = fopen(certfile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, certfile, strerror(errno)); + goto end; } } else if (!strcmp(*argv, "-key")) { if (--argc < 1) goto bad; - file = *(++argv); - if (!(signkeyfp = fopen(file, "r"))) { - error_print(); - return -1; + signkeyfile = *(++argv); + if (!(signkeyfp = fopen(signkeyfile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, signkeyfile, strerror(errno)); + goto end; } } else if (!strcmp(*argv, "-pass")) { if (--argc < 1) goto bad; - pass = *(++argv); + signpass = *(++argv); } else if (!strcmp(*argv, "-ex_key")) { if (--argc < 1) goto bad; - file = *(++argv); - if (!(enckeyfp = fopen(file, "r"))) { - error_print(); - return -1; + enckeyfile = *(++argv); + if (!(enckeyfp = fopen(enckeyfile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, enckeyfile, strerror(errno)); + goto end; } } else if (!strcmp(*argv, "-ex_pass")) { if (--argc < 1) goto bad; - ex_pass = *(++argv); + encpass = *(++argv); + } else if (!strcmp(*argv, "-cacert")) { + if (--argc < 1) goto bad; + cacertfile = *(++argv); + if (!(cacertfp = fopen(cacertfile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, cacertfile, strerror(errno)); + goto end; + } } else { fprintf(stderr, "%s: invalid option '%s'\n", prog, *argv); return 1; @@ -132,67 +142,69 @@ bad: argc--; argv++; } - - if (!certfp) { - error_print(); - return -1; + if (!certfile) { + fprintf(stderr, "%s: '-cert' option required\n", prog); + goto end; } - if (!signkeyfp) { - error_print(); - return -1; + if (!signkeyfile) { + fprintf(stderr, "%s: '-key' option required\n", prog); + goto end; } - if (!enckeyfp) { - error_print(); - return -1; + if (!signpass) { + fprintf(stderr, "%s: '-pass' option required\n", prog); + goto end; + } + if (!enckeyfile) { + fprintf(stderr, "%s: '-ex_key' option required\n", prog); + goto end; + } + if (!encpass) { + fprintf(stderr, "%s: '-ex_pass' option required\n", prog); + goto end; } - if (!pass) { - pass = getpass("Sign Key Password : "); + if (sm2_private_key_info_decrypt_from_pem(&signkey, signpass, signkeyfp) != 1) { + fprintf(stderr, "%s: load private key failure\n", prog); + goto end; } - if (sm2_private_key_info_decrypt_from_pem(&signkey, pass, signkeyfp) != 1) { - error_print(); - return -1; + if (sm2_private_key_info_decrypt_from_pem(&enckey, encpass, enckeyfp) != 1) { + fprintf(stderr, "%s: load private key failure\n", prog); + goto end; } - if (!ex_pass) { - ex_pass = getpass("Encryption Key Password : "); - } - if (sm2_private_key_info_decrypt_from_pem(&enckey, ex_pass, enckeyfp) != 1) { - error_print(); - return -1; - } + printf("start ...........\n"); memset(&conn, 0, sizeof(conn)); - if (tlcp_accept(&conn, port, certfp, &signkey, &enckey, - NULL, verify_buf, 4096) != 1) { - error_print(); - return -1; + + if (tlcp_accept(&conn, port, certfp, &signkey, &enckey, cacertfp, verify_buf, 4096) != 1) { + fprintf(stderr, "%s: tlcp accept failure\n", prog); + goto end; } - // 我要做一个反射的服务器,接收到用户的输入之后,再反射回去 for (;;) { - // 接收一个消息 - // 按道理说第二次执行的时候是不可能成功的了,因此客户端没有数据发过来 do { len = sizeof(buf); if (tls_recv(&conn, (uint8_t *)buf, &len) != 1) { - error_print(); - return -1; + fprintf(stderr, "%s: recv failure\n", prog); + goto end; } } while (!len); - // 把这个消息再发回去 if (tls_send(&conn, (uint8_t *)buf, len) != 1) { - error_print(); - return -1; + fprintf(stderr, "%s: send failure\n", prog); + goto end; } - - fprintf(stderr, "-----------------\n\n\n\n\n\n"); - } - return 0; +end: + gmssl_secure_clear(&signkey, sizeof(signkey)); + gmssl_secure_clear(&enckey, sizeof(enckey)); + if (certfp) fclose(certfp); + if (signkeyfp) fclose(signkeyfp); + if (enckeyfp) fclose(enckeyfp); + if (cacertfp) fclose(cacertfp); + return ret; }