From 3bad4ad10359625459b6d058436f2068d369ba7b Mon Sep 17 00:00:00 2001 From: "Dr. Pala" Date: Sun, 1 Sep 2024 21:02:26 -0400 Subject: [PATCH 01/12] Added CRYPTO layer. Removing X509 functions from CRYPTO layer. --- .../libpki/crypto/composite/composite_ctx.h | 224 ++ .../libpki/crypto/composite/composite_init.h | 25 + .../libpki/crypto/composite/composite_key.h | 294 ++ .../libpki/crypto/composite/composite_pmeth.h | 66 + .../libpki/crypto/composite/composite_types.h | 125 + .../libpki/crypto/composite/composite_utils.h | 46 + include/libpki/crypto/crypto_keypair.h | 268 ++ include/libpki/crypto/crypto_keyparams.h | 118 + include/libpki/crypto/crypto_operations.h | 44 + include/libpki/crypto/crypto_utils.h | 117 + include/libpki/crypto/hsm/hsm.h | 235 ++ include/libpki/crypto/hsm/openssl/Makefile.am | 27 + include/libpki/crypto/hsm/openssl/Makefile.in | 796 ++++++ include/libpki/crypto/hsm/openssl/data_st.h | 1422 ++++++++++ .../crypto/hsm/openssl/openssl_data_store.h | 19 + .../libpki/crypto/hsm/openssl/openssl_hsm.c | 441 +++ .../libpki/crypto/hsm/openssl/openssl_hsm.h | 85 + .../crypto/hsm/openssl/openssl_hsm_cb.c | 430 +++ .../crypto/hsm/openssl/openssl_hsm_cb.h | 9 + .../crypto/hsm/openssl/openssl_hsm_obj.c | 22 + .../crypto/hsm/openssl/openssl_hsm_obj.h | 23 + .../crypto/hsm/openssl/openssl_hsm_pkey.c | 1214 ++++++++ .../crypto/hsm/openssl/openssl_hsm_pkey.h | 20 + .../libpki/crypto/hsm/openssl/pki_oid_defs.h | 659 +++++ include/libpki/crypto/hsm/openssl/types.h | 106 + include/libpki/crypto/hsm/pkcs11/pkcs11_hsm.h | 84 + .../libpki/crypto/hsm/pkcs11/pkcs11_hsm_obj.h | 46 + .../crypto/hsm/pkcs11/pkcs11_hsm_pkey.h | 41 + .../libpki/crypto/hsm/pkcs11/pkcs11_utils.h | 86 + .../libpki/crypto/hsm/pkcs11/rsa/cryptoki.h | 112 + include/libpki/crypto/hsm/pkcs11/rsa/pkcs11.h | 265 ++ .../crypto/hsm/pkcs11/rsa/pkcs11_func.h | 152 + .../libpki/crypto/hsm/pkcs11/rsa/pkcs11f.h | 939 +++++++ .../libpki/crypto/hsm/pkcs11/rsa/pkcs11t.h | 2003 ++++++++++++++ include/libpki/crypto/hsm/types.h | 328 +++ include/libpki/crypto/hsm/wolfssl/data_st.h | 19 + .../libpki/crypto/hsm/wolfssl/wolfssl_hsm.h | 85 + .../crypto/hsm/wolfssl/wolfssl_hsm_cb.h | 9 + .../crypto/hsm/wolfssl/wolfssl_hsm_obj.h | 23 + .../crypto/hsm/wolfssl/wolfssl_hsm_pkey.h | 20 + include/libpki/crypto/types.h | 239 ++ include/libpki/libconf/compat.h | 48 + include/libpki/libconf/defines.h | 214 ++ include/libpki/libconf/defines.h.in | 214 ++ include/libpki/libconf/features.h | 20 + include/libpki/libconf/features.h.in | 21 + include/libpki/libconf/system.h | 362 +++ include/libpki/libconf/types.h | 137 + include/libpki/libconf/version.h | 55 + include/libpki/libconf/version.h.in | 55 + include/libpki/pki.h | 376 +++ include/libpki/pki_config.h.in | 117 + include/libpki/pki_io.h | 26 + include/libpki/pkix/cmc/cmc.h | 443 +++ include/libpki/pkix/cmc/cmc_cert_req.h | 31 + include/libpki/pkix/est/est.h | 252 ++ include/libpki/pkix/est/pki_x509_est_asn1.h | 15 + include/libpki/pkix/est/pki_x509_est_attrs.h | 108 + include/libpki/pkix/est/pki_x509_est_data.h | 28 + include/libpki/pkix/est/pki_x509_est_msg.h | 39 + include/libpki/pkix/ocsp/pki_ocsp_req.h | 89 + include/libpki/pkix/ocsp/pki_ocsp_resp.h | 135 + include/libpki/pkix/pki_msg.h | 71 + include/libpki/pkix/pki_msg_req.h | 113 + include/libpki/pkix/pki_msg_resp.h | 96 + include/libpki/pkix/prqp/http_client.h | 31 + include/libpki/pkix/prqp/prqp.h | 194 ++ include/libpki/pkix/prqp/prqp_asn1.h | 275 ++ include/libpki/pkix/prqp/prqp_bio.h | 58 + include/libpki/pkix/prqp/prqp_lib.h | 129 + include/libpki/pkix/prqp/prqp_req_io.h | 43 + include/libpki/pkix/prqp/prqp_resp_io.h | 43 + include/libpki/pkix/prqp/prqp_srv.h | 25 + include/libpki/pkix/prqp/prqp_stack.h | 135 + include/libpki/pkix/scep/pki_x509_scep_asn1.h | 15 + .../libpki/pkix/scep/pki_x509_scep_attrs.h | 108 + include/libpki/pkix/scep/pki_x509_scep_data.h | 28 + include/libpki/pkix/scep/pki_x509_scep_msg.h | 39 + include/libpki/pkix/scep/scep.h | 254 ++ include/libpki/pkix/types.h | 35 + include/libpki/token/token.h | 184 ++ include/libpki/token/token_data.h | 29 + include/libpki/token/token_id.h | 19 + include/libpki/token/types.h | 115 + include/libpki/utils/asn1.h | 33 + include/libpki/utils/banners.h | 50 + include/libpki/utils/encoder.h | 16 + include/libpki/utils/net/dns.h | 39 + include/libpki/utils/net/http_s.h | 113 + include/libpki/utils/net/ldap.h | 28 + include/libpki/utils/net/pkcs11.h | 20 + include/libpki/utils/net/pki_mysql.h | 24 + include/libpki/utils/net/pki_pg.h | 24 + include/libpki/utils/net/pki_socket.h | 97 + include/libpki/utils/net/sock.h | 71 + include/libpki/utils/net/ssl.h | 390 +++ include/libpki/utils/net/types.h | 125 + include/libpki/utils/net/url.h | 101 + include/libpki/utils/pki_cred.h | 30 + include/libpki/utils/pki_err.h | 224 ++ include/libpki/utils/pki_id.h | 53 + include/libpki/utils/pki_id_info.h | 25 + include/libpki/utils/pki_init.h | 45 + include/libpki/utils/pki_log.h | 113 + include/libpki/utils/pki_mem.h | 112 + include/libpki/utils/pki_threads.h | 19 + include/libpki/utils/pki_threads_vars.h | 50 + include/libpki/utils/profile.h | 56 + include/libpki/utils/pthread_init.h | 8 + include/libpki/utils/stack.h | 241 ++ include/libpki/utils/support.h | 67 + include/libpki/utils/types.h | 85 + include/libpki/x509/extensions.h | 30 + include/libpki/x509/io/pki_keypair_io.h | 59 + include/libpki/x509/io/pki_msg_req_io.h | 32 + include/libpki/x509/io/pki_msg_resp_io.h | 16 + include/libpki/x509/io/pki_ocsp_req_io.h | 44 + include/libpki/x509/io/pki_ocsp_resp_io.h | 44 + include/libpki/x509/io/pki_x509_cert_io.h | 38 + include/libpki/x509/io/pki_x509_cms_io.h | 60 + include/libpki/x509/io/pki_x509_crl_io.h | 37 + include/libpki/x509/io/pki_x509_io.h | 53 + include/libpki/x509/io/pki_x509_p12_io.h | 64 + include/libpki/x509/io/pki_x509_pkcs7_io.h | 61 + include/libpki/x509/io/pki_x509_req_io.h | 38 + include/libpki/x509/io/pki_x509_xpair_io.h | 51 + include/libpki/x509/pki_algor.h | 189 ++ include/libpki/x509/pki_integer.h | 28 + include/libpki/x509/pki_oid.h | 21 + include/libpki/x509/pki_string.h | 65 + include/libpki/x509/pki_time.h | 22 + include/libpki/x509/pki_x509.h | 322 +++ include/libpki/x509/pki_x509_attribute.h | 72 + include/libpki/x509/pki_x509_cert.h | 97 + include/libpki/x509/pki_x509_cert_mem.h | 16 + include/libpki/x509/pki_x509_cms.h | 272 ++ include/libpki/x509/pki_x509_crl.h | 68 + include/libpki/x509/pki_x509_data_st.h | 81 + include/libpki/x509/pki_x509_extension.h | 25 + include/libpki/x509/pki_x509_item.h | 16 + include/libpki/x509/pki_x509_mem.h | 26 + include/libpki/x509/pki_x509_mime.h | 30 + include/libpki/x509/pki_x509_name.h | 30 + include/libpki/x509/pki_x509_p12.h | 69 + include/libpki/x509/pki_x509_pkcs7.h | 150 + include/libpki/x509/pki_x509_profile.h | 30 + include/libpki/x509/pki_x509_req.h | 64 + include/libpki/x509/pki_x509_signature.h | 8 + include/libpki/x509/pki_x509_xpair.h | 32 + include/libpki/x509/pki_x509_xpair_asn1.h | 19 + include/libpki/x509/types.h | 95 + src/crypto/artifacts/3gpp/README.md | 4 + src/crypto/artifacts/Makefile.am | 27 + src/crypto/artifacts/docsis/README.md | 4 + .../artifacts/docsis/docsis_test_certs.c | 2 + .../artifacts/docsis/docsis_test_keys.c | 2 + src/crypto/artifacts/matter/README.md | 4 + src/crypto/artifacts/ocf/README.md | 4 + src/crypto/artifacts/pki_testing.c | 278 ++ src/crypto/artifacts/wba/README.md | 4 + src/crypto/artifacts/webpki/README.md | 4 + src/crypto/artifacts/wfa/README.md | 4 + src/crypto/artifacts/winnforum/README.md | 4 + src/crypto/artifacts/x9f/README.md | 4 + src/crypto/artifacts/x9f/x9f_dev_certs.c | 2 + src/crypto/artifacts/x9f/x9f_dev_keys.c | 2 + src/crypto/composite/Makefile.am | 37 + src/crypto/composite/Makefile.in | 901 ++++++ src/crypto/composite/composite_ameth.c | 1686 ++++++++++++ src/crypto/composite/composite_ameth_lcl.h | 70 + src/crypto/composite/composite_ctx.c | 1015 +++++++ src/crypto/composite/composite_err.c | 42 + src/crypto/composite/composite_init.c | 487 ++++ src/crypto/composite/composite_key.c | 408 +++ src/crypto/composite/composite_ossl_lcl.h | 243 ++ src/crypto/composite/composite_pmeth.c | 1917 +++++++++++++ src/crypto/composite/composite_utils.c | 86 + src/crypto/hsm/Makefile.am | 40 + src/crypto/hsm/Makefile.in | 908 ++++++ src/crypto/hsm/hsm_keypair.c | 129 + src/crypto/hsm/hsm_main.c | 1373 +++++++++ src/crypto/hsm/hsm_slot.c | 248 ++ src/crypto/hsm/openssl/Makefile.am | 27 + src/crypto/hsm/openssl/Makefile.in | 796 ++++++ src/crypto/hsm/openssl/openssl_hsm.c | 441 +++ src/crypto/hsm/openssl/openssl_hsm_cb.c | 430 +++ src/crypto/hsm/openssl/openssl_hsm_obj.c | 22 + src/crypto/hsm/openssl/openssl_hsm_pkey.c | 1214 ++++++++ src/crypto/hsm/pkcs11/Makefile.am | 45 + src/crypto/hsm/pkcs11/Makefile.in | 823 ++++++ src/crypto/hsm/pkcs11/pkcs11_hsm.c | 1114 ++++++++ src/crypto/hsm/pkcs11/pkcs11_hsm_obj.c | 1366 +++++++++ src/crypto/hsm/pkcs11/pkcs11_hsm_pkey.c | 1438 ++++++++++ src/crypto/hsm/pkcs11/utils/pkcs11_init.c | 1071 ++++++++ src/crypto/hsm/wolfssl/Makefile.am | 27 + src/crypto/hsm/wolfssl/wolfssl_hsm.c | 441 +++ src/crypto/hsm/wolfssl/wolfssl_hsm_cb.c | 430 +++ src/crypto/hsm/wolfssl/wolfssl_hsm_obj.c | 22 + src/crypto/hsm/wolfssl/wolfssl_hsm_pkey.c | 1214 ++++++++ src/crypto/pki_algor.c | 2228 +++++++++++++++ src/crypto/pki_digest.c | 315 +++ src/crypto/pki_hmac.c | 300 ++ src/crypto/pki_kdf.c | 22 + src/crypto/pki_keypair.c | 1664 +++++++++++ src/crypto/pki_keyparams.c | 1149 ++++++++ src/crypto/pki_oid.c | 209 ++ src/crypto/pki_rand.c | 34 + src/pkix/cmc/Makefile.am | 25 + src/pkix/cmc/Makefile.in | 779 ++++++ src/pkix/cmc/asn1.c | 407 +++ src/pkix/cmc/cmc_cert_req.c | 297 ++ src/pkix/cmc/cmc_simple.c | 48 + src/pkix/est/Makefile.am | 26 + src/pkix/est/Makefile.in | 793 ++++++ src/pkix/est/pki_x509_est_asn1.c | 17 + src/pkix/est/pki_x509_est_attr.c | 563 ++++ src/pkix/est/pki_x509_est_data.c | 91 + src/pkix/est/pki_x509_est_msg.c | 216 ++ src/pkix/pki_x509_p12.c | 1020 +++++++ src/pkix/pki_x509_pkcs7.c | 1489 ++++++++++ src/pkix/pki_x509_req.c | 812 ++++++ src/pkix/prqp/Makefile.am | 32 + src/pkix/prqp/Makefile.in | 844 ++++++ src/pkix/prqp/asn1_req.c | 147 + src/pkix/prqp/asn1_res.c | 132 + src/pkix/prqp/http_client.c | 57 + src/pkix/prqp/prqp_bio.c | 572 ++++ src/pkix/prqp/prqp_lib.c | 2448 +++++++++++++++++ src/pkix/prqp/prqp_req_io.c | 86 + src/pkix/prqp/prqp_resp_io.c | 86 + src/pkix/prqp/prqp_srv.c | 286 ++ src/pkix/scep/Makefile.am | 32 + src/pkix/scep/Makefile.in | 800 ++++++ src/pkix/scep/pki_x509_scep_asn1.c | 17 + src/pkix/scep/pki_x509_scep_attr.c | 563 ++++ src/pkix/scep/pki_x509_scep_data.c | 91 + src/pkix/scep/pki_x509_scep_msg.c | 216 ++ src/utils/banners.c | 26 + src/utils/io/Makefile.am | 35 + src/utils/io/Makefile.in | 908 ++++++ src/utils/io/pki_keypair_io.c | 155 ++ src/utils/io/pki_msg_req_io.c | 80 + src/utils/io/pki_msg_resp_io.c | 76 + src/utils/io/pki_ocsp_req_io.c | 265 ++ src/utils/io/pki_ocsp_resp_io.c | 83 + src/utils/io/pki_x509_cert_io.c | 131 + src/utils/io/pki_x509_cms_io.c | 71 + src/utils/io/pki_x509_crl_io.c | 116 + src/utils/io/pki_x509_io.c | 550 ++++ src/utils/io/pki_x509_p12_io.c | 124 + src/utils/io/pki_x509_pkcs7_io.c | 81 + src/utils/io/pki_x509_req_io.c | 83 + src/utils/io/pki_x509_xpair_io.c | 164 ++ src/utils/net/Makefile.am | 31 + src/utils/net/Makefile.in | 865 ++++++ src/utils/net/dns.c | 278 ++ src/utils/net/http_s.c | 988 +++++++ src/utils/net/ldap.c | 232 ++ src/utils/net/mysql.c | 457 +++ src/utils/net/pg.c | 410 +++ src/utils/net/pkcs11.c | 334 +++ src/utils/net/pki_socket.c | 352 +++ src/utils/net/sock.c | 631 +++++ src/utils/net/ssl.c | 1270 +++++++++ src/utils/net/url.c | 1570 +++++++++++ src/utils/pki_config.c | 1091 ++++++++ src/utils/pki_cred.c | 136 + src/utils/pki_err.c | 246 ++ src/utils/pki_init.c | 640 +++++ src/utils/pki_log.c | 581 ++++ src/utils/pki_mem.c | 906 ++++++ src/utils/pki_threads.c | 142 + src/utils/pki_threads_vars.c | 435 +++ src/utils/pki_x509_mem.c | 510 ++++ src/utils/pki_x509_mime.c | 25 + src/utils/profile.c | 327 +++ src/utils/stack.c | 464 ++++ src/utils/support.c | 235 ++ src/x509/extensions.c | 104 + 279 files changed, 76824 insertions(+) create mode 100644 include/libpki/crypto/composite/composite_ctx.h create mode 100644 include/libpki/crypto/composite/composite_init.h create mode 100644 include/libpki/crypto/composite/composite_key.h create mode 100644 include/libpki/crypto/composite/composite_pmeth.h create mode 100644 include/libpki/crypto/composite/composite_types.h create mode 100644 include/libpki/crypto/composite/composite_utils.h create mode 100644 include/libpki/crypto/crypto_keypair.h create mode 100644 include/libpki/crypto/crypto_keyparams.h create mode 100644 include/libpki/crypto/crypto_operations.h create mode 100644 include/libpki/crypto/crypto_utils.h create mode 100644 include/libpki/crypto/hsm/hsm.h create mode 100644 include/libpki/crypto/hsm/openssl/Makefile.am create mode 100644 include/libpki/crypto/hsm/openssl/Makefile.in create mode 100644 include/libpki/crypto/hsm/openssl/data_st.h create mode 100644 include/libpki/crypto/hsm/openssl/openssl_data_store.h create mode 100644 include/libpki/crypto/hsm/openssl/openssl_hsm.c create mode 100644 include/libpki/crypto/hsm/openssl/openssl_hsm.h create mode 100644 include/libpki/crypto/hsm/openssl/openssl_hsm_cb.c create mode 100644 include/libpki/crypto/hsm/openssl/openssl_hsm_cb.h create mode 100644 include/libpki/crypto/hsm/openssl/openssl_hsm_obj.c create mode 100644 include/libpki/crypto/hsm/openssl/openssl_hsm_obj.h create mode 100644 include/libpki/crypto/hsm/openssl/openssl_hsm_pkey.c create mode 100644 include/libpki/crypto/hsm/openssl/openssl_hsm_pkey.h create mode 100644 include/libpki/crypto/hsm/openssl/pki_oid_defs.h create mode 100644 include/libpki/crypto/hsm/openssl/types.h create mode 100644 include/libpki/crypto/hsm/pkcs11/pkcs11_hsm.h create mode 100644 include/libpki/crypto/hsm/pkcs11/pkcs11_hsm_obj.h create mode 100644 include/libpki/crypto/hsm/pkcs11/pkcs11_hsm_pkey.h create mode 100644 include/libpki/crypto/hsm/pkcs11/pkcs11_utils.h create mode 100644 include/libpki/crypto/hsm/pkcs11/rsa/cryptoki.h create mode 100644 include/libpki/crypto/hsm/pkcs11/rsa/pkcs11.h create mode 100644 include/libpki/crypto/hsm/pkcs11/rsa/pkcs11_func.h create mode 100644 include/libpki/crypto/hsm/pkcs11/rsa/pkcs11f.h create mode 100644 include/libpki/crypto/hsm/pkcs11/rsa/pkcs11t.h create mode 100644 include/libpki/crypto/hsm/types.h create mode 100644 include/libpki/crypto/hsm/wolfssl/data_st.h create mode 100644 include/libpki/crypto/hsm/wolfssl/wolfssl_hsm.h create mode 100644 include/libpki/crypto/hsm/wolfssl/wolfssl_hsm_cb.h create mode 100644 include/libpki/crypto/hsm/wolfssl/wolfssl_hsm_obj.h create mode 100644 include/libpki/crypto/hsm/wolfssl/wolfssl_hsm_pkey.h create mode 100644 include/libpki/crypto/types.h create mode 100644 include/libpki/libconf/compat.h create mode 100644 include/libpki/libconf/defines.h create mode 100644 include/libpki/libconf/defines.h.in create mode 100644 include/libpki/libconf/features.h create mode 100644 include/libpki/libconf/features.h.in create mode 100644 include/libpki/libconf/system.h create mode 100644 include/libpki/libconf/types.h create mode 100644 include/libpki/libconf/version.h create mode 100644 include/libpki/libconf/version.h.in create mode 100644 include/libpki/pki.h create mode 100644 include/libpki/pki_config.h.in create mode 100644 include/libpki/pki_io.h create mode 100644 include/libpki/pkix/cmc/cmc.h create mode 100644 include/libpki/pkix/cmc/cmc_cert_req.h create mode 100644 include/libpki/pkix/est/est.h create mode 100644 include/libpki/pkix/est/pki_x509_est_asn1.h create mode 100644 include/libpki/pkix/est/pki_x509_est_attrs.h create mode 100644 include/libpki/pkix/est/pki_x509_est_data.h create mode 100644 include/libpki/pkix/est/pki_x509_est_msg.h create mode 100644 include/libpki/pkix/ocsp/pki_ocsp_req.h create mode 100644 include/libpki/pkix/ocsp/pki_ocsp_resp.h create mode 100644 include/libpki/pkix/pki_msg.h create mode 100644 include/libpki/pkix/pki_msg_req.h create mode 100644 include/libpki/pkix/pki_msg_resp.h create mode 100644 include/libpki/pkix/prqp/http_client.h create mode 100644 include/libpki/pkix/prqp/prqp.h create mode 100644 include/libpki/pkix/prqp/prqp_asn1.h create mode 100644 include/libpki/pkix/prqp/prqp_bio.h create mode 100644 include/libpki/pkix/prqp/prqp_lib.h create mode 100644 include/libpki/pkix/prqp/prqp_req_io.h create mode 100644 include/libpki/pkix/prqp/prqp_resp_io.h create mode 100644 include/libpki/pkix/prqp/prqp_srv.h create mode 100644 include/libpki/pkix/prqp/prqp_stack.h create mode 100644 include/libpki/pkix/scep/pki_x509_scep_asn1.h create mode 100644 include/libpki/pkix/scep/pki_x509_scep_attrs.h create mode 100644 include/libpki/pkix/scep/pki_x509_scep_data.h create mode 100644 include/libpki/pkix/scep/pki_x509_scep_msg.h create mode 100644 include/libpki/pkix/scep/scep.h create mode 100644 include/libpki/pkix/types.h create mode 100644 include/libpki/token/token.h create mode 100644 include/libpki/token/token_data.h create mode 100644 include/libpki/token/token_id.h create mode 100644 include/libpki/token/types.h create mode 100644 include/libpki/utils/asn1.h create mode 100644 include/libpki/utils/banners.h create mode 100644 include/libpki/utils/encoder.h create mode 100644 include/libpki/utils/net/dns.h create mode 100644 include/libpki/utils/net/http_s.h create mode 100644 include/libpki/utils/net/ldap.h create mode 100644 include/libpki/utils/net/pkcs11.h create mode 100644 include/libpki/utils/net/pki_mysql.h create mode 100644 include/libpki/utils/net/pki_pg.h create mode 100644 include/libpki/utils/net/pki_socket.h create mode 100644 include/libpki/utils/net/sock.h create mode 100644 include/libpki/utils/net/ssl.h create mode 100644 include/libpki/utils/net/types.h create mode 100644 include/libpki/utils/net/url.h create mode 100644 include/libpki/utils/pki_cred.h create mode 100644 include/libpki/utils/pki_err.h create mode 100644 include/libpki/utils/pki_id.h create mode 100644 include/libpki/utils/pki_id_info.h create mode 100644 include/libpki/utils/pki_init.h create mode 100644 include/libpki/utils/pki_log.h create mode 100644 include/libpki/utils/pki_mem.h create mode 100644 include/libpki/utils/pki_threads.h create mode 100644 include/libpki/utils/pki_threads_vars.h create mode 100644 include/libpki/utils/profile.h create mode 100644 include/libpki/utils/pthread_init.h create mode 100644 include/libpki/utils/stack.h create mode 100644 include/libpki/utils/support.h create mode 100644 include/libpki/utils/types.h create mode 100644 include/libpki/x509/extensions.h create mode 100644 include/libpki/x509/io/pki_keypair_io.h create mode 100644 include/libpki/x509/io/pki_msg_req_io.h create mode 100644 include/libpki/x509/io/pki_msg_resp_io.h create mode 100644 include/libpki/x509/io/pki_ocsp_req_io.h create mode 100644 include/libpki/x509/io/pki_ocsp_resp_io.h create mode 100644 include/libpki/x509/io/pki_x509_cert_io.h create mode 100644 include/libpki/x509/io/pki_x509_cms_io.h create mode 100644 include/libpki/x509/io/pki_x509_crl_io.h create mode 100644 include/libpki/x509/io/pki_x509_io.h create mode 100644 include/libpki/x509/io/pki_x509_p12_io.h create mode 100644 include/libpki/x509/io/pki_x509_pkcs7_io.h create mode 100644 include/libpki/x509/io/pki_x509_req_io.h create mode 100644 include/libpki/x509/io/pki_x509_xpair_io.h create mode 100644 include/libpki/x509/pki_algor.h create mode 100644 include/libpki/x509/pki_integer.h create mode 100644 include/libpki/x509/pki_oid.h create mode 100644 include/libpki/x509/pki_string.h create mode 100644 include/libpki/x509/pki_time.h create mode 100644 include/libpki/x509/pki_x509.h create mode 100644 include/libpki/x509/pki_x509_attribute.h create mode 100644 include/libpki/x509/pki_x509_cert.h create mode 100644 include/libpki/x509/pki_x509_cert_mem.h create mode 100644 include/libpki/x509/pki_x509_cms.h create mode 100644 include/libpki/x509/pki_x509_crl.h create mode 100644 include/libpki/x509/pki_x509_data_st.h create mode 100644 include/libpki/x509/pki_x509_extension.h create mode 100644 include/libpki/x509/pki_x509_item.h create mode 100644 include/libpki/x509/pki_x509_mem.h create mode 100644 include/libpki/x509/pki_x509_mime.h create mode 100644 include/libpki/x509/pki_x509_name.h create mode 100644 include/libpki/x509/pki_x509_p12.h create mode 100644 include/libpki/x509/pki_x509_pkcs7.h create mode 100644 include/libpki/x509/pki_x509_profile.h create mode 100644 include/libpki/x509/pki_x509_req.h create mode 100644 include/libpki/x509/pki_x509_signature.h create mode 100644 include/libpki/x509/pki_x509_xpair.h create mode 100644 include/libpki/x509/pki_x509_xpair_asn1.h create mode 100644 include/libpki/x509/types.h create mode 100644 src/crypto/artifacts/3gpp/README.md create mode 100644 src/crypto/artifacts/Makefile.am create mode 100644 src/crypto/artifacts/docsis/README.md create mode 100644 src/crypto/artifacts/docsis/docsis_test_certs.c create mode 100644 src/crypto/artifacts/docsis/docsis_test_keys.c create mode 100644 src/crypto/artifacts/matter/README.md create mode 100644 src/crypto/artifacts/ocf/README.md create mode 100644 src/crypto/artifacts/pki_testing.c create mode 100644 src/crypto/artifacts/wba/README.md create mode 100644 src/crypto/artifacts/webpki/README.md create mode 100644 src/crypto/artifacts/wfa/README.md create mode 100644 src/crypto/artifacts/winnforum/README.md create mode 100644 src/crypto/artifacts/x9f/README.md create mode 100644 src/crypto/artifacts/x9f/x9f_dev_certs.c create mode 100644 src/crypto/artifacts/x9f/x9f_dev_keys.c create mode 100644 src/crypto/composite/Makefile.am create mode 100644 src/crypto/composite/Makefile.in create mode 100644 src/crypto/composite/composite_ameth.c create mode 100644 src/crypto/composite/composite_ameth_lcl.h create mode 100644 src/crypto/composite/composite_ctx.c create mode 100644 src/crypto/composite/composite_err.c create mode 100644 src/crypto/composite/composite_init.c create mode 100644 src/crypto/composite/composite_key.c create mode 100644 src/crypto/composite/composite_ossl_lcl.h create mode 100644 src/crypto/composite/composite_pmeth.c create mode 100644 src/crypto/composite/composite_utils.c create mode 100644 src/crypto/hsm/Makefile.am create mode 100644 src/crypto/hsm/Makefile.in create mode 100644 src/crypto/hsm/hsm_keypair.c create mode 100644 src/crypto/hsm/hsm_main.c create mode 100644 src/crypto/hsm/hsm_slot.c create mode 100644 src/crypto/hsm/openssl/Makefile.am create mode 100644 src/crypto/hsm/openssl/Makefile.in create mode 100644 src/crypto/hsm/openssl/openssl_hsm.c create mode 100644 src/crypto/hsm/openssl/openssl_hsm_cb.c create mode 100644 src/crypto/hsm/openssl/openssl_hsm_obj.c create mode 100644 src/crypto/hsm/openssl/openssl_hsm_pkey.c create mode 100644 src/crypto/hsm/pkcs11/Makefile.am create mode 100644 src/crypto/hsm/pkcs11/Makefile.in create mode 100644 src/crypto/hsm/pkcs11/pkcs11_hsm.c create mode 100644 src/crypto/hsm/pkcs11/pkcs11_hsm_obj.c create mode 100644 src/crypto/hsm/pkcs11/pkcs11_hsm_pkey.c create mode 100644 src/crypto/hsm/pkcs11/utils/pkcs11_init.c create mode 100644 src/crypto/hsm/wolfssl/Makefile.am create mode 100644 src/crypto/hsm/wolfssl/wolfssl_hsm.c create mode 100644 src/crypto/hsm/wolfssl/wolfssl_hsm_cb.c create mode 100644 src/crypto/hsm/wolfssl/wolfssl_hsm_obj.c create mode 100644 src/crypto/hsm/wolfssl/wolfssl_hsm_pkey.c create mode 100644 src/crypto/pki_algor.c create mode 100644 src/crypto/pki_digest.c create mode 100644 src/crypto/pki_hmac.c create mode 100644 src/crypto/pki_kdf.c create mode 100644 src/crypto/pki_keypair.c create mode 100644 src/crypto/pki_keyparams.c create mode 100644 src/crypto/pki_oid.c create mode 100644 src/crypto/pki_rand.c create mode 100644 src/pkix/cmc/Makefile.am create mode 100644 src/pkix/cmc/Makefile.in create mode 100644 src/pkix/cmc/asn1.c create mode 100644 src/pkix/cmc/cmc_cert_req.c create mode 100644 src/pkix/cmc/cmc_simple.c create mode 100644 src/pkix/est/Makefile.am create mode 100644 src/pkix/est/Makefile.in create mode 100644 src/pkix/est/pki_x509_est_asn1.c create mode 100644 src/pkix/est/pki_x509_est_attr.c create mode 100644 src/pkix/est/pki_x509_est_data.c create mode 100644 src/pkix/est/pki_x509_est_msg.c create mode 100644 src/pkix/pki_x509_p12.c create mode 100644 src/pkix/pki_x509_pkcs7.c create mode 100644 src/pkix/pki_x509_req.c create mode 100644 src/pkix/prqp/Makefile.am create mode 100644 src/pkix/prqp/Makefile.in create mode 100644 src/pkix/prqp/asn1_req.c create mode 100644 src/pkix/prqp/asn1_res.c create mode 100644 src/pkix/prqp/http_client.c create mode 100644 src/pkix/prqp/prqp_bio.c create mode 100644 src/pkix/prqp/prqp_lib.c create mode 100644 src/pkix/prqp/prqp_req_io.c create mode 100644 src/pkix/prqp/prqp_resp_io.c create mode 100644 src/pkix/prqp/prqp_srv.c create mode 100644 src/pkix/scep/Makefile.am create mode 100644 src/pkix/scep/Makefile.in create mode 100644 src/pkix/scep/pki_x509_scep_asn1.c create mode 100644 src/pkix/scep/pki_x509_scep_attr.c create mode 100644 src/pkix/scep/pki_x509_scep_data.c create mode 100644 src/pkix/scep/pki_x509_scep_msg.c create mode 100644 src/utils/banners.c create mode 100644 src/utils/io/Makefile.am create mode 100644 src/utils/io/Makefile.in create mode 100644 src/utils/io/pki_keypair_io.c create mode 100644 src/utils/io/pki_msg_req_io.c create mode 100644 src/utils/io/pki_msg_resp_io.c create mode 100644 src/utils/io/pki_ocsp_req_io.c create mode 100644 src/utils/io/pki_ocsp_resp_io.c create mode 100644 src/utils/io/pki_x509_cert_io.c create mode 100644 src/utils/io/pki_x509_cms_io.c create mode 100644 src/utils/io/pki_x509_crl_io.c create mode 100644 src/utils/io/pki_x509_io.c create mode 100644 src/utils/io/pki_x509_p12_io.c create mode 100644 src/utils/io/pki_x509_pkcs7_io.c create mode 100644 src/utils/io/pki_x509_req_io.c create mode 100644 src/utils/io/pki_x509_xpair_io.c create mode 100644 src/utils/net/Makefile.am create mode 100644 src/utils/net/Makefile.in create mode 100644 src/utils/net/dns.c create mode 100644 src/utils/net/http_s.c create mode 100644 src/utils/net/ldap.c create mode 100644 src/utils/net/mysql.c create mode 100644 src/utils/net/pg.c create mode 100644 src/utils/net/pkcs11.c create mode 100644 src/utils/net/pki_socket.c create mode 100644 src/utils/net/sock.c create mode 100644 src/utils/net/ssl.c create mode 100644 src/utils/net/url.c create mode 100644 src/utils/pki_config.c create mode 100644 src/utils/pki_cred.c create mode 100644 src/utils/pki_err.c create mode 100644 src/utils/pki_init.c create mode 100644 src/utils/pki_log.c create mode 100644 src/utils/pki_mem.c create mode 100644 src/utils/pki_threads.c create mode 100644 src/utils/pki_threads_vars.c create mode 100644 src/utils/pki_x509_mem.c create mode 100644 src/utils/pki_x509_mime.c create mode 100644 src/utils/profile.c create mode 100644 src/utils/stack.c create mode 100644 src/utils/support.c create mode 100644 src/x509/extensions.c diff --git a/include/libpki/crypto/composite/composite_ctx.h b/include/libpki/crypto/composite/composite_ctx.h new file mode 100644 index 00000000..864c3d42 --- /dev/null +++ b/include/libpki/crypto/composite/composite_ctx.h @@ -0,0 +1,224 @@ +/* BEGIN: composite_local.h */ + +// Composite Crypto authentication methods. +// (c) 2021 by Massimiliano Pala + +#ifndef _LIBPKI_COMPOSITE_CTX_H +#define _LIBPKI_COMPOSITE_CTX_H + +#ifndef _LIBPKI_COMPOSITE_TYPES_H +#include +#endif + +#ifndef _LIBPKI_OID_DEFS_H +#include +#endif + +#ifndef _LIBPKI_COMPAT_H +#include +#endif + +#ifndef _LIBPKI_LOG_H +#include +#endif + +#ifndef _LIBPKI_ERRORS_H +#include +#endif + +#ifndef _LIBPKI_KEYPAIR_H +#include +#endif + +BEGIN_C_DECLS + +// ==================== +// Functions Prototypes +// ==================== + +// COMPOSITE_CTX: Utility Functions +// -------------------------------- + +/*! \brief Allocates a new Composite CTX */ +COMPOSITE_CTX * COMPOSITE_CTX_new_null(); + +/*! + * @brief Allocates a new Composite CTX and sets the default digest + * + * This function allocates a new Composite CTX and sets the default + * digest algorithm to be used when no digest is specified for the + * composite operation and one or more components require a digest. + * + * @param alg The digest algorithm to be used as default + * @retval The new Composite CTX or NULL in case of errors + */ +COMPOSITE_CTX * COMPOSITE_CTX_new(const PKI_DIGEST_ALG * md); + +/*! \brief Frees the memory associated with a Composite CTX */ +void COMPOSITE_CTX_free(COMPOSITE_CTX * ctx); + +/*! \brief Sets the MD for the Composite CTX */ +int COMPOSITE_CTX_set_md(COMPOSITE_CTX * ctx, const PKI_DIGEST_ALG * md); + +/*! \brief Returns the MD set for the CTX */ +const EVP_MD * COMPOSITE_CTX_get_md(COMPOSITE_CTX * ctx); + +/*! \brief Sets the default MD for the Generic Composite with no hash-n-sign */ +int COMPOSITE_CTX_set_default_md(COMPOSITE_CTX * ctx, const EVP_MD * md); + +/*! \brief Returns the default MD that is used in Generic Composite with no hash-n-sign */ +const EVP_MD * COMPOSITE_CTX_get_default_md(COMPOSITE_CTX * ctx); + +/*! \brief Adds a new key to the CTX for Key Generation Ops */ +int COMPOSITE_CTX_pkey_push(COMPOSITE_CTX * comp_ctx, + PKI_X509_KEYPAIR_VALUE * pkey); + +/*! \brief Removes and returns an entry from the stack of Keys */ +int COMPOSITE_CTX_pkey_pop(COMPOSITE_CTX * ctx, + PKI_X509_KEYPAIR_VALUE ** pkey, + const PKI_DIGEST_ALG ** md); + +/*! \brief Clears the stack of keys in the Composite CTX */ +int COMPOSITE_CTX_pkey_clear(COMPOSITE_CTX * ctx); + +/*! \brief Returns a reference to the stack of keys from the CTX */ +int COMPOSITE_CTX_components_get0(const COMPOSITE_CTX * const ctx, + const COMPOSITE_KEY_STACK ** const components); + +/*! \brief Sets the MD for the Composite CTX */ +int COMPOSITE_CTX_components_set0(COMPOSITE_CTX * ctx, + COMPOSITE_KEY_STACK * const components); + +/*! \brief Detaches the components from the CTX */ +int COMPOSITE_CTX_components_detach(COMPOSITE_CTX * ctx, + COMPOSITE_KEY_STACK ** const components); + +/*! \brief Generates and returns the list of signature algorithms + * + * This function generates the list of signature algorithms for the + * set of configured keys inside the context. + * + * For each key in the components stack, the algorithm is selected + * by the following criteria: + * - If the key is an explicit composite, the algorithm selection is + * determined by the signature OID itself that must match the key + * type (OID). + * - If the key is a generic composite, the algorithm selection is + * determined by looking at the presence of the ctx->md algorithm + * that indicates the use of has-n-sign (all algorithms will use + * the same digest). If the ctx->md is not set, then the default + * algorithm (ctx->default_md) is used when the algorithm does not + * support direct signing. + * + * The ownership of the returned structure is not transferred to + * the caller, so the caller should not free it. + * + * @param ctx The Composite CTX to use for signing operation + * @param algors The return pointer that references the internal structure + * @retval Returns PKI_OK on success, PKI_ERR on failure +*/ +int COMPOSITE_CTX_algors_new0(COMPOSITE_CTX * ctx, + const int pkey_type, + const ASN1_ITEM * asn1_type, + const COMPOSITE_KEY_STACK * const components, + X509_ALGORS ** algors); + +/*! \brief Generates and returns the list of explicit algorithms + * + * This function generates the list of signature algorithms for the + * set of configured keys inside the context. + * + * For each key in the components stack, the algorithm is selected + * by looking at the pkey_type (same ID for Keys and Signatures). + * + * The ownership of the returned structure is not transferred to + * the caller, so the caller should not free it. + * + * @param ctx The Composite CTX to use for signing operation + * @param algors The return pointer that references the internal structure + * @retval Returns PKI_OK on success, PKI_ERR on failure +*/ +int COMPOSITE_CTX_explicit_algors_new0(COMPOSITE_CTX * ctx, + const int pkey_type, + const ASN1_ITEM * asn1_type, + const COMPOSITE_KEY_STACK * const components, + X509_ALGORS ** algors); + +/*! \brief Clears the list of signature algorithms */ +int COMPOSITE_CTX_algors_clear(COMPOSITE_CTX * const ctx); + +/*! + * @brief Returns a reference the list of signature algorithms + * + * This function returns a reference to the list of signature algorithms + * that are supported by the Composite CTX. The list is returned as a + * pointer to a X509_ALGORS structure. + * + * For each key in the components stack, the algorithm is selected + * by the following criteria: + * - If the key is an explicit composite, the algorithm selection is + * determined by the signature OID itself that must match the key + * type (OID). + * - If the key is a generic composite, the algorithm selection is + * determined by looking at the presence of the ctx->md algorithm + * that indicates the use of has-n-sign (all algorithms will use + * the same digest). If the ctx->md is not set, then the default + * algorithm (ctx->default_md) is used when the algorithm does not + * support direct signing. + * + * The ownership of the returned structure is transferred to the + * ctx, so the caller should not free it. + * + * @param ctx The Composite CTX to use for signing operation + * @param algors The pointer to the X509_ALGORS structure + * @return + */ +int COMPOSITE_CTX_algors_set0(COMPOSITE_CTX * const ctx, + X509_ALGORS * const algors); + +/*! + * @brief Returns a reference the list of signature algorithms + * + * This function returns a reference to the list of configured + * signature algorithms. The list is returned as a pointer to a + * X509_ALGORS structure. + * + * The ownership of the returned structure is not transferred to + * the ctx, so the caller should free it. + * + * @param ctx The Composite CTX to use for signing operation + * @param algors The return pointer to the internal structure + * @retval Returns PKI_OK on success, PKI_ERR on failure + */ +int COMPOSITE_CTX_algors_get0(const COMPOSITE_CTX * const ctx, + const X509_ALGORS ** const algors); + +/*! + * @brief Detaches the list of signature algorithms + * + * This function returns a reference to the list of configured + * signature algorithms and detaches it from the ctx. The list is + * returned as a pointer to a X509_ALGORS structure. + * + * The ownership of the returned structure is transferred to + * the ctx, so the caller should manage it (i.e., free it if + * it was allocated or simply discarded). + * + * @param ctx The Composite CTX to use for signing operation + * @param algors The return pointer to the internal structure + * @retval Returns PKI_OK on success, PKI_ERR on failure + */ +int COMPOSITE_CTX_algors_detach(COMPOSITE_CTX * const ctx, + X509_ALGORS ** const algors); + +/*! \brief Sets the K-of-N for the Composite CTX */ +int COMPOSITE_CTX_set_kofn(COMPOSITE_CTX * ctx, int kofn); + +/*! \brief Returns the K-of-N set for the CTX */ +int COMPOSITE_CTX_get_kofn(COMPOSITE_CTX * ctx); + +END_C_DECLS + +#endif // End of _LIBPKI_COMPOSITE_CTX_H + +/* END: composite_ctx.h */ diff --git a/include/libpki/crypto/composite/composite_init.h b/include/libpki/crypto/composite/composite_init.h new file mode 100644 index 00000000..ae9c15cf --- /dev/null +++ b/include/libpki/crypto/composite/composite_init.h @@ -0,0 +1,25 @@ +/* OpenCA libpki package +* (c) 2000-2006 by Massimiliano Pala and OpenCA Group +* All Rights Reserved +* +* =================================================================== +* Released under OpenCA LICENSE +*/ +#ifndef _LIBPKI_COMPOSITE_INIT_H +#define _LIBPKI_COMPOSITE_INIT_H + +#ifndef _LIBPKI_COMPAT_H +#include +#endif + +BEGIN_C_DECLS + +int PKI_COMPOSITE_init(); + +int PKI_EXPLICIT_COMPOSITE_init(); + +int PKI_COMPOSITE_PKEY_new(char * name, int flags); + +END_C_DECLS + +#endif // End of _LIBPKI_PQC_INIT_H \ No newline at end of file diff --git a/include/libpki/crypto/composite/composite_key.h b/include/libpki/crypto/composite/composite_key.h new file mode 100644 index 00000000..a13de16b --- /dev/null +++ b/include/libpki/crypto/composite/composite_key.h @@ -0,0 +1,294 @@ +/* BEGIN: composite_local.h */ + +// Composite Crypto authentication methods. +// (c) 2021 by Massimiliano Pala + +#ifndef _LIBPKI_COMPOSITE_KEY_H +#define _LIBPKI_COMPOSITE_KEY_H + +#ifndef _LIBPKI_OS_H +#include +#endif + +#ifndef _LIBPKI_COMPOSITE_TYPES_H +#include +#endif + +#ifndef _LIBPKI_OID_DEFS_H +#include +#endif + +#ifndef _LIBPKI_PKI_X509_H +#include +#endif + +#ifndef _LIBPKI_KEYPAIR_H +#include +#endif + +BEGIN_C_DECLS + +// ==================== +// Functions Prototypes +// ==================== + +// COMPOSITE_KEY: Stack Aliases +// ---------------------------- + +#define COMPOSITE_KEY_STACK_new() sk_EVP_PKEY_new_null() + // Allocates a new stack of EVP_PKEY + +#define COMPOSITE_KEY_STACK_free(p) PKI_STACK_free ((PKI_STACK *)p) + // Free a stack of EVP_PKEYs + +#define COMPOSITE_KEY_STACK_new_null() sk_EVP_PKEY_new_null() + // Allocates a new stack of EVP_PKEY + +#define COMPOSITE_KEY_STACK_push(key, val) sk_EVP_PKEY_push(key, val) + // Pushes a new EVP_PKEY to the key + +#define COMPOSITE_KEY_STACK_pop(key) sk_EVP_PKEY_pop(key) + // Removes the last EVP_PKEY from the key + +#define COMPOSITE_KEY_STACK_pop_free(key) sk_EVP_PKEY_pop_free(key, EVP_PKEY_free) + // Removes all the elements of the sk and sk itself + +#define COMPOSITE_KEY_STACK_num(key) sk_EVP_PKEY_num(key) + // Gets the number of components of a key + +#define COMPOSITE_KEY_STACK_value(key, num) sk_EVP_PKEY_value(key, num) + // Returns the num-th EVP_PKEY in the stack + +#define COMPOSITE_KEY_STACK_add(key, value, num) sk_EVP_PKEY_insert(key, value, num) + // Adds a component at num-th position + +#define COMPOSITE_KEY_STACK_del(key, num) EVP_PKEY_free(sk_EVP_PKEY_delete(key, num)) + // Deletes the num-th component from the key + +#define COMPOSITE_KEY_STACK_get0(key, num) sk_EVP_PKEY_value(key, num) + // Alias for the COMPOSITE_KEY_num() define + +#define COMPOSITE_KEY_STACK_dup(key) sk_EVP_PKEY_deep_copy(key, EVP_PKEY_dup, EVP_PKEY_free) + // Duplicates (deep copy) the key + +/// @brief Free all the entries, but not the stack structure itself +/// @brief Pops and free all components from the stack +/// @param key The stack to empty +void COMPOSITE_KEY_STACK_clear(COMPOSITE_KEY_STACK * sk); + +// COMPOSITE_MD: Stack Aliases +// ---------------------------- + +#define COMPOSITE_MD_STACK_new() sk_EVP_MD_new_null() + // Allocates a new stack of EVP_PKEY + +#define COMPOSITE_MD_STACK_free(p) PKI_STACK_free ((PKI_STACK *)p) + // Free a stack of EVP_PKEYs + +#define COMPOSITE_MD_STACK_new_null() sk_EVP_MD_new_null() + // Allocates a new stack of EVP_PKEY + +#define COMPOSITE_MD_STACK_push(key, val) sk_EVP_MD_push(key, val) + // Pushes a new EVP_PKEY to the key + +#define COMPOSITE_MD_STACK_pop(key) sk_EVP_MD_pop(key) + // Removes the last EVP_PKEY from the key + +#define COMPOSITE_MD_STACK_num(key) sk_EVP_MD_num(key) + // Gets the number of components of a key + +#define COMPOSITE_MD_STACK_value(key, num) sk_EVP_MD_value(key, num) + // Returns the num-th EVP_PKEY in the stack + +#define COMPOSITE_MD_STACK_add(key, value, num) sk_EVP_MD_insert(key, value, num) + // Adds a component at num-th position + +#define COMPOSITE_MD_STACK_del(key, num) sk_EVP_MD_delete(key, num) + // Deletes the num-th component from the key + +#define COMPOSITE_MD_STACK_get0(key, num) sk_EVP_MD_value(key, num) + // Alias for the COMPOSITE_KEY_num() define + +#define COMPOSITE_MD_STACK_dup(key) sk_EVP_MD_dup(key) + // Duplicates (deep copy) the key + +//! @brief Free all the entries, but not the stack structure itself +//! @brief Pops and free all components from the stack +//! @param key The stack to empty +void COMPOSITE_MD_STACK_clear(COMPOSITE_MD_STACK * sk); + +//! @brief Free all the entries together with the stack structure itself +//! @param key The stack to empty +void COMPOSITE_MD_STACK_pop_free(COMPOSITE_MD_STACK * sk); + +// COMPOSITE_KEY: Allocation and management functions +// -------------------------------------------------- + +/*! + * \brief Allocates a new Composite Key + */ +COMPOSITE_KEY * COMPOSITE_KEY_new(void); + +/*! + * @brief Free the memory associated with the composite key itself +*/ +void COMPOSITE_KEY_free(COMPOSITE_KEY * key); + +/*! + * \brief Adds a new key component at the end of the list + * + * @param key The Composite key to add the component to + * @param val The PKI_X509_KEYPAIR_VALUE component to add + * @retval Returns '1' if successful and '0' otherwise + */ +int COMPOSITE_KEY_push(COMPOSITE_KEY * key, PKI_X509_KEYPAIR_VALUE * val); + +/*! + * \brief Removes the last component from the COMPOSITE_KEY + * + * @param key The Composite key to remove the component from + * @retval The pointer to the removed PKI_X509_KEYPAIR_VALUE + * or NULL otherwise +*/ +PKI_X509_KEYPAIR_VALUE * COMPOSITE_KEY_pop(COMPOSITE_KEY * key); + +/*! + * \brief Removes and free the memory of all components from the key + * + * @param key The Composite key to remove the components from + * @retval This function does not return a value + */ +void COMPOSITE_KEY_pop_free(COMPOSITE_KEY * key); + +/*! + * \brief Returns the number of components + * + * @param key The COMPOSITE_KEY to count the element of + * @retval The number of components in the key +*/ +int COMPOSITE_KEY_num(COMPOSITE_KEY * key); + +/*! + * \brief Returns the num-th key component + * + * This function returns the pointer to the num-th component of + * the key. The ownership of the component is retained by the + * key, thus the caller must not free the retrieved component. + * + * @param key The COMPOSITE_KEY to retrieve the component from + * @param num The number of the component to retrieve + * @retval The pointer to the num-th entry +*/ +PKI_X509_KEYPAIR_VALUE * COMPOSITE_KEY_value(COMPOSITE_KEY * key, + int num); + +/*! + * \brief Adds a component at num-th position + * + * @param key The COMPOSITE_KEY_to add the component to + * @param value The PKI_X509_KEYPAIR_VALUE to add + * @param num The position where to insert the component + * @retval The function returns PKI_OK if successful and PKI_ERR + * otherwise. + */ +int COMPOSITE_KEY_add(COMPOSITE_KEY * key, + PKI_X509_KEYPAIR_VALUE * value, + int num); + +/*! + * \brief Deletes the num-th component from the key + * + * @param key The COMPOSITE_KEY_to delete the component from + * @param num The num-th of the component to delete + * @retval The function returns PKI_OK if successful and PKI_ERR otherwise. + */ +int COMPOSITE_KEY_del(COMPOSITE_KEY * key, int num); + +/*! + * \brief Deletes all components of a COMPOSITE_KEY + * + * @param key The COMPOSITE_KEY_to delete the components from + * @retval The function returns PKI_OK if successful and PKI_ERR otherwise. + */ +int COMPOSITE_KEY_clear(COMPOSITE_KEY *key); + +/*! \brief Alias for @COMPOSITE_KEY_num() function */ +#define COMPOSITE_KEY_get0(key, num) COMPOSITE_KEY_value(key, num) + +/*! + * \brief Duplicates a COMPOSITE_KEY structure + * + * @param key The COMPOSITE_KEY to duplicate + * @retval The duplicated key or NULL in case of errors + */ +COMPOSITE_KEY * COMPOSITE_KEY_dup(const COMPOSITE_KEY * const key); + +/*! + * \brief Returns the total size of the components + */ +int COMPOSITE_KEY_size(COMPOSITE_KEY * key); + +/*! + * \brief Returns the total size in bits of the components + * (does this even make sense ?) + */ +int COMPOSITE_KEY_bits(COMPOSITE_KEY * bits); + +/*! + * \brief Returns the estimated security bits + * + * Returns the security bits of the composite key + * which is the lowest (if the OR logic is implemented) + * or is the highest (if the AND logic is implemented) + * among the key components. + */ +int COMPOSITE_KEY_security_bits(COMPOSITE_KEY * sec_bits); + +/*! + * @brief Sets the signature validation policy (k-of-n) + * + * This function sets the k-of-n policy of the composite key. + * The policy is defined as the minimum number of components + * that must be validated in order to consider the signature + * valid. + * + * @param comp_key The COMPOSITE_KEY to set the policy to + * @param kofn The k-of-n policy to set + * @retval 1 if successful and 0 otherwise + */ +int COMPOSITE_KEY_set_kofn(COMPOSITE_KEY * comp_key, int kofn); + +/*! + * @brief Returns the signature validation policy (k-of-n) + * + * This function returns the k-of-n policy of the composite key. + * The policy is defined as the minimum number of components + * that must be validated in order to consider the signature + * valid. + * + * @param comp_key The COMPOSITE_KEY to retrieve the policy from + * @retval The k-of-n policy of the key (-1 if not set or set to 0) + */ +int COMPOSITE_KEY_get_kofn(COMPOSITE_KEY * comp_key); + +/*! + * @brief Returns PKI_OK if the signature validation policy is set (k-of-n) + * + * This function checks if the k-of-n policy of the composite key + * is set. The policy is defined as the minimum number of components + * that must be validated in order to consider the signature + * valid. + * + * @param comp_key The COMPOSITE_KEY to retrieve the policy from + * @retval PKI_OK if the policy is set and greater than 0, PKI_ERR otherwise + */ + +int COMPOSITE_KEY_has_kofn(COMPOSITE_KEY * comp_key); + +END_C_DECLS + +#endif + +/* END: composite_local.h */ + +// #endif // ENABLE_COMPOSITE \ No newline at end of file diff --git a/include/libpki/crypto/composite/composite_pmeth.h b/include/libpki/crypto/composite/composite_pmeth.h new file mode 100644 index 00000000..8d40f97f --- /dev/null +++ b/include/libpki/crypto/composite/composite_pmeth.h @@ -0,0 +1,66 @@ +/* BEGIN: composite_pmenth.h */ + +// Composite Crypto authentication methods. +// (c) 2021 by Massimiliano Pala +// +// This file contains the definitions for the EVP_PKEY_METHOD that implements: +// +// Composite Crypto (OR Logic) +// +// the corresponding functions are defined in composite_ameth.c + +#ifndef _LIBPKI_COMPOSITE_PKEY_METH_H +#define _LIBPKI_COMPOSITE_PKEY_METH_H + +#ifndef _LIBPKI_OS_H +#include +#endif + +#ifndef _LIBPKI_COMPOSITE_UTILS_H +#include +#endif + +#ifndef _LIBPKI_COMPOSITE_TYPES_H +#include +#endif + +#ifndef _LIBPKI_COMPOSITE_KEY_H +#include +#endif + +#ifndef _LIBPKI_COMPOSITE_CTX_H +#include +#endif + +#ifndef HEADER_ENVELOPE_H +#include +#endif + +#ifndef _LIBPKI_COMPAT_H +#include +#endif + +#ifndef HEADER_X509_H +#include +#endif + +#ifndef _STDIO_H_ +#include +#endif + +BEGIN_C_DECLS + +// =========================== +// Data Structures and Defines +// =========================== + +// ========================== +// EVP_PKEY_METHOD Prototypes +// ========================== + + +END_C_DECLS + +#endif // _LIBPKI_COMPOSITE_PKEY_METH_H + +/* END: composite_pmeth.h */ \ No newline at end of file diff --git a/include/libpki/crypto/composite/composite_types.h b/include/libpki/crypto/composite/composite_types.h new file mode 100644 index 00000000..067c444b --- /dev/null +++ b/include/libpki/crypto/composite/composite_types.h @@ -0,0 +1,125 @@ +/* BEGIN: composite_local.h */ + +// Composite Crypto authentication methods. +// (c) 2021 by Massimiliano Pala + +#ifndef _LIBPKI_CRYPTO_TYPES_H +#include +#endif + +#ifndef _LIBPKI_SYSTEM_H +#include +#endif + +#ifndef _LIBPKI_COMPOSITE_TYPES_H +#define _LIBPKI_COMPOSITE_TYPES_H + + +BEGIN_C_DECLS + +#ifdef ENABLE_COMPOSITE +# ifndef CRYPTO_NO_MLDSA_COMPOSITE +# ifndef CRYPTO_NO_MLDSA44_ECDSA +# define CRYPTO_MLDSA44_ECDSA_PKEY COMPOSITE_CRYPTO_KEY +# endif +# ifndef CRYPTO_NO_MLDSA44_ECDSA +# define CRYPTO_MLDSA44_ED25519_PKEY COMPOSITE_CRYPTO_KEY +# endif +# endif +#endif + +// ======================== +// Composite Crypto Support +// ======================== + +// Basic CTRL values for COMPOSITE support +# define EVP_PKEY_CTRL_COMPOSITE_PUSH 0x201 +# define EVP_PKEY_CTRL_COMPOSITE_POP 0x202 +# define EVP_PKEY_CTRL_COMPOSITE_ADD 0x203 +# define EVP_PKEY_CTRL_COMPOSITE_DEL 0x204 +# define EVP_PKEY_CTRL_COMPOSITE_CLEAR 0x205 + +// ============================== +// Declarations & Data Structures +// ============================== + +DEFINE_STACK_OF(EVP_PKEY); + // Provides the Definition for the stack of keys + +/*! \brief Stack of Composite Key Components (EVP_PKEY) */ +typedef STACK_OF(EVP_PKEY) COMPOSITE_KEY_STACK; + +/*! + * \brief Structure to hold the stack of key components + * and validation param (K of N) + */ +typedef struct _libpki_composite_key_st { + int algorithm; + COMPOSITE_KEY_STACK * components; + ASN1_INTEGER * params; +} COMPOSITE_KEY; + +/*! + * @brief Defines a stack of MDs + * @note This is used to define the MDs used for + * signature calculation + */ +DEFINE_STACK_OF_CONST(EVP_MD); +typedef STACK_OF(EVP_MD) COMPOSITE_MD_STACK; + +/*! + * @brief Defines a stack of PKEY contexts + */ +DEFINE_STACK_OF(EVP_PKEY_CTX); + +/*! + * @brief Defines a s tack of PKI_DIGEST_ALG contexts + */ +DEFINE_STACK_OF(EVP_MD_CTX); + + +/*! + * @brief Composite Key Context structure +*/ +typedef struct _libpki_composite_ctx { + + // MD for Hash-N-Sign + const EVP_MD * md; + + // Key Components for Key Generation + COMPOSITE_KEY_STACK * components; + + // Key Generation Parameters + ASN1_INTEGER * params; + + // Default hash for signature calculation + // in generic composite key operations when + // no-hash is used and the specific component + // does not support direct signing + const EVP_MD * default_md; + + // List of Algorithms that is used to pass + // the different X509_ALGOR to the individual + // components + X509_ALGORS * sig_algs; + + // ASN1 ITEM for signature parameters generations + const ASN1_ITEM * asn1_item; + +} COMPOSITE_CTX; + +// // Used to Concatenate the encodings of the different +// // components when encoding via the ASN1 meth (priv_encode) +// DEFINE_STACK_OF(ASN1_OCTET_STRING) + +// Used to Concatenate the encodings of the different +// components when encoding via the ASN1 meth (priv_encode) +DEFINE_STACK_OF(ASN1_BIT_STRING) + +END_C_DECLS + +#endif + +/* END: composite_local.h */ + +// #endif // ENABLE_COMPOSITE \ No newline at end of file diff --git a/include/libpki/crypto/composite/composite_utils.h b/include/libpki/crypto/composite/composite_utils.h new file mode 100644 index 00000000..ad658544 --- /dev/null +++ b/include/libpki/crypto/composite/composite_utils.h @@ -0,0 +1,46 @@ +/* BEGIN: composite_utils.h */ + +// Composite Crypto authentication methods. +// (c) 2021 by Massimiliano Pala + +#ifndef _LIBPKI_COMPOSITE_UTILS_H +#define _LIBPKI_COMPOSITE_UTILS_H + +#ifndef _LIBPKI_OS_H +#include +#endif + +#ifndef _LIBPKI_OID_DEFS_H +#include +#endif + +#ifndef _LIBPKI_PKI_X509_H +#include +#endif + +#ifndef _LIBPKI_KEYPAIR_H +#include +#endif + +BEGIN_C_DECLS + +// Declares the assign function, we can not use the +// define mechanism because the EVP_PKEY_COMPOSITE is +// not defined at compile time + +/// \brief Assigns a COMPOSITE key to the OpenSSL's PKEY +int EVP_PKEY_assign_COMPOSITE(EVP_PKEY *pkey, void *comp_key); + +/// \brief Sets the PKEY ID in a PKEY Method +int EVP_PKEY_meth_set_id(EVP_PKEY_METHOD * meth, int pkey_id, int flags); + +/// \brief Sets the PKEY ID in a ANS1 Method +int EVP_PKEY_asn1_meth_set_id(EVP_PKEY_ASN1_METHOD * pkey_ameth, int pkey_id); + +END_C_DECLS + +#endif + +/* END: composite_utils.h */ + +// #endif // ENABLE_COMPOSITE \ No newline at end of file diff --git a/include/libpki/crypto/crypto_keypair.h b/include/libpki/crypto/crypto_keypair.h new file mode 100644 index 00000000..fb9cdeff --- /dev/null +++ b/include/libpki/crypto/crypto_keypair.h @@ -0,0 +1,268 @@ +/* crypto_keypair.h */ + +#ifndef _LIBPKI_SYSTEM_H +#include +#endif + +#ifndef _LIBPKI_CRYPTO_TYPES_H +#include +#endif + +#ifndef _LIBPKI_CRYPTO_KEYPAIR_H +#define _LIBPKI_CRYPTO_KEYPAIR_H + +int CRYPTO_KEYPAIR_new(CRYPTO_KEYPAIR ** out, + HSM * hsm); + +void CRYPTO_KEYPAIR_free(CRYPTO_KEYPAIR *key); + +int CRYPTO_KEYPAIR_generate(CRYPTO_KEYPAIR *key, const CRYPTO_KEYPARAMS * params, char * label); + +int CRYPTO_KEYPAIR_clear(CRYPTO_KEYPAIR *key); + +int CRYPTO_KEYPAIR_get(unsigned char ** privkey, /* p8 */ + size_t * privkey_size, + unsigned char ** pubkey, /* pub bitstring */ + size_t * pubkey_size, + PKI_CRED * cred, + const CRYPTO_KEYPAIR * key); + +int CRYPTO_KEYPAIR_set(CRYPTO_KEYPAIR ** key, + const unsigned char * in, /* p8 */ + size_t size, + PKI_CRED * cred); + +CRYPTO_HASH CRYPTO_KEYPAIR_info(int * size, int * requires_hash, int * default_hash, + int * key_type, int * curve, int * bits, char * label, int * id, const CRYPTO_KEYPAIR * key); + + +// // CRYPTO_KEYPAIR *CRYPTO_KEYPAIR_new_kp(PKI_KEYPARAMS * kp, +// // PKI_CRED * cred, +// // char * label, +// // HSM * hsm); + +// // CRYPTO_KEYPAIR *CRYPTO_KEYPAIR_new_url(CRYPTO_TYPE type, +// // int bits, +// // URL * url, +// // PKI_CRED * cred, +// // HSM * hsm); + +// // CRYPTO_KEYPAIR *CRYPTO_KEYPAIR_new_url_kp(PKI_KEYPARAMS * kp, +// // URL * url, +// // PKI_CRED * cred, +// // HSM * hsm); + +// // /* ------------------------ General Functions ----------------------- */ + +// // char *CRYPTO_KEYPAIR_get_parsed(const CRYPTO_KEYPAIR *pkey ); + +// // CRYPTO_TYPE CRYPTO_KEYPAIR_get_scheme(const CRYPTO_KEYPAIR *k); + +// // void * CRYPTO_KEYPAIR_get_algor(const CRYPTO_KEYPAIR * k, +// // const PKI_DIGEST_ALG * digest); + +// // int CRYPTO_KEYPAIR_get_id(const CRYPTO_KEYPAIR * key); + +// // int CRYPTO_KEYPAIR_VALUE_get_id(const CRYPTO_KEYPAIR_VALUE * pkey); + +// // // /*! +// // // * \brief Returns the OSSL key type of the keypair +// // // * +// // // * This function returns the OSSL key type of the keypair. The +// // // * returned value can be used to compare with PKEY_METHOD backed +// // // * keys. +// // // * +// // // * @param pkey A pointer to the CRYPTO_KEYPAIR_VALUE data structure +// // // * @return The OSSL key type of the keypair (int) +// // // */ +// // // int CRYPTO_KEYPAIR_get_ossl_type(const CRYPTO_KEYPAIR * pkey); + +// // // /*! +// // // * @brief Returns the OSSL key type of the keypair value +// // // * +// // // * This function returns the OSSL key type of the keypair value. The +// // // * returned value can be used to compare with PKEY_METHOD backed +// // // * keys (e.g., type == EVP_PKEY_RSA) +// // // * +// // // * @param pkey A pointer to the CRYPTO_KEYPAIR_VALUE data structure +// // // * @return The OSSL key type of the keypair value (int) +// // // */ +// // // int CRYPTO_KEYPAIR_VALUE_get_ossl_type(const CRYPTO_KEYPAIR_VALUE * pkey); + +// /// @brief Returns the ID of the default digest algorithm for a CRYPTO_KEYPAIR +// /// @param key A CRYPTO_KEYPAIR data structure +// /// @return The PKI_ID of the identified algorithm or PKI_ID_UNKNOWN +// int CRYPTO_KEYPAIR_get_default_digest(const CRYPTO_KEYPAIR * key); + +// /// @brief Returns the ID of the default digest algorithm for a CRYPTO_KEYPAIR_VALUE +// /// @param pkey A CRYPTO_KEYPAIR_VALUE data structure +// /// @return The PKI_ID of the identified algorithm or PKI_ID_UKNOWN +// int CRYPTO_KEYPAIR_VALUE_get_default_digest(const CRYPTO_KEYPAIR_VALUE * pkey); + +// /*! +// * @brief Checks if a kepair requires a digest algorithm for signing +// * @param k The CRYPTO_KEYPAIR data structure +// * @return PKI_OK if a digest is required, PKI_ERR otherwise +// */ +// int CRYPTO_KEYPAIR_requires_digest(const CRYPTO_KEYPAIR * k); + +// /*! +// * @brief Checks if a kepair requires a digest algorithm for signing +// * @param k The CRYPTO_KEYPAIR_VALUE data structure +// * @return PKI_OK if a digest is required, PKI_ERR otherwise +// */ +// int CRYPTO_KEYPAIR_VALUE_requires_digest(const CRYPTO_KEYPAIR_VALUE * pkey); + +// /// @brief Returns PKI_OK if the digest algorithm is supported by the Public Key +// /// @param k A pointer to the CRYPTO_KEYPAIR data structure +// /// @param digest A pointer to te PKI_DIGEST_ALG +// /// @return The PKI_OK value if the digest is supported, PKI_ERR otherwise +// int CRYPTO_KEYPAIR_is_digest_supported(const CRYPTO_KEYPAIR * k, const PKI_DIGEST_ALG * digest); + +// /// @brief Returns if the passed digest is supported by the Public Key +// /// @param k A pointer to the CRYPTO_KEYPAIR_VALUE data structure +// /// @param digest A pointer to te PKI_DIGEST_ALG +// /// @return The PKI_OK value if the digest is supported, PKI_ERR otherwise +// int CRYPTO_KEYPAIR_VALUE_is_digest_supported(const CRYPTO_KEYPAIR_VALUE * pkey, const PKI_DIGEST_ALG * digest); + +// int CRYPTO_KEYPAIR_get_size(const CRYPTO_KEYPAIR *k); + +// PKI_MEM *CRYPTO_KEYPAIR_get_pubkey(const CRYPTO_KEYPAIR *kp); + +// PKI_MEM *CRYPTO_KEYPAIR_get_privkey(const CRYPTO_KEYPAIR *kp); + +// CRYPTO_DIGEST *CRYPTO_KEYPAIR_VALUE_pub_digest(const CRYPTO_KEYPAIR_VALUE * pkey, +// const PKI_DIGEST_ALG * md ); + +// CRYPTO_TYPE CRYPTO_KEYPAIR_VALUE_get_scheme(const CRYPTO_KEYPAIR_VALUE *pVal); + +// PKI_X509_ALGOR_VALUE * CRYPTO_KEYPAIR_VALUE_get_algor (const CRYPTO_KEYPAIR_VALUE * pVal, +// const PKI_ID digest_id); + +// int CRYPTO_KEYPAIR_VALUE_get_size (const CRYPTO_KEYPAIR_VALUE *pKey ); + +// CRYPTO_DIGEST *CRYPTO_KEYPAIR_pub_digest (const CRYPTO_KEYPAIR * pkey, +// const PKI_DIGEST_ALG * md); + +// /* ------------------------ EC Specific ------------------------------ */ + +// /*! +// * \brief Returns the PKI_ID of the EC curve of the Key (EC keys only) +// */ +// int CRYPTO_KEYPAIR_get_curve(const CRYPTO_KEYPAIR *kp); + +// /* ----------------------- PKCS#8 Format ----------------------------- */ + +// PKI_MEM *CRYPTO_KEYPAIR_VALUE_get_p8 (const CRYPTO_KEYPAIR_VALUE * pkey ); + +// PKI_MEM *CRYPTO_KEYPAIR_get_p8(const CRYPTO_KEYPAIR *key ); + +// CRYPTO_KEYPAIR_VALUE *CRYPTO_KEYPAIR_VALUE_new_p8(const PKI_MEM *buf ); + +// CRYPTO_KEYPAIR *CRYPTO_KEYPAIR_new_p8(const PKI_MEM *buf ); + +// /* --------------------- PKEY Encrypt/Decrypt --------------------------- */ + +// /*! @brief This function encrypts the input data under a keypair and a padding scheme. +// * +// * @param pVal is the CRYPTO_KEYPAIR_VALUE that will be used for encryption +// * @param data is the pointer to the input data +// * @param data_len is the size of the input data +// * @param pad is the padding scheme to use (def. OAEP) +// * @return A pointer to a PKI_MEM structure that contains the encrypted data. +// */ +// PKI_MEM * CRYPTO_KEYPAIR_VALUE_encrypt(const CRYPTO_KEYPAIR_VALUE * pVal, +// const unsigned char * const data, +// size_t const data_len, +// int const flags); + +// /*! @brief This function encrypts the input data under a keypair and a padding scheme. +// * +// * @param pVal is the CRYPTO_KEYPAIR that will be used for encryption +// * @param data is the pointer to the input data +// * @param data_len is the size of the input data +// * @param pad is the padding scheme to use (def. OAEP) +// * @return A pointer to a PKI_MEM structure that contains the encrypted data. +// */ +// PKI_MEM * CRYPTO_KEYPAIR_encrypt(const CRYPTO_KEYPAIR * keypair, +// const unsigned char * const data, +// size_t const data_len, +// int const flags); + +// /*! @brief This function decrypts the input data via a keypair and a padding scheme. +// * +// * @param pVal is the CRYPTO_KEYPAIR_VALUE that was used to encrypt the data +// * @param data is the pointer to the encrypted data +// * @param data_len is the length of the encrypted data (bytes) +// * @param padding is the selected padding mode (def. OAEP) +// * @return a pointer to a PKI_MEM that contains the decrypted data. +// */ +// PKI_MEM * CRYPTO_KEYPAIR_VALUE_decrypt(const CRYPTO_KEYPAIR_VALUE * pVal, +// const unsigned char * const data, +// size_t const data_len, +// int const flags); + +// /*! @brief This function decrypts the input data via a keypair and a padding scheme. +// * +// * @param pVal is the CRYPTO_KEYPAIR that was used to encrypt the data +// * @param data is the pointer to the encrypted data +// * @param data_len is the length of the encrypted data (bytes) +// * @param padding is the selected padding mode (def. OAEP) +// * @return a pointer to a PKI_MEM that contains the decrypted data. +// */ +// PKI_MEM * CRYPTO_KEYPAIR_decrypt(const CRYPTO_KEYPAIR * keypair, +// const unsigned char * const data, +// size_t const data_len, +// int const flags); + +// /*! \brief Exports a raw public key value into a PKI_MEM +// * +// * This function returns the internal structure of a public key in +// * its DER representation from a CRYPTO_KEYPAIR data structure. +// * For example, for RSA keys this function exports the following +// * data: +// * +// * rsaKey := SEQUENCE { +// * modulus INTEGER, +// * publicExponent INTEGER } +// * +// * in DER format in the output buffer. If the @pki_mem parameter +// * or the deferred pointer (@*pki_mem) are NULL, a new PKI_MEM +// * structure will be allocated and returned. In case the *pki_mem +// * is not NULL, the passed PKI_MEM structure will be used (if +// * any data is present it will be first freed with PKI_Free). +// * The function returns NULL in case of errors. +// * +// * @param k_val The pointer to the CRYPTO_KEYPAIR to use +// * @param pki_mem The output structure where to store the data +// * @retval A pointer to the PKI_MEM with the retrieved data. +// */ +// PKI_MEM *CRYPTO_KEYPAIR_get_public_bitstring(const CRYPTO_KEYPAIR * const k_val, +// PKI_MEM ** pki_mem); + +// /*! \brief Exports a raw public key value into a PKI_MEM +// * +// * This function returns the internal structure of a public key in +// * its DER representation from a CRYPTO_KEYPAIR_VALUE pointer. +// * For example, for RSA keys this function exports the following +// * data: +// * +// * rsaKey := SEQUENCE { +// * modulus INTEGER, +// * publicExponent INTEGER } +// * +// * in DER format in the output buffer. If the @pki_mem parameter +// * or the deferred pointer (@*pki_mem) are NULL, a new PKI_MEM +// * structure will be allocated and returned. In case the *pki_mem +// * is not NULL, the passed PKI_MEM structure will be used (if +// * any data is present it will be first freed with PKI_Free). +// * The function returns NULL in case of errors. +// * +// * @param k_val The pointer to the CRYPTO_KEYPAIR_VALUE to use +// * @param pki_mem The output structure where to store the data +// * @retval A pointer to the PKI_MEM with the retrieved data. +// */ +// PKI_MEM *CRYPTO_KEYPAIR_VALUE_get_public_bitstring(const CRYPTO_KEYPAIR_VALUE * const k_val, +// PKI_MEM ** pki_mem); + +#endif diff --git a/include/libpki/crypto/crypto_keyparams.h b/include/libpki/crypto/crypto_keyparams.h new file mode 100644 index 00000000..068343d5 --- /dev/null +++ b/include/libpki/crypto/crypto_keyparams.h @@ -0,0 +1,118 @@ +/* openssl/CRYPTO_KEYPARAMS.c */ + +#ifndef _LIBPKI_CRYPTO_TYPES_H +#include +#endif + +#ifndef _LIBPKI_UTILS_TYPES_H +#include +#endif + + +#ifndef _LIBPKI_CRYPTO_KEYPARAMS_H +#define _LIBPKI_CRYPTO_KEYPARAMS_H + + +/*! \brief Allocates a new CRYPTO_KEYPARAMS structure + * + * This function allocates a new CRYPTO_KEYPARAMS structure and returns a pointer + * to it. The scheme parameter is used to specify the scheme of the CRYPTO_KEYPARAMS + * object to be created. If the scheme is not supported, the function will return + * NULL. + * + * @param scheme The scheme of the CRYPTO_KEYPARAMS object to be created + * @param conf The PKI_CONFIG object to be used with the CRYPTO_KEYPARAMS object + * @return A pointer to the newly created CRYPTO_KEYPARAMS object + */ +CRYPTO_KEYPARAMS *CRYPTO_KEYPARAMS_new(CRYPTO_TYPE algor, const PKI_CONFIG *conf); + +/*! \breif Frees the CRYPTO_KEYPARAMS structure + * + * This function frees the CRYPTO_KEYPARAMS structure and all of its associated + * memory. + * + * @param kp A pointer to the CRYPTO_KEYPARAMS structure to be freed + */ +void CRYPTO_KEYPARAMS_free(CRYPTO_KEYPARAMS *params); + +/*! \brief Returns the type of the CRYPTO_KEYPARAMS structure + * + * This function returns the type of the CRYPTO_KEYPARAMS structure. + * + * @param kp The CRYPTO_KEYPARAMS structure + * @return The type of the CRYPTO_KEYPARAMS structure + */ +CRYPTO_TYPE CRYPTO_KEYPARAMS_type(const CRYPTO_KEYPARAMS * params); + + +/*! + * @brief Sets the scheme and security bits in the CRYPTO_KEYPARAMS structure + * + * This function sets the scheme and security bits in the CRYPTO_KEYPARAMS + * structure. If the scheme is not supported, the function will return + * PKI_ERR. + * + * @param kp The CRYPTO_KEYPARAMS structure to set + * @param scheme_id The requested scheme to set in the structure + * @param sec_bits The requested security bits + * @retval PKI_OK on success, PKI_ERR on failure + */ +int CRYPTO_KEYPARAMS_set_type(CRYPTO_KEYPARAMS * params, CRYPTO_TYPE algor); + +/*! + * @brief Sets the size (in bits) for the RSA key type + * + * This function sets the size (in bits) for the RSA key type in the + * CRYPTO_KEYPARAMS structure. + * + * @param kp The CRYPTO_KEYPARAMS structure to set + * @param bits The size (in bits) to set + * @retval PKI_OK on success, PKI_ERR on failure + * @see CRYPTO_KEYPARAMS + */ +int CRYPTO_KEYPARAMS_RSA_set(CRYPTO_KEYPARAMS * kp, int bits); + +/*! \brief Sets the parameters for the EC key type + * + * This function sets the parameters for the EC key type in the CRYPTO_KEYPARAMS + * structure. The curveName parameter is used to specify the curve to be used. + * The curveForm parameter is used to specify the form of the curve. The ans1flags + * parameter is used to specify the flags to be used. + * + * @param kp The CRYPTO_KEYPARAMS structure to set + * @param curveName The name of the curve to set + * @param curveForm The form of the curve to set + * @param ans1flags The flags to set + * @retval PKI_OK on success, PKI_ERR on failure + * @see CRYPTO_KEYPARAMS + */ +int CRYPTO_KEYPARAMS_ECDSA_set(CRYPTO_KEYPARAMS * kp, + const char * curveName, + CRYPTO_EC_FORM curveForm, + int ans1flags); + +// ======================== +// Composite Crypto Support +// ======================== + +#ifdef ENABLE_COMPOSITE + +/*! \brief Adds a key to the list of keys for Composite keys */ +int CRYPTO_KEYPARAMS_add_key(CRYPTO_KEYPARAMS * kp, PKI_X509_KEYPAIR * key); + +/*! \brief Sets the k_of_n parameter for Composite keys */ +int CRYPTO_KEYPARAMS_set_kofn(CRYPTO_KEYPARAMS * kp, int kofn); + +#endif // End of ENABLE_COMPOSITE + +// ========================= +// Open Quantum Safe Support +// ========================= + +#if defined(ENABLE_OQS) || defined(ENABLE_OQSPROV) + +int CRYPTO_KEYPARAMS_MLDSA_set(CRYPTO_KEYPARAMS * params, PKI_ALGOR_OQS_PARAM algParam); + +#endif // End of ENABLE_OQS + +#endif // _LIBPKI_CRYPTO_KEYPARAMS_H diff --git a/include/libpki/crypto/crypto_operations.h b/include/libpki/crypto/crypto_operations.h new file mode 100644 index 00000000..a526d29e --- /dev/null +++ b/include/libpki/crypto/crypto_operations.h @@ -0,0 +1,44 @@ +/* pki_keypair.h */ + +#ifndef _LIBPKI_SYSTEM_H +#include +#endif + +#ifndef _LIBPKI_CRYPTO_TYPES_H +#include +#endif + +#ifndef _LIBPKI_CRYPTO_OPERATIONS_H +#define _LIBPKI_CRYPTO_OPERATIONS_H + +int CRYPTO_sign(unsigned char ** sig, + size_t * sig_len, + const unsigned char * data, + size_t data_len, + const CRYPTO_HASH * digest, + const CRYPTO_KEYPAIR * key); + +int CRYPTO_verify(const unsigned char * sig, + size_t sig_len, + const unsigned char * data, + size_t data_len, + const CRYPTO_HASH * digest, + const CRYPTO_KEYPAIR * key); + +/*! @brief This function encrypts the input data under a keypair and a padding scheme. + * + * @param pVal is the CRYPTO_KEYPAIR_VALUE that will be used for encryption + * @param data is the pointer to the input data + * @param data_len is the size of the input data + * @param pad is the padding scheme to use (def. OAEP) + * @return A pointer to a PKI_MEM structure that contains the encrypted data. + */ +int CRYPTO_encrypt(const unsigned char ** enc_data, + size_t const enc_data_size, + const unsigned char * const data, + size_t const data_len, + int const flags, + const CRYPTO_KEYPAIR * keypair); + + +#endif diff --git a/include/libpki/crypto/crypto_utils.h b/include/libpki/crypto/crypto_utils.h new file mode 100644 index 00000000..e8259ff3 --- /dev/null +++ b/include/libpki/crypto/crypto_utils.h @@ -0,0 +1,117 @@ +/* libpki/pki_algor.h */ + +#ifndef _LIBPKI_OS_H +#include +#endif + +#ifndef _LIBPKI_CRYPTO_TYPES_H +#include +#endif + +#ifndef _LIBPKI_CRYPTO_UTILS_H +#define _LIBPKI_CRYPTO_UTILS_H + +/*! + * @brief Returns an array of random bytes + * @param buf The buffer to store the random bytes + * @param num The size of the buffer + * @return PKI_OK if the operation was successful, PKI_ERR otherwise + */ +int CRYPTO_RAND(unsigned char **buf, size_t size); + +/*! \brief Digests the data using the specified algorithm + * + * This function digests the data using the specified algorithm and returns the + * digest in the out parameter. The out_size parameter is used to store the size + * of the digest. The algorithm parameter is used to specify the algorithm to be + * used. The data parameter is used to specify the data to be digested. The size + * parameter is used to specify the size of the data. The salt parameter is used + * to specify the salt to be used with the data. The salt_size parameter is used + * to specify the size of the salt. The pepper parameter is used to specify the + * pepper to be used with the data. The pepper_size parameter is used to specify + * the size of the pepper. + * + * @param out The digest + * @param out_size The size of the digest + * @param algorithm The algorithm to be used + * @param data The data to be digested + * @param size The size of the data + * @param salt The salt to be used or NULL + * @param salt_size The size of the salt + * @param pepper The pepper to be used or NULL + * @param pepper_size The size of the pepper + * @param hsm The HSM to be used or NULL + * @return PKI_OK if successful, PKI_ERR otherwise + * @see CRYPTO_HASH + */ +int CRYPTO_DIGEST(unsigned char **out, size_t *out_size, + CRYPTO_TYPE algorithm, const unsigned char *data, size_t size, + const unsigned char * salt, size_t salt_size, + const unsigned char * pepper, size_t pepper_size, HSM * hsm); + +/*! \brief Signs the data using the specified HMAC algorithm and key + * + * This function signs the data using the specified HMAC algorithm and key and + * returns the signature in the out parameter. The out_size parameter is used to + * store the size of the signature. The hmac_algo parameter is used to specify + * the HMAC algorithm to be used. The key parameter is used to specify the key to + * be used with the HMAC algorithm. The key_size parameter is used to specify the + * size of the key. The data parameter is used to specify the data to be signed. + * The size parameter is used to specify the size of the data. The hash_algo + * parameter is used to specify the hash algorithm to be used with the HMAC + * algorithm. The hsm parameter is used to specify the HSM to be used. + * + * @param out The signature + * @param out_size The size of the signature + * @param hmac_algo The HMAC algorithm to be used + * @param key The key to be used + * @param key_size The size of the key + * @param data The data to be signed + * @param size The size of the data + * @param hash_algo The hash algorithm to be used + * @param hsm The HSM to be used + * @return PKI_OK if successful, PKI_ERR otherwise + * @see CRYPTO_HASH + * @see CRYPTO_DIGEST + */ +int CRYPTO_HMAC(unsigned char **out, size_t *out_size, + CRYPTO_TYPE hmac_algo, unsigned char *key, size_t key_size, + const unsigned char *data, size_t size, + CRYPTO_HASH hash_algo, HSM *hsm); + +/*! \brief Derives a symmetric key by using the specified algorithm + * + * This function derives a symmetric key by using the specified algorithm and + * returns the key in the out parameter. The out_size parameter is used to store + * the size of the key. The algorithm parameter is used to specify the algorithm + * to be used. The label parameter is used to specify the label to be used with + * the key. The label_size parameter is used to specify the size of the label. + * The key parameter is used to specify the key to be used with the label. The + * key_size parameter is used to specify the size of the key. The data parameter + * is used to specify the data to be used with the key. The data_size parameter + * is used to specify the size of the data. + * + * @param out The key + * @param out_size The size of the key + * @param algorithm The algorithm to be used + * @param label The label to be used + * @param label_size The size of the label + * @param key The key to be used + * @param key_size The size of the key + * @param data The data to be used + * @param data_size The size of the data + * @return PKI_OK if successful, PKI_ERR otherwise + * @see CRYPTO_HASH + */ +int CRYPTO_KDF(unsigned char ** out, + size_t * outlen, + unsigned char * label, + size_t labelen, + unsigned char * key, + size_t keylen, + unsigned char * data, + size_t datalen, + const CRYPTO_HASH hash_alg); + +#endif /* _LIBPKI_CRYPTO_UTILS_H */ + diff --git a/include/libpki/crypto/hsm/hsm.h b/include/libpki/crypto/hsm/hsm.h new file mode 100644 index 00000000..3ad5afc2 --- /dev/null +++ b/include/libpki/crypto/hsm/hsm.h @@ -0,0 +1,235 @@ +/* HSM API */ + +#ifndef _LIBPKI_HSM_TYPES_H +#include +#endif + +#ifndef _LIBPKI_CRYPTO_TYPES_H +#include +#endif + +#ifndef _LIBPKI_CRYPTO_HSM_H +#define _LIBPKI_CRYPTO_HSM_H + +/* ----------------------- HSM Management ---------------------------- */ + +HSM *HSM_new(const char * const dir, const char * const name ); + +HSM *HSM_new_fips(const char * const dir, const char * const name); + +const HSM *HSM_get_default( void ); + +int HSM_free ( HSM *hsm ); + +int HSM_init( HSM *hsm ); + +int HSM_init_fips (HSM *hsm); + +int HSM_set_fips_mode(const HSM *hsm, int k); + +int HSM_is_fips_mode(const HSM *hsm); + +/* ---------------------- Slot Management Functions ----------------------- */ + +unsigned long HSM_SLOT_num ( HSM *hsm ); +int HSM_SLOT_select(unsigned long num, PKI_CRED *cred, HSM *hsm ); +int HSM_SLOT_clear(unsigned long num, PKI_CRED *cred, HSM *hsm ); + +HSM_SLOT_INFO * HSM_SLOT_INFO_get ( unsigned long num, HSM *hsm ); +int HSM_SLOT_INFO_print( unsigned long num, PKI_CRED *cred, HSM *hsm ); +void HSM_SLOT_INFO_free ( HSM_SLOT_INFO *sl_info, HSM *hsm ); + +int HSM_SLOT_wrap(byte ** out, size_t * out_size, PKI_CRED *cred, void * driver_raw_key, HSM *hsm); +int HSM_SLOT_unwrap(void * driver_raw_key, byte * in, size_t * in_size, PKI_CRED *cred, HSM *hsm); + +int HSM_SLOT_keypair_del(void * driver_raw_key, HSM *hsm ); +int HSM_SLOT_keypair_new(CRYPTO_KEYPARAMS * params, HSM *hsm); + +int HSM_SLOT_objects_del(byte * label, PKI_CRED *cred, HSM *hsm); +int HSM_SLOT_objects_get(PKI_STACK ** sk, PKI_TYPE type, byte * label, PKI_TYPE format, HSM *hsm); + +/* -------------------- Login/Logout functions ----------------------- */ + +int HSM_login ( HSM *hsm, PKI_CRED *cred ); +int HSM_logout ( HSM *hsm ); + +unsigned long HSM_get_errno ( const HSM *hsm ); + +char *HSM_get_errdesc ( unsigned long err, const HSM *hsm ); + +/* ------------------ Signing Functions Prototypes ------------------- */ + +int HSM_sign(const unsigned char * data, + size_t data_sz, + unsigned char ** sig, + size_t * sig_sz, + void * driver_key, + HSM * hsm); + +int HSM_verify(const unsigned char * data, + size_t data_sz, + const unsigned char * sig, + size_t sig_sz, + void * driver_key, + HSM * hsm); + +int HSM_derive(const unsigned char * out, + size_t out_sz, + const unsigned char * sig, + size_t sig_sz, + void * driver_key, + HSM * hsm); + +int HSM_encrypt(const unsigned char * data, + size_t data_sz, + const unsigned char * sig, + size_t sig_sz, + void * driver_key, + HSM * hsm); + +int HSM_decrypt(const unsigned char * data, + size_t data_len, + const unsigned char * sig, + size_t sig_len, + void * driver_key, + HSM * hsm); + + +// // int PKI_X509_sign (PKI_X509 *x, +// // const PKI_DIGEST_ALG *alg, +// // const PKI_X509_KEYPAIR *key ); + +// // PKI_MEM *PKI_sign (const PKI_MEM *der, +// // const PKI_DIGEST_ALG *alg, +// // const PKI_X509_KEYPAIR *key ); + +// // int PKI_X509_verify(const PKI_X509 *x, +// // const PKI_X509_KEYPAIR *key ); + +// // int PKI_X509_verify_cert(const PKI_X509 *x, +// // const PKI_X509_CERT *cert ); + +// // int PKI_verify_signature(const PKI_MEM * data, +// // const PKI_MEM * sig, +// // const PKI_X509_ALGOR_VALUE * alg, +// // const ASN1_ITEM * it, +// // const PKI_X509_KEYPAIR * key ); + +// // // /* ------------------- PKI Object Retrieval ( Get ) ----------------------- */ + +// // // PKI_X509_STACK *HSM_X509_STACK_get_url ( PKI_DATATYPE type, URL *url, +// // // PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ); + +// // // /* --------------------- PKI Object Import ( Put ) ------------------------ */ + +// // // int HSM_X509_STACK_put_url ( PKI_X509_STACK *sk, URL *url, +// // // PKI_CRED *cred, HSM *hsm ); + +// // // int HSM_MEM_STACK_put_url ( PKI_MEM_STACK *sk, URL *url, PKI_DATATYPE type, +// // // PKI_CRED *cred, HSM *hsm ); + +// // // /* --------------------- PKI Object Delete ( Del ) ------------------------ */ + +// // // int HSM_X509_STACK_del ( PKI_X509_STACK *sk ); + +// // // int HSM_X509_del_url ( PKI_DATATYPE type, URL *url, PKI_CRED *cred, HSM *hsm ); + +// // // const PKI_X509_CALLBACKS * HSM_X509_get_cb ( PKI_DATATYPE type, HSM *hsm ); + +// #endif +// /* HSM Object Management Functions */ + +// /* ----------------------- HSM Management ---------------------------- */ + +// unsigned long HSM_get_errno ( const HSM *hsm ); +// char *HSM_get_errdesc ( unsigned long err, const HSM *hsm ); + +// const HSM *HSM_get_default( void ); + +// int HSM_free ( HSM *hsm ); + +// HSM *HSM_new(const char * const dir, const char * const name ); +// HSM *HSM_new_fips(const char * const dir, const char * const name); + +// int HSM_init( HSM *hsm ); +// int HSM_init_fips (HSM *hsm); + +// int HSM_is_fips_mode(const HSM *hsm); +// int HSM_set_fips_mode(const HSM *hsm, int k); + +// /* -------------------- Login/Logout functions ----------------------- */ + +// int HSM_login ( HSM *hsm, PKI_CRED *cred ); +// int HSM_logout ( HSM *hsm ); +// int HSM_set_sign_algor (PKI_X509_ALGOR_VALUE *alg, HSM *hsm ); + +// /* ------------------ Signing Functions Prototypes ------------------- */ + +// int PKI_X509_sign (PKI_X509 *x, +// const PKI_DIGEST_ALG *alg, +// const PKI_X509_KEYPAIR *key ); + +// PKI_MEM *PKI_sign (const PKI_MEM *der, +// const PKI_DIGEST_ALG *alg, +// const PKI_X509_KEYPAIR *key ); + +// int PKI_X509_verify(const PKI_X509 *x, +// const PKI_X509_KEYPAIR *key ); + +// int PKI_X509_verify_cert(const PKI_X509 *x, +// const PKI_X509_CERT *cert ); + +// int PKI_verify_signature(const PKI_MEM * data, +// const PKI_MEM * sig, +// const PKI_X509_ALGOR_VALUE * alg, +// const ASN1_ITEM * it, +// const PKI_X509_KEYPAIR * key ); + +// /* ------------------- PKI Object Retrieval ( Get ) ----------------------- */ + +// PKI_X509_STACK *HSM_X509_STACK_get_url ( PKI_DATATYPE type, URL *url, +// PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ); + +// /* --------------------- PKI Object Import ( Put ) ------------------------ */ + +// int HSM_X509_STACK_put_url ( PKI_X509_STACK *sk, URL *url, +// PKI_CRED *cred, HSM *hsm ); + +// int HSM_MEM_STACK_put_url ( PKI_MEM_STACK *sk, URL *url, PKI_DATATYPE type, +// PKI_CRED *cred, HSM *hsm ); + +// /* --------------------- PKI Object Delete ( Del ) ------------------------ */ + +// int HSM_X509_STACK_del ( PKI_X509_STACK *sk ); + +// int HSM_X509_del_url ( PKI_DATATYPE type, URL *url, PKI_CRED *cred, HSM *hsm ); + +// const PKI_X509_CALLBACKS * HSM_X509_get_cb ( PKI_DATATYPE type, HSM *hsm ); + +// /* ---------------------- Slot Management Functions ----------------------- */ + +// unsigned long HSM_SLOT_num ( HSM *hsm ); +// int HSM_SLOT_select ( unsigned long num, PKI_CRED *cred, HSM *hsm ); +// int HSM_SLOT_clear ( unsigned long num, PKI_CRED *cred, HSM *hsm ); + +// HSM_SLOT_INFO * HSM_SLOT_INFO_get ( unsigned long num, HSM *hsm ); +// int HSM_SLOT_INFO_print( unsigned long num, PKI_CRED *cred, HSM *hsm ); +// void HSM_SLOT_INFO_free ( HSM_SLOT_INFO *sl_info, HSM *hsm ); + +// /* -------------------- Key Management Functions --------------------- */ + +// /* Generate a new Keypair */ +// PKI_X509_KEYPAIR *HSM_X509_KEYPAIR_new( PKI_KEYPARAMS *params, char *label, +// PKI_CRED *cred, HSM *hsm ); + +// PKI_X509_KEYPAIR *HSM_X509_KEYPAIR_new_url( PKI_KEYPARAMS *params, URL *url, +// PKI_CRED *cred, HSM *driver ); + +// /* --------------------------- Wrap/Unwrap ---------------------------- */ + +// PKI_MEM *HSM_X509_KEYPAIR_wrap ( PKI_X509_KEYPAIR *key, PKI_CRED *cred ); + +// PKI_X509_KEYPAIR *HSM_X509_KEYPAIR_unwrap ( PKI_MEM *mem, +// URL *url, PKI_CRED *cred, HSM *hsm ); + +#endif /* _LIBPKI_CRYPTO_HSM_H */ diff --git a/include/libpki/crypto/hsm/openssl/Makefile.am b/include/libpki/crypto/hsm/openssl/Makefile.am new file mode 100644 index 00000000..7520b4fe --- /dev/null +++ b/include/libpki/crypto/hsm/openssl/Makefile.am @@ -0,0 +1,27 @@ +## OpenCA Makefile - by Massimiliano Pala +## (c) 1999-2009 by Massimiliano Pala and OpenCA Project +## All Rights Reserved + +TOP = ../.. +include $(TOP)/global-vars + +BASE_DEFS = + +DEFS = $(OPENCA_DEFS) + +AM_CPPFLAGS = -I$(TOP) \ + $(openssl_cflags) \ + $(libxml2_cflags) \ + $(COND_INCLUDES) + +SRCS = \ + openssl_hsm.c \ + openssl_hsm_pkey.c \ + openssl_hsm_obj.c \ + openssl_hsm_cb.c + +noinst_LTLIBRARIES = libpki-token-openssl.la + +libpki_token_openssl_la_SOURCES = $(SRCS) +libpki_token_openssl_la_CFLAGS = $(BUILD_LIBPKI_CFLAGS) + diff --git a/include/libpki/crypto/hsm/openssl/Makefile.in b/include/libpki/crypto/hsm/openssl/Makefile.in new file mode 100644 index 00000000..1feca2a9 --- /dev/null +++ b/include/libpki/crypto/hsm/openssl/Makefile.in @@ -0,0 +1,796 @@ +# Makefile.in generated by automake 1.16.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = src/drivers/openssl +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(SHELL) $(top_srcdir)/build/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/src/libpki/config.h \ + $(top_builddir)/src/libpki/libpki_enables.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +libpki_token_openssl_la_LIBADD = +am__objects_1 = libpki_token_openssl_la-openssl_hsm.lo \ + libpki_token_openssl_la-openssl_hsm_pkey.lo \ + libpki_token_openssl_la-openssl_hsm_obj.lo \ + libpki_token_openssl_la-openssl_hsm_cb.lo +am_libpki_token_openssl_la_OBJECTS = $(am__objects_1) +libpki_token_openssl_la_OBJECTS = \ + $(am_libpki_token_openssl_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libpki_token_openssl_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(libpki_token_openssl_la_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src/libpki +depcomp = $(SHELL) $(top_srcdir)/build/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = \ + ./$(DEPDIR)/libpki_token_openssl_la-openssl_hsm.Plo \ + ./$(DEPDIR)/libpki_token_openssl_la-openssl_hsm_cb.Plo \ + ./$(DEPDIR)/libpki_token_openssl_la-openssl_hsm_obj.Plo \ + ./$(DEPDIR)/libpki_token_openssl_la-openssl_hsm_pkey.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libpki_token_openssl_la_SOURCES) +DIST_SOURCES = $(libpki_token_openssl_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/build/depcomp \ + $(top_srcdir)/build/mkinstalldirs +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_DATE = @BUILD_DATE@ +BUILD_DATE_FULL = @BUILD_DATE_FULL@ +BUILD_DATE_PRETTY = @BUILD_DATE_PRETTY@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CHMOD = @CHMOD@ +CHOWN = @CHOWN@ +CP = @CP@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CPU = @CPU@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CXX = @CXX@ +CYGPATH_W = @CYGPATH_W@ +DATE = @DATE@ +DEFS = $(OPENCA_DEFS) +DEPDIR = @DEPDIR@ +DESTDIR = @DESTDIR@ +DIST_NAME = @DIST_NAME@ +DIST_VERSION = @DIST_VERSION@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +GZIP = @GZIP@ +HAS_PKGCONF = @HAS_PKGCONF@ +INSTALL = @INSTALL@ +INSTALL_BUILDER = @INSTALL_BUILDER@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKE = @MAKE@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR = @MKDIR@ +MKDIR_P = @MKDIR_P@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PDFLATEX = @PDFLATEX@ +PERL = @PERL@ +PG_CONFIG = @PG_CONFIG@ +PG_CPPFLAGS = @PG_CPPFLAGS@ +PKGMK = @PKGMK@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POD2MAN = @POD2MAN@ +PWD = @PWD@ +RANLIB = @RANLIB@ +RC = @RC@ +RPM = @RPM@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TAR = @TAR@ +TODAY = @TODAY@ +VERSION = @VERSION@ +ZIP = @ZIP@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_aux_dir = @ac_aux_dir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +arch_target = @arch_target@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +composite_cflags = @composite_cflags@ +composite_ldadd = @composite_ldadd@ +composite_ldflags = @composite_ldflags@ +conf_dir = @conf_dir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +day = @day@ +dist_group = @dist_group@ +dist_user = @dist_user@ +docdir = @docdir@ +dvidir = @dvidir@ +enable_debug = @enable_debug@ +etc_dir = @etc_dir@ +exec_prefix = @exec_prefix@ +extra_checks = @extra_checks@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +hr = @hr@ +htmldir = @htmldir@ +iface_age = @iface_age@ +iface_current = @iface_current@ +iface_revision = @iface_revision@ +iface_version = @iface_version@ +include_dir = @include_dir@ +include_prefix = @include_prefix@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +kmf_cflags = @kmf_cflags@ +kmf_ldadd = @kmf_ldadd@ +kmf_libflags = @kmf_libflags@ +kmf_prefix = @kmf_prefix@ +ldap_cflags = @ldap_cflags@ +ldap_ldadd = @ldap_ldadd@ +ldap_ldflags = @ldap_ldflags@ +ldap_prefix = @ldap_prefix@ +ldap_vendor = @ldap_vendor@ +lib_major = @lib_major@ +lib_micro = @lib_micro@ +lib_minor = @lib_minor@ +lib_prefix = @lib_prefix@ +lib_revision = @lib_revision@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libpki_cflags = @libpki_cflags@ +libpki_ldadd = @libpki_ldadd@ +libpki_ldflags = @libpki_ldflags@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +min = @min@ +mkdir_p = @mkdir_p@ +mon = @mon@ +my_cflags = @my_cflags@ +my_ldadd = @my_ldadd@ +my_ldflags = @my_ldflags@ +myarch = @myarch@ +mybits = @mybits@ +mybits_install = @mybits_install@ +mysql_cflags = @mysql_cflags@ +mysql_config = @mysql_config@ +mysql_ldadd = @mysql_ldadd@ +mysql_ldflags = @mysql_ldflags@ +mysql_prefix = @mysql_prefix@ +oldincludedir = @oldincludedir@ +openssl_cflags = @openssl_cflags@ +openssl_include = @openssl_include@ +openssl_ldadd = @openssl_ldadd@ +openssl_ldflags = @openssl_ldflags@ +openssl_prefix = @openssl_prefix@ +openssl_static_libs = @openssl_static_libs@ +oqs_cflags = @oqs_cflags@ +oqs_ldadd = @oqs_ldadd@ +oqs_ldflags = @oqs_ldflags@ +oqsprov_cflags = @oqsprov_cflags@ +oqsprov_ldadd = @oqsprov_ldadd@ +oqsprov_ldflags = @oqsprov_ldflags@ +package_build = @package_build@ +package_prefix = @package_prefix@ +pdfdir = @pdfdir@ +pg_cflags = @pg_cflags@ +pg_config = @pg_config@ +pg_ldadd = @pg_ldadd@ +pg_ldflags = @pg_ldflags@ +pg_prefix = @pg_prefix@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pthread_opts = @pthread_opts@ +resolv_ldadd = @resolv_ldadd@ +rpath = @rpath@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sdkver = @sdkver@ +sec = @sec@ +sharedstatedir = @sharedstatedir@ +shlext = @shlext@ +shlib_history = @shlib_history@ +shlib_version = @shlib_version@ +srcdir = @srcdir@ +sys_cflags = @sys_cflags@ +sys_ldadd = @sys_ldadd@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +test_libs = @test_libs@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +txt_revision = @txt_revision@ +xml2_cflags = @xml2_cflags@ +xml2_config = @xml2_config@ +xml2_include = @xml2_include@ +xml2_ldadd = @xml2_ldadd@ +xml2_ldflags = @xml2_ldflags@ +xml2_prefix = @xml2_prefix@ +yr = @yr@ +TOP = ../.. +BASE_DEFS = +AM_CPPFLAGS = -I$(TOP) \ + $(openssl_cflags) \ + $(libxml2_cflags) \ + $(COND_INCLUDES) + +SRCS = \ + openssl_hsm.c \ + openssl_hsm_pkey.c \ + openssl_hsm_obj.c \ + openssl_hsm_cb.c + +noinst_LTLIBRARIES = libpki-token-openssl.la +libpki_token_openssl_la_SOURCES = $(SRCS) +libpki_token_openssl_la_CFLAGS = $(BUILD_LIBPKI_CFLAGS) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/drivers/openssl/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/drivers/openssl/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libpki-token-openssl.la: $(libpki_token_openssl_la_OBJECTS) $(libpki_token_openssl_la_DEPENDENCIES) $(EXTRA_libpki_token_openssl_la_DEPENDENCIES) + $(AM_V_CCLD)$(libpki_token_openssl_la_LINK) $(libpki_token_openssl_la_OBJECTS) $(libpki_token_openssl_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_token_openssl_la-openssl_hsm.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_token_openssl_la-openssl_hsm_cb.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_token_openssl_la-openssl_hsm_obj.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_token_openssl_la-openssl_hsm_pkey.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +libpki_token_openssl_la-openssl_hsm.lo: openssl_hsm.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_token_openssl_la_CFLAGS) $(CFLAGS) -MT libpki_token_openssl_la-openssl_hsm.lo -MD -MP -MF $(DEPDIR)/libpki_token_openssl_la-openssl_hsm.Tpo -c -o libpki_token_openssl_la-openssl_hsm.lo `test -f 'openssl_hsm.c' || echo '$(srcdir)/'`openssl_hsm.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_token_openssl_la-openssl_hsm.Tpo $(DEPDIR)/libpki_token_openssl_la-openssl_hsm.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='openssl_hsm.c' object='libpki_token_openssl_la-openssl_hsm.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_token_openssl_la_CFLAGS) $(CFLAGS) -c -o libpki_token_openssl_la-openssl_hsm.lo `test -f 'openssl_hsm.c' || echo '$(srcdir)/'`openssl_hsm.c + +libpki_token_openssl_la-openssl_hsm_pkey.lo: openssl_hsm_pkey.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_token_openssl_la_CFLAGS) $(CFLAGS) -MT libpki_token_openssl_la-openssl_hsm_pkey.lo -MD -MP -MF $(DEPDIR)/libpki_token_openssl_la-openssl_hsm_pkey.Tpo -c -o libpki_token_openssl_la-openssl_hsm_pkey.lo `test -f 'openssl_hsm_pkey.c' || echo '$(srcdir)/'`openssl_hsm_pkey.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_token_openssl_la-openssl_hsm_pkey.Tpo $(DEPDIR)/libpki_token_openssl_la-openssl_hsm_pkey.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='openssl_hsm_pkey.c' object='libpki_token_openssl_la-openssl_hsm_pkey.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_token_openssl_la_CFLAGS) $(CFLAGS) -c -o libpki_token_openssl_la-openssl_hsm_pkey.lo `test -f 'openssl_hsm_pkey.c' || echo '$(srcdir)/'`openssl_hsm_pkey.c + +libpki_token_openssl_la-openssl_hsm_obj.lo: openssl_hsm_obj.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_token_openssl_la_CFLAGS) $(CFLAGS) -MT libpki_token_openssl_la-openssl_hsm_obj.lo -MD -MP -MF $(DEPDIR)/libpki_token_openssl_la-openssl_hsm_obj.Tpo -c -o libpki_token_openssl_la-openssl_hsm_obj.lo `test -f 'openssl_hsm_obj.c' || echo '$(srcdir)/'`openssl_hsm_obj.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_token_openssl_la-openssl_hsm_obj.Tpo $(DEPDIR)/libpki_token_openssl_la-openssl_hsm_obj.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='openssl_hsm_obj.c' object='libpki_token_openssl_la-openssl_hsm_obj.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_token_openssl_la_CFLAGS) $(CFLAGS) -c -o libpki_token_openssl_la-openssl_hsm_obj.lo `test -f 'openssl_hsm_obj.c' || echo '$(srcdir)/'`openssl_hsm_obj.c + +libpki_token_openssl_la-openssl_hsm_cb.lo: openssl_hsm_cb.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_token_openssl_la_CFLAGS) $(CFLAGS) -MT libpki_token_openssl_la-openssl_hsm_cb.lo -MD -MP -MF $(DEPDIR)/libpki_token_openssl_la-openssl_hsm_cb.Tpo -c -o libpki_token_openssl_la-openssl_hsm_cb.lo `test -f 'openssl_hsm_cb.c' || echo '$(srcdir)/'`openssl_hsm_cb.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_token_openssl_la-openssl_hsm_cb.Tpo $(DEPDIR)/libpki_token_openssl_la-openssl_hsm_cb.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='openssl_hsm_cb.c' object='libpki_token_openssl_la-openssl_hsm_cb.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_token_openssl_la_CFLAGS) $(CFLAGS) -c -o libpki_token_openssl_la-openssl_hsm_cb.lo `test -f 'openssl_hsm_cb.c' || echo '$(srcdir)/'`openssl_hsm_cb.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/libpki_token_openssl_la-openssl_hsm.Plo + -rm -f ./$(DEPDIR)/libpki_token_openssl_la-openssl_hsm_cb.Plo + -rm -f ./$(DEPDIR)/libpki_token_openssl_la-openssl_hsm_obj.Plo + -rm -f ./$(DEPDIR)/libpki_token_openssl_la-openssl_hsm_pkey.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/libpki_token_openssl_la-openssl_hsm.Plo + -rm -f ./$(DEPDIR)/libpki_token_openssl_la-openssl_hsm_cb.Plo + -rm -f ./$(DEPDIR)/libpki_token_openssl_la-openssl_hsm_obj.Plo + -rm -f ./$(DEPDIR)/libpki_token_openssl_la-openssl_hsm_pkey.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-noinstLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + +include $(TOP)/global-vars + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/include/libpki/crypto/hsm/openssl/data_st.h b/include/libpki/crypto/hsm/openssl/data_st.h new file mode 100644 index 00000000..88fd112f --- /dev/null +++ b/include/libpki/crypto/hsm/openssl/data_st.h @@ -0,0 +1,1422 @@ +/* OpenCA libpki package +* (c) 2000-2006 by Massimiliano Pala and OpenCA Group +* All Rights Reserved +* +* =================================================================== +* Released under OpenCA LICENSE +*/ + +#ifndef _LIBPKI_HEADER_DATA_ST_H +#define _LIBPKI_HEADER_DATA_ST_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include + +#ifdef ENABLE_ECDSA +#include +#endif + +#ifdef ENABLE_OQS +#include +#endif + +#if OPENSSL_VERSION_NUMBER > 0x1010000fL +# define DECLARE_STACK_OF DEFINE_STACK_OF +#endif + +#if OPENSSL_VERSION_NUMBER < 0x1010000fL + +// EVP_MD_CTX Interface +# define EVP_MD_CTX_new EVP_MD_CTX_create +# define EVP_MD_CTX_free EVP_MD_CTX_destroy +# define EVP_MD_CTX_reset EVP_MD_CTX_cleanup + +// HMAC Interface +# define HMAC_CTX_reset HMAC_CTX_cleanup +#endif + +//! \brief EVP CTRL to set the number of required valid signatures (K of N) +#define COMPOSITE_PKEY_CTRL_SET_K_OF_N 0x301 + +//! \brief EVP CTRL to get the number of required valid signatures (K of N) +#define COMPOSITE_PKEY_CTRL_GET_K_OF_N 0x302 + +//! \brief Type definition for ASN1_BIT_STRING +typedef ASN1_BIT_STRING PKI_X509_SIGNATURE; + +/* Some useful Key definitions */ +#define PKI_RSA_KEY RSA +#define PKI_DSA_KEY DSA + +#ifdef ENABLE_ECDSA +#define PKI_EC_KEY EC_KEY +#endif + +#ifdef ENABLE_COMPOSITE +# define PKI_COMPOSITE_KEY COMPOSITE_KEY +#endif + +#ifdef ENABLE_COMBINED +# define PKI_COMBINED_KEY COMBINED_KEY +#endif + +#define PKI_ID int +#define PKI_ID_UNKNOWN NID_undef + +#define PKI_DIGEST_ALG EVP_MD + +#define PKI_X509_ALGOR_VALUE X509_ALGOR + +#define PKI_CIPHER EVP_CIPHER + +#define PKI_X509_NAME X509_NAME + +#define PKI_DIGEST_ALG_NULL (PKI_DIGEST_ALG *) EVP_md_null() +#define PKI_DIGEST_ALG_ID_NULL NID_undef + +#define PKI_DIGEST_ALG_UNKNOWN (PKI_DIGEST_ALG *) NULL +#define PKI_DIGEST_ALG_ID_UNKNOWN NID_undef + + // =========== + // Family: DSA + // =========== + + +/* Begin - NID_dsa */ +#ifdef NID_dsa +#define ENABLE_DSA +#define PKI_ALGOR_DSA NID_dsa +#define PKI_ALGOR_ID_DSA NID_dsa +#else +#define PKI_ALGOR_DSA NID_undef +#define PKI_ALGOR_ID_DSA NID_undef +#endif +/* End - NID_dsa */ + + + // =========== + // Family: RSA + // =========== + +/* Begin - NID_rsaEncryption */ +#ifdef NID_rsaEncryption +#define ENABLE_RSA +#define PKI_ALGOR_RSA NID_rsaEncryption +#define PKI_ALGOR_ID_RSA NID_rsaEncryption +#else +#define PKI_ALGOR_DSA NID_undef +#define PKI_ALGOR_ID_DSA NID_undef +#endif +/* End - NID_rsaEncryption */ + +/* Begin - NID_rsassaPss or EVP_PKEY_RSA_PSS */ +#ifdef NID_rsassaPss +#define ENABLE_RSAPSS +#define PKI_ALGOR_RSAPSS NID_rsassaPss +#define PKI_ALGOR_ID_RSAPSS NID_rsassaPss +#else +#define PKI_ALGOR_RSAPSS NID_undef +#define PKI_ALGOR_ID_RSAPSS NID_undef +#endif +/* End - NID_rsassaPss */ + + // ========== + // Family: EC + // ========== + +/* Begin - NID_X9_62_id_ecPublicKey or EVP_PKEY_EC */ +#ifdef EVP_PKEY_EC +#define PKI_ALGOR_ECDSA EVP_PKEY_EC +#define PKI_ALGOR_ID_ECDSA EVP_PKEY_EC +#else +#define PKI_ALGOR_ECDSA NID_undef +#define PKI_ALGOR_ID_ECDSA NID_undef +#endif +/* End - NID_X9_62_id_ecPublicKey or EVP_PKEY_EC */ + + // ============= + // Family: ED448 + // ============= + +/* Begin - ED 448 or EVP_PKEY_ED448 */ +#ifdef EVP_PKEY_X448 +#define ENABLE_X448 +#define PKI_ALGOR_X448 EVP_PKEY_X448 +#define PKI_ALGOR_ID_X448 EVP_PKEY_X448 +#else +#undef ENABLE_X448 +#define PKI_ALGOR_X448 NID_undef +#define PKI_ALGOR_ID_X448 NID_undef +#endif +/* End - ED 448 or EVP_PKEY_ED448 */ + +/* Begin - ED 448 or EVP_PKEY_ED448 */ +#ifdef EVP_PKEY_EC +#define ENABLE_ED448 +#define PKI_ALGOR_ED448 EVP_PKEY_ED448 +#define PKI_ALGOR_ID_ED448 EVP_PKEY_ED448 +#else +#undef ENABLE_ED448 +#define PKI_ALGOR_ED448 NID_undef +#define PKI_ALGOR_ID_ED448 NID_undef +#endif +/* End - ED 448 or EVP_PKEY_ED448 */ + + // =============== + // Family: ED25519 + // =============== + +/* Begin - X25519 or EVP_PKEY_X25519 */ +#ifdef EVP_PKEY_X25519 +#define ENABLE_X25519 +#define PKI_ALGOR_X25519 EVP_PKEY_X25519 +#define PKI_ALGOR_ID_X25519 EVP_PKEY_X25519 +#else +#undef ENABLE_X25519 +#define PKI_ALGOR_X25519 NID_undef +#define PKI_ALGOR_ID_X25519 NID_undef +#endif +/* End - X25591 or EVP_PKEY_X25519 */ + +/* Begin - ED 25519 or EVP_PKEY_ED25519 */ +#ifdef EVP_PKEY_ED25519 +#define ENABLE_ED25519 +#define PKI_ALGOR_ED25519 EVP_PKEY_ED25519 +#define PKI_ALGOR_ID_ED25519 EVP_PKEY_ED25519 +#else +#undef ENABLE_ED25519 +#define PKI_ALGOR_ED25519 NID_undef +#define PKI_ALGOR_ID_ED25519 NID_undef +#endif +/* End - ED 25519 or EVP_PKEY_ED25519 */ + + // ================= + // Digest Algorithms + // ================= + +// #define PKI_ALGOR_MD2 NID_md2 +// #define PKI_DIGEST_ALG_MD2 (PKI_DIGEST_ALG *) EVP_md2() +#ifndef OPENSSL_FIPS +#ifdef NID_md4 +#define ENABLE_MD4 +#define PKI_ALGOR_MD4 NID_md4 +#define PKI_ALGOR_ID_MD4 NID_md4 +#define PKI_DIGEST_ALG_MD4 (PKI_DIGEST_ALG *) EVP_md4() +#else +#define PKI_ALGOR_MD4 NID_undef +#define PKI_ALGOR_ID_MD4 NID_undef +#define PKI_DIGEST_ALG_MD4 (PKI_DIGEST_ALG *) NULL; +#endif +#endif // FIPS_MODE + +// Support for MD5 +#ifdef NID_md5 +#define ENABLE_MD5 +#define PKI_ALGOR_MD5 NID_md5 +#define PKI_ALGOR_ID_MD5 NID_md5 +#define PKI_DIGEST_ALG_MD5 (PKI_DIGEST_ALG *) EVP_md5() +#else +#define PKI_ALGOR_MD5 NID_undef +#define PKI_ALGOR_ID_MD5 NID_undef +#define PKI_DIGEST_ALG_MD5 (PKI_DIGEST_ALG *) NULL +#endif +#define PKI_DIGEST_ALG_MD5_SIZE 16 + +// Support for SHA1 +#ifdef NID_sha1 +#define ENABLE_SHA1 +#define PKI_ALGOR_SHA1 NID_sha1 +#define PKI_ALGOR_ID_SHA1 NID_sha1 +#define PKI_DIGEST_ALG_SHA1 (PKI_DIGEST_ALG *) EVP_sha1() +#else +#define PKI_ALGOR_SHA1 NID_undef +#define PKI_ALGOR_ID_SHA1 NID_undef +#define PKI_DIGEST_ALG_SHA1 (PKI_DIGEST_ALG *) NULL +#endif +#define PKI_ALGOR_SHA1_SIZE 20 + + // ============ + // Family: SHA2 + // ============ + +// Support for SHA-224 +#ifdef NID_sha224 +#define ENABLE_SHA2 +#define ENABLE_SHA224 +#define PKI_ALGOR_SHA224 NID_sha224 +#define PKI_ALGOR_ID_SHA224 NID_sha224 +#define PKI_DIGEST_ALG_ID_SHA224 NID_sha224 +#define PKI_DIGEST_ALG_SHA224 (PKI_DIGEST_ALG *) EVP_sha224() +#else +#define PKI_ALGOR_SHA224 NID_undef +#define PKI_ALGOR_ID_SHA224 NID_undef +#define PKI_DIGEST_ALG_ID_SHA224 NID_undef +#define PKI_DIGEST_ALG_SHA224 (PKI_DIGEST_ALG *) NULL +#endif +#define PKI_ALGOR_SHA224_SIZE 28 + +// Support for SHA-256 +#ifdef NID_sha256 +#define ENABLE_SHA2 +#define ENABLE_SHA256 +#define PKI_ALGOR_SHA256 NID_sha256 +#define PKI_ALGOR_ID_SHA256 NID_sha256 +#define PKI_DIGEST_ALG_SHA256 (PKI_DIGEST_ALG *) EVP_sha256() +#define PKI_DIGEST_ALG_ID_SHA256 NID_sha256 +#else +#define PKI_ALGOR_SHA256 NID_undef +#define PKI_ALGOR_ID_SHA256 NID_undef +#define PKI_DIGEST_ALG_SHA256 (PKI_DIGEST_ALG *) NULL +#define PKI_DIGEST_ALG_ID_SHA256 NID_undef +#endif + +#define PKI_ALGOR_SHA256_SIZE 32 + +// Support for SHA-384 +#ifdef NID_sha384 +#define ENABLE_SHA2 +#define ENABLE_SHA384 +#define PKI_ALGOR_SHA384 NID_sha384 +#define PKI_ALGOR_ID_SHA384 NID_sha384 +#define PKI_DIGEST_ALG_SHA384 (PKI_DIGEST_ALG *) EVP_sha384() +#define PKI_DIGEST_ALG_ID_SHA384 NID_sha384 +#else +#define PKI_ALGOR_SHA384 NID_undef +#define PKI_ALGOR_ID_SHA384 NID_undef +#define PKI_DIGEST_ALG_SHA384 (PKI_DIGEST_ALG *) NULL +#define PKI_DIGEST_ALG_ID_SHA384 NID_undef +#endif + +#define PKI_ALGOR_SHA384_SIZE 48 + +// Support for SHA-512 +#ifdef NID_sha512 +#define ENABLE_SHA2 +#define ENABLE_SHA512 +#define PKI_ALGOR_SHA512 NID_sha512 +#define PKI_ALGOR_ID_SHA512 NID_sha512 +#define PKI_DIGEST_ALG_SHA512 (PKI_DIGEST_ALG *) EVP_sha512() +#define PKI_DIGEST_ALG_ID_SHA512 NID_sha512 +#else +#define PKI_ALGOR_SHA512 NID_undef +#define PKI_ALGOR_ID_SHA512 NID_undef +#define PKI_DIGEST_ALG_SHA512 (PKI_DIGEST_ALG *) NULL +#define PKI_DIGEST_ALG_ID_SHA512 NID_undef +#endif + +#define PKI_ALGOR_SHA512_SIZE 64 + + // ============== + // Family: RIPEMD + // ============== + +#ifdef NID_ripemd128 +#define ENABLE_RIPEMD +#define ENABLE_RIPEMD128 +#define PKI_ALGOR_RIPEMD128 NID_ripemd128 +#define PKI_ALGOR_ID_RIPEMD128 NID_ripemd128 +#define PKI_DIGEST_ALG_RIPEMD128 (PKI_DIGEST_ALG *) EVP_ripemd128() +#define PKI_DIGEST_ALG_ID_RIPEMD128 NID_ripemd128 +#else +#define PKI_ALGOR_RIPEMD128 NID_undef +#define PKI_ALGOR_ID_RIPEMD128 NID_undef +#define PKI_DIGEST_ALG_RIPEMD128 (PKI_DIGEST_ALG *) NULL +#define PKI_DIGEST_ALG_ID_RIPEMD128 NID_undef +#endif + +#define PKI_ALGOR_RIPEMD128_SIZE 16 + +#ifdef NID_ripemd160 +#define ENABLE_RIPEMD +#define ENABLE_RIPEMD160 +#define PKI_ALGOR_RIPEMD160 NID_ripemd160 +#define PKI_ALGOR_ID_RIPEMD160 NID_ripemd160 +#define PKI_DIGEST_ALG_RIPEMD160 (PKI_DIGEST_ALG *) EVP_ripemd160() +#define PKI_DIGEST_ALG_ID_RIPEMD160 NID_ripemd160 +#else +#define PKI_ALGOR_RIPEMD160 NID_undef +#define PKI_ALGOR_ID_RIPEMD160 NID_undef +#define PKI_DIGEST_ALG_RIPEMD160 (PKI_DIGEST_ALG *) NULL +#define PKI_DIGEST_ALG_ID_RIPEMD160 NID_undef +#endif + +#define PKI_ALGOR_RIPEMD160_SIZE 20 + + + // ============ + // Family: SHA3 + // ============ + +// Support for SHA3-256 +#ifdef NID_sha3_256 +#define ENABLE_SHA3 +#define ENABLE_SHA3_256 +#define PKI_ALGOR_SHA3_256 NID_sha3_256 +#define PKI_ALGOR_ID_SHA3_256 NID_sha3_256 +#define PKI_DIGEST_ALG_SHA3_256 (PKI_DIGEST_ALG *) EVP_sha3_256() +#define PKI_DIGEST_ALG_ID_SHA3_256 NID_sha3_256 +#else +#define PKI_ALGOR_SHA3_256 NID_undef +#define PKI_ALGOR_ID_SHA3_256 NID_undef +#define PKI_DIGEST_ALG_SHA3_256 (PKI_DIGEST_ALG *) NULL +#define PKI_DIGEST_ALG_ID_SHA3_256 NID_undef +#endif + +#define PKI_ALGOR_SHA3_256_SIZE 32 + +// Support for SHA3-384 +#ifdef NID_sha3_384 +#define ENABLE_SHA3 +#define ENABLE_SHA3_384 +#define PKI_ALGOR_SHA3_384 NID_sha3_384 +#define PKI_ALGOR_ID_SHA3_384 NID_sha3_384 +#define PKI_DIGEST_ALG_SHA3_384 (PKI_DIGEST_ALG *) EVP_sha3_384() +#define PKI_DIGEST_ALG_ID_SHA3_384 NID_sha_384 +#else +#define PKI_ALGOR_SHA3_384 NID_undef +#define PKI_ALGOR_ID_SHA3_384 NID_undef +#define PKI_DIGEST_ALG_SHA3_384 (PKI_DIGEST_ALG *) NULL +#define PKI_DIGEST_ALG_ID_SHA3_384 NID_undef +#endif + +#define PKI_ALGOR_SHA3_384_SIZE 48 + +// Support for SHA3-512 +#ifdef NID_sha3_512 +#define ENABLE_SHA3 +#define ENABLE_SHA3_512 +#define PKI_ALGOR_SHA3_512 NID_sha3_512 +#define PKI_ALGOR_ID_SHA3_512 NID_sha3_512 +#define PKI_DIGEST_ALG_SHA3_512 (PKI_DIGEST_ALG *) EVP_sha3_512() +#define PKI_DIGEST_ALG_ID_SHA3_512 NID_sha3_512 +#else +#define PKI_ALGOR_SHA3_256 NID_undef +#define PKI_ALGOR_ID_SHA3_512 NID_undef +#define PKI_DIGEST_ALG_SHA3_256 (PKI_DIGEST_ALG *) NULL +#define PKI_DIGEST_ALG_SHA3_256 NID_undef +#endif + +#define PKI_ALGOR_SHA512_SIZE 64 + + // ============= + // Family: SHAKE + // ============= + +// Support for SHAKE-128 +#ifdef NID_shake128 +#define ENABLE_SHAKE +#define ENABLE_SHAKE128 +#define PKI_ALGOR_SHAKE128 NID_shake128 +#define PKI_ALGOR_ID_SHAKE128 NID_shake128 +#define PKI_DIGEST_ALG_SHAKE128 (PKI_DIGEST_ALG *) EVP_shake128() +#define PKI_DIGEST_ALG_ID_SHAKE128 NID_shake128 +#else +#define PKI_ALGOR_SHAKE128 NID_undef +#define PKI_ALGOR_ID_SHAKE128 NID_undef +#define PKI_DIGEST_ALG_SHAKE128 (PKI_DIGEST_ALG *) NULL +#define PKI_DIGEST_ALG_ID_SHAKE128 NID_undef +#endif +#define PKI_ALGOR_SHAKE128_SIZE 16 + +// Support for SHAKE-256 +#ifdef NID_shake256 +#define ENABLE_SHAKE +#define ENABLE_SHAKE256 +#define PKI_ALGOR_SHAKE256 NID_shake256 +#define PKI_ALGOR_ID_SHAKE256 NID_shake256 +#define PKI_DIGEST_ALG_SHAKE256 (PKI_DIGEST_ALG *) EVP_shake256() +#define PKI_DIGEST_ALG_ID_SHAKE256 NID_shake256 +#else +#define PKI_ALGOR_SHAKE128 NID_undef +#define PKI_ALGOR_ID_SHAKE256 NID_undef +#define PKI_DIGEST_ALG_SHAKE128 (PKI_DIGEST_ALG *) NULL +#define PKI_DIGEST_ALG_ID_SHAKE256 NID_undef +#endif +#define PKI_ALGOR_SHAKE256_SIZE 32 + + +#define PKI_ALGOR_NULL NULL + +#define PKI_ALGOR_ID int +#define PKI_ALGOR_ID_UNKNOWN -1 + + // ==================== + // Signature Algorithms + // ==================== + +#define PKI_ALGOR_RSA_MD5 NID_md5WithRSAEncryption +#define PKI_ALGOR_ID_RSA_MD5 NID_md5WithRSAEncryption +#define PKI_ALGOR_RSA_MD4 NID_md4WithRSAEncryption +#define PKI_ALGOR_ID_RSA_MD4 NID_md4WithRSAEncryption +#define PKI_ALGOR_RSA_SHA1 NID_sha1WithRSAEncryption +#define PKI_ALGOR_ID_RSA_SHA1 NID_sha1WithRSAEncryption + +#ifdef ENABLE_ECDSA +#define PKI_DIGEST_ALG_ECDSA_SHA1 (PKI_DIGEST_ALG *)EVP_ecdsa() +#define PKI_DIGEST_ALG_ECDSA_DSS1 (PKI_DIGEST_ALG *)EVP_ecdsa() +#else +#define PKI_DIGEST_ALG_ECDSA_DSS1 NULL +#define PKI_DIGEST_ALG_ECDSA_SHA1 NULL +#endif + +#ifdef ENABLE_SHA224 +#define PKI_ALGOR_RSA_SHA224 NID_sha224WithRSAEncryption +#define PKI_ALGOR_ID_RSA_SHA224 NID_sha224WithRSAEncryption +#else +#define PKI_ALGOR_RSA_SHA224 NID_undef +#define PKI_ALGOR_ID_RSA_SHA224 NID_undef +#endif + +#ifdef ENABLE_SHA256 +#define ENABLE_RSA_SHA_2 +#define PKI_DIGEST_ALG_RSA_DEFAULT PKI_DIGEST_ALG_SHA256 +#define PKI_ALGOR_RSA_SHA256 NID_sha256WithRSAEncryption +#define PKI_ALGOR_ID_RSA_SHA256 NID_sha256WithRSAEncryption +#else +#define PKI_DIGEST_ALG_RSA_DEFAULT PKI_DIGEST_ALG_SHA1 +#define PKI_ALGOR_RSA_SHA256 NID_undef +#define PKI_ALGOR_ID_RSA_SHA256 NID_undef +#endif + +#ifdef ENABLE_SHA384 +#define PKI_ALGOR_RSA_SHA384 NID_sha384WithRSAEncryption +#define PKI_ALGOR_ID_RSA_SHA384 NID_sha384WithRSAEncryption +#else +#define PKI_ALGOR_RSA_SHA384 NID_undef +#define PKI_ALGOR_ID_RSA_SHA384 NID_undef +#endif + +#ifdef ENABLE_SHA512 +#define PKI_ALGOR_RSA_SHA512 NID_sha512WithRSAEncryption +#define PKI_ALGOR_ID_RSA_SHA512 NID_sha512WithRSAEncryption +#else +#define PKI_ALGOR_RSA_SHA512 NID_undef +#define PKI_ALGOR_ID_RSA_SHA512 NID_undef +#endif + +#ifdef ENABLE_RIPEMD128 +#define PKI_ALGOR_RSA_RIPEMD128 NID_ripemd128WithRSA +#define PKI_ALGOR_ID_RSA_RIPEMD128 NID_ripemd128WithRSA +#else +#define PKI_ALGOR_RSA_RIPEMD128 NID_undef +#define PKI_ALGOR_ID_RSA_RIPEMD128 NID_undef +#endif + +#ifdef ENABLE_RIPEMD160 +#define PKI_ALGOR_RSA_RIPEMD160 NID_ripemd160WithRSA +#define PKI_ALGOR_ID_RSA_RIPEMD160 NID_ripemd160WithRSA +#else +#define PKI_ALGOR_RSA_RIPEMD160 NID_undef +#define PKI_ALGOR_ID_RSA_RIPEMD160 NID_undef +#endif + +#ifdef ENABLE_SHA3_256 +#define PKI_ALGOR_RSA_SHA3_256 NID_RSA_SHA3_256 +#define PKI_ALGOR_ID_RSA_SHA3_256 NID_RSA_SHA3_256 +#else +#define PKI_ALGOR_RSA_SHA3_256 NID_undef +#define PKI_ALGOR_ID_RSA_SHA3_256 NID_undef +#endif + +#ifdef ENABLE_SHA3_384 +#define PKI_ALGOR_RSA_SHA3_384 NID_RSA_SHA3_384 +#define PKI_ALGOR_ID_RSA_SHA3_384 NID_RSA_SHA3_384 +#else +#define PKI_ALGOR_RSA_SHA3_384 NID_undef +#define PKI_ALGOR_ID_RSA_SHA3_384 NID_undef +#endif + +#ifdef ENABLE_SHA3_512 +#define PKI_ALGOR_RSA_SHA3_512 NID_RSA_SHA3_512 +#define PKI_ALGOR_ID_RSA_SHA3_512 NID_RSA_SHA3_512 +#else +#define PKI_ALGOR_RSA_SHA3_512 NID_undef +#define PKI_ALGOR_ID_RSA_SHA3_512 NID_undef +#endif + +/* Old DSS1 Algorithm - not needed in OpenSSL v1.0.0+ */ +#if OPENSSL_VERSION_NUMBER < 0x1000000fL +#define PKI_ALGOR_DSS1 60000 +#define PKI_ALGOR_ID_DSS1 60000 +#define PKI_ALGOR_ECDSA_DSS1 60001 +#define PKI_ALGOR_ID_ECDSA_DSS1 60001 +#define PKI_DIGEST_ALG_DSS1 (PKI_DIGEST_ALG *) EVP_dss1() +#else +#define PKI_ALGOR_DSS1 NID_undef +#define PKI_ALGOR_ID_DSS1 NID_undef +#define PKI_ALGOR_ECDSA_DSS1 NID_undef +#define PKI_ALGOR_ID_ECDSA_DSS1 NID_undef +#define PKI_DIGEST_ALG_DSS1 NULL +#endif + +/* Begin - NID_dsaWithSHA1 */ +#ifdef NID_dsaWithSHA1 +#define ENABLE_DSA +#define ENABLE_DSA_SHA_1 +#define PKI_ALGOR_DSA_SHA1 NID_dsaWithSHA1 +#define PKI_ALGOR_ID_DSA_SHA1 NID_dsaWithSHA1 +#else +#define PKI_ALGOR_DSA_SHA1 NID_undef +#define PKI_ALGOR_ID_DSA_SHA1 NID_undef +#endif +/* End - NID_dsaWithSHA1 */ + +/* Begin - NID_dsa_with_SHA224 */ +#ifdef NID_dsa_with_SHA224 +#define ENABLE_DSA +#define ENABLE_DSA_SHA224 +#define PKI_ALGOR_DSA_SHA224 NID_dsa_with_SHA224 +#define PKI_ALGOR_ID_DSA_SHA224 NID_dsa_with_SHA224 +#else +#define PKI_ALGOR_DSA_SHA224 NID_undef +#define PKI_ALGOR_ID_DSA_SHA224 NID_undef +#endif +/* End - NID_dsa_with_SHA224 */ + +/* Begin - NID_dsa_with_SHA256 */ +#ifdef NID_dsa_with_SHA256 +#define ENABLE_DSA_SHA256 +#define PKI_DIGEST_ALG_DSA_DEFAULT PKI_DIGEST_ALG_SHA256 +#define PKI_ALGOR_DSA_SHA256 NID_dsa_with_SHA256 +#define PKI_ALGOR_ID_DSA_SHA256 NID_dsa_with_SHA256 +#else +#define PKI_DIGEST_ALG_DSA_DEFAULT PKI_DIGEST_ALG_SHA1 +#define PKI_ALGOR_DSA_SHA256 NID_undef +#define PKI_ALGOR_ID_DSA_SHA256 NID_undef +#endif +/* End - NID_dsa_with_SHA256 */ + +/* Begin - NID_dsa_with_SHA384 */ +#ifdef NID_dsa_with_SHA384 +#define ENABLE_DSA_SHA384 +#define PKI_ALGOR_DSA_SHA384 NID_dsa_with_SHA384 +#define PKI_ALGOR_ID_DSA_SHA384 NID_dsa_with_SHA384 +#else +#define PKI_ALGOR_DSA_SHA384 NID_undef +#define PKI_ALGOR_ID_DSA_SHA384 NID_undef +#endif +/* End - NID_dsa_with_SHA384 */ + +/* Begin - NID_dsa_with_SHA512 */ +#ifdef NID_dsa_with_SHA512 +#define ENABLE_DSA_SHA512 +#define PKI_ALGOR_DSA_SHA512 NID_dsa_with_SHA512 +#define PKI_ALGOR_ID_DSA_SHA512 NID_dsa_with_SHA512 +#else +#define PKI_ALGOR_DSA_SHA512 NID_undef +#define PKI_ALGOR_ID_DSA_SHA512 NID_undef +#endif +/* End - NID_dsa_with_SHA256 */ + +/* Begin - NID_ecdsa_with_SHA1 */ +#ifdef NID_ecdsa_with_SHA1 +#define ENABLE_ECDSA_SHA1 +#define PKI_ALGOR_ECDSA_SHA1 NID_ecdsa_with_SHA1 +#define PKI_ALGOR_ID_ECDSA_SHA1 NID_ecdsa_with_SHA1 +#else +#define PKI_ALGOR_ECDSA_SHA1 NID_undef +#define PKI_ALGOR_ID_ECDSA_SHA1 NID_undef +#endif +/* End - NID_ecdsa_with_SHA1 */ + +/* Begin - NID_ecdsa_with_224 */ +#ifdef NID_ecdsa_with_SHA224 +#define ENABLE_ECDSA_SHA_2 +#define PKI_ALGOR_ECDSA_SHA224 NID_ecdsa_with_SHA224 +#define PKI_ALGOR_ID_ECDSA_SHA224 NID_ecdsa_with_SHA224 +#else +#define PKI_ALGOR_ECDSA_SHA224 NID_undef +#define PKI_ALGOR_ID_ECDSA_SHA224 NID_undef +#endif +/* End - NID_ecdsa_with_SHA224 */ + +/* Begin - NID_ecdsa_with_SHA256 */ +#ifdef NID_ecdsa_with_SHA256 +#define PKI_DIGEST_ALG_ECDSA_DEFAULT PKI_DIGEST_ALG_SHA256 +#define PKI_ALGOR_ECDSA_SHA256 NID_ecdsa_with_SHA256 +#define PKI_ALGOR_ID_ECDSA_SHA256 NID_ecdsa_with_SHA256 +#else +#define PKI_DIGEST_ALG_ECDSA_DEFAULT PKI_DIGEST_ALG_DSS1 +#define PKI_ALGOR_ECDSA_SHA256 NID_undef +#define PKI_ALGOR_ID_ECDSA_SHA256 NID_undef +#endif +/* End - NID_ecdsa_with_SHA256 */ + +/* Begin - NID_ecdsa_with_384 */ +#ifdef NID_ecdsa_with_SHA384 +#define PKI_ALGOR_ECDSA_SHA384 NID_ecdsa_with_SHA384 +#define PKI_ALGOR_ID_ECDSA_SHA384 NID_ecdsa_with_SHA384 +#else +#define PKI_ALGOR_ECDSA_SHA384 NID_undef +#define PKI_ALGOR_ID_ECDSA_SHA384 NID_undef +#endif +/* End - NID_ecdsa_with_SHA384 */ + +/* Begin - NID_ecdsa_with_512 */ +#ifdef NID_ecdsa_with_SHA512 +#define PKI_ALGOR_ECDSA_SHA512 NID_ecdsa_with_SHA512 +#define PKI_ALGOR_ID_ECDSA_SHA512 NID_ecdsa_with_SHA512 +#else +#define PKI_ALGOR_ECDSA_SHA512 NID_undef +#define PKI_ALGOR_ID_ECDSA_SHA512 NID_undef +#endif +/* End - NID_ecdsa_with_SHA512 */ + +/* Begin - NID_ecdsa_with_sha3_256 */ +#ifdef NID_ecdsa_with_SHA3_256 +#define PKI_ALGOR_ECDSA_SHA3_256 NID_ecdsa_with_SHA3_256 +#define PKI_ALGOR_ID_ECDSA_SHA3_256 NID_ecdsa_with_SHA3_256 +#else +#define PKI_ALGOR_ECDSA_SHA3_256 NID_undef +#define PKI_ALGOR_ID_ECDSA_SHA3_256 NID_undef +#endif +/* End - NID_ecdsa_with_sha3_256 */ + +/* Begin - NID_ecdsa_with_sha3_384 */ +#ifdef NID_ecdsa_with_SHA3_384 +#define PKI_ALGOR_ECDSA_SHA3_384 NID_ecdsa_with_SHA3_384 +#define PKI_ALGOR_ID_ECDSA_SHA3_384 NID_ecdsa_with_SHA3_384 +#else +#define PKI_ALGOR_ECDSA_SHA3_384 NID_undef +#define PKI_ALGOR_ID_ECDSA_SHA3_384 NID_undef +#endif +/* End - NID_ecdsa_with_sha3_384 */ + +/* Begin - NID_ecdsa_with_sha3_384 */ +#ifdef NID_ecdsa_with_SHA3_512 +#define PKI_ALGOR_ECDSA_SHA3_512 NID_ecdsa_with_SHA3_512 +#define PKI_ALGOR_ID_ECDSA_SHA3_512 NID_ecdsa_with_SHA3_512 +#else +#define PKI_ALGOR_ECDSA_SHA3_512 NID_undef +#define PKI_ALGOR_ID_ECDSA_SHA3_512 NID_undef +#endif +/* End - NID_ecdsa_with_sha3_384 */ + +// ======================= // +// Post Quantum Algorithms // +// ======================= // + +/* Begin - NID_falcon512 - open-quantum-safe */ +#ifdef NID_falcon512 +#define PKI_ALGOR_FALCON512 NID_falcon512 +#define PKI_ALGOR_ID_FALCON512 NID_falcon512 +#else +#define PKI_ALGOR_FALCON512 NID_undef +#define PKI_ALGOR_ID_FALCON512 NID_undef +#endif +/* End - NID_falcon512 - open-quantum-safe */ + +/* Begin - NID_falcon512 - open-quantum-safe */ +#ifdef NID_falcon1024 +#define PKI_ALGOR_FALCON1024 NID_falcon1024 +#define PKI_ALGOR_ID_FALCON1024 NID_falcon1024 +#else +#define PKI_ALGOR_FALCON1024 NID_undef +#define PKI_ALGOR_ID_FALCON1024 NID_undef +#endif +/* End - NID_falcon512 - open-quantum-safe */ + +/* Begin - NID_dilithium2 - open-quantum-safe */ +#ifdef NID_dilithium2 +#define PKI_ALGOR_DILITHIUM2 NID_dilithium2 +#define PKI_ALGOR_ID_DILITHIUM2 NID_dilithium2 +#else +#define PKI_ALGOR_DILITHIUM2 NID_undef +#define PKI_ALGOR_ID_DILITHIUM2 NID_undef +#endif +/* End - NID_dilithium2 - open-quantum-safe */ + +/* Begin - NID_dilithium3 - open-quantum-safe */ +#ifdef NID_dilithium3 +#define PKI_ALGOR_DILITHIUM3 NID_dilithium3 +#define PKI_ALGOR_ID_DILITHIUM3 NID_dilithium3 +#else +#define PKI_ALGOR_DILITHIUM3 NID_undef +#define PKI_ALGOR_ID_DILITHIUM3 NID_undef +#endif +/* End - NID_dilithium3 - open-quantum-safe */ + +/* Begin - NID_dilithium5_aes - open-quantum-safe */ +#ifdef NID_dilithium5 +#define PKI_ALGOR_DILITHIUM5 NID_dilithium5 +#define PKI_ALGOR_ID_DILITHIUM5 NID_dilithium5 +#else +#define PKI_ALGOR_DILITHIUM5 NID_undef +#define PKI_ALGOR_ID_DILITHIUM5 NID_undef +#endif +/* End - NID_dilithium5 - open-quantum-safe */ + +/* Begin - NID_dilithium2_aes - open-quantum-safe */ +#ifdef NID_dilithium2_aes +#define PKI_ALGOR_DILITHIUM2_AES NID_dilithium2_aes +#define PKI_ALGOR_ID_DILITHIUM2_AES NID_dilithium2_aes +#else +#define PKI_ALGOR_DILITHIUM2_AES NID_undef +#define PKI_ALGOR_ID_DILITHIUM2_AES NID_undef +#endif +/* End - NID_dilithium2_aes - open-quantum-safe */ + +/* Begin - NID_dilithium3_aes - open-quantum-safe */ +#ifdef NID_dilithium3_aes +#define PKI_ALGOR_DILITHIUM3_AES NID_dilithium3_aes +#define PKI_ALGOR_ID_DILITHIUM3_AES NID_dilithium3_aes +#else +#define PKI_ALGOR_DILITHIUM3_AES NID_undef +#define PKI_ALGOR_ID_DILITHIUM3_AES NID_undef +#endif +/* End - NID_dilithium3_aes - open-quantum-safe */ + +/* Begin - NID_dilithium5_aes - open-quantum-safe */ +#ifdef NID_dilithium5_aes +#define PKI_ALGOR_DILITHIUM5_AES NID_dilithium5_aes +#define PKI_ALGOR_ID_DILITHIUM5_AES NID_dilithium5_aes +#else +#define PKI_ALGOR_DILITHIUM5_AES NID_undef +#define PKI_ALGOR_ID_DILITHIUM5_AES NID_undef +#endif +/* End - NID_dilithium5_aes - open-quantum-safe */ + +/* Begin - NID_sphincssha2128fsimple - open-quantum-safe */ +#ifdef NID_sphincssha2128fsimple +#define PKI_ALGOR_SPHINCS_SHA2_128_F NID_sphincssha2128fsimple +#define PKI_ALGOR_ID_SPHINCS_SHA2_128_F NID_sphincssha2128fsimple +#else +#define PKI_ALGOR_SPHINCS_SHA2_128_F NID_undef +#define PKI_ALGOR_ID_SPHINCS_SHA2_128_F NID_undef +#endif +/* End - NID_sphincssha2128fsimple - open-quantum-safe */ + +/* Begin - NID_sphincssha2128ssimple - open-quantum-safe */ +#ifdef NID_sphincssha2128ssimple +#define PKI_ALGOR_SPHINCS_SHA2_128_S NID_sphincssha2128ssimple +#define PKI_ALGOR_ID_SPHINCS_SHA2_128_S NID_sphincssha2128ssimple +#else +#define PKI_ALGOR_SPHINCS_SHA2_128_S NID_undef +#define PKI_ALGOR_ID_SPHINCS_SHA2_128_S NID_undef +#endif +/* End - NID_sphincssha2128ssimple - open-quantum-safe */ + +/* Begin - NID_sphincssha2192fsimple - open-quantum-safe */ +#ifdef NID_sphincssha2192fsimple +#define PKI_ALGOR_SPHINCS_SHA2_192_F NID_sphincssha2192fsimple +#define PKI_ALGOR_ID_SPHINCS_SHA2_192_F NID_sphincssha2192fsimple +#else +#define PKI_ALGOR_SPHINCS_SHA2_192_F NID_undef +#define PKI_ALGOR_ID_SPHINCS_SHA2_192_F NID_undef +#endif +/* End - NID_sphincssha2192fsimple - open-quantum-safe */ + +/* Begin - NID_sphincssha2192ssimple - open-quantum-safe */ +#ifdef NID_sphincssha2192ssimple +#define PKI_ALGOR_SPHINCS_SHA2_192_S NID_sphincssha2192ssimple +#define PKI_ALGOR_ID_SPHINCS_SHA2_192_S NID_sphincssha2192ssimple +#else +#define PKI_ALGOR_SPHINCS_SHA2_192_S NID_undef +#define PKI_ALGOR_ID_SPHINCS_SHA2_192_S NID_undef +#endif +/* End - NID_sphincssha2192ssimple - open-quantum-safe */ + + + // ============= + // Family: Kyber + // ============= + + +# ifdef OQS_ENABLE_KEM_KYBER + +/* Classic Kyber - Level 1 - 512 */ +# ifdef NID_kyber512 +# define PKI_ALGOR_KYBER512 NID_kyber512 +# define PKI_ALGOR_ID_KYBER512 NID_kyber512 +# else +# define PKI_ALGOR_KYBER512 NID_undef +# define PKI_ALGOR_ID_KYBER512 NID_undef +# endif + +/* Classic Kyber - Level 3 - 768 */ +# ifdef NID_kyber768 +# define PKI_ALGOR_KYBER768 NID_kyber768 +# define PKI_ALGOR_ID_KYBER768 NID_kyber768 +# else +# define PKI_ALGOR_KYBER768 NID_undef +# define PKI_ALGOR_ID_KYBER768 NID_undef +# endif + +/* Classic Kyber - Level 5 - 1024 */ +# ifdef NID_kyber1024 +# define PKI_ALGOR_KYBER1024 NID_kyber1024 +# define PKI_ALGOR_ID_KYBER1024 NID_kyber1024 +# else +# define PKI_ALGOR_KYBER1024 NID_undef +# define PKI_ALGOR_ID_KYBER1024 NID_undef +# endif + +#endif + +/* Begin - Classic McEliece - open-quantum-safe */ +#ifdef OQS_ENABLE_KEM_CLASSIC_MCELIECE + +/* Classic McEliece - Level 1 - 348864 */ +# ifdef OQS_ENABLE_KEM_classic_mceliece_348864 +# define PKI_ALGOR_CLASSIC_MCELIECE1 OQS_ENABLE_KEM_classic_mceliece_348864 +# define PKI_ALGOR_ID_CLASSIC_MCELIECE1 OQS_ENABLE_KEM_classic_mceliece_348864 +# else +# define PKI_ALGOR_CLASSIC_MCELIECE1 NID_undef +# define PKI_ALGOR_ID_CLASSIC_MCELIECE1 NID_undef +# endif + +/* Classic McEliece - Level 2 - 460896 */ +# ifdef OQS_ENABLE_KEM_classic_mceliece_460896 +# define PKI_ALGOR_CLASSIC_MCELIECE2 OQS_ENABLE_KEM_classic_mceliece_460896 +# define PKI_ALGOR_ID_CLASSIC_MCELIECE2 OQS_ENABLE_KEM_classic_mceliece_460896 +# else +# define PKI_ALGOR_CLASSIC_MCELIECE2 NID_undef +# define PKI_ALGOR_ID_CLASSIC_MCELIECE2 NID_undef +# endif + +/* Classic McEliece */ +# ifdef OQS_ENABLE_KEM_classic_mceliece_6688128 +# define PKI_ALGOR_CLASSIC_MCELIECE3 OQS_ENABLE_KEM_classic_mceliece_6688128 +# define PKI_ALGOR_ID_CLASSIC_MCELIECE3 OQS_ENABLE_KEM_classic_mceliece_6688128 +# else +# define PKI_ALGOR_CLASSIC_MCELIECE3 NID_undef +# define PKI_ALGOR_ID_CLASSIC_MCELIECE3 NID_undef +# endif + +/* Classic McEliece */ +# ifdef OQS_ENABLE_KEM_classic_mceliece_6960119 +# define PKI_ALGOR_CLASSIC_MCELIECE4 OQS_ENABLE_KEM_classic_mceliece_6960119 +# define PKI_ALGOR_ID_CLASSIC_MCELIECE4 OQS_ENABLE_KEM_classic_mceliece_6960119 +# else +# define PKI_ALGOR_CLASSIC_MCELIECE4 NID_undef +# define PKI_ALGOR_ID_CLASSIC_MCELIECE4 NID_undef +# endif + +/* Classic McEliece */ +# ifdef OQS_ENABLE_KEM_classic_mceliece_8192128 +# define PKI_ALGOR_CLASSIC_MCELIECE5 OQS_ENABLE_KEM_classic_mceliece_8192128 +# define PKI_ALGOR_ID_CLASSIC_MCELIECE5 OQS_ENABLE_KEM_classic_mceliece_8192128 +# else +# define PKI_ALGOR_CLASSIC_MCELIECE5 NID_undef +# define PKI_ALGOR_ID_CLASSIC_MCELIECE5 NID_undef +# endif + + +#endif +/* End - OQS_ENABLE_KEM_CLASSIC_MCELIECE - open-quantum-safe */ + +// ============================================ // +// Composite Crypto and Post Quantum Algorithms // +// ============================================ // + +/* Begin - NID_rsa3072_falcon512 - open-quantum-safe */ +#ifdef NID_rsa3072_falcon512 +#define PKI_ALGOR_COMPOSITE_RSA_FALCON512 NID_rsa3072_falcon512 +#define PKI_ALGOR_ID_COMPOSITE_RSA_FALCON512 NID_rsa3072_falcon512 +#else +#define PKI_ALGOR_COMPOSITE_RSA_FALCON512 NID_undef +#define PKI_ALGOR_ID_COMPOSITE_RSA_FALCON512 NID_undef +#endif +/* End - NID_rsa3072_falcon512 - open-quantum-safe */ + +/* Begin - NID_p256_falcon512 - open-quantum-safe */ +#ifdef NID_p256_falcon512 +#define PKI_ALGOR_COMPOSITE_ECDSA_FALCON512 NID_p256_falcon512 +#define PKI_ALGOR_ID_COMPOSITE_ECDSA_FALCON512 NID_p256_falcon512 +#else +#define PKI_ALGOR_COMPOSITE_ECDSA_FALCON512 NID_undef +#define PKI_ALGOR_ID_COMPOSITE_ECDSA_FALCON512 NID_undef +#endif +/* End - NID_p256_falcon512 - open-quantum-safe */ + +/* Begin - NID_p521_falcon1024 - open-quantum-safe */ +#ifdef NID_p521_falcon1024 +#define PKI_ALGOR_COMPOSITE_ECDSA_FALCON1024 NID_p521_falcon1024 +#define PKI_ALGOR_ID_COMPOSITE_ECDSA_FALCON1024 NID_p521_falcon1024 +#else +#define PKI_ALGOR_COMPOSITE_ECDSA_FALCON1024 NID_undef +#define PKI_ALGOR_ID_COMPOSITE_ECDSA_FALCON1024 NID_undef +#endif +/* End - NID_p521_falcon1024 - open-quantum-safe */ + +/* Begin - NID_rsa3072_dilithium2 - open-quantum-safe */ +#ifdef NID_rsa3072_dilithium2 +#define PKI_ALGOR_COMPOSITE_RSA_DILITHIUM2 NID_rsa3072_dilithium2 +#define PKI_ALGOR_ID_COMPOSITE_RSA_DILITHIUM2 NID_rsa3072_dilithium2 +#else +#define PKI_ALGOR_COMPOSITE_RSA_DILITHIUM2 NID_undef +#define PKI_ALGOR_ID_COMPOSITE_RSA_DILITHIUM2 NID_undef +#endif +/* End - NID_rsa3072_dilithium2 - open-quantum-safe */ + +/* Begin - NID_rsa3072_dilithium2_aes - open-quantum-safe */ +#ifdef NID_rsa3072_dilithium2_aes +#define PKI_ALGOR_COMPOSITE_RSA_DILITHIUM2_AES NID_rsa3072_dilithium2_aes +#define PKI_ALGOR_ID_COMPOSITE_RSA_DILITHIUM2_AES NID_rsa3072_dilithium2_aes +#else +#define PKI_ALGOR_COMPOSITE_RSA_DILITHIUM2_AES NID_undef +#define PKI_ALGOR_ID_COMPOSITE_RSA_DILITHIUM2_AES NID_undef +#endif +/* End - NID_rsa3072_dilithium2_aes - open-quantum-safe */ + +/* Begin - NID_p256_dilithium2 - open-quantum-safe */ +#ifdef NID_p256_dilithium2 +#define PKI_ALGOR_COMPOSITE_ECDSA_DILITHIUM2 NID_p256_dilithium2 +#define PKI_ALGOR_ID_COMPOSITE_ECDSA_DILITHIUM2 NID_p256_dilithium2 +#else +#define PKI_ALGOR_COMPOSITE_ECDSA_DILITHIUM2 NID_undef +#define PKI_ALGOR_ID_COMPOSITE_ECDSA_DILITHIUM2 NID_undef +#endif +/* End - NID_p256_dilithium2 - open-quantum-safe */ + +/* Begin - NID_p384_dilithium3 - open-quantum-safe */ +#ifdef NID_p384_dilithium3 +#define PKI_ALGOR_COMPOSITE_ECDSA_DILITHIUM3 NID_p384_dilithium3 +#define PKI_ALGOR_ID_COMPOSITE_ECDSA_DILITHIUM3 NID_p384_dilithium3 +#else +#define PKI_ALGOR_COMPOSITE_ECDSA_DILITHIUM3 NID_undef +#define PKI_ALGOR_ID_COMPOSITE_ECDSA_DILITHIUM3 NID_undef +#endif +/* End - NID_p384_dilithium3 - open-quantum-safe */ + +/* Begin - NID_p521_dilithium5 - open-quantum-safe */ +#ifdef NID_p521_dilithium5 +#define PKI_ALGOR_COMPOSITE_ECDSA_DILITHIUM5 NID_p521_dilithium5 +#define PKI_ALGOR_ID_COMPOSITE_ECDSA_DILITHIUM5 NID_p521_dilithium5 +#else +#define PKI_ALGOR_COMPOSITE_ECDSA_DILITHIUM5 NID_undef +#define PKI_ALGOR_ID_COMPOSITE_ECDSA_DILITHIUM5 NID_undef +#endif +/* End - NID_p521_dilithium5 - open-quantum-safe */ + +/* Begin - NID_p256_dilithium2_aes - open-quantum-safe */ +#ifdef NID_p256_dilithium2_aes +#define PKI_ALGOR_COMPOSITE_ECDSA_DILITHIUM2_AES NID_p256_dilithium2_aes +#define PKI_ALGOR_ID_COMPOSITE_ECDSA_DILITHIUM2_AES NID_p256_dilithium2_aes +#else +#define PKI_ALGOR_COMPOSITE_ECDSA_DILITHIUM2_AES NID_undef +#define PKI_ALGOR_ID_COMPOSITE_ECDSA_DILITHIUM2_AES NID_undef +#endif +/* End - NID_p256_dilithium2_aes - open-quantum-safe */ + +/* Begin - NID_p384_dilithium3_aes - open-quantum-safe */ +#ifdef NID_p384_dilithium3_aes +#define PKI_ALGOR_COMPOSITE_ECDSA_DILITHIUM3_AES NID_p384_dilithium3_aes +#define PKI_ALGOR_ID_COMPOSITE_ECDSA_DILITHIUM3_AES NID_p384_dilithium3_aes +#else +#define PKI_ALGOR_COMPOSITE_ECDSA_DILITHIUM3_AES NID_undef +#define PKI_ALGOR_ID_COMPOSITE_ECDSA_DILITHIUM3_AES NID_undef +#endif +/* End - NID_p384_dilithium3_aes - open-quantum-safe */ + +/* Begin - NID_p521_dilithium5_aes - open-quantum-safe */ +#ifdef NID_p521_dilithium5_aes +#define PKI_ALGOR_COMPOSITE_ECDSA_DILITHIUM5_AES NID_p521_dilithium5_aes +#define PKI_ALGOR_ID_COMPOSITE_ECDSA_DILITHIUM5_AES NID_p521_dilithium5_aes +#else +#define PKI_ALGOR_COMPOSITE_ECDSA_DILITHIUM5_AES NID_undef +#define PKI_ALGOR_ID_COMPOSITE_ECDSA_DILITHIUM5_AES NID_undef +#endif +/* End - NID_p521_dilithium5_aes - open-quantum-safe */ + +/* Begin - NID_p256_sphincssha256128frobust - open-quantum-safe */ +#ifdef NID_p256_sphincssha256128frobust +#define PKI_ALGOR_COMPOSITE_P256_SPHINCS_SHA256 NID_p256_sphincssha256128frobust +#define PKI_ALGOR_ID_COMPOSITE_P256_SPHINCS_SHA256 NID_p256_sphincssha256128frobust +#else +#define PKI_ALGOR_COMPOSITE_P256_SPHINCS_SHA256 NID_undef +#define PKI_ALGOR_ID_COMPOSITE_P256_SPHINCS_SHA256 NID_undef +#endif +/* End - NID_p256_sphincssha256128frobust - open-quantum-safe */ + +/* Begin - NID_p256_sphincsshake256128frobust - open-quantum-safe */ +#ifdef NID_p256_sphincsshake256128frobust +#define PKI_ALGOR_COMPOSITE_P256_SPHINCS_SHAKE256 NID_p256_sphincsshake256128frobust +#define PKI_ALGOR_ID_COMPOSITE_P256_SPHINCS_SHAKE256 NID_p256_sphincsshake256128frobust +#else +#define PKI_ALGOR_P256_COMPOSITE_SPHINCS_SHAKE256 NID_undef +#define PKI_ALGOR_ID_P256_COMPOSITE_SPHINCS_SHAKE256 NID_undef +#endif +/* End - NID_p256_sphincsshake256128frobust - open-quantum-safe */ + +// ======================================== // +// Composite Crypto and Composite_OR Crypto // +// ======================================== // + +// /* Begin - NID_composite */ +// #ifdef ENABLE_COMBINED +// #define PKI_ALGOR_COMBINED NID_combined; +// #define PKI_ALGOR_ID_COMBINED NID_combined; +// #define int PKI_ALGOR_COMBINED NID_combined; +// #define int PKI_ALGOR_ID_COMBINED NID_combined; +// #else +// #define PKI_ALGOR_COMBINED NID_undef; +// #define PKI_ALGOR_ID_COMBINED NID_undef; +// #endif +// /* End - NID_combined */ + +// // /* Begin - NID_composite */ +// // #ifdef ENABLE_COMPOSITE +// // #define PKI_ALGOR_ID_COMPOSITE NID_composite +// // #define PKI_ALGOR_COMPOSITE_OR NID_composite +// // #define PKI_ALGOR_ID_COMPOSITE_OR NID_composite +// // #else +// // #define PKI_ALGOR_COMPOSITE_OR NID_undef; +// // #define PKI_ALGOR_ID_COMPOSITE_OR NID_undef; +// // #endif +// // /* End - NID_rsa3072_falcon512 */ + +/* Default DIGEST algorithm */ +#ifdef ENABLE_SHA256 +#define PKI_DIGEST_ALG_DEFAULT PKI_DIGEST_ALG_SHA256 +#define PKI_DIGEST_ALG_ID_DEFAULT PKI_ALGOR_ID_SHA256 +#define PKI_ALGOR_DEFAULT PKI_ALGOR_ID_RSA_SHA256 +#define PKI_ALGOR_ID_DEFAULT PKI_ALGOR_ID_RSA_SHA256 +#else +#define PKI_DIGEST_ALG_DEFAULT PKI_DIGEST_ALG_SHA1 +#define PKI_DIGEST_ALG_ID_DEFAULT PKI_ALGOR_ID_SHA1 +#define PKI_ALGOR_DEFAULT PKI_ALGOR_ID_RSA_SHA1 +#define PKI_ALGOR_ID_DEFAULT PKI_ALGOR_ID_RSA_SHA1 +#endif + +#define PKI_OID ASN1_OBJECT +#define PKI_TIME ASN1_GENERALIZEDTIME +#define PKI_INTEGER ASN1_INTEGER +#define PKI_OCTET_STRING ASN1_OCTETSTRING + +/* This should capture all the EVP_CIPHERS available, for example + * for des, use PKI_CIPHER(des, ede, cbc), for 3des use + * PKI_CIPHER(des,ede3,cbc). For AES, instead, use the */ +// #define PKI_CIPHER(name,bits,mode) EVP_ ##name _ ##bits _ ##mode() + +/* Empty - Does nothing */ +#define PKI_CIPHER_NULL EVP_enc_null() + +/* This should capture all the AES ciphers */ +#define PKI_CIPHER_AES(bits,mode) PKI_CIPHER_AES_##bits (mode) +#define PKI_CIPHER_AES_128(mode) EVP_aes_128_ ##mode () +#define PKI_CIPHER_AES_192(mode) EVP_aes_192_ ##mode () +#define PKI_CIPHER_AES_256(mode) EVP_aes_256_ ##mode () + +/* This should capture all the DESX ciphers */ +#define PKI_CIPHER_DESX(mode) EVP_desx_##mode () + +/* This should capture all the DES ciphers */ +#define PKI_CIPHER_DES(mode) EVP_des_##mode () + +/* This should capture all the DESX ciphers */ +#define PKI_CIPHER_3DES(mode) EVP_des_ede3_##mode () + +/* This should capture all the DESX ciphers */ +#define PKI_CIPHER_IDEA(mode) EVP_idea_##mode () + +/* This should capture all the DESX ciphers */ +#define PKI_CIPHER_CAST5(mode) EVP_cast5_##mode () + +/* This should capture all the CAMELLIA ciphers */ +#define PKI_CIPHER_CAMELLIA(bits,mode) PKI_CIPHER_CAMELLIA_##bits (mode) +#define PKI_CIPHER_CAMELLIA_128(mode) EVP_camellia_128_##mode () +#define PKI_CIPHER_CAMELLIA_192(mode) EVP_camellia_192_##mode () +#define PKI_CIPHER_CAMELLIA_256(mode) EVP_camellia_256_##mode () + + +/* Old Ciphers */ +#define PKI_CIPHER_RC5(mode) EVP_rc5_##mode () +#define PKI_CIPHER_RC2(mode) EVP_rc2_##mode () + +/* ECDSA - NIST curves easy identifiers */ +/* prime field curves */ +#define NID_P192 NID_X9_62_prime192v1 +#define NID_P224 NID_secp224r1 +#define NID_P256 NID_X9_62_prime256v1 +#define NID_P384 NID_secp384r1 +#define NID_P521 NID_secp521r1 +/* characteristic two field curves */ +#define NID_K163 NID_sect163k1 +#define NID_K233 NID_sect233k1 +#define NID_K283 NID_sect283k1 +#define NID_K409 NID_sect409k1 +#define NID_K571 NID_sect571k1 + +#define NID_B163 NID_sect163r2 +#define NID_B233 NID_sect233r1 +#define NID_B283 NID_sect283r1 +#define NID_B409 NID_sect409r1 +#define NID_B571 NID_sect571r1 + +#ifdef ENABLE_ECDSA +#define PKI_EC_KEY_CURVE_DEFAULT NID_P256 +#else +#define PKI_EC_KEY_CURVE_DEFAULT NID_undef +#endif + +/* Directly Supported Relative Distinguished Name Types (RDN) */ + +typedef enum { + PKI_X509_NAME_TYPE_NONE = NID_undef, + PKI_X509_NAME_TYPE_UNKNOWN = NID_undef, + PKI_X509_NAME_TYPE_DC = NID_domainComponent , + PKI_X509_NAME_TYPE_O = NID_organizationName , + PKI_X509_NAME_TYPE_OU = NID_organizationalUnitName , + PKI_X509_NAME_TYPE_C = NID_countryName, + PKI_X509_NAME_TYPE_ST = NID_stateOrProvinceName , + PKI_X509_NAME_TYPE_L = NID_localityName , + PKI_X509_NAME_TYPE_CN = NID_commonName, + PKI_X509_NAME_TYPE_EMAIL= NID_pkcs9_emailAddress , +#ifdef NID_uniqueIdentifier + PKI_X509_NAME_TYPE_UID = NID_uniqueIdentifier , +#else + PKI_X509_NAME_TYPE_UID = 102 , +#endif + PKI_X509_NAME_TYPE_SN = NID_serialNumber , + // Strange Types - do not use them... :D + PKI_X509_NAME_TYPE_S = NID_surname , + PKI_X509_NAME_TYPE_G = NID_givenName , + PKI_X509_NAME_TYPE_I = NID_initials , + PKI_X509_NAME_TYPE_T = NID_title , + PKI_X509_NAME_TYPE_D = NID_description , + PKI_X509_NAME_TYPE_name = NID_name , + PKI_X509_NAME_TYPE_dnQualifier = NID_dnQualifier , + PKI_X509_NAME_TYPE_DATA = NID_data , + PKI_X509_NAME_TYPE_SERIALNUMBER = NID_serialNumber , +} PKI_X509_NAME_TYPE; + +// PKI_X509_NAME_RDN - useful when getting specific parts of a DN only +typedef struct pki_x509_name_rdn { + PKI_X509_NAME_TYPE type; + char * value; +} PKI_X509_NAME_RDN; + +/// @brief Internal Value for LibPKI extensions +#define PKI_X509_EXTENSION_VALUE X509_EXTENSION + +// Missing definition from OpenSSL (x509v3.h) +typedef STACK_OF(ACCESS_DESCRIPTION) SUBJECT_INFO_ACCESS; + +/// @brief LibPKI Extension's Generic Data Structure +typedef struct pki_x509_extension_st { + int type; + int critical; + PKI_OID *oid; + union { + void * ptr; + PKI_X509_EXTENSION_VALUE * x509_ext; + BASIC_CONSTRAINTS * basicConstraints; + PKEY_USAGE_PERIOD * usagePeriod; + ASN1_OCTET_STRING * subjectKeyIdentifier; + AUTHORITY_INFO_ACCESS * authorityInfoAccess; + SUBJECT_INFO_ACCESS * subjectInfoAccess; + EXTENDED_KEY_USAGE * extendedKeyUsage; + CRL_DIST_POINTS * crlDistributionPoints; + AUTHORITY_KEYID * authorityKeyIdentifier; + OTHERNAME * otherName; + POLICY_CONSTRAINTS * policyConstraints; + POLICY_MAPPING * policyMapping; + STACK_OF(GENERAL_NAMES *) subjectAltNames; + NAME_CONSTRAINTS * nameConstraints; + ASN1_INTEGER * inhibitAnyPolicy; + CRL_DIST_POINTS * freshestCRL; + ASN1_INTEGER * crlNumber; + ISSUING_DIST_POINT * issuingDistributionPoint; // CRLs + } value; +} PKI_X509_EXTENSION; + + +// Typedef for EC Form +typedef point_conversion_form_t PKI_EC_KEY_FORM; + +// Defines for supported EC Form +#define PKI_EC_KEY_FORM_UNKNOWN 0 +#define PKI_EC_KEY_FORM_COMPRESSED POINT_CONVERSION_COMPRESSED +#define PKI_EC_KEY_FORM_UNCOMPRESSED POINT_CONVERSION_UNCOMPRESSED +#define PKI_EC_KEY_FORM_HYBRID POINT_CONVERSION_HYBRID + +// Default Value +#define PKI_EC_KEY_FORM_DEFAULT PKI_EC_KEY_FORM_UNCOMPRESSED + +// ASN1 flags for EC keys +typedef enum { + PKI_EC_KEY_ASN1_EXPLICIT_CURVE = OPENSSL_EC_EXPLICIT_CURVE, + PKI_EC_KEY_ASN1_NAMED_CURVE = OPENSSL_EC_NAMED_CURVE, + PKI_EC_KEY_ASN1_IMPLICIT_CURVE = -1 +} PKI_EC_KEY_ASN1; + +// Default for ASN1 flag +#define PKI_EC_KEY_ASN1_DEFAULT PKI_EC_KEY_ASN1_NAMED_CURVE + +typedef struct pki_keyparams_st { + int bits; + int sec_bits; + int pq_sec_bits; + + PKI_SCHEME_ID scheme; + PKI_ALGOR_ID pkey_type; + + // RSA scheme parameters + struct { + int exponent; + int bits; + } rsa; + // DSA scheme parameters + + struct { + int bits; + } dsa; + +#ifdef ENABLE_ECDSA + // EC scheme parameters + struct { + int curve; + PKI_EC_KEY_FORM form; + int asn1flags; + } ec; +#endif // ENABLE_ECDSA + +#if defined(ENABLE_OQS) || defined(ENABLE_OQSPROV) + struct { + PKI_ALGOR_ID algId; + } oqs; +#endif // ENABLE_OQS + +#ifdef ENABLE_COMPOSITE + struct { + PKI_ALGOR_ID algorithm; + PKI_X509_KEYPAIR_STACK * k_stack; + ASN1_INTEGER * k_of_n; + } comp; +#endif + +} PKI_KEYPARAMS; + +#if defined(ENABLE_OQS) || defined(ENABLE_OQSPROV) + +typedef enum { + PKI_ALGOR_OQS_PARAM_UNKNOWN = 0, + PKI_ALGOR_OQS_PARAM_DILITHIUM_AES, + PKI_ALGOR_OQS_PARAM_SPHINCS_SHAKE +} PKI_ALGOR_OQS_PARAM; + +#endif + +typedef X509_REVOKED PKI_X509_CRL_ENTRY; + +typedef struct pki_digest_data { + const PKI_DIGEST_ALG *algor; + unsigned char *digest; + size_t size; +} CRYPTO_DIGEST; + +typedef struct pki_store_st { + void *store_ptr; +} PKI_STORE; + +#define PKI_X509_KEYPAIR_VALUE EVP_PKEY +#define PKI_X509_KEYPAIR PKI_X509 + +#define PKI_X509_CERT_VALUE X509 +#define PKI_X509_CERT PKI_X509 + +#define PKI_X509_REQ_VALUE X509_REQ +#define PKI_X509_REQ PKI_X509 + +#define PKI_X509_CRL_VALUE X509_CRL +#define PKI_X509_CRL PKI_X509 + +#define PKI_X509_PKCS7_VALUE PKCS7 +#define PKI_X509_PKCS7 PKI_X509 + +#define PKI_X509_CMS_VALUE CMS_ContentInfo +#define PKI_X509_CMS PKI_X509 + +#define PKI_X509_CMS_SIGNER_INFO CMS_SignerInfo +#define PKI_X509_CMS_RECIPIENT_INFO CMS_RecipientInfo + +#define PKI_X509_PKCS12_VALUE PKCS12 +#define PKI_X509_PKCS12_DATA STACK_OF(PKCS7) +#define PKI_X509_PKCS12 PKI_X509 + +#define PKI_OCSP_REQ_SINGLE OCSP_ONEREQ +#define PKI_OCSP_CERTID OCSP_CERTID + +#define PKI_X509_OCSP_REQ_VALUE OCSP_REQUEST +#define PKI_X509_OCSP_REQ PKI_X509 + +/* OCSP support */ + +typedef enum { + PKI_OCSP_CERTSTATUS_GOOD = V_OCSP_CERTSTATUS_GOOD, + PKI_OCSP_CERTSTATUS_REVOKED = V_OCSP_CERTSTATUS_REVOKED, + PKI_OCSP_CERTSTATUS_UNKNOWN = V_OCSP_CERTSTATUS_UNKNOWN +} PKI_OCSP_CERTSTATUS; + +typedef enum { + PKI_X509_OCSP_RESP_STATUS_SUCCESSFUL = 0, + PKI_X509_OCSP_RESP_STATUS_MALFORMEDREQUEST = 1, + PKI_X509_OCSP_RESP_STATUS_INTERNALERROR = 2, + PKI_X509_OCSP_RESP_STATUS_TRYLATER = 3, + PKI_X509_OCSP_RESP_STATUS_SIGREQUIRED = 5, + PKI_X509_OCSP_RESP_STATUS_UNAUTHORIZED = 6 +} PKI_X509_OCSP_RESP_STATUS; + +//! @brief LibPKI X509 OCSP Response Structure +typedef struct pki_ocsp_resp_st { + PKI_X509_OCSP_RESP_STATUS status; //! Status of the response + OCSP_RESPONSE * resp; // ! OCSP Response + OCSP_BASICRESP * bs; //! OCSP Basic Response +} PKI_X509_OCSP_RESP_VALUE; + +//! @brief OCSP Response Backward Compatibility name +#define PKI_OCSP_RESP PKI_X509_OCSP_RESP_VALUE +typedef enum { + PKI_X509_OCSP_RESPID_NOT_SET = -1, + PKI_X509_OCSP_RESPID_TYPE_BY_NAME = 0, + PKI_X509_OCSP_RESPID_TYPE_BY_KEYID = 1 +} PKI_X509_OCSP_RESPID_TYPE; + +#define PKI_X509_OCSP_BASICRESP_VALUE OCSP_BASICRESP + +// #define PKI_X509_OCSP_RESP_VALUE OCSP_RESPONSE +#define PKI_X509_OCSP_RESP PKI_X509 + +#define PKI_X509_XPAIR_VALUE PKI_XPAIR +#define PKI_X509_XPAIR PKI_X509 + +#define PKI_X509_PRQP_REQ_VALUE PKI_PRQP_REQ +#define PKI_X509_PRQP_REQ PKI_X509 + +#define PKI_X509_PRQP_RESP_VALUE PKI_PRQP_RESP +#define PKI_X509_PRQP_RESP PKI_X509 + +#include +#include + +#define __B64_write_bio_internal(type,bio,data,p) ({ BIO *b64; int r;\ + b64 = BIO_new(BIO_f_base64()) ; \ + bio = BIO_push(b64, bio) ; \ + r = i2d_##type##p(bio, data); \ + BIO_flush(bio); \ + bio = BIO_pop(bio); \ + BIO_free(b64); PKI_OK ;}) + +#define B64_write_bio(type,bio,data) \ + __B64_write_bio_internal(type,bio,data,_bio) + + +/* End of _LIBPKI_HEADER_DATA_ST_H */ +#endif diff --git a/include/libpki/crypto/hsm/openssl/openssl_data_store.h b/include/libpki/crypto/hsm/openssl/openssl_data_store.h new file mode 100644 index 00000000..0d57f982 --- /dev/null +++ b/include/libpki/crypto/hsm/openssl/openssl_data_store.h @@ -0,0 +1,19 @@ +/* OpenCA libpki package +* (c) 2000-2006 by Massimiliano Pala and OpenCA Group +* All Rights Reserved +* +* =================================================================== +* Released under OpenCA LICENSE +*/ + +#ifndef _LIBPKI_HEADER_OPENSSL_DATA_ST_H +#define _LIBPKI_HEADER_OPENSSL_DATA_ST_H + +#include + +typedef struct pki_openssl_store_st { + void *store_ptr; +} PKI_OPENSSL_STORE; + +/* End of _LIBPKI_HEADER_OPENSSL_DATA_ST_H */ +#endif diff --git a/include/libpki/crypto/hsm/openssl/openssl_hsm.c b/include/libpki/crypto/hsm/openssl/openssl_hsm.c new file mode 100644 index 00000000..3d00fc68 --- /dev/null +++ b/include/libpki/crypto/hsm/openssl/openssl_hsm.c @@ -0,0 +1,441 @@ +/* HSM Object Management Functions */ + +// Single Include +#include + +/* Callbacks for Software OpenSSL HSM */ +const HSM_CALLBACKS openssl_hsm_callbacks = { + /* Errno */ + HSM_OPENSSL_get_errno, + /* Err Descr */ + HSM_OPENSSL_get_errdesc, + /* Init */ + HSM_OPENSSL_init, + /* Free */ + HSM_OPENSSL_free, + /* Login */ + NULL, + /* Logout */ + NULL, + /* Set Algorithm */ + NULL, /* HSM_OPENSSL_algor_set, */ + /* Set fips mode */ + HSM_OPENSSL_set_fips_mode, + /* Fips operation mode */ + HSM_OPENSSL_is_fips_mode, + /* General Sign */ + NULL, /* HSM_OPENSSL_sign, */ + /* ASN1 General Sign */ + NULL, /* HSM_OPENSSL_asn1_sign, */ + /* General Verify */ + NULL, /* HSM_OPENSSL_verify, */ + /* ASN1 General Verify */ + NULL, /* HSM_OPENSSL_verify, */ + /* Key Generation */ + HSM_OPENSSL_X509_KEYPAIR_new, + /* Free Keypair Function */ + HSM_OPENSSL_X509_KEYPAIR_free, + /* Key Wrapping */ + NULL, // HSM_OPENSSL_X509_KEYPAIR_STACK_wrap, + /* Key Unwrapping */ + NULL, // HSM_OPENSSL_X509_KEYPAIR_STACK_unwrap, + /* Obj Load Function */ + NULL, // HSM_OPENSSL_X509_STACK_get_url, + /* Obj Add Function */ + NULL, // HSM_OPENSSL_X509_STACK_put_url, + /* Obj Del Function */ + NULL, /* HSM_OPENSSL_X509_STACK_del_url */ + /* Get the number of available Slots */ + NULL, // HSM_OPENSSL_SLOT_num, + /* Get Slot info */ + HSM_OPENSSL_SLOT_INFO_get, + /* Free Slot info */ + NULL, /* HSM_OPENSSL_SLOT_INFO_free */ + /* Set the current slot */ + NULL, /* HSM_OPENSSL_SLOT_select */ + /* Cleans up the current slot */ + NULL, /* HSM_OPENSSL_SLOT_clean */ + /* Get X509 Callbacks */ + HSM_OPENSSL_X509_get_cb +}; + +/* Structure for PKI_TOKEN definition */ +HSM openssl_hsm = { + + /* Version of the token */ + 1, + + /* Description of the HSM */ + "OpenSSL Software HSM", + + /* Manufacturer */ + "OpenSSL Project", + + /* Pointer to the HSM config file and parsed structure*/ + NULL, + + /* One of PKI_HSM_TYPE value */ + HSM_TYPE_SOFTWARE, + + /* URL for the ID of the driver, this is filled at load time */ + NULL, + + /* Pointer to the driver structure */ + NULL, + + /* Pointer to internal session handler */ + NULL, + + /* Credential for the HSM - usually used for the SO */ + NULL, + + /* is Logged In ? */ + 0, + + /* is Cred Set ? */ + 0, + + /* is Login Required ? */ + 0, + + /* Callbacks Structures */ + &openssl_hsm_callbacks +}; + + +HSM_SLOT_INFO openssl_slot_info = { + + /* Device Manufacturer ID */ + "OpenSSL", + + /* Device Description */ + "Software interface", + + /* Hardware Version */ + 1, + 0, + + /* Firmware Version */ + 1, + 0, + + /* Initialized */ + 1, + + /* Present */ + 1, + + /* Removable */ + 0, + + /* Hardware */ + 0, + + /* Token Info */ + { + /* Token Label */ + "Unknown Label\x0 ", + /* ManufacturerID */ + "Unknown\x0 ", + /* Model */ + "Unknown\x0 ", + /* Serial Number */ + "0\x0 ", + /* Max Sessions */ + 65535, + /* Current Sessions */ + 0, + /* Max Pin Len */ + 0, + /* Min Pin Len */ + 0, + /* Memory Pub Total */ + 0, + /* Memory Pub Free */ + 0, + /* Memory Priv Total */ + 0, + /* Memory Priv Free */ + 0, + /* HW Version Major */ + 1, + /* HW Version Minor */ + 0, + /* FW Version Major */ + 1, + /* FW Version Minor */ + 0, + /* HAS Random Number Generator (RNG) */ + 1, + /* HAS clock */ + 0, + /* Login is Required */ + 0, + /* utcTime */ + "" + } + +}; + +unsigned long HSM_OPENSSL_get_errno ( void ) +{ + unsigned long ret = 0; + + ret = ERR_get_error(); + + return ret; +} + +char * HSM_OPENSSL_get_errdesc ( unsigned long err, char *str, size_t size ) +{ + char * ret = NULL; + + if (err == 0) err = ERR_get_error(); + + if (str && size > 0) + { + ERR_error_string_n ( err, str, size ); + ret = str; + } + else ret = ERR_error_string(err, NULL); + + return ret; +} + +const HSM * HSM_OPENSSL_get_default( void ) +{ + return ((const HSM *)&openssl_hsm); +} + +HSM *HSM_OPENSSL_new ( PKI_CONFIG *conf ) +{ + HSM *hsm = NULL; + + hsm = (HSM *) PKI_Malloc ( sizeof( HSM )); + memcpy( hsm, &openssl_hsm, sizeof( HSM)); + + /* Not really needed! */ + hsm->callbacks = &openssl_hsm_callbacks; + + if( conf ) { + hsm->config = conf; + } + + hsm->type = HSM_TYPE_SOFTWARE; + + return( hsm ); +} + +int HSM_OPENSSL_free ( HSM *driver, PKI_CONFIG *conf ) { + + if( driver == NULL ) return (PKI_OK); + + return (PKI_ERR); +} + +int HSM_OPENSSL_init( HSM *driver, PKI_CONFIG *conf ) { + + if( driver == NULL ) return (PKI_ERR); + + /* Checks the FIPS mode */ + if (PKI_is_fips_mode() == PKI_OK) + { + if (HSM_OPENSSL_set_fips_mode(driver, 1) == PKI_ERR) + return PKI_ERR; + } + + /* No need for initialization of the software driver */ + return PKI_OK; +} + +/*! + * \brief Sets the fips operation mode when the parameter is != 0, + * otherwise it sets the HSM in non-fips mode + */ +int HSM_OPENSSL_set_fips_mode(const HSM *driver, int k) { + +#ifdef OPENSSL_FIPS + return (FIPS_mode_set(k) == 1 ? PKI_OK : PKI_ERR); +#else + return PKI_ERR; +#endif + +} + +/*! + * \brief Returns 0 if HSM is operating in non-FIPS mode, true (!0) if FIPS + * mode is enabled. + */ +int HSM_OPENSSL_is_fips_mode(const HSM *driver) +{ +#ifdef OPENSSL_FIPS + return (FIPS_mode() == 0 ? PKI_ERR : PKI_OK); +#else + return PKI_ERR; +#endif + +} + +/* ----------------------- General Signing function -------------------- */ + +// PKI_MEM * HSM_OPENSSL_sign(PKI_MEM * der, PKI_DIGEST_ALG * digest, PKI_X509_KEYPAIR *key) { + +// EVP_MD_CTX *ctx = NULL; +// // Digest's context + +// size_t out_size = 0; +// // size_t ossl_ret = 0; + +// PKI_MEM *out_mem = NULL; +// // Output buffer + +// EVP_PKEY *pkey = NULL; +// // Signing Key Value + +// int digestResult = -1; +// int def_nid = NID_undef; +// // OpenSSL return value + +// if (!der || !der->data || !key || !key->value) +// { +// PKI_ERROR( PKI_ERR_PARAM_NULL, NULL); +// return NULL; +// } + +// // Private Key +// pkey = PKI_X509_get_value(key); +// if (!pkey) { +// PKI_ERROR(PKI_ERR_PARAM_NULL, "Cannot retrieve the internal value of the key (PKEY)."); +// return NULL; +// } + +// // Get the Maximum size of a signature +// out_size = (size_t) EVP_PKEY_size(pkey); + +// // Gets the default digest for the key +// digestResult = EVP_PKEY_get_default_digest_nid(pkey, &def_nid); + +// // PKI_DEBUG("Requested Digest for Signing is %s", digest ? PKI_ID_get_txt(EVP_MD_nid(digest)) : "NULL"); +// // PKI_DEBUG("Checking Default Digest for PKEY %d (%s) is %d (%s) (result = %d)", +// // EVP_PKEY_id(pkey), PKI_ID_get_txt(EVP_PKEY_id(pkey)), def_nid, PKI_ID_get_txt(def_nid), digestResult); + +// // Checks for error +// if (digest == NULL && digestResult <= 0) { +// PKI_DEBUG("Cannot get the default digest for signing key (type: %d)", EVP_PKEY_id(pkey)); +// return NULL; +// } + +// // If the returned value is == 2, then the returned +// // digest is mandatory and cannot be replaced +// if (digestResult == 2 && def_nid != EVP_MD_nid(digest)) { +// // // Checks if we are in a no-hash mandatory +// // if (def_nid == NID_undef && (digest != EVP_md_null() && digest != NULL)) { +// // PKI_DEBUG("PKEY requires no hash but got one (%d)", EVP_MD_nid(digest)); +// // return NULL; +// // } +// // // Checks if we are using the mandated digest +// // if ((digest != NULL && def_nid != NID_undef) || (def_nid != EVP_MD_nid(digest))) { +// // PKI_DEBUG("PKEY requires digest (%d) but got (%d)", def_nid, EVP_MD_nid(digest)); +// // return NULL; +// // } +// PKI_DEBUG("PKEY requires %s digest (mandatory) and cannot be used with %s digest (requested).", +// def_nid == NID_undef ? "NO" : PKI_ID_get_txt(def_nid), +// digest == NULL ? "NO" : PKI_ID_get_txt(EVP_MD_nid(digest))); +// return NULL; +// } + +// // Initialize the return structure +// if ((out_mem = PKI_MEM_new ((size_t)out_size)) == NULL) { +// PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); +// return NULL; +// } + +// // Creates the context +// if ((ctx = EVP_MD_CTX_create()) == NULL) { +// PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); +// goto err; +// } + +// // Initializes the Context +// EVP_MD_CTX_init(ctx); + +// // PKI_DEBUG("MD (digest) = %p (EVP_md_null = %p) (EVP_md_null() ==> %d)", +// // digest, EVP_md_null, EVP_md_null() == digest); + +// // DEBUG +// // PKI_DEBUG("MD (digest) in DigestSignInit: %d (%s)", +// // digest ? EVP_MD_nid(digest) : NID_undef, digest ? PKI_DIGEST_ALG_get_parsed(digest) : ""); + +// // Initializes the Digest and does special processing for when the +// // EVP_md_null() is used to indicate that the NO HASH was requested +// if (!EVP_DigestSignInit(ctx, NULL /* &pctx */, EVP_md_null() == digest ? NULL : digest, NULL, pkey)) { +// PKI_ERROR(PKI_ERR_SIGNATURE_CREATE, "Cannot Initialize EVP_DigestSignInit()"); +// goto err; +// } + +// if (EVP_DigestSign(ctx, out_mem->data, &out_size, der->data, der->size) <= 0) { +// PKI_ERROR(PKI_ERR_SIGNATURE_CREATE, "Cannot generate signature via EVP_DigestSign()"); +// goto err; +// } + +// // Update the size of the signature +// out_mem->size = (size_t) out_size; + +// // // Updates the Digest calculation with the TBS data +// // if (EVP_DigestSignUpdate(ctx, +// // der->data, +// // der->size) <= 0) { +// // PKI_ERROR(PKI_ERR_SIGNATURE_CREATE, "Cannot Update EVP_DigestSignUpdate()"); +// // goto err; +// // } + +// // // Finalize the MD +// // // EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_FINALISE); + +// // // Finalizes the Signature calculation and saves it in the output buffer +// // if (EVP_DigestSignFinal(ctx, +// // out_mem->data, +// // &out_size) <= 0) { +// // PKI_ERROR(PKI_ERR_SIGNATURE_CREATE, "Cannot Finalize EVP_DigestSignFinal()"); +// // goto err; +// // } +// // else out_mem->size = (size_t) out_size; + +// // All Done +// goto end; + +// err: + +// // Error Condition, free the output's memory +// if (out_mem) PKI_MEM_free(out_mem); +// out_mem = NULL; + +// end: +// // Cleanup the context +// #if OPENSSL_VERSION_NUMBER <= 0x1010000f +// if (ctx) EVP_MD_CTX_cleanup(ctx); +// #else +// if (ctx) EVP_MD_CTX_reset(ctx); +// #endif + +// // Frees the CTX structure +// if (ctx) EVP_MD_CTX_destroy(ctx); + +// // Returns the result or NULL +// return out_mem; +// } + +/* ---------------------- OPENSSL Slot Management Functions ---------------- */ + +HSM_SLOT_INFO * HSM_OPENSSL_SLOT_INFO_get (unsigned long num, HSM *hsm) { + + HSM_SLOT_INFO *ret = NULL; + + ret = (HSM_SLOT_INFO *) PKI_Malloc ( sizeof (HSM_SLOT_INFO)); + memcpy( ret, &openssl_slot_info, sizeof( HSM_SLOT_INFO )); + + return (ret); +} + +/* -------------------- OPENSSL Callbacks Management Functions ------------- */ + diff --git a/include/libpki/crypto/hsm/openssl/openssl_hsm.h b/include/libpki/crypto/hsm/openssl/openssl_hsm.h new file mode 100644 index 00000000..326f25d6 --- /dev/null +++ b/include/libpki/crypto/hsm/openssl/openssl_hsm.h @@ -0,0 +1,85 @@ +/* libpki/drivers/openssl/openssl_hsm.h */ + +#ifndef _LIBPKI_HSM_OPENSSL_H +#define _LIBPKI_HSM_OPENSSL_H + +#include + +#include + +#ifndef _LIBPKI_COMPAT_H +#include +#endif + +#ifndef _LIBPKI_HSM_ST_H +#include +#endif + +#ifndef _LIBPKI_OPENSSL_HSM_CB_H +#include +#endif + +#ifndef _LIBPKI_HEADERS_OPENSSL_PKEY_H +#include +#endif + +#ifndef _LIBPKI_ERRORS_H +#include +#endif + +#ifndef _LIBPKI_INIT_H +#include +#endif + +#ifndef _LIBPKI_PKI_X509_H +#include +#endif + +#ifndef _LIBPKI_LOG_H +#include +#endif + +#ifndef _LIBPKI_PKI_ID_H +#include +#endif + +#include + +BEGIN_C_DECLS + + // ==================== + // Functions Prototypes + // ==================== + +unsigned long HSM_OPENSSL_get_errno ( void ); +char * HSM_OPENSSL_get_errdesc ( unsigned long err, char *str, size_t size ); + +HSM * HSM_OPENSSL_new( PKI_CONFIG *conf ); +const HSM * HSM_OPENSSL_get_default( void ); + +int HSM_OPENSSL_free ( HSM *driver, PKI_CONFIG *conf ); +int HSM_OPENSSL_init ( HSM *driver, PKI_CONFIG *conf ); + +int HSM_OPENSSL_set_fips_mode(const HSM *driver, int k); +int HSM_OPENSSL_is_fips_mode(const HSM *driver); + +/* ---------------------- Sign/Verify functions ----------------------- */ + +/* + * int HSM_OPENSSL_sign ( PKI_MEM *der, PKI_X509_KEYPAIR *key, + * PKI_DIGEST_ALG *al); + */ + +PKI_MEM * HSM_OPENSSL_sign ( PKI_MEM *der, PKI_DIGEST_ALG *digest, + PKI_X509_KEYPAIR *key ); + +/* +int HSM_OPENSSL_verify ( PKI_X509 *x, PKI_X509_KEYPAIR *key ); +*/ + +/* ---------------------- OPENSSL Slot Management Functions ---------------- */ +HSM_SLOT_INFO * HSM_OPENSSL_SLOT_INFO_get ( unsigned long num, HSM *hsm_void); + +END_C_DECLS + +#endif diff --git a/include/libpki/crypto/hsm/openssl/openssl_hsm_cb.c b/include/libpki/crypto/hsm/openssl/openssl_hsm_cb.c new file mode 100644 index 00000000..8da2a7c9 --- /dev/null +++ b/include/libpki/crypto/hsm/openssl/openssl_hsm_cb.c @@ -0,0 +1,430 @@ +#include +#include + +#include +#include + +const PKI_X509_CALLBACKS PKI_OPENSSL_X509_KEYPAIR_CALLBACKS = { + // Memory Management + (void *) EVP_PKEY_new, // PKI_KEYPAIR_new_null + (void *) EVP_PKEY_free, // PKI_KEYPAIR_free + (void *) OPENSSL_HSM_KEYPAIR_dup, // PKI_KEYPAIR_dup + + // Data Retrieval + (void *) NULL, // PKI_KEYPAIR_get_parsed + (void *) NULL, // PKI_KEYPAIR_data; + (void *) NULL, // PKI_KEYPAIR_print_parsed; + + // Data Conversion + NULL, // (void *) PEM_write_bio_PUBKEY, // PEM format + (void *) OPENSSL_HSM_write_bio_PrivateKey, // PEM format + // (void *) PEM_write_bio_PKCS8PrivateKey, // PEM format + (void *) i2d_PrivateKey_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL, // XML format + + // Data Conversion + (void *) PEM_read_bio_PrivateKey,// PEM format + (void *) d2i_PrivateKey_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL // XML format +}; + +const PKI_X509_CALLBACKS PKI_OPENSSL_X509_CERT_CALLBACKS = { + /* Memory Management */ + (void*)X509_new, + (void*)X509_free, + (void*)X509_dup, + + /* Data Retrieval */ + (void *) PKI_X509_CERT_get_parsed, + (void *) PKI_X509_CERT_get_data, + (void *) PKI_X509_CERT_print_parsed, + + /* Data Conversion */ +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + (void *) PEM_write_bio_X509_AUX, // PEM format +#else + (void *) PEM_write_bio_X509, // PEM format +#endif + NULL, // PEM EX (encrypted) format + (void *) i2d_X509_bio, // DER format + (void *) X509_print, // TXT format + NULL, // B64 format (B64_write_bio) + NULL, // XML format + + /* Data Conversion */ + (void *) PEM_read_bio_X509_AUX, // PEM format + (void *) d2i_X509_bio, // DER format + NULL, // TXT format + NULL, // B64 format + NULL // XML format +}; + + +const PKI_X509_CALLBACKS PKI_OPENSSL_X509_REQ_CALLBACKS = { + /* Memory Management */ + (void *) X509_REQ_new, + (void *) X509_REQ_free, + (void *) X509_REQ_dup, + + /* Data Retrieval */ + (void *) PKI_X509_REQ_get_parsed, + (void *) PKI_X509_REQ_get_data, + (void *) PKI_X509_REQ_print_parsed, + + /* Data Conversion */ + (void *) PEM_write_bio_X509_REQ, // PEM format + NULL, // PEM EX (encrypted) format + (void *) i2d_X509_REQ_bio, // DER format + (void *) X509_REQ_print, // TXT format + (void *) NULL, // B64 format + (void *) NULL, // XML format + + /* Data Conversion */ + (void *) PEM_read_bio_X509_REQ, // PEM format + (void *) d2i_X509_REQ_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL // XML format +}; + +const PKI_X509_CALLBACKS PKI_OPENSSL_X509_CRL_CALLBACKS = { + /* Memory Management */ + (void *) X509_CRL_new, + (void *) X509_CRL_free, + (void *) X509_CRL_dup, + + /* Data Retrieval */ + (void *) PKI_X509_CRL_get_parsed, + (void *) PKI_X509_CRL_get_data, + (void *) NULL, // PKI_X509_CRL_print_parsed, + + /* Data Conversion */ + (void *) PEM_write_bio_X509_CRL, // PEM format + NULL, // PEM EX (encrypted) format + (void *) i2d_X509_CRL_bio, // DER format + (void *) X509_CRL_print, // TXT format + (void *) NULL, // B64 format + (void *) NULL, // XML format + + /* Data Conversion */ + (void *) PEM_read_bio_X509_CRL, // PEM format + (void *) d2i_X509_CRL_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL // XML format +}; + +const PKI_X509_CALLBACKS PKI_OPENSSL_X509_PKCS7_CALLBACKS = { + + /* Memory Management */ + (void *) PKCS7_new, + (void *) PKCS7_free, + (void *) PKCS7_dup, + + /* Data Retrieval */ + (void *) NULL, // PKI_X509_PKCS7_get_parsed; + (void *) NULL, // PKI_X509_PKCS7_get_data; + (void *) NULL, // PKI_X509_PKCS7_print_parsed; + + /* Data Conversion */ + (void *) PEM_write_bio_PKCS7, // PEM format + NULL, // PEM EX (encrypted) format + (void *) i2d_PKCS7_bio, // DER format + (void *) PKI_X509_PKCS7_VALUE_print_bio, // TXT format + (void *) NULL, // B64 format + (void *) NULL, // XML format + + /* Data Conversion */ + (void *) PEM_read_bio_PKCS7, // PEM format + (void *) d2i_PKCS7_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL // XML format +}; + + +const PKI_X509_CALLBACKS PKI_OPENSSL_X509_CMS_CALLBACKS = { + + /* Memory Management */ + (void *) PKI_X509_CMS_VALUE_new, + (void *) PKI_X509_CMS_VALUE_free, + (void *) PKI_X509_CMS_VALUE_dup, + + /* Data Retrieval */ + (void *) NULL, // PKI_X509_PKCS7_get_parsed; + (void *) NULL, // PKI_X509_PKCS7_get_data; + (void *) NULL, // PKI_X509_PKCS7_print_parsed; + + /* Data Conversion */ + (void *) PEM_write_bio_CMS, // PEM format + NULL, // PEM EX (encrypted) format + (void *) i2d_CMS_bio, // DER format + (void *) PKI_X509_CMS_VALUE_print_bio, // TXT format + (void *) NULL, // B64 format + (void *) NULL, // XML format + + /* Data Conversion */ + (void *) PEM_read_bio_CMS, // PEM format + (void *) d2i_CMS_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL // XML format +}; + + +const PKI_X509_CALLBACKS PKI_OPENSSL_X509_PKCS12_CALLBACKS = { + // Memory Management + (void *) PKCS12_new, + (void *) PKCS12_free, + (void *) NULL, + + // Data Retrieval + (void *) NULL, // PKI_X509_PKCS12_get_parsed; + (void *) NULL, // PKI_X509_PKCS12_get_data; + (void *) NULL, // PKI_X509_PKCS12_print_parsed; + + // Data Conversion + (void *) PEM_write_bio_PKCS12, // PEM format + NULL, // PEM EX (encrypted) format + (void *) i2d_PKCS12_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL, // XML format + + // Data Conversion + (void *) PEM_read_bio_PKCS12, // PEM format + (void *) d2i_PKCS12_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL // XML format +}; + +const PKI_X509_CALLBACKS PKI_OPENSSL_X509_OCSP_REQ_CALLBACKS = { + // Memory Management + (void *) OCSP_REQUEST_new, + (void *) OCSP_REQUEST_free, + (void *) NULL, + + // Data Retrieval + (void *) PKI_X509_OCSP_REQ_get_parsed, // PKI_X509_OCSP_REQ_get_parsed; + (void *) PKI_X509_OCSP_REQ_get_data, // PKI_X509_OCSP_REQ_get_data; + (void *) NULL, // PKI_X509_OCSP_REQ_print_parsed; + + // Data Conversion + (void *) PEM_write_bio_OCSP_REQ,// PEM format + NULL, // PEM EX (encrypted) format + (void *) i2d_OCSP_REQ_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL, // XML format + + // Data Conversion + (void *) PEM_read_bio_OCSP_REQ, // PEM format + (void *) d2i_OCSP_REQ_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL // XML format +}; + +const PKI_X509_CALLBACKS PKI_OPENSSL_X509_OCSP_RESP_CALLBACKS = { + // Memory Management + (void *) PKI_OCSP_RESP_new, + (void *) PKI_OCSP_RESP_free, + (void *) NULL, + + // Data Retrieval + (void *) PKI_X509_OCSP_RESP_get_parsed, + (void *) PKI_X509_OCSP_RESP_get_data, + (void *) NULL, // PKI_X509_OCSP_RESP_print_parsed; + + // Data Conversion + (void *) PEM_write_bio_PKI_X509_OCSP_RESP_VALUE, // PEM format + NULL, // PEM EX (encrypted) format + (void *) i2d_PKI_X509_OCSP_RESP_VALUE_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL, // XML format + + // Data Conversion + (void *) PEM_read_bio_PKI_X509_OCSP_RESP_VALUE,// PEM format + (void *) d2i_PKI_X509_OCSP_RESP_VALUE_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL // XML format +}; + +const PKI_X509_CALLBACKS PKI_OPENSSL_X509_XPAIR_CALLBACKS = { + // Memory Management + (void *) PKI_XPAIR_new_null, + (void *) PKI_XPAIR_free, + (void *) NULL, + + // Data Retrieval + (void *) NULL, // PKI_X509_XPAIR_get_parsed;sed; + (void *) NULL, // PKI_X509_XPAIR_get_data; + (void *) NULL, // PKI_X509_XPAIR_print_parsed; + + // Data Conversion + (void *) PEM_write_bio_PKI_XPAIR, // PEM format + NULL, // PEM EX (encrypted) format + (void *) i2d_PKI_XPAIR_bio, // DER format + (void *) PKI_XPAIR_print, // TXT format + (void *) NULL, // B64 format + (void *) NULL, // XML format + + // Data Conversion + (void *) PEM_read_bio_PKI_XPAIR,// PEM format + (void *) d2i_PKI_XPAIR_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL // XML format +}; + +const PKI_X509_CALLBACKS PKI_OPENSSL_X509_PRQP_REQ_CALLBACKS = { + // Memory Management + (void *) PKI_PRQP_REQ_new, + (void *) PKI_PRQP_REQ_free, + (void *) PKI_PRQP_REQ_dup, + + // Data Retrieval + (void *) NULL, //PKI_X509_PRQP_REQ_get_parsed, // PKI_X509_OCSP_REQ_get_parsed; + (void *) PKI_X509_PRQP_REQ_get_data, // PKI_X509_OCSP_REQ_get_data; + (void *) NULL, // PKI_X509_OCSP_REQ_print_parsed; + + // Data Conversion + (void *) PEM_write_bio_PRQP_REQ,// PEM format + NULL, // PEM EX (encrypted) format + (void *) i2d_PRQP_REQ_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL, // XML format + + // Data Conversion + (void *) PEM_read_bio_PRQP_REQ, // PEM format + (void *) d2i_PRQP_REQ_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL // XML format +}; + +const PKI_X509_CALLBACKS PKI_OPENSSL_X509_PRQP_RESP_CALLBACKS = { + // Memory Management + (void *) PKI_PRQP_RESP_new, + (void *) PKI_PRQP_RESP_free, + (void *) PKI_PRQP_RESP_dup, + + // Data Retrieval + (void *) NULL,//PKI_X509_PRQP_RESP_get_parsed, + (void *) PKI_X509_PRQP_RESP_get_data, + (void *) NULL, // PKI_X509_OCSP_RESP_print_parsed; + + // Data Conversion (write of the ->value data ) + (void *) PEM_write_bio_PRQP_RESP, // PEM format + NULL, // PEM EX (encrypted) format + (void *) i2d_PRQP_RESP_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL, // XML format + + // Data Conversion (read the ->value) + (void *) PEM_read_bio_PRQP_RESP,// PEM format + (void *) d2i_PRQP_RESP_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL // XML format +}; + + +const PKI_X509_CALLBACKS_FULL PKI_OPENSSL_X509_CALLBACKS_FULL = { + // X509_KEYPAIR + &PKI_OPENSSL_X509_KEYPAIR_CALLBACKS, + // X509_CERT + &PKI_OPENSSL_X509_CERT_CALLBACKS, + // X509_REQ + &PKI_OPENSSL_X509_REQ_CALLBACKS, + // X509_CRL + &PKI_OPENSSL_X509_CRL_CALLBACKS, + // X509_PKCS7 + &PKI_OPENSSL_X509_PKCS7_CALLBACKS, + // X509_CMS + &PKI_OPENSSL_X509_CMS_CALLBACKS, + // X509_PKCS12 + &PKI_OPENSSL_X509_PKCS12_CALLBACKS, + // X509_OCSP_REQ + &PKI_OPENSSL_X509_OCSP_REQ_CALLBACKS, + // X509_OCSP_RESP + &PKI_OPENSSL_X509_OCSP_RESP_CALLBACKS, + // X509_OCSP_XPAIR + &PKI_OPENSSL_X509_XPAIR_CALLBACKS, + // X509_OCSP_CMS + NULL, // &PKI_OPENSSL_X509_CMC_CALLBACKS, + // X509_OCSP_SCEP + &PKI_OPENSSL_X509_PKCS7_CALLBACKS, // &PKI_OPENSSL_X509_SCEP_CALLBACKS + // PRQP_REQ + &PKI_OPENSSL_X509_PRQP_REQ_CALLBACKS, + // PRQP_RESP + &PKI_OPENSSL_X509_PRQP_RESP_CALLBACKS +}; + +const PKI_X509_CALLBACKS *HSM_OPENSSL_X509_get_cb ( PKI_DATATYPE type ) { + + const PKI_X509_CALLBACKS *ret = NULL; + + switch ( type ) { + case PKI_DATATYPE_X509_KEYPAIR : + ret = &PKI_OPENSSL_X509_KEYPAIR_CALLBACKS; + break; + case PKI_DATATYPE_X509_CERT : + ret = &PKI_OPENSSL_X509_CERT_CALLBACKS; + break; + case PKI_DATATYPE_X509_REQ : + ret = &PKI_OPENSSL_X509_REQ_CALLBACKS; + break; + case PKI_DATATYPE_X509_CRL : + ret = &PKI_OPENSSL_X509_CRL_CALLBACKS; + break; + case PKI_DATATYPE_X509_PKCS7 : + ret = &PKI_OPENSSL_X509_PKCS7_CALLBACKS; + break; + case PKI_DATATYPE_X509_CMS : + ret = &PKI_OPENSSL_X509_CMS_CALLBACKS; + break; + case PKI_DATATYPE_X509_PKCS12 : + ret = &PKI_OPENSSL_X509_PKCS12_CALLBACKS; + break; + case PKI_DATATYPE_X509_OCSP_REQ : + ret = &PKI_OPENSSL_X509_OCSP_REQ_CALLBACKS; + break; + case PKI_DATATYPE_X509_OCSP_RESP : + ret = &PKI_OPENSSL_X509_OCSP_RESP_CALLBACKS; + break; + case PKI_DATATYPE_X509_XPAIR : + ret = &PKI_OPENSSL_X509_XPAIR_CALLBACKS; + break; + case PKI_DATATYPE_X509_CMS_MSG : + // TODO: Provide support for CMS + // ret = &PKI_OPENSSL_X509_CMS; + break; + case PKI_DATATYPE_EST_MSG : + // TODO: Provide support for EST + // ret = &PKI_OPENSSL_X509_CMS_CALLBACKS; + break; + case PKI_DATATYPE_SCEP_MSG : + ret = &PKI_OPENSSL_X509_PKCS7_CALLBACKS; + break; + case PKI_DATATYPE_X509_PRQP_REQ : + ret = &PKI_OPENSSL_X509_PRQP_REQ_CALLBACKS; + break; + case PKI_DATATYPE_X509_PRQP_RESP : + ret = &PKI_OPENSSL_X509_PRQP_RESP_CALLBACKS; + break; + default: + return NULL; + } + + return ret; +} diff --git a/include/libpki/crypto/hsm/openssl/openssl_hsm_cb.h b/include/libpki/crypto/hsm/openssl/openssl_hsm_cb.h new file mode 100644 index 00000000..16022fef --- /dev/null +++ b/include/libpki/crypto/hsm/openssl/openssl_hsm_cb.h @@ -0,0 +1,9 @@ +/* src/libpki/drivers/openssl_hsm_cb.h */ + +#ifndef _LIBPKI_OPENSSL_HSM_CB_H +#define _LIBPKI_OPENSSL_HSM_CB_H + +const PKI_X509_CALLBACKS *HSM_OPENSSL_X509_get_cb ( PKI_DATATYPE type ); + +#endif + diff --git a/include/libpki/crypto/hsm/openssl/openssl_hsm_obj.c b/include/libpki/crypto/hsm/openssl/openssl_hsm_obj.c new file mode 100644 index 00000000..72dae836 --- /dev/null +++ b/include/libpki/crypto/hsm/openssl/openssl_hsm_obj.c @@ -0,0 +1,22 @@ +/* openssl/pki_pkey.c */ + +#include + +/* ---------------- OpenSSL HSM Keypair get/put --------------------------- */ + +PKI_STACK * HSM_OPENSSL_OBJSK_get_url ( PKI_DATATYPE type, URL *url, + PKI_CRED *cred, void *hsm ) { + + PKI_log_debug("HSM_OPENSSL_OBJSK_get_url()::Deprecated"); + + return NULL; +} + +PKI_X509_KEYPAIR_STACK * HSM_OPENSSL_X509_KEYPAIR_get_url ( URL *url, + PKI_CRED *cred, HSM *hsm) { + + PKI_log_debug("HSM_OPENSSL_X509_KEYPAIR_get_url()::Deprecated"); + + return NULL; +} + diff --git a/include/libpki/crypto/hsm/openssl/openssl_hsm_obj.h b/include/libpki/crypto/hsm/openssl/openssl_hsm_obj.h new file mode 100644 index 00000000..07ea6ea9 --- /dev/null +++ b/include/libpki/crypto/hsm/openssl/openssl_hsm_obj.h @@ -0,0 +1,23 @@ +/* ENGINE Object Management Functions */ + +#ifndef _LIBPKI_HEADERS_OPENSSL_OBJSK_H +#define _LIBPKI_HEADERS_OPENSSL_OBJSK_H + +/* ------------------- Retrieves a stack of objects ------------------- */ +PKI_STACK * HSM_OPENSSL_OBJSK_get_url ( PKI_DATATYPE type, URL *url, + PKI_CRED *cred, void *hsm ); + +int HSM_OPENSSL_OBJSK_add_url ( PKI_STACK *sk, PKI_DATATYPE type, URL *url, + PKI_CRED *cred, void *hsm ); + +int HSM_OPENSSL_OBJSK_del_url ( PKI_STACK *sk, PKI_DATATYPE type, URL *url, + PKI_CRED *cred, void *hsm); + +PKI_MEM_STACK * HSM_OPENSSL_OBJSK_wrap_url ( PKI_STACK *, PKI_DATATYPE type, + URL *url, PKI_CRED *cred, void *hsm); + +/* --------------------- Internal Functions --------------------------- */ +PKI_X509_KEYPAIR_STACK * HSM_OPENSSL_KEYPAIR_get_url (URL *url, PKI_CRED *cred, + HSM *hsm); +#endif + diff --git a/include/libpki/crypto/hsm/openssl/openssl_hsm_pkey.c b/include/libpki/crypto/hsm/openssl/openssl_hsm_pkey.c new file mode 100644 index 00000000..fc1e6c54 --- /dev/null +++ b/include/libpki/crypto/hsm/openssl/openssl_hsm_pkey.c @@ -0,0 +1,1214 @@ +/* openssl/pki_pkey.c */ + +/* Internal usage only - we want to keep the lib abstract */ +#ifndef _LIBPKI_HSM_OPENSSL_PKEY_H +#define _LIBPKI_HSM_OPENSSL_PKEY_H + +#include + +PKI_RSA_KEY * _pki_rsakey_new( PKI_KEYPARAMS *kp ); +PKI_DSA_KEY * _pki_dsakey_new( PKI_KEYPARAMS *kp ); +#ifdef ENABLE_ECDSA +PKI_EC_KEY * _pki_ecdsakey_new( PKI_KEYPARAMS *kp); +#else +void * _pki_ecdsakey_new( PKI_KEYPARAMS *kp ); +#endif + +int _evp_ctx_key_generation(int pkey_type, PKI_X509_KEYPAIR_VALUE ** pkey) { + + EVP_PKEY_CTX * pctx = NULL; + // Key generation context + + // Input Checks + if (!pkey) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return PKI_ERR; + } + + if (pkey_type <= 0) { + PKI_ERROR(PKI_ERR_PARAM_RANGE, NULL); + return PKI_ERR; + } + + pctx = EVP_PKEY_CTX_new_id(pkey_type, NULL); + if (!pctx) { + PKI_DEBUG("Can not create context for key generation (%d)", pkey_type); + return PKI_ERR; + } + + if (EVP_PKEY_keygen_init(pctx) <= 0) { + PKI_DEBUG("Can not init ED448 context"); + EVP_PKEY_CTX_free(pctx); + return PKI_ERR; + } + + if (EVP_PKEY_keygen(pctx, pkey) <= 0) { + PKI_DEBUG("Can not generate ED448 key"); + EVP_PKEY_CTX_free(pctx); + return PKI_ERR; + } + + EVP_PKEY_CTX_free(pctx); + if (!*pkey) { + PKI_DEBUG("Can not generate ED448 key"); + return PKI_ERR; + } + + return PKI_OK; +} + +int _evp_ctx_key_generation_rsa(PKI_KEYPARAMS * const params, PKI_X509_KEYPAIR_VALUE ** pkey) { + + EVP_PKEY_CTX * pctx = NULL; + // Key generation context + + // Input Checks + if (!pkey || !params) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return PKI_ERR; + } + + if (params->pkey_type <= 0) { + PKI_ERROR(PKI_ERR_PARAM_RANGE, NULL); + return PKI_ERR; + } + + pctx = EVP_PKEY_CTX_new_id(params->pkey_type, NULL); + if (!pctx) { + PKI_DEBUG("Can not create context for key generation (%d)", params->pkey_type); + return PKI_ERR; + } + + // ==================== + // Set the RSA key size + // ==================== + + int bits = params->rsa.bits; + if (bits <= 0) { + if (bits <= 0) { + if (bits <= 0) bits = PKI_RSA_KEY_DEFAULT_SIZE; + } + bits = PKI_SCHEME_ID_get_bitsize(params->scheme, params->sec_bits); + } + + if (EVP_PKEY_keygen_init(pctx) <= 0) { + PKI_DEBUG("Can not init ED448 context"); + EVP_PKEY_CTX_free(pctx); + return PKI_ERR; + } + + if (EVP_PKEY_CTX_set_rsa_keygen_bits(pctx, bits) <= 0) { + PKI_DEBUG("Can not set RSA key size (%d)", bits); + EVP_PKEY_CTX_free(pctx); + return PKI_ERR; + } + params->bits = bits; + params->rsa.bits = bits; + + if (EVP_PKEY_keygen(pctx, pkey) <= 0) { + PKI_DEBUG("Can not generate ED448 key"); + EVP_PKEY_CTX_free(pctx); + return PKI_ERR; + } + + EVP_PKEY_CTX_free(pctx); + if (!*pkey) { + PKI_DEBUG("Can not generate ED448 key"); + return PKI_ERR; + } + + return PKI_OK; +} + +int _pki_rand_init( void ); + +/* End of _LIBPKI_INTERNAL_PKEY_H */ +#endif + +int _pki_rand_seed( void ) { + unsigned char seed[20]; + + if (!RAND_bytes(seed, 20)) return 0; + + RAND_seed(seed, sizeof seed); + + return(1); +} + +PKI_RSA_KEY * _pki_rsakey_new( PKI_KEYPARAMS *kp ) { + + PKI_RSA_KEY *rsa = NULL; + + int bits = PKI_RSA_KEY_DEFAULT_SIZE; + + if ( kp && kp->bits > 0 ) bits = kp->bits; + + if ( bits < PKI_RSA_KEY_MIN_SIZE ) { + PKI_DEBUG("WARNING: RSA Key size smaller than minimum safe size (%d vs. %d)", + bits, PKI_RSA_KEY_DEFAULT_SIZE); + return NULL; + } else if ( bits < PKI_RSA_KEY_DEFAULT_SIZE ) { + PKI_DEBUG("WARNING: RSA Key size smaller than default safe size (%d vs. %d)", + bits, PKI_RSA_KEY_DEFAULT_SIZE); + } + +#if OPENSSL_VERSION_NUMBER > 0x30000000L + EVP_PKEY_CTX * pkey_ctx = NULL; + EVP_PKEY * pkey = NULL; + + OSSL_LIB_CTX * ossl_libctx = PKI_init_get_ossl_library_ctx(); + + // Tries to create the context by using the key id + if ((pkey_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL)) == NULL) { + // Tries to create the context by using the name + pkey_ctx = EVP_PKEY_CTX_new_from_name(ossl_libctx, "RSA", NULL); + } + if (!pkey_ctx) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Cannot create EVP_PKEY_CTX"); + return NULL; + } + + // Initializes the key generation operation + if (EVP_PKEY_keygen_init(pkey_ctx) < 0) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Cannot init EVP_PKEY_CTX"); + EVP_PKEY_CTX_free(pkey_ctx); + return NULL; + } + + // Sets the RSA key size (parameter) + if (EVP_PKEY_CTX_set_rsa_keygen_bits(pkey_ctx, bits) < 0) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Cannot set RSA key size"); + EVP_PKEY_CTX_free(pkey_ctx); + return NULL; + } + + // Generates the new key + if (!EVP_PKEY_generate(pkey_ctx, &pkey)) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Cannot generate EVP_PKEY"); + EVP_PKEY_CTX_free(pkey_ctx); + return NULL; + } + + // Extracts the RSA key + rsa = EVP_PKEY_get1_RSA(pkey); + + // Free allocated heap memory + if (pkey) EVP_PKEY_free(pkey); + if (pkey_ctx) EVP_PKEY_CTX_free(pkey_ctx); + + if (!rsa) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Cannot extract RSA key from EVP_PKEY"); + return NULL; + } +#else + unsigned long e = RSA_F4; + // Default exponent (65537) + + BIGNUM *bne = NULL; + int ossl_rc = 0; + + if ((bne = BN_new()) != NULL) { + if (1 != BN_set_word(bne, e)) { + PKI_ERROR(PKI_ERR_GENERAL, NULL); + return NULL; + } + } else { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return NULL; + } + + if ((rsa = RSA_new()) == NULL) { + BN_free(bne); + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return NULL; + } + + if ((ossl_rc = RSA_generate_key_ex(rsa, bits, bne, NULL)) != 1 ) { + /* Error */ + BN_free(bne); + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, NULL); + return NULL; + } + + BN_free(bne); +#endif + + /* Let's return the RSA_KEY infrastructure */ + return (rsa); +}; + +PKI_DSA_KEY * _pki_dsakey_new( PKI_KEYPARAMS *kp ) { + + PKI_DSA_KEY *k = NULL; + unsigned char seed[20]; + + int bits = PKI_DSA_KEY_DEFAULT_SIZE; + + if ( kp && kp->bits > 0 ) bits = kp->bits; + + if ( bits < PKI_DSA_KEY_MIN_SIZE ) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_SIZE_SHORT, NULL); + return NULL; + }; + + if (!RAND_bytes(seed, 20)) { + /* Not enought rand ? */ + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Too low Entropy"); + return NULL; + } + + if ((k = DSA_new()) == NULL) { + // Memory Allocation Error + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Too low Entropy"); + return NULL; + } + + if (1 != DSA_generate_parameters_ex(k, bits, seed, 20, NULL, NULL, NULL)) { + if( k ) DSA_free( k ); + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Can not generated DSA params"); + return NULL; + } + + return( k ); +} + +#ifdef ENABLE_ECDSA +PKI_EC_KEY * _pki_ecdsakey_new( PKI_KEYPARAMS *kp ) { + /* ECDSA is a little more complicated than the other + schemes as it involves a group of functions. As the + purpose of this library is to provide a very hi-level + easy to use library, we will provide some hardwired + parameters. + */ + PKI_EC_KEY *k = NULL; + EC_builtin_curve *curves = NULL; + EC_GROUP *group = NULL; + size_t num_curves = 0; + int degree = 0; + + int bits = PKI_EC_KEY_DEFAULT_SIZE; + int curve = PKI_EC_KEY_CURVE_DEFAULT; + int flags = PKI_EC_KEY_ASN1_DEFAULT; + + PKI_EC_KEY_FORM form = PKI_EC_KEY_FORM_DEFAULT; + + /* Get the number of available ECDSA curves in OpenSSL */ + if ((num_curves = EC_get_builtin_curves(NULL, 0)) < 1 ) { + /* No curves available! */ + PKI_ERROR(PKI_ERR_OBJECT_CREATE, "Builtin EC curves"); + return NULL; + } + + /* Alloc the needed memory */ +#if OPENSSL_VERSION_NUMBER < 0x1010000fL + curves = OPENSSL_malloc((int)(sizeof(EC_builtin_curve) * num_curves)); +#else + curves = OPENSSL_malloc(sizeof(EC_builtin_curve) * num_curves); +#endif + + /* Check for memory allocation */ + if (curves == NULL) return NULL; + + /* Get the builtin curves */ + if (!EC_get_builtin_curves(curves, (size_t) num_curves)) + { + PKI_ERROR(PKI_ERR_OBJECT_CREATE, "Can not get builtin EC curves (%d)", num_curves); + goto err; + return NULL; + } + + /* We completely change behavior - we adopt one of the two + * curves suggested by NIST. In particular: + * - NID_secp384r1 + * - NID_secp521r1 + * For today (2008) usage, the first curve + SHA256 seems to be + * the best approach + */ + + if( kp && kp->bits > 0 ) { + bits = kp->bits; + }; + + if(bits < PKI_EC_KEY_MIN_SIZE ){ + PKI_ERROR(PKI_ERR_X509_KEYPAIR_SIZE_SHORT, "%d", bits); + return NULL; + }; + + if( kp && kp->ec.curve > 0 ) { + curve = kp->ec.curve; + } else { + if( bits <= 112 ) { + bits = 112; + curve = NID_secp112r1; + } else if( bits <= 128 ) { + bits = 128; + curve = NID_secp128r1; + } else if( bits <= 160 ) { + bits = 160; + curve = NID_secp160r1; + } else if( bits <= 192 ) { + bits = 192; + curve = NID_X9_62_prime192v1; + } else if( bits <= 224 ) { + bits = 224; + curve = NID_secp224r1; + } else if( bits <= 256 ) { + bits = 256; + curve = NID_X9_62_prime256v1; + } else if( bits <= 384 ) { + bits = 384; + curve = NID_secp384r1; + } else { + bits = 512; + curve = NID_secp521r1; + }; + }; + + /* Initialize the key */ + if ((k = EC_KEY_new()) == NULL) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, NULL); + goto err; + return NULL; + } + + if((group = EC_GROUP_new_by_curve_name(curve)) == NULL ) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Invalid Curve - %d", curve); + goto err; + return NULL; + }; + + EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); + EC_GROUP_set_point_conversion_form(group, form); + + /* Assign the group to the key */ + if (EC_KEY_set_group(k, group) == 0) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Invalid Group"); + goto err; + return NULL; + } + + /* Sets the point compression */ + if ( kp && kp->ec.form != PKI_EC_KEY_FORM_UNKNOWN ) { + form = kp->ec.form; + }; + EC_KEY_set_conv_form(k, (point_conversion_form_t)form); + + /* Sets the type of parameters, flags > 0 ==> by OID, + * flags == 0 ==> specifiedCurve + */ + if ( kp->ec.asn1flags > -1 ) { + flags = kp->ec.asn1flags; + }; + EC_KEY_set_asn1_flag(k, flags); + + /* We do not need it now, let's free the group */ + if ( group ) EC_GROUP_free( group ); + group = NULL; + + if((group = (EC_GROUP *) EC_KEY_get0_group(k)) != NULL ) { + EC_GROUP_set_asn1_flag( group, OPENSSL_EC_NAMED_CURVE ); + }; + + degree = EC_GROUP_get_degree(EC_KEY_get0_group(k)); + + if( degree < bits ) { + /* Fix the problem, let's get the right bits */ + bits = degree; + } + + // // Let's cycle through all the available curves + // // until we find one that matches (if any) + // i = (i + 1 ) % num_curves; + // + // } while ( (degree < bits ) && (i != n_start) ); + + /* Now generate the key */ + if (!EC_KEY_generate_key(k)) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, NULL ); + goto err; + return NULL; + } + + /* Verify the Key to be ok */ + if (!EC_KEY_check_key(k)) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Verify failed for ECDSA key" ); + goto err; + return NULL; + } + + // EC_KEY_set_enc_flags(k, EC_PKEY_NO_PARAMETERS); + // ecKeyPnt = (struct __ec_key_st2 *) k; + // ecKeyPnt->version = 1; + + goto end; + +err: + if( curves ) free ( curves ); + if ( group ) EC_GROUP_free( group ); + + if( k ) { + EC_KEY_free ( k ); + k = NULL; + }; + +end: + return ( k ); +} + +#else /* EVP_PKEY_EC */ + +void * _pki_ecdsakey_new( PKI_KEYPARAMS *kp ) { + PKI_ERROR(PKI_ERR_NOT_IMPLEMENTED, NULL); + return ( NULL ); +} + +#endif + +#if defined(ENABLE_OQS) || defined(ENABLE_OQSPROV) + +EVP_PKEY_CTX * _pki_get_evp_pkey_ctx(PKI_KEYPARAMS *kp) { + + EVP_PKEY_CTX *ctx = NULL; + // Key generation context to be returned + + // Input Checks + if (!kp) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return NULL; + } + + // Checks we have an algorithm Identifier + if (!kp->oqs.algId) { + PKI_DEBUG("Missing algorithm ID for OQS key generation"); + return NULL; + } + +#ifdef ENABLE_OQS + + const EVP_PKEY_ASN1_METHOD *ameth; + // ASN1 Method + + ENGINE *tmpeng = NULL; + // Temporary Engine + + int pkey_id = -1; + // PKEY ID + + // TODO: + // ===== + // + // This mechanism does not seem to be working for Kyber + // we need to update the mechanism to include Kyber and other + // algorithms. + + if ((ameth = EVP_PKEY_asn1_find(&tmpeng, kp->oqs.algId)) != NULL) { + ERR_clear_error(); + EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth); + + PKI_DEBUG("Ameth = %d, AlgId = %d", pkey_id, kp->oqs.algId); + + } else { + + PKI_log_debug("Missing ASN1 Method for algorithm '%s', using the KeyId (%d).", + PKI_ALGOR_ID_txt(kp->oqs.algId), kp->oqs.algId); + pkey_id = kp->oqs.algId; + + } + + // Generates the new context + if ((ctx = EVP_PKEY_CTX_new_id(pkey_id, NULL)) == NULL) goto err; + +#else + OSSL_LIB_CTX * libctx = PKI_init_get_ossl_library_ctx(); + // OpenSSL Library Context + + // Gets the name of the algorithm + const char * sigalg_name = PKI_ID_get_txt(kp->oqs.algId); + if (!sigalg_name) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Cannot get algorithm name"); + goto err; + } + + // Generates the new context + ctx = EVP_PKEY_CTX_new_from_name(libctx, sigalg_name, NULL); + if (!ctx) { + PKI_DEBUG("Cannot create the pkey context for algorithm '%s'", sigalg_name); + goto err; + } + +#endif + + // Let's set the operation (check EVP_PKEY_CTX_ctrl function -pmeth_lib.c:432) + // Use the EVP interface to initialize the operation (crypto/evp/pmeth_gn.c:69) + if (EVP_PKEY_keygen_init(ctx) <= 0) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Cannot Initialize Key Generation"); + goto err; + } + +#ifdef ENABLE_COMPOSITE + + // CTX operations for Composite Crypto + // + // EVP_PKEY_CTRL_COMPOSITE_PUSH + // EVP_PKEY_CTRL_COMPOSITE_POP + // EVP_PKEY_CTRL_COMPOSITE_ADD + // EVP_PKEY_CTRL_COMPOSITE_DEL + // EVP_PKEY_CTRL_COMPOSITE_CLEAR + +#ifdef ENABLE_COMBINED + if ((kp->scheme == PKI_SCHEME_COMPOSITE || + kp->scheme == PKI_SCHEME_COMBINED) + && kp->comp.k_stack != NULL) { +#else + if (kp->scheme == PKI_SCHEME_COMPOSITE + && kp->comp.k_stack != NULL) { +#endif + for (int i = 0; i < PKI_STACK_X509_KEYPAIR_elements(kp->comp.k_stack); i++) { + + PKI_X509_KEYPAIR * tmp_key = NULL; + + // Let's get the i-th PKI_X509_KEYPAIR + tmp_key = PKI_STACK_X509_KEYPAIR_get_num(kp->comp.k_stack, i); + // Now we can use the CRTL interface to pass the new keys + if (EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_COMPOSITE_PUSH, 0, tmp_key->value) <= 0) { + PKI_log_debug("Cannot add key via the CTRL interface"); + goto err; + } + } + } +#endif + + return ctx; + + err: + + PKI_log_debug("Error initializing context for [scheme: %d, algId: %d]\n", + kp->scheme, kp->oqs.algId); + + if (ctx) EVP_PKEY_CTX_free(ctx); + return NULL; +} + +#endif + +#ifdef ENABLE_COMPOSITE +PKI_COMPOSITE_KEY * _pki_composite_new( PKI_KEYPARAMS *kp ) { + + PKI_COMPOSITE_KEY *k = NULL; + const char * scheme_name = PKI_SCHEME_ID_get_parsed(kp->scheme); + if (!scheme_name) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Unknown Scheme"); + return NULL; + } + + if ((k = COMPOSITE_KEY_new()) == NULL) { + // Memory Allocation Error + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return NULL; + } + + int pkey_type = kp->pkey_type; // PKI_ID_get_by_name(PKI_SCHEME_ID_get_parsed(kp->scheme)); + if (pkey_type <= 0) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Unknown Algorithm"); + COMPOSITE_KEY_free(k); + return NULL; + } + + // Let's set the algorithm + k->algorithm = pkey_type; + + PKI_DEBUG("Creating a Composite Key"); + PKI_DEBUG("Scheme: %d (%s)", kp->scheme, PKI_SCHEME_ID_get_parsed(kp->scheme)); + PKI_DEBUG("Pkey Type: %d (%s)", pkey_type, OBJ_nid2sn(pkey_type)); + + // if (PKI_SCHEME_ID_is_explicit_composite(kp->scheme)) { + // PKI_DEBUG("Explicit Composite Key"); + // k->algorithm = pkey_type; + // } else if (PKI_SCHEME_ID_is_composite(kp->scheme)) { + // PKI_DEBUG("Gemeric Composite Key"); + // k->algorithm = pkey_type; + // } else if (PKI_SCHEME_ID_is_post_quantum(kp->scheme)) { + // PKI_DEBUG("Unknown Composite Key"); + // k->algorithm = kp->oqs.algId; + // } + + if (kp->comp.k_stack != NULL) { + + // // Clears current components (if any) + // if (k->components) COMPOSITE_KEY_clear(k); + + // // Transfers the ownership of the stack to the composite key + // k->components = kp->comp.k_stack; + + // // Let's replace the stack in the keyparams with a new one + // if ((kp->comp.k_stack = PKI_STACK_X509_KEYPAIR_new()) == NULL) { + // PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + // } + + for (int i = 0; i < PKI_STACK_X509_KEYPAIR_elements(kp->comp.k_stack); i++) { + + PKI_X509_KEYPAIR * tmp_key = NULL; + PKI_X509_KEYPAIR_VALUE * tmp_val = NULL; + + // Let's get the i-th PKI_X509_KEYPAIR + tmp_key = PKI_STACK_X509_KEYPAIR_get_num(kp->comp.k_stack, i); + if (!tmp_key) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Cannot get key from stack"); + COMPOSITE_KEY_free(k); + return NULL; + } + + // Let's get the internal value + PKI_X509_detach(tmp_key, (void **)&tmp_val, NULL, NULL); + if (!tmp_val) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Cannot get key value"); + COMPOSITE_KEY_free(k); + return NULL; + } + tmp_key->value = NULL; + + // // Free the memory associated with the PKI_X509_KEYPAIR + // PKI_X509_KEYPAIR_free(tmp_key); + tmp_key = NULL; + + // Pushes the Key onto the stack + // COMPOSITE_KEY_push(k, tmp_key->value); + if (PKI_ERR == COMPOSITE_KEY_push(k, tmp_val)) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Cannot push key onto stack"); + COMPOSITE_KEY_free(k); + return NULL; + } + + // // Now we can use the CRTL interface to pass the new keys + // if (EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_KEYGEN, + // EVP_PKEY_CTRL_COMPOSITE_PUSH, 0, tmp_key->value) <= 0) { + // PKI_log_debug("Cannot add key via the CTRL interface"); + // goto err; + // } + } + } + + // kp->comp.k_stack = NULL; + + // Adds the Parameter (k-of-n) to the key + if (kp->comp.k_of_n != NULL) { + if (k->params) ASN1_INTEGER_free(k->params); + k->params = ASN1_INTEGER_dup(kp->comp.k_of_n); + } + + // All Done. + return k; +} +#endif + +PKI_X509_KEYPAIR *HSM_OPENSSL_X509_KEYPAIR_new(PKI_KEYPARAMS * kp, + URL * url, + PKI_CRED * cred, + HSM * driver ) { + + PKI_X509_KEYPAIR *ret = NULL; + PKI_X509_KEYPAIR_VALUE * value = NULL; + // PKI_RSA_KEY *rsa = NULL; + PKI_DSA_KEY *dsa = NULL; + +#ifdef ENABLE_ECDSA + PKI_EC_KEY *ec = NULL; +#endif + +#if defined(ENABLE_OQS) || defined(ENABLE_OQSPROV) + EVP_PKEY_CTX * ctx = NULL; +#endif + +#ifdef ENABLE_COMPOSITE + COMPOSITE_KEY * composite = NULL; +#endif + +#ifdef ENABLE_COMBINED + EVP_PKEY_COMBINED * combined = NULL; +#endif + + PKI_SCHEME_ID type = PKI_SCHEME_DEFAULT; + + if (!kp) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return NULL; + } + + if ( kp && kp->scheme != PKI_SCHEME_UNKNOWN ) type = kp->scheme; + + // if ((ret = PKI_X509_new(PKI_DATATYPE_X509_KEYPAIR, driver)) == NULL) { + // PKI_ERROR(PKI_ERR_OBJECT_CREATE, "KeyPair"); + // return NULL; + // } + + // if((ret->value = (PKI_X509_KEYPAIR_VALUE *) EVP_PKEY_new()) == NULL ) { + // PKI_ERROR(PKI_ERR_OBJECT_CREATE, "KeyPair Value"); + // return NULL; + // } + + if( _pki_rand_seed() == 0 ) { + /* Probably low level of randomization available */ + PKI_log_debug("WARNING, low rand available!"); + } + + switch (type) { + +#ifdef ENABLE_ED448 + case PKI_SCHEME_ED448: { + int success = _evp_ctx_key_generation(PKI_ALGOR_ID_ED448, &value); + if (!success) { + PKI_DEBUG("Cannot generate the ED448 key"); + goto err; + } + } break; +#endif + +#ifdef ENABLE_X448 + case PKI_SCHEME_X448: { + int success = _evp_ctx_key_generation(PKI_ALGOR_ID_X448, &value); + if (!success) { + PKI_DEBUG("Cannot generate the X448 key"); + goto err; + } + } break; +#endif + +#ifdef ENABLE_ED25519 + case PKI_SCHEME_ED25519: { + int success = _evp_ctx_key_generation(PKI_ALGOR_ID_ED25519, &value); + if (!success) { + PKI_DEBUG("Cannot generate the ED448 key"); + goto err; + } + } break; +#endif + +#ifdef ENABLE_X25519 + case PKI_SCHEME_X25519: { + int success = _evp_ctx_key_generation(PKI_ALGOR_ID_X25519, &value); + if (!success) { + PKI_DEBUG("Cannot generate the ED448 key"); + goto err; + } + } break; +#endif + + case PKI_SCHEME_RSAPSS: + case PKI_SCHEME_RSA: { + // if ((rsa = _pki_rsakey_new( kp )) == NULL ) { + // PKI_DEBUG("Cannot generate the RSA key"); + // goto err; + // } + // if (!EVP_PKEY_assign_RSA((EVP_PKEY *) value, rsa)) { + // PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Can not assign RSA key"); + // if( rsa ) RSA_free( rsa ); + // goto err; + // } + int success = _evp_ctx_key_generation_rsa(kp, &value); + if (!success) { + PKI_DEBUG("Cannot generate the RSA key"); + goto err; + } + } break; + + case PKI_SCHEME_DSA: { + if ((dsa = _pki_dsakey_new( kp )) == NULL ) { + PKI_DEBUG("Cannot generate the DSA key"); + goto err; + } + if (!DSA_generate_key( dsa )) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, NULL); + goto err; + } + if ((value = (PKI_X509_KEYPAIR_VALUE *) EVP_PKEY_new()) == NULL ) { + PKI_ERROR(PKI_ERR_OBJECT_CREATE, "KeyPair Value"); + return NULL; + } + if (!EVP_PKEY_assign_DSA(value, dsa)) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Can not assign DSA key"); + if( dsa ) DSA_free ( dsa ); + goto err; + } + dsa=NULL; + } break; + +#ifdef ENABLE_ECDSA + + case PKI_SCHEME_ECDSA: { + if ((ec = _pki_ecdsakey_new( kp )) == NULL ) { + PKI_DEBUG("Cannot generate the ECDSA key"); + goto err; + } + if ((value = (PKI_X509_KEYPAIR_VALUE *) EVP_PKEY_new()) == NULL ) { + PKI_ERROR(PKI_ERR_OBJECT_CREATE, "KeyPair Value"); + return NULL; + } + if (!EVP_PKEY_assign_EC_KEY(value, ec)){ + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Can not assign ECDSA key"); + if( ec ) EC_KEY_free ( ec ); + goto err; + } + } break; + +#ifdef ENABLE_COMPOSITE + + // Generic Composite + case PKI_SCHEME_COMPOSITE: + // Explicit Composite + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_RSA: + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_P256: + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_BRAINPOOL256: + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_ED25519: + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_P384: + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_BRAINPOOL384: + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_ED448: + case PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_P256: + case PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_BRAINPOOL256: + case PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_ED25519: + case PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_RSA: + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_FALCON1024_P521: + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_FALCON1024_RSA: { + + if ((composite = _pki_composite_new(kp)) == NULL) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Can not initiate keypair generation"); + goto err; + } + if ((value = (PKI_X509_KEYPAIR_VALUE *) EVP_PKEY_new()) == NULL ) { + PKI_ERROR(PKI_ERR_OBJECT_CREATE, "KeyPair Value"); + return NULL; + } + if (!EVP_PKEY_assign_COMPOSITE(value, composite)) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Can not assign COMPOSITE key"); + if (composite) COMPOSITE_KEY_free(composite); + goto err; + } + } break; +#endif + +#ifdef ENABLE_COMBINED + case PKI_SCHEME_COMBINED: + if ((combined = _pki_combined_new(kp)) == NULL) { + if (ret) HSM_OPENSSL_X509_KEYPAIR_free(ret); + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Can not initiate keypair generation"); + return NULL; + }; + if ((value = (PKI_X509_KEYPAIR_VALUE *) EVP_PKEY_new()) == NULL ) { + PKI_ERROR(PKI_ERR_OBJECT_CREATE, "KeyPair Value"); + return NULL; + } + if (!EVP_PKEY_assign_COMBINED(value, combined)) { + if (ret) HSM_OPENSSL_X509_KEYPAIR_free(ret); + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Can not assign COMBINED key"); + if (combined) COMBINED_KEY_free(combined); + return NULL; + } + combined=NULL; + break; +#endif + +#endif // ENABLE_ECDSA + + default: + +#if defined(ENABLE_OQS) || defined(ENABLE_OQSPROV) + if ((ctx = _pki_get_evp_pkey_ctx(kp)) == NULL) { + PKI_DEBUG("Cannot generate the PQC key"); + goto err; + } + if (EVP_PKEY_keygen(ctx, &value) <= 0) { + if (ctx) EVP_PKEY_CTX_free(ctx); + goto err; + } + EVP_PKEY_CTX_free(ctx); + ctx = NULL; + +#else + /* No recognized scheme */ + PKI_ERROR(PKI_ERR_HSM_SCHEME_UNSUPPORTED, "%d", type ); + goto err; + +#endif // ENABLE_OQS || ENABLE_OQSPROV + + } + + // Checks that a Key was generated + if (!value) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Can not generate keypair"); + goto err; + } + + // Allocates the PKI_X509_KEYPAIR structure + if ((ret = PKI_X509_new(PKI_DATATYPE_X509_KEYPAIR, driver)) == NULL) { + PKI_ERROR(PKI_ERR_OBJECT_CREATE, "KeyPair"); + return NULL; + } + + /* Sets the value in the PKI_X509_KEYPAIR structure */ + if (PKI_ERR == PKI_X509_attach(ret, PKI_DATATYPE_X509_KEYPAIR, value, driver)) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Can not attach keypair"); + goto err; + } + + // Sets the requirement for the digest in the key + if (PKI_SCHEME_ID_requires_digest(type)) { + ret->signature_digest_required = 1; + } + + /* Let's return the PKEY infrastructure */ + return ret; + +err: + + // Memory Cleanup + if (value) EVP_PKEY_free(value); + if (ret) PKI_X509_KEYPAIR_free(ret); + +#if defined(ENABLE_OQS) || defined(ENABLE_OQSPROV) + if (ctx) EVP_PKEY_CTX_free(ctx); +#endif // ENABLE_OQS || ENABLE_OQSPROV + + // Error + return NULL; +} + +/* Key Free function */ +void HSM_OPENSSL_X509_KEYPAIR_free ( PKI_X509_KEYPAIR *pkey ) { + + if( !pkey) return; + + PKI_X509_free ( pkey ); + + return; +} + +// OpenSSL Fix +// When writing PEM formatted Keys the wrong version "0" is +// used by the default EVP_PKEY_ write functions for EC keys, +// we have to provide our own function until OpenSSL solve +// this issue + +int OPENSSL_HSM_write_bio_PrivateKey (BIO * bp, + EVP_PKEY * x, + const EVP_CIPHER * enc, + unsigned char * out_buffer, + int klen, + pem_password_cb * cb, + void * u) { + + int ret = PKI_ERR; + // Return value + + // Input Check + if (!x || !bp) return PKI_ERR; + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + // Let's get the scheme of the key + PKI_SCHEME_ID pkey_scheme = PKI_X509_KEYPAIR_VALUE_get_scheme(x); + if (!pkey_scheme) { + PKI_DEBUG("ERROR, can not get the scheme of key (key id: %d)", + PKI_X509_KEYPAIR_VALUE_get_id(x)); + return PKI_ERR; + } + // Let's get the type of the key + int pkey_type = PKI_ID_UNKNOWN; + switch (pkey_scheme) { + +#ifdef ENABLE_ECDSA + + // EC + case PKI_SCHEME_ED25519: { + pkey_type = EVP_PKEY_ED25519; + } break; + + case PKI_SCHEME_X25519: { + pkey_type = EVP_PKEY_X25519; + } break; + + case PKI_SCHEME_ED448: { + pkey_type = EVP_PKEY_ED448; + } break; + + case PKI_SCHEME_X448: { + pkey_type = EVP_PKEY_X448; + } break; + + case PKI_SCHEME_ECDSA: { + pkey_type = EVP_PKEY_EC; + } break; + +#endif // End of ENABLE_ECDSA + + default: { + // Nothing to do here + pkey_type = PKI_X509_KEYPAIR_VALUE_get_id(x); + } break; + } +#else // OpenSSL 1.1.1 + // Let's get the type of key + int pkey_type = EVP_PKEY_type(PKI_X509_KEYPAIR_VALUE_get_id(x)); +#endif // End of OPENSSL_VERSION_NUMBER >= 0x30000000L + + + // Different functions depending on the Key type + switch(pkey_type) + { + +#ifdef ENABLE_ECDSA + case EVP_PKEY_EC: { +# if OPENSSL_VERSION_NUMBER >= 0x30000000L + ret = PEM_write_bio_ECPrivateKey(bp, + EVP_PKEY_get0_EC_KEY(x), enc, (unsigned char *) out_buffer, klen, cb, u); +# elif OPENSSL_VERSION_NUMBER < 0x1010000fL + ret = PEM_write_bio_ECPrivateKey(bp, + x->pkey.ec, enc, (unsigned char *) out_buffer, klen, cb, u); +# else + ret = PEM_write_bio_ECPrivateKey(bp, + EVP_PKEY_get0_EC_KEY(x), enc, (unsigned char *) out_buffer, klen, cb, u); +# endif + if (!ret) { + PKI_DEBUG("Internal Error while encoding EC Key (PEM)."); + return PKI_ERR; + } + } break; +#endif + + default: { + if ((ret = PEM_write_bio_PKCS8PrivateKey(bp, x, enc, + (char *) out_buffer, klen, cb, u)) != 1) { + // Debug Info + PKI_DEBUG("Key Type NOT supported (%d)", pkey_type); + // Error Condition + return PKI_ERR; + } + } + } + + // All Done + return ret; +} + +// OpenSSL Fix +// +// Strangely enough OpenSSL does not provide an EVP_PKEY_dup() +// function, we supply it + +EVP_PKEY *OPENSSL_HSM_KEYPAIR_dup(EVP_PKEY *kVal) +{ + EVP_PKEY *ret = NULL; + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + + ret = EVP_PKEY_dup(kVal); + +#else + + int pkey_type = PKI_X509_KEYPAIR_VALUE_get_id(kVal); + if(!kVal) return NULL; + + if ((ret = EVP_PKEY_new()) == NULL) return NULL; + + if (!EVP_PKEY_copy_parameters(ret, kVal)) return NULL; + + switch (pkey_type) + { + + case EVP_PKEY_RSA: { + RSA *rsa = NULL; +// #if OPENSSL_VERSION_NUMBER >= 0x30000000L +// if (((rsa = EVP_PKEY_get1_RSA(kVal)) == NULL) || +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + if (((rsa = EVP_PKEY_get0_RSA(kVal)) == NULL) || +#else + if (((rsa = (RSA *)EVP_PKEY_get0(kVal)) == NULL) || +#endif + (!EVP_PKEY_set1_RSA(ret, rsa))) { + PKI_DEBUG("ERROR, can not duplicate the RSA key"); + return NULL; + } + } break; + + case EVP_PKEY_DH: { + DH *dh = NULL; +// #if OPENSSL_VERSION_NUMBER >= 0x30000000L +// if ( ((dh = EVP_PKEY_get1_DH(kVal)) == NULL) || +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + if ( ((dh = EVP_PKEY_get0_DH(kVal)) == NULL) || +#else + if ( ((dh = (DH *)EVP_PKEY_get0(kVal)) == NULL) || +#endif + (!EVP_PKEY_set1_DH(ret, dh))) { + PKI_DEBUG("ERROR, can not duplicate the DH key"); + return NULL; + } + } break; + +#ifdef ENABLE_ECDSA + case EVP_PKEY_EC: { + EC_KEY * ec = NULL; +// #if OPENSSL_VERSION_NUMBER >= 0x30000000L +// if (((ec = EVP_PKEY_get1_EC_KEY(kVal)) == NULL) || +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + if (((ec = EVP_PKEY_get0_EC_KEY(kVal)) == NULL) || +#else + if (((ec = (EC_KEY *)EVP_PKEY_get0(kVal)) == NULL) || +#endif + (!EVP_PKEY_set1_EC_KEY(ret, ec))) { + PKI_DEBUG("ERROR, can not duplicate the ECDSA key"); + return NULL; + } + } break; +#endif + +#ifdef ENABLE_DSA + case EVP_PKEY_DSA: { + DSA *dsa = NULL; +// #if OPENSSL_VERSION_NUMBER >= 0x30000000L +// if ( ((dsa = EVP_PKEY_get1_DSA(kVal)) == NULL) || +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + if ( ((dsa = EVP_PKEY_get0_DSA(kVal)) == NULL) || +#else + if ( ((dsa = (DSA *)EVP_PKEY_get0(kVal)) == NULL) || +#endif + (!EVP_PKEY_set1_DSA(ret, dsa))) { + PKI_DEBUG("ERROR, can not duplicate the DSA key"); + return NULL; + } + } break; +#endif + + default: { + PKI_MEM * mem = PKI_X509_KEYPAIR_VALUE_get_p8(kVal); + if (!mem) { + PKI_DEBUG("ERROR, can not serialize the key to PKCS8 format."); + return NULL; + } + + // Free the memory associated with the PKI_X509_KEYPAIR + if (ret) EVP_PKEY_free(ret); + + // Let's create a new PKI_X509_KEYPAIR from the PKCS8 data + ret = PKI_X509_KEYPAIR_VALUE_new_p8(mem); + if (!ret) { + PKI_DEBUG("ERROR, can not deserialize the key from PKCS8 format."); + return NULL; + } + + // Returns the newly allocated key + return ret; + + } break; + } + + // Update the reference for the PKEY + if (!EVP_PKEY_up_ref(kVal)) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Cannot update PKEY references"); + return NULL; + } +#endif + + + // All Done + return ret; +}; + diff --git a/include/libpki/crypto/hsm/openssl/openssl_hsm_pkey.h b/include/libpki/crypto/hsm/openssl/openssl_hsm_pkey.h new file mode 100644 index 00000000..1afdcd5f --- /dev/null +++ b/include/libpki/crypto/hsm/openssl/openssl_hsm_pkey.h @@ -0,0 +1,20 @@ +/* ENGINE Object Management Functions */ + +#ifndef _LIBPKI_HEADERS_OPENSSL_PKEY_H +#define _LIBPKI_HEADERS_OPENSSL_PKEY_H + + +/* ------------------- Keypair Functions --------------------- */ + +PKI_X509_KEYPAIR *HSM_OPENSSL_X509_KEYPAIR_new( PKI_KEYPARAMS *pk, + URL *url, PKI_CRED *cred, HSM *driver ); +void HSM_OPENSSL_X509_KEYPAIR_free ( PKI_X509_KEYPAIR *pkey ); + +int OPENSSL_HSM_write_bio_PrivateKey (BIO *bp, EVP_PKEY *x, + const EVP_CIPHER *enc, unsigned char *kstr, int klen, + pem_password_cb *cb, void *u); + +EVP_PKEY *OPENSSL_HSM_KEYPAIR_dup(EVP_PKEY *kVal); + +#endif + diff --git a/include/libpki/crypto/hsm/openssl/pki_oid_defs.h b/include/libpki/crypto/hsm/openssl/pki_oid_defs.h new file mode 100644 index 00000000..df720554 --- /dev/null +++ b/include/libpki/crypto/hsm/openssl/pki_oid_defs.h @@ -0,0 +1,659 @@ +/* OpenCA libpki package +* (c) 2000-2006 by Massimiliano Pala and OpenCA Group +* All Rights Reserved +* +* =================================================================== +* Released under OpenCA LICENSE +*/ + +#ifndef _LIBPKI_OID_DEFS_H +#define _LIBPKI_OID_DEFS_H + +// Library configuration +#include + +#ifdef ENABLE_OQS +# ifndef OQS_H +# include +# endif +#endif + +BEGIN_C_DECLS + +// ======================= +// Initialization Function +// ======================= + +int PKI_X509_OID_init(); + +// =============== +// General Defines +// =============== + +// GENERAL +# define LEVEL_OF_ASSURANCE_OID "1.3.6.1.4.1.18227.50.1" +# define LEVEL_OF_ASSURANCE_NAME "levelOfAssurance" +# define LEVEL_OF_ASSURANCE_DESC "Level Of Assurance" + +# define CERTIFICATE_USAGE_OID "1.3.6.1.4.1.18227.50.2" +# define CERTIFICATE_USAGE_NAME "certificateUsage" +# define CERTIFICATE_USAGE_DESC "Certificate Usage" + +# define CERTIFICATE_TEMPLATE_OID "1.3.6.1.4.1.18227.50.3" +# define CERTIFICATE_TEMPLATE_NAME "certificateTemplate" +# define CERTIFICATE_TEMPLATE_DESC "Certificate Template" + +// PEN +# define OPENCA_OID "1.3.6.1.4.1.18227" +# define OPENCA_NAME "OpenCA" +# define OPENCA_DESC "OpenCA Labs Private Enterprise Number" + +// GENERIC +# define OPENCA_ALG_OID OPENCA_OID ".2" +# define OPENCA_ALG_PKEY_OID OPENCA_ALG_OID ".1" +# define OPENCA_ALG_SIGS_OID OPENCA_ALG_OID ".2" +# define OPENCA_ALG_KEMS_OID OPENCA_ALT_OID ".3" +# define OPENCA_ALG_HASH_OID OPENCA_ALT_OID ".4" +# define OPENCA_ALG_HMAC_OID OPENCA_ALT_OID ".5" +# define OPENCA_ALG_SYM_OID OPENCA_ALT_OID ".6" + +// ===================== +// Public Key Algorithms +// ===================== + +// PKEY - EXP +# define OPENCA_ALG_PKEY_EXP_OID OPENCA_ALG_PKEY_OID ".999" + +// PKEY - COMPOSITE KEY +# define OPENCA_ALG_PKEY_EXP_COMP_OID "2.16.840.1.114027.80.4.1" +# define OPENCA_ALG_PKEY_EXP_COMP_NAME "COMPOSITE" +# define OPENCA_ALG_PKEY_EXP_COMP_DESC "Composite Key" + +// PKEY - EXP - ALT KEY +# define OPENCA_ALG_PKEY_EXP_ALT_OID OPENCA_ALG_PKEY_EXP_OID ".2" +# define OPENCA_ALG_PKEY_EXP_ALT_NAME "MULTIKEY" +# define OPENCA_ALG_PKEY_EXP_ALT_DESC "Multiple Key" + +// PKEY - EXP - DILITHIUM X +# define OPENCA_ALG_PKEY_EXP_DILITHIUMX_OID OPENCA_ALG_PKEY_EXP_OID ".3" +# define OPENCA_ALG_PKEY_EXP_DILITHIUMX_NAME "DilithiumX3" +# define OPENCA_ALG_PKEY_EXP_DILITHIUMX_DESC "DilithiumX3" + +// PKEY - PQC +# define OPENCA_ALG_PKEY_PQC_OID OPENCA_ALG_PKEY_OID ".1" + +// PKEY - PQC - FALCON +# define OPENCA_ALG_PKEY_PQC_FALCON_OID OPENCA_ALG_PKEY_PQC_OID ".1" +# define OPENCA_ALG_PKEY_PQC_FALCON_NAME "Falcon" +# define OPENCA_ALG_PKEY_PQC_FALCON_DESC "Falcon Lattice-Based Crypto Scheme" + +// # define OPENCA_ALG_PKEY_PQC_FALCON512_OID "1.3.9999.3.1" +# define OPENCA_ALG_PKEY_PQC_FALCON512_OID "1.3.9999.3.6" +# define OPENCA_ALG_PKEY_PQC_FALCON512_NAME "falcon512" +# define OPENCA_ALG_PKEY_PQC_FALCON512_DESC "falcon512" + +// # define OPENCA_ALG_PKEY_PQC_FALCON1024_OID "1.3.9999.3.4" +# define OPENCA_ALG_PKEY_PQC_FALCON1024_OID "1.3.9999.3.9" +# define OPENCA_ALG_PKEY_PQC_FALCON1024_NAME "falcon1024" +# define OPENCA_ALG_PKEY_PQC_FALCON1024_DESC "falcon1024" + +// PKEY - PQC - DILITHIUM +# define OPENCA_ALG_PKEY_PQC_DILITHIUM_OID OPENCA_ALG_PKEY_PQC_OID ".2" +# define OPENCA_ALG_PKEY_PQC_DILITHIUM_NAME "dilithium" +# define OPENCA_ALG_PKEY_PQC_DILITHIUM_DESC "dilithium Lattice-Based Crypto Scheme" + +# define OPENCA_ALG_PKEY_PQC_DILITHIUM2_OID "1.3.6.1.4.1.2.267.7.4.4" +# define OPENCA_ALG_PKEY_PQC_DILITHIUM2_NAME "dilithium2" +# define OPENCA_ALG_PKEY_PQC_DILITHIUM2_DESC "dilithium2" + +# define OPENCA_ALG_PKEY_PQC_DILITHIUM3_OID "1.3.6.1.4.1.2.267.7.6.5" +# define OPENCA_ALG_PKEY_PQC_DILITHIUM3_NAME "dilithium3" +# define OPENCA_ALG_PKEY_PQC_DILITHIUM3_DESC "dilithium3" + +# define OPENCA_ALG_PKEY_PQC_DILITHIUM5_OID "1.3.6.1.4.1.2.267.7.8.7" +# define OPENCA_ALG_PKEY_PQC_DILITHIUM5_NAME "dilithium5" +# define OPENCA_ALG_PKEY_PQC_DILITHIUM5_DESC "dilithium5" + +// PKEY - PQC - SPHINCS + +# define OPENCA_ALG_PKEY_PQC_SPHINCS_OID OPENCA_ALG_PKEY_PQC_OID ".3" +# define OPENCA_ALG_PKEY_PQC_SPHINCS_NAME "sphincs" +# define OPENCA_ALG_PKEY_PQC_SPHINCS_DESC "sphincs Lattice-Based Crypto Scheme" + +# define OPENCA_ALG_PKEY_PQC_SPHINCS128_F_SIMPLE_OID "1.3.9999.6.4.13" +# define OPENCA_ALG_PKEY_PQC_SPHINCS128_F_SIMPLE_NAME "sphincssha2128fsimple" +# define OPENCA_ALG_PKEY_PQC_SPHINCS128_F_SIMPLE_DESC "sphincs128f" + +# define OPENCA_ALG_PKEY_PQC_SPHINCS128_S_SIMPLE_OID "1.3.9999.6.4.16" +# define OPENCA_ALG_PKEY_PQC_SPHINCS128_S_SIMPLE_NAME "sphincs128s" +# define OPENCA_ALG_PKEY_PQC_SPHINCS128_S_SIMPLE_DESC "sphincs128s" + +# define OPENCA_ALG_PKEY_PQC_SPHINCS192_F_SIMPLE_OID "1.3.9999.6.5.10" +# define OPENCA_ALG_PKEY_PQC_SPHINCS192_F_SIMPLE_NAME "sphincssha2192fsimple" +# define OPENCA_ALG_PKEY_PQC_SPHINCS192_F_SIMPLE_DESC "sphincs192f" + +// PKEY - PQC - KYBER + +# define OPENCA_ALG_PKEY_PQC_KYBER512_OID OPENCA_ALG_PKEY_PQC_OID ".50" +# define OPENCA_ALG_PKEY_PQC_KYBER512_NAME "Kyber512" +# define OPENCA_ALG_PKEY_PQC_KYBER512_DESC "Kyber512" + +# define OPENCA_ALG_PKEY_PQC_KYBER768_OID OPENCA_ALG_PKEY_PQC_OID ".51" +# define OPENCA_ALG_PKEY_PQC_KYBER768_NAME "Kyber768" +# define OPENCA_ALG_PKEY_PQC_KYBER768_DESC "Kyber768" + +# define OPENCA_ALG_PKEY_PQC_KYBER1024_OID OPENCA_ALG_PKEY_PQC_OID ".52" +# define OPENCA_ALG_PKEY_PQC_KYBER1024_NAME "Kyber1024" +# define OPENCA_ALG_PKEY_PQC_KYBER1024_DESC "Kyber1024" + +// ==================== +// Composite Signatures +// ==================== + +// PKEY - COMPOSITE + +# define OPENCA_ALG_SIGS_COMP_OID OPENCA_ALG_SIGS_OID ".1" +// # define OPENCA_ALG_SIGS_COMP_OID OPENCA_ALG_OID ".1" +// # define OPENCA_ALG_SIGS_COMP_OID OPENCA_ALG_PKEY_EXP_COMP_OID +# define OPENCA_ALG_SIGS_COMP_DESC "CompositeWithNoHash" +# define OPENCA_ALG_SIGS_COMP_NAME "COMPOSITE-NULL" + +# define OPENCA_ALG_SIGS_COMP_SHA1_OID OPENCA_ALG_SIGS_COMP_OID ".1" +# define OPENCA_ALG_SIGS_COMP_SHA1_DESC "CompositeWithSha1" +# define OPENCA_ALG_SIGS_COMP_SHA1_NAME "COMPOSITE-SHA1" + +# define OPENCA_ALG_SIGS_COMP_SHA256_OID OPENCA_ALG_SIGS_COMP_OID ".2" +# define OPENCA_ALG_SIGS_COMP_SHA256_DESC "CompositeWithSha256" +# define OPENCA_ALG_SIGS_COMP_SHA256_NAME "COMPOSITE-SHA256" + +# define OPENCA_ALG_SIGS_COMP_SHA384_OID OPENCA_ALG_SIGS_COMP_OID ".3" +# define OPENCA_ALG_SIGS_COMP_SHA384_DESC "CompositeWithSha384" +# define OPENCA_ALG_SIGS_COMP_SHA384_NAME "COMPOSITE-SHA384" + +# define OPENCA_ALG_SIGS_COMP_SHA512_OID OPENCA_ALG_SIGS_COMP_OID ".4" +# define OPENCA_ALG_SIGS_COMP_SHA512_DESC "CompositeWithSha512" +# define OPENCA_ALG_SIGS_COMP_SHA512_NAME "COMPOSITE-SHA512" + +# define OPENCA_ALG_SIGS_COMP_SHA3_256_OID OPENCA_ALG_SIGS_COMP_OID ".5" +# define OPENCA_ALG_SIGS_COMP_SHA3_256_DESC "CompositeWithSha3At256" +# define OPENCA_ALG_SIGS_COMP_SHA3_256_NAME "COMPOSITE-SHA3_256" + +# define OPENCA_ALG_SIGS_COMP_SHA3_384_OID OPENCA_ALG_SIGS_COMP_OID ".6" +# define OPENCA_ALG_SIGS_COMP_SHA3_384_DESC "CompositeWithSha3At384" +# define OPENCA_ALG_SIGS_COMP_SHA3_384_NAME "COMPOSITE-SHA3_384" + +# define OPENCA_ALG_SIGS_COMP_SHA3_512_OID OPENCA_ALG_SIGS_COMP_OID ".7" +# define OPENCA_ALG_SIGS_COMP_SHA3_512_DESC "CompositeWithSha3At512" +# define OPENCA_ALG_SIGS_COMP_SHA3_512_NAME "COMPOSITE-SHA3_512" + +# define OPENCA_ALG_SIGS_COMP_SHAKE128_OID OPENCA_ALG_SIGS_COMP_OID ".8" +# define OPENCA_ALG_SIGS_COMP_SHAKE128_DESC "CompositeWithShake128" +# define OPENCA_ALG_SIGS_COMP_SHAKE128_NAME "COMPOSITE-SHAKE128" + +# define OPENCA_ALG_SIGS_COMP_SHAKE256_OID OPENCA_ALG_SIGS_COMP_OID ".9" +# define OPENCA_ALG_SIGS_COMP_SHAKE256_DESC "CompositeWithShake256" +# define OPENCA_ALG_SIGS_COMP_SHAKE256_NAME "COMPOSITE-SHAKE256" + +// // ====================== +// // Alternative Signatures +// // ====================== + +// // PKEY - MULTIKEY +// // # define OPENCA_ALG_SIGS_ALT_OID OPENCA_ALG_SIGS_OID ".2" +// # define OPENCA_ALG_SIGS_ALT_OID OPENCA_ALG_OID ".2" +// # define OPENCA_ALG_SIGS_ALT_DESC "MultikeyWithNoHash" +// # define OPENCA_ALG_SIGS_ALT_NAME "MULTIKEY-NULL" + +// # define OPENCA_ALG_SIGS_ALT_SHA1_OID OPENCA_ALG_SIGS_ALT_OID ".1" +// # define OPENCA_ALG_SIGS_ALT_SHA1_DESC "MultikeyWithSha1" +// # define OPENCA_ALG_SIGS_ALT_SHA1_NAME "MULTIKEY-SHA1" + +// # define OPENCA_ALG_SIGS_ALT_SHA256_OID OPENCA_ALG_SIGS_ALT_OID ".2" +// # define OPENCA_ALG_SIGS_ALT_SHA256_DESC "MultikeyWithSha256" +// # define OPENCA_ALG_SIGS_ALT_SHA256_NAME "MULTIKEY-SHA256" + +// # define OPENCA_ALG_SIGS_ALT_SHA384_OID OPENCA_ALG_SIGS_ALT_OID ".3" +// # define OPENCA_ALG_SIGS_ALT_SHA384_DESC "MultikeyWithSha384" +// # define OPENCA_ALG_SIGS_ALT_SHA384_NAME "MULTIKEY-SHA384" + +// # define OPENCA_ALG_SIGS_ALT_SHA512_OID OPENCA_ALG_SIGS_ALT_OID ".4" +// # define OPENCA_ALG_SIGS_ALT_SHA512_DESC "MultikeyWithSha512" +// # define OPENCA_ALG_SIGS_ALT_SHA512_NAME "MULTIKEY-SHA512" + +// # define OPENCA_ALG_SIGS_ALT_SHA3_256_OID OPENCA_ALG_SIGS_ALT_OID ".5" +// # define OPENCA_ALG_SIGS_ALT_SHA3_256_DESC "MultikeyWithSha3At256" +// # define OPENCA_ALG_SIGS_ALT_SHA3_256_NAME "MULTIKEY-SHA3_256" + +// # define OPENCA_ALG_SIGS_ALT_SHA3_384_OID OPENCA_ALG_SIGS_ALT_OID ".6" +// # define OPENCA_ALG_SIGS_ALT_SHA3_384_DESC "MultikeyWithSha3At384" +// # define OPENCA_ALG_SIGS_ALT_SHA3_384_NAME "MULTIKEY-SHA3_384" + +// # define OPENCA_ALG_SIGS_ALT_SHA3_512_OID OPENCA_ALG_SIGS_ALT_OID ".7" +// # define OPENCA_ALG_SIGS_ALT_SHA3_512_DESC "MultikeyWithSha3At512" +// # define OPENCA_ALG_SIGS_ALT_SHA3_512_NAME "MULTIKEY-SHA3_512" + +// # define OPENCA_ALG_SIGS_ALT_SHAKE128_OID OPENCA_ALG_SIGS_ALT_OID ".8" +// # define OPENCA_ALG_SIGS_ALT_SHAKE128_DESC "MultikeyWithShake128" +// # define OPENCA_ALG_SIGS_ALT_SHAKE128_NAME "MULTIKEY-SHAKE128" + +// # define OPENCA_ALG_SIGS_ALT_SHAKE256_OID OPENCA_ALG_SIGS_ALT_OID ".9" +// # define OPENCA_ALG_SIGS_ALT_SHAKE256_DESC "MultikeyWithShake256" +// # define OPENCA_ALG_SIGS_ALT_SHAKE256_NAME "MULTIKEY-SHAKE256" + +// ======================= +// Experimental +// ======================= + +// SIGS - EXP +# define OPENCA_ALG_SIGS_EXP_OID OPENCA_ALG_SIGS_OID ".998" + +// SIGS - EXP - DILITHIUM +# define OPENCA_ALG_SIGS_EXP_DILITHIUMX_OID OPENCA_ALG_SIGS_EXP_OID ".1" + +// SIGS - EXP - DILITHIUM - DILITHIUMX +# define OPENCA_ALG_SIGS_EXP_DILITHIUMX3_OID OPENCA_ALG_SIGS_EXP_DILITHIUMX_OID ".1" +# define OPENCA_ALG_SIGS_EXP_DILITHIUMX3_DESC "DilithiumX3NoHash" +# define OPENCA_ALG_SIGS_EXP_DILITHIUMX3_NAME "DILITHIUMX3-NULL" + +# define OPENCA_ALG_SIGS_EXP_DILITHIUMX3_SHA256_OID OPENCA_ALG_SIGS_EXP_DILITHIUMX3_OID ".2" +# define OPENCA_ALG_SIGS_EXP_DILITHIUMX3_SHA256_DESC "DilithiumX3WithSha256" +# define OPENCA_ALG_SIGS_EXP_DILITHIUMX3_SHA256_NAME "DILITHIUMX3-SHA256" + +# define OPENCA_ALG_SIGS_EXP_DILITHIUMX3_SHA384_OID OPENCA_ALG_SIGS_EXP_DILITHIUMX3_OID ".3" +# define OPENCA_ALG_SIGS_EXP_DILITHIUMX3_SHA384_DESC "DilithiumX3WithSha384" +# define OPENCA_ALG_SIGS_EXP_DILITHIUMX3_SHA384_NAME "DILITHIUMX3-SHA384" + +# define OPENCA_ALG_SIGS_EXP_DILITHIUMX3_SHA512_OID OPENCA_ALG_SIGS_EXP_DILITHIUMX3_OID ".4" +# define OPENCA_ALG_SIGS_EXP_DILITHIUMX3_SHA512_DESC "DilithiumX3WithSha512" +# define OPENCA_ALG_SIGS_EXP_DILITHIUMX3_SHA512_NAME "DILITHIUMX3-SHA512" + +# define OPENCA_ALG_SIGS_EXP_DILITHIUMX3_SHA3_256_OID OPENCA_ALG_SIGS_EXP_DILITHIUMX3_OID ".5" +# define OPENCA_ALG_SIGS_EXP_DILITHIUMX3_SHA3_256_DESC "DilithiumX3WithSha3At256" +# define OPENCA_ALG_SIGS_EXP_DILITHIUMX3_SHA3_256_NAME "DILITHIUMX3-SHA3_256" + +# define OPENCA_ALG_SIGS_EXP_DILITHIUMX3_SHA3_384_OID OPENCA_ALG_SIGS_EXP_DILITHIUMX3_OID ".6" +# define OPENCA_ALG_SIGS_EXP_DILITHIUMX3_SHA3_384_DESC "DilithiumX3WithSha3At384" +# define OPENCA_ALG_SIGS_EXP_DILITHIUMX3_SHA3_384_NAME "DILITHIUMX3-SHA3_384" + +# define OPENCA_ALG_SIGS_EXP_DILITHIUMX3_SHA3_512_OID OPENCA_ALG_SIGS_EXP_DILITHIUMX3_OID ".7" +# define OPENCA_ALG_SIGS_EXP_DILITHIUMX3_SHA3_512_DESC "DilithiumX3WithSha3At512" +# define OPENCA_ALG_SIGS_EXP_DILITHIUMX3_SHA3_512_NAME "DILITHIUMX3-SHA3_512" + +# define OPENCA_ALG_SIGS_EXP_DILITHIUMX3_SHAKE128_OID OPENCA_ALG_SIGS_EXP_DILITHIUMX3_OID ".8" +# define OPENCA_ALG_SIGS_EXP_DILITHIUMX3_SHAKE128_DESC "DilithiumX3WithShake128" +# define OPENCA_ALG_SIGS_EXP_DILITHIUMX3_SHAKE128_NAME "DILITHIUMX3-SHAKE128" + +# define OPENCA_ALG_SIGS_EXP_DILITHIUMX3_SHAKE256_OID OPENCA_ALG_SIGS_EXP_DILITHIUMX3_OID ".9" +# define OPENCA_ALG_SIGS_EXP_DILITHIUMX3_SHAKE256_DESC "DilithiumX3WithShake256" +# define OPENCA_ALG_SIGS_EXP_DILITHIUMX3_SHAKE256_NAME "DILITHIUMX3-SHAKE256" + +// ======================= +// Post-Quantum Signatures +// ======================= + +// # define OPENCA_ALG_SIGS_PQC_OID OPENCA_ALG_SIGS_OID ".999" +# define OPENCA_ALG_SIGS_PQC_OID OPENCA_OID ".999" + +// Dilithium3 and Dilithium5 +// ------------------------- +# define OPENCA_ALG_SIGS_PQC_DILITHIUM_OID OPENCA_ALG_SIGS_PQC_OID ".1" + +// Dilithium Level 3 + +# define OPENCA_ALG_SIGS_PQC_DILITHIUM2_EXT_OID OPENCA_ALG_SIGS_PQC_DILITHIUM_OID ".1" + +# define OPENCA_ALG_SIGS_PQC_DILITHIUM2_OID "1.3.6.1.4.1.2.267.7.4.4" +# define OPENCA_ALG_SIGS_PQC_DILITHIUM2_DESC "Dilithium2" "WithNoHash" +# define OPENCA_ALG_SIGS_PQC_DILITHIUM2_NAME "Dilithium2" + +# define OPENCA_ALG_SIGS_PQC_DILITHIUM2_SHA256_OID OPENCA_ALG_SIGS_PQC_DILITHIUM2_EXT_OID ".1" +# define OPENCA_ALG_SIGS_PQC_DILITHIUM2_SHA256_DESC "Dilithium2" "WithSha256" +# define OPENCA_ALG_SIGS_PQC_DILITHIUM2_SHA256_NAME "DILITHIUM2-SHA256" + +# define OPENCA_ALG_SIGS_PQC_DILITHIUM2_SHA384_OID OPENCA_ALG_SIGS_PQC_DILITHIUM2_EXT_OID ".2" +# define OPENCA_ALG_SIGS_PQC_DILITHIUM2_SHA384_DESC "Dilithium2" "WithSha384" +# define OPENCA_ALG_SIGS_PQC_DILITHIUM2_SHA384_NAME "DILITHIUM2-SHA384" + +# define OPENCA_ALG_SIGS_PQC_DILITHIUM2_SHA512_OID OPENCA_ALG_SIGS_PQC_DILITHIUM2_EXT_OID ".3" +# define OPENCA_ALG_SIGS_PQC_DILITHIUM2_SHA512_DESC "Dilithium2" "WithSha512" +# define OPENCA_ALG_SIGS_PQC_DILITHIUM2_SHA512_NAME "DILITHIUM2-SHA512" + +# define OPENCA_ALG_SIGS_PQC_DILITHIUM2_SHA3_256_OID OPENCA_ALG_SIGS_PQC_DILITHIUM2_EXT_OID ".4" +# define OPENCA_ALG_SIGS_PQC_DILITHIUM2_SHA3_256_DESC "Dilithium2" "WithSha3At256" +# define OPENCA_ALG_SIGS_PQC_DILITHIUM2_SHA3_256_NAME "DILITHIUM2-SHA3_256" + +# define OPENCA_ALG_SIGS_PQC_DILITHIUM2_SHA3_384_OID OPENCA_ALG_SIGS_PQC_DILITHIUM2_EXT_OID ".5" +# define OPENCA_ALG_SIGS_PQC_DILITHIUM2_SHA3_384_DESC "Dilithium2" "WithSha3At384" +# define OPENCA_ALG_SIGS_PQC_DILITHIUM2_SHA3_384_NAME "DILITHIUM2-SHA3_384" + +# define OPENCA_ALG_SIGS_PQC_DILITHIUM2_SHA3_512_OID OPENCA_ALG_SIGS_PQC_DILITHIUM2_EXT_OID ".6" +# define OPENCA_ALG_SIGS_PQC_DILITHIUM2_SHA3_512_DESC "Dilithium2" "WithSha3At512" +# define OPENCA_ALG_SIGS_PQC_DILITHIUM2_SHA3_512_NAME "DILITHIUM2-SHA3_512" + +# define OPENCA_ALG_SIGS_PQC_DILITHIUM2_SHAKE128_OID OPENCA_ALG_SIGS_PQC_DILITHIUM2_EXT_OID ".7" +# define OPENCA_ALG_SIGS_PQC_DILITHIUM2_SHAKE128_DESC "Dilithium2" "WithShake128" +# define OPENCA_ALG_SIGS_PQC_DILITHIUM2_SHAKE128_NAME "DILITHIUM2-SHAKE128" + +# define OPENCA_ALG_SIGS_PQC_DILITHIUM2_SHAKE256_OID OPENCA_ALG_SIGS_PQC_DILITHIUM2_EXT_OID ".8" +# define OPENCA_ALG_SIGS_PQC_DILITHIUM2_SHAKE256_DESC "Dilithium2" "WithShake256" +# define OPENCA_ALG_SIGS_PQC_DILITHIUM2_SHAKE256_NAME "DILITHIUM2-SHAKE256" + +// Dilithium Level 3 + +# define OPENCA_ALG_SIGS_PQC_DILITHIUM3_EXT_OID OPENCA_ALG_SIGS_PQC_DILITHIUM_OID ".2" + +# define OPENCA_ALG_SIGS_PQC_DILITHIUM3_OID "1.3.6.1.4.1.2.267.7.6.5" +# define OPENCA_ALG_SIGS_PQC_DILITHIUM3_DESC "Dilithium3" +# define OPENCA_ALG_SIGS_PQC_DILITHIUM3_NAME "Dilithium3" + +// # define OPENCA_ALG_SIGS_PQC_DILITHIUM3_SHA256_OID OPENCA_ALG_SIGS_PQC_DILITHIUM3_EXT_OID ".1" +// # define OPENCA_ALG_SIGS_PQC_DILITHIUM3_SHA256_DESC "Dilithium3" "WithSha256" +// # define OPENCA_ALG_SIGS_PQC_DILITHIUM3_SHA256_NAME "DILITHIUM3-SHA256" + +# define OPENCA_ALG_SIGS_PQC_DILITHIUM3_SHA384_OID OPENCA_ALG_SIGS_PQC_DILITHIUM3_EXT_OID ".2" +# define OPENCA_ALG_SIGS_PQC_DILITHIUM3_SHA384_DESC "Dilithium3" "WithSha384" +# define OPENCA_ALG_SIGS_PQC_DILITHIUM3_SHA384_NAME "DILITHIUM3-SHA384" + +# define OPENCA_ALG_SIGS_PQC_DILITHIUM3_SHA512_OID OPENCA_ALG_SIGS_PQC_DILITHIUM3_EXT_OID ".3" +# define OPENCA_ALG_SIGS_PQC_DILITHIUM3_SHA512_DESC "Dilithium3" "WithSha512" +# define OPENCA_ALG_SIGS_PQC_DILITHIUM3_SHA512_NAME "DILITHIUM3-SHA512" + +// # define OPENCA_ALG_SIGS_PQC_DILITHIUM3_SHA3_256_OID OPENCA_ALG_SIGS_PQC_DILITHIUM3_EXT_OID ".4" +// # define OPENCA_ALG_SIGS_PQC_DILITHIUM3_SHA3_256_DESC "Dilithium3" "WithSha3At256" +// # define OPENCA_ALG_SIGS_PQC_DILITHIUM3_SHA3_256_NAME "DILITHIUM3-SHA3_256" + +# define OPENCA_ALG_SIGS_PQC_DILITHIUM3_SHA3_384_OID OPENCA_ALG_SIGS_PQC_DILITHIUM3_EXT_OID ".5" +# define OPENCA_ALG_SIGS_PQC_DILITHIUM3_SHA3_384_DESC "Dilithium3" "WithSha3At384" +# define OPENCA_ALG_SIGS_PQC_DILITHIUM3_SHA3_384_NAME "DILITHIUM3-SHA3_384" + +# define OPENCA_ALG_SIGS_PQC_DILITHIUM3_SHA3_512_OID OPENCA_ALG_SIGS_PQC_DILITHIUM3_EXT_OID ".6" +# define OPENCA_ALG_SIGS_PQC_DILITHIUM3_SHA3_512_DESC "Dilithium3" "WithSha3At512" +# define OPENCA_ALG_SIGS_PQC_DILITHIUM3_SHA3_512_NAME "DILITHIUM3-SHA3_512" + +// # define OPENCA_ALG_SIGS_PQC_DILITHIUM3_SHAKE128_OID OPENCA_ALG_SIGS_PQC_DILITHIUM3_EXT_OID ".7" +// # define OPENCA_ALG_SIGS_PQC_DILITHIUM3_SHAKE128_DESC "Dilithium3" "WithShake128" +// # define OPENCA_ALG_SIGS_PQC_DILITHIUM3_SHAKE128_NAME "DILITHIUM3-SHAKE128" + +# define OPENCA_ALG_SIGS_PQC_DILITHIUM3_SHAKE256_OID OPENCA_ALG_SIGS_PQC_DILITHIUM3_EXT_OID ".8" +# define OPENCA_ALG_SIGS_PQC_DILITHIUM3_SHAKE256_DESC "Dilithium3" "WithShake256" +# define OPENCA_ALG_SIGS_PQC_DILITHIUM3_SHAKE256_NAME "DILITHIUM3-SHAKE256" + +// Dilithium Level 5 + +# define OPENCA_ALG_SIGS_PQC_DILITHIUM5_EXT_OID OPENCA_ALG_SIGS_PQC_DILITHIUM_OID ".3" + +# define OPENCA_ALG_SIGS_PQC_DILITHIUM5_OID "1.3.6.1.4.1.2.267.7.8.7" +# define OPENCA_ALG_SIGS_PQC_DILITHIUM5_DESC "Dilithium5" "WithNoHash" +# define OPENCA_ALG_SIGS_PQC_DILITHIUM5_NAME "DILITHIUM5" + +// # define OPENCA_ALG_SIGS_PQC_DILITHIUM5_SHA256_OID OPENCA_ALG_SIGS_PQC_DILITHIUM5_EXT_OID ".1" +// # define OPENCA_ALG_SIGS_PQC_DILITHIUM5_SHA256_DESC "Dilithium5" "WithSha256" +// # define OPENCA_ALG_SIGS_PQC_DILITHIUM5_SHA256_NAME "DILITHIUM5-SHA256" + +// # define OPENCA_ALG_SIGS_PQC_DILITHIUM5_SHA384_OID OPENCA_ALG_SIGS_PQC_DILITHIUM5_EXT_OID ".2" +// # define OPENCA_ALG_SIGS_PQC_DILITHIUM5_SHA384_DESC "Dilithium5" "WithSha384" +// # define OPENCA_ALG_SIGS_PQC_DILITHIUM5_SHA384_NAME "DILITHIUM5-SHA384" + +# define OPENCA_ALG_SIGS_PQC_DILITHIUM5_SHA512_OID OPENCA_ALG_SIGS_PQC_DILITHIUM5_EXT_OID ".3" +# define OPENCA_ALG_SIGS_PQC_DILITHIUM5_SHA512_DESC "Dilithium5" "WithSha512" +# define OPENCA_ALG_SIGS_PQC_DILITHIUM5_SHA512_NAME "DILITHIUM5-SHA512" + +// # define OPENCA_ALG_SIGS_PQC_DILITHIUM5_SHA3_256_OID OPENCA_ALG_SIGS_PQC_DILITHIUM5_EXT_OID ".4" +// # define OPENCA_ALG_SIGS_PQC_DILITHIUM5_SHA3_256_DESC "Dilithium5" "WithSha3At256" +// # define OPENCA_ALG_SIGS_PQC_DILITHIUM5_SHA3_256_NAME "DILITHIUM5-SHA3_256" + +// # define OPENCA_ALG_SIGS_PQC_DILITHIUM5_SHA3_384_OID OPENCA_ALG_SIGS_PQC_DILITHIUM5_EXT_OID ".5" +// # define OPENCA_ALG_SIGS_PQC_DILITHIUM5_SHA3_384_DESC "Dilithium5" "WithSha3At384" +// # define OPENCA_ALG_SIGS_PQC_DILITHIUM5_SHA3_384_NAME "DILITHIUM5-SHA3_384" + +# define OPENCA_ALG_SIGS_PQC_DILITHIUM5_SHA3_512_OID OPENCA_ALG_SIGS_PQC_DILITHIUM5_EXT_OID ".6" +# define OPENCA_ALG_SIGS_PQC_DILITHIUM5_SHA3_512_DESC "Dilithium5" "WithSha3At512" +# define OPENCA_ALG_SIGS_PQC_DILITHIUM5_SHA3_512_NAME "DILITHIUM5-SHA3_512" + +// # define OPENCA_ALG_SIGS_PQC_DILITHIUM5_SHAKE128_OID OPENCA_ALG_SIGS_PQC_DILITHIUM5_EXT_OID ".7" +// # define OPENCA_ALG_SIGS_PQC_DILITHIUM5_SHAKE128_DESC "Dilithium5" "WithShake128" +// # define OPENCA_ALG_SIGS_PQC_DILITHIUM5_SHAKE128_NAME "DILITHIUM5-SHAKE128" + +# define OPENCA_ALG_SIGS_PQC_DILITHIUM5_SHAKE256_OID OPENCA_ALG_SIGS_PQC_DILITHIUM5_EXT_OID ".8" +# define OPENCA_ALG_SIGS_PQC_DILITHIUM5_SHAKE256_DESC "Dilithium5" "WithShake256" +# define OPENCA_ALG_SIGS_PQC_DILITHIUM5_SHAKE256_NAME "DILITHIUM5-SHAKE256" + +// Falcon512 and Falcon1024 +// ------------------------ + +# define OPENCA_ALG_SIGS_PQC_FALCON_OID OPENCA_ALG_SIGS_PQC_OID ".2" + +// Falcon Level 512 + +# define OPENCA_ALG_SIGS_PQC_FALCON512_EXT_OID OPENCA_ALG_SIGS_PQC_FALCON_OID ".1" + +# define OPENCA_ALG_SIGS_PQC_FALCON512_OID "1.3.9999.3.6" +# define OPENCA_ALG_SIGS_PQC_FALCON512_DESC "Falcon512" +# define OPENCA_ALG_SIGS_PQC_FALCON512_NAME "Falcon512" // Was "Falcon-512" + +# define OPENCA_ALG_SIGS_PQC_FALCON512_SHA256_OID OPENCA_ALG_SIGS_PQC_FALCON512_EXT_OID ".1.1" +# define OPENCA_ALG_SIGS_PQC_FALCON512_SHA256_DESC "Falcon512WithSha256" +# define OPENCA_ALG_SIGS_PQC_FALCON512_SHA256_NAME "FALCON512-SHA256" + +# define OPENCA_ALG_SIGS_PQC_FALCON512_SHA384_OID OPENCA_ALG_SIGS_PQC_FALCON512_EXT_OID ".2.1" +# define OPENCA_ALG_SIGS_PQC_FALCON512_SHA384_DESC "Falcon512WithSha384" +# define OPENCA_ALG_SIGS_PQC_FALCON512_SHA384_NAME "FALCON512-SHA384" + +# define OPENCA_ALG_SIGS_PQC_FALCON512_SHA512_OID OPENCA_ALG_SIGS_PQC_FALCON512_EXT_OID ".3.1" +# define OPENCA_ALG_SIGS_PQC_FALCON512_SHA512_DESC "Falcon512WithSha512" +# define OPENCA_ALG_SIGS_PQC_FALCON512_SHA512_NAME "FALCON512-SHA512" + +# define OPENCA_ALG_SIGS_PQC_FALCON512_SHA3_256_OID OPENCA_ALG_SIGS_PQC_FALCON512_EXT_OID ".4.1" +# define OPENCA_ALG_SIGS_PQC_FALCON512_SHA3_256_DESC "Falcon512WithSha3At256" +# define OPENCA_ALG_SIGS_PQC_FALCON512_SHA3_256_NAME "FALCON512-SHA3_256" + +# define OPENCA_ALG_SIGS_PQC_FALCON512_SHA3_384_OID OPENCA_ALG_SIGS_PQC_FALCON512_EXT_OID ".5.1" +# define OPENCA_ALG_SIGS_PQC_FALCON512_SHA3_384_DESC "Falcon512WithSha3At384" +# define OPENCA_ALG_SIGS_PQC_FALCON512_SHA3_384_NAME "FALCON512-SHA3_384" + +# define OPENCA_ALG_SIGS_PQC_FALCON512_SHA3_512_OID OPENCA_ALG_SIGS_PQC_FALCON512_EXT_OID ".6.1" +# define OPENCA_ALG_SIGS_PQC_FALCON512_SHA3_512_DESC "Falcon512WithSha3At512" +# define OPENCA_ALG_SIGS_PQC_FALCON512_SHA3_512_NAME "FALCON512-SHA3_512" + +# define OPENCA_ALG_SIGS_PQC_FALCON512_SHAKE128_OID OPENCA_ALG_SIGS_PQC_FALCON512_EXT_OID ".7.1" +# define OPENCA_ALG_SIGS_PQC_FALCON512_SHAKE128_DESC "Falcon512WithShake128" +# define OPENCA_ALG_SIGS_PQC_FALCON512_SHAKE128_NAME "FALCON512-SHAKE128" + +# define OPENCA_ALG_SIGS_PQC_FALCON512_SHAKE256_OID OPENCA_ALG_SIGS_PQC_FALCON512_EXT_OID ".8.1" +# define OPENCA_ALG_SIGS_PQC_FALCON512_SHAKE256_DESC "Falcon512WithShake256" +# define OPENCA_ALG_SIGS_PQC_FALCON512_SHAKE256_NAME "FALCON512-SHAKE256" + +// Falcon Level 1024 + +# define OPENCA_ALG_SIGS_PQC_FALCON1024_EXT_OID OPENCA_ALG_SIGS_PQC_FALCON_OID ".2" + +# define OPENCA_ALG_SIGS_PQC_FALCON1024_OID "1.3.9999.3.9" +# define OPENCA_ALG_SIGS_PQC_FALCON1024_NAME "Falcon1024WithNoHash" +# define OPENCA_ALG_SIGS_PQC_FALCON1024_DESC "FALCON1024" + +# define OPENCA_ALG_SIGS_PQC_FALCON1024_SHA256_OID OPENCA_ALG_SIGS_PQC_FALCON1024_EXT_OID ".1.1" +# define OPENCA_ALG_SIGS_PQC_FALCON1024_SHA256_DESC "Falcon1024WithSha256" +# define OPENCA_ALG_SIGS_PQC_FALCON1024_SHA256_NAME "FALCON1024-SHA256" + +# define OPENCA_ALG_SIGS_PQC_FALCON1024_SHA384_OID OPENCA_ALG_SIGS_PQC_FALCON1024_EXT_OID ".2.1" +# define OPENCA_ALG_SIGS_PQC_FALCON1024_SHA384_DESC "Falcon1024WithSha384" +# define OPENCA_ALG_SIGS_PQC_FALCON1024_SHA384_NAME "FALCON1024-SHA384" + +# define OPENCA_ALG_SIGS_PQC_FALCON1024_SHA512_OID OPENCA_ALG_SIGS_PQC_FALCON1024_EXT_OID ".3.1" +# define OPENCA_ALG_SIGS_PQC_FALCON1024_SHA512_DESC "Falcon1024WithSha512" +# define OPENCA_ALG_SIGS_PQC_FALCON1024_SHA512_NAME "FALCON1024-SHA512" + +# define OPENCA_ALG_SIGS_PQC_FALCON1024_SHA3_256_OID OPENCA_ALG_SIGS_PQC_FALCON1024_EXT_OID ".4.1" +# define OPENCA_ALG_SIGS_PQC_FALCON1024_SHA3_256_DESC "Falcon1024WithSha3At256" +# define OPENCA_ALG_SIGS_PQC_FALCON1024_SHA3_256_NAME "FALCON1024-SHA3_256" + +# define OPENCA_ALG_SIGS_PQC_FALCON1024_SHA3_384_OID OPENCA_ALG_SIGS_PQC_FALCON1024_EXT_OID ".5.1" +# define OPENCA_ALG_SIGS_PQC_FALCON1024_SHA3_384_DESC "Falcon1024WithSha3At384" +# define OPENCA_ALG_SIGS_PQC_FALCON1024_SHA3_384_NAME "FALCON1024-SHA3_384" + +# define OPENCA_ALG_SIGS_PQC_FALCON1024_SHA3_512_OID OPENCA_ALG_SIGS_PQC_FALCON1024_EXT_OID ".6.1" +# define OPENCA_ALG_SIGS_PQC_FALCON1024_SHA3_512_DESC "Falcon1024WithSha3At512" +# define OPENCA_ALG_SIGS_PQC_FALCON1024_SHA3_512_NAME "FALCON1024-SHA3_512" + +# define OPENCA_ALG_SIGS_PQC_FALCON1024_SHAKE128_OID OPENCA_ALG_SIGS_PQC_FALCON1024_EXT_OID ".7.1" +# define OPENCA_ALG_SIGS_PQC_FALCON1024_SHAKE128_DESC "Falcon1024WithShake128" +# define OPENCA_ALG_SIGS_PQC_FALCON1024_SHAKE128_NAME "FALCON1024-SHAKE128" + +# define OPENCA_ALG_SIGS_PQC_FALCON1024_SHAKE256_OID OPENCA_ALG_SIGS_PQC_FALCON1024_EXT_OID ".8.1" +# define OPENCA_ALG_SIGS_PQC_FALCON1024_SHAKE256_DESC "Falcon1024WithShake256" +# define OPENCA_ALG_SIGS_PQC_FALCON1024_SHAKE256_NAME "FALCON1024-SHAKE256" + +// Sphincs+ 128 and Sphincs+ 192 +// ----------------------------- + +# define OPENCA_ALG_SIGS_PQC_SPHINCS_F_SIMPLE_OID OPENCA_ALG_SIGS_PQC_OID ".3" + +// Sphincs+ 128 + +# define OPENCA_ALG_SIGS_PQC_SPHINCS128_F_SIMPLE_EXT_OID OPENCA_ALG_SIGS_PQC_SPHINCS_F_SIMPLE_OID ".1" + +# define OPENCA_ALG_SIGS_PQC_SPHINCS128_F_SIMPLE_OID "1.3.9999.6.4.13" +# define OPENCA_ALG_SIGS_PQC_SPHINCS128_F_SIMPLE_NAME "Sphincs128FWithNoHash" +# define OPENCA_ALG_SIGS_PQC_SPHINCS128_F_SIMPLE_DESC "SPHINCS128F" + +// Sphincs+ 192 + +# define OPENCA_ALG_SIGS_PQC_SPHINCS192_F_SIMPLE_EXT_OID OPENCA_ALG_SIGS_PQC_SPHINCS_F_SIMPLE_OID ".2" + +# define OPENCA_ALG_SIGS_PQC_SPHINCS192_F_SIMPLE_OID "1.3.9999.6.5.10" +# define OPENCA_ALG_SIGS_PQC_SPHINCS192_F_SIMPLE_NAME "Sphincs192FWithNoHash" +# define OPENCA_ALG_SIGS_PQC_SPHINCS192_F_SIMPLE_DESC "SPHINCS192F" + +// ======= +// Aliases +// ======= + +// Composite Key Alias +# define OPENCA_ALG_PKEY_EXP_COMP_OID_ENTRUST OPENCA_ALG_PKEY_EXP_COMP_OID +# define OPENCA_ALG_PKEY_EXP_COMP_DESC_ENTRUST OPENCA_ALG_PKEY_EXP_COMP_NAME +# define OPENCA_ALG_PKEY_EXP_COMP_NAME_ENTRUST OPENCA_ALG_PKEY_EXP_COMP_DESC + +// Explicit Composite Key Alias + +#define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_OID "2.16.840.1.114027.80.5.1" + +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_RSA_SHA256_OID OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_OID ".1" +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_RSA_SHA256_DESC "id-Dilithium3-RSA-PKCS15-SHA256" +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_RSA_SHA256_NAME "DILITHIUM3-RSA-SHA256" + +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_P256_SHA256_OID OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_OID ".2" +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_P256_SHA256_DESC "id-Dilithium3-ECDSA-P256-SHA256" +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_P256_SHA256_NAME "DILITHIUM3-P256-SHA256" + +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_BRAINPOOL256_SHA256_OID OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_OID ".3" +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_BRAINPOOL256_SHA256_DESC "id-Dilithium3-ECDSA-BrainpoolP256r1-SHA256" +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_BRAINPOOL256_SHA256_NAME "DILITHIUM3-BRAINPOOL256-SHA256" + +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_ED25519_OID OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_OID ".4" +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_ED25519_DESC "id-Dilithium3-Ed25519" +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_ED25519_NAME "DILITHIUM3-ED25519" + +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_P384_SHA384_OID OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_OID ".5" +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_P384_SHA384_DESC "id-Dilithium5-ECDSA-P384-SHA384" +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_P384_SHA384_NAME "DILITHIUM5-P384-SHA384" + +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_BRAINPOOL384_SHA384_OID OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_OID ".6" +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_BRAINPOOL384_SHA384_DESC "id-Dilithium5-ECDSA-BrainpoolP384r1-SHA384" +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_BRAINPOOL384_SHA384_NAME "DILITHIUM5-BRAINPOOL384-SHA384" + +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_ED448_OID OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_OID ".7" +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_ED448_DESC "id-Dilithium5-Ed448" +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_ED448_NAME "DILITHIUM5-ED448" + +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_FALCON512_P256_SHA256_OID OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_OID ".8.1" +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_FALCON512_P256_SHA256_DESC "id-Falcon512-P256-SHA256" +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_FALCON512_P256_SHA256_NAME "FALCON512-P256-SHA256" + +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_FALCON512_BRAINPOOL256_SHA256_OID OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_OID ".9.1" +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_FALCON512_BRAINPOOL256_SHA256_DESC "id-Falcon512-Brainpool256r1-SHA256" +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_FALCON512_BRAINPOOL256_SHA256_NAME "FALCON512-BRAINPOOL256-SHA256" + +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_FALCON512_ED25519_OID OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_OID ".10.1" +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_FALCON512_ED25519_DESC "id-Falcon512-Ed25519" +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_FALCON512_ED25519_NAME "FALCON512-ED25519" + +// # define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_SPHINCS256_P256_SHA256_OID OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_OID ".11" +// # define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_SPHINCS256_P256_SHA256_DESC "id-Sphincs256-ECDSA-P256-SHA256" +// # define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_SPHINCS256_P256_SHA256_NAME "SPHINCS256-P256-SHA256" + +// # define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_SPHINCS256_BRAINPOOL256_SHA256_OID OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_OID ".12" +// # define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_SPHINCS256_BRAINPOOL256_SHA256_DESC "id-Sphincs256-ECDSA-BrainpoolP256r1-SHA256" +// # define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_SPHINCS256_BRAINPOOL256_SHA256_NAME "SPHINCS256-BRAINPOOL256-SHA256" + +// # define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_SPHINCS256_ED25519_OID OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_OID ".13" +// # define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_SPHINCS256_ED25519_DESC "id-Sphincs256-Ed25519" +// # define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_SPHINCS256_ED25519_NAME "SPHINCS256-ED25519" + +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_RSAPSS_SHA256_OID OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_OID ".14" +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_RSAPSS_SHA256_DESC "id-Dilithium3-RSAPSS-SHA256" +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_RSAPSS_SHA256_NAME "DILITHIUM3-RSAPSS-SHA256" + +// Non-ID Combinations +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_FALCON512_RSA_SHA256_OID OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_OID ".20.1" +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_FALCON512_RSA_SHA256_DESC "id-Falcon512-RSA-SHA256" +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_FALCON512_RSA_SHA256_NAME "FALCON512-RSA-SHA256" + +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_FALCON1024_P521_SHA512_OID OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_OID ".21.1" +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_FALCON1024_P521_SHA512_DESC "id-Dilithium5-Falcon1024-P521-SHA512" +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_FALCON1024_P521_SHA512_NAME "DILITHIUM5-FALCON1024-P512-SHA512" + +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_FALCON1024_RSA_SHA256_OID OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_OID ".22.1" +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_FALCON1024_RSA_SHA256_DESC "id-Dilithium5-Falcon1024-RSA-SHA256" +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_FALCON1024_RSA_SHA256_NAME "DILITHIUM5-FALCON1024-RSA-SHA256" + +// # define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_SPHINCS256_RSA_SHA256_OID OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_OID ".30" +// # define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_SPHINCS256_RSA_SHA256_DESC "id-Sphincs256-RSA-SHA256" +// # define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_SPHINCS256_RSA_SHA256_NAME "SPHINCS256-RSA-SHA256" + +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_KEMKEY_OID "2.16.840.1.114027.80.999" +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_KEMKEY_DESC "id-Composite-KEM" +# define OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_KEMKEY_NAME "COMPOSITE-KEM" + +// // Explicit Composite Signatures + +// #define OPENCA_ALG_SIGS_EXP_COMP_EXPLICIT_OID "2.16.840.1.114027.80.5.3" + +// # define OPENCA_ALG_SIGS_EXP_DILITHIUM3_RSA_SHA256_OID OPENCA_ALG_SIGS_EXP_COMP_EXPLICIT_OID ".1" +// # define OPENCA_ALG_SIGS_EXP_DILITHIUM3_RSA_SHA256_DESC "Sha256WithDilithium3AndRSA" +// # define OPENCA_ALG_SIGS_EXP_DILITHIUM3_RSA_SHA256_NAME "DILITHIUM3-RSA-SHA256" + +// # define OPENCA_ALG_SIGS_EXP_DILITHIUM3_ECDSA_SHA256_OID OPENCA_ALG_SIGS_EXP_COMP_EXPLICIT_OID ".2" +// # define OPENCA_ALG_SIGS_EXP_DILITHIUM3_ECDSA_SHA256_DESC "Sha256WithDilithium3AndECDSA" +// # define OPENCA_ALG_SIGS_EXP_DILITHIUM3_ECDSA_SHA256_NAME "DILITHIUM3-SHA256-ECDSA" + +// # define OPENCA_ALG_SIGS_EXP_DILITHIUM3_ED25519_OID OPENCA_ALG_SIGS_EXP_COMP_EXPLICIT_OID ".4" +// # define OPENCA_ALG_SIGS_EXP_DILITHIUM3_ED25519_DESC "Dilithium3AndEd25519" +// # define OPENCA_ALG_SIGS_EXP_DILITHIUM3_ED25519_NAME "DILITHIUM3-ED25519-NULL" + +// # define OPENCA_ALG_SIGS_EXP_DILITHIUM5_ECDSA_SHA384_OID OPENCA_ALG_SIGS_EXP_COMP_EXPLICIT_OID ".5" +// # define OPENCA_ALG_SIGS_EXP_DILITHIUM5_ECDSA_SHA384_DESC "Sha384WithDilithium5AndECDSA" +// # define OPENCA_ALG_SIGS_EXP_DILITHIUM5_ECDSA_SHA384_NAME "DILITHIUM5-P384-SHA384" + +// # define OPENCA_ALG_SIGS_EXP_DILITHIUM5_BRAINPOOL384_SHA384_OID OPENCA_ALG_SIGS_EXP_COMP_EXPLICIT_OID ".6" +// # define OPENCA_ALG_SIGS_EXP_DILITHIUM5_BRAINPOOL384_SHA384_DESC "Sha384WithDilithium5AndECDSA" +// # define OPENCA_ALG_SIGS_EXP_DILITHIUM5_BRAINPOOL384_SHA384_NAME "DILITHIUM5-BRAINPOOL384-SHA384" + +// # define OPENCA_ALG_SIGS_EXP_DILITHIUM5_ED448_OID OPENCA_ALG_SIGS_EXP_COMP_EXPLICIT_OID ".7" +// # define OPENCA_ALG_SIGS_EXP_DILITHIUM5_ED448_DESC "Dilithium5-Ed448" +// # define OPENCA_ALG_SIGS_EXP_DILITHIUM5_ED448_NAME "DILITHIUM5-ED448-NULL" + +// # define OPENCA_ALG_SIGS_EXP_FALCON512_SHA256_ECDSA_OID OPENCA_ALG_SIGS_EXP_COMP_EXPLICIT_OID ".8" +// # define OPENCA_ALG_SIGS_EXP_FALCON512_SHA256_ECDSA_DESC "Sha256WithFalcon512AndECDSA" +// # define OPENCA_ALG_SIGS_EXP_FALCON512_SHA256_ECDSA_NAME "FALCON512-ECDSA-SHA256" + +// # define OPENCA_ALG_SIGS_EXP_FALCON512_ED25519_OID OPENCA_ALG_SIGS_EXP_COMP_EXPLICIT_OID ".10" +// # define OPENCA_ALG_SIGS_EXP_FALCON512_ED25519_DESC "Falcon512-ED25519" +// # define OPENCA_ALG_SIGS_EXP_FALCON512_ED25519_NAME "FALCON512-ED25519-NULL" + +// # define OPENCA_ALG_SIGS_EXP_SPHINCS256_SHA256_ECDSA_OID OPENCA_ALG_SIGS_EXP_COMP_EXPLICIT_OID ".11" +// # define OPENCA_ALG_SIGS_EXP_SPHINCS256_SHA256_ECDSA_DESC "Sha256WithSphincs256sAndECDSA" +// # define OPENCA_ALG_SIGS_EXP_SPHINCS256_SHA256_ECDSA_NAME "SPHINCS256-SHA256-ECDSA" + +END_C_DECLS + +#endif // End of _LIBPKI_POST_QUANTUM_SIGS_H diff --git a/include/libpki/crypto/hsm/openssl/types.h b/include/libpki/crypto/hsm/openssl/types.h new file mode 100644 index 00000000..1a60941f --- /dev/null +++ b/include/libpki/crypto/hsm/openssl/types.h @@ -0,0 +1,106 @@ +/* crypto_types.h */ + +#ifndef _LIBPKI_SYSTEM_H +# include +#endif + +#ifdef ENABLE_OQS +# include +#endif + +#ifdef _LIBPKI_UTILS_TYPES_H +#include +#endif + +#ifndef CRYPTO_NO_OPENSSL +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include + +#ifdef ENABLE_ECDSA +#include +#endif + +#ifdef ENABLE_OQS +#include +#endif +#endif + +#ifndef _LIBPKI_OPENSSL_TYPES_H +#define _LIBPKI_OPENSSL_TYPES_H + +BEGIN_C_DECLS + +#if defined(ENABLE_OQS) || defined(ENABLE_OQSPROV) + +typedef enum { + PKI_ALGOR_OQS_PARAM_UNKNOWN = 0, + PKI_ALGOR_OQS_PARAM_DILITHIUM_AES, + PKI_ALGOR_OQS_PARAM_SPHINCS_SHAKE +} PKI_ALGOR_OQS_PARAM; + +#endif + +BEGIN_C_DECLS + +/* Crypto Library Asymmetric Key */ +typedef struct EVP_PKEY CRYPTO_PKEY; + +/* Crypto Library Hash Type */ +typedef EVP_MD CRYPTO_HASH; + +/* Crypto Library General Cipher Type */ +typedef EVP_CIPHER CRYPTO_CIPHER; + +/* Some useful Key definitions */ +#ifndef CRYPTO_NO_RSA +#define CRYPTO_RSA RSA +#ifndef CRYPTO_NO_RSAPSS +#define CRYPTO_RSAPSS RSA +#endif +#endif + +#ifdef ENABLE_ECDSA +#define CRYPTO_EC EC_KEY +#endif + +// Typedef for EC Form +typedef point_conversion_form_t CRYPTO_EC_FORM; + +// Defines for supported EC Form +#define CRYPTO_EC_FORM_UNKNOWN 0 +#define CRYPTO_EC_FORM_COMPRESSED POINT_CONVERSION_COMPRESSED +#define CRYPTO_EC_FORM_UNCOMPRESSED POINT_CONVERSION_UNCOMPRESSED +#define CRYPTO_EC_FORM_HYBRID POINT_CONVERSION_HYBRID + +// Default Value +#define CRYPTO_EC_FORM_DEFAULT CRYPTO_EC_FORM_UNCOMPRESSED + +// ASN1 flags for EC keys +typedef enum { + CRYPTO_EC_ASN1_EXPLICIT_CURVE = OPENSSL_EC_EXPLICIT_CURVE, + CRYPTO_EC_ASN1_NAMED_CURVE = OPENSSL_EC_NAMED_CURVE, + CRYPTO_EC_ASN1_IMPLICIT_CURVE = -1 +} CRYPTO_EC_KEY_ASN1; + +// Default for ASN1 flag +#define CRYPTO_EC_KEY_ASN1_DEFAULT CRYPTO_EC_KEY_ASN1_NAMED_CURVE + +END_C_DECLS + +#endif /* _LIBPKI_OPENSSL_TYPES_H */ diff --git a/include/libpki/crypto/hsm/pkcs11/pkcs11_hsm.h b/include/libpki/crypto/hsm/pkcs11/pkcs11_hsm.h new file mode 100644 index 00000000..afed81a4 --- /dev/null +++ b/include/libpki/crypto/hsm/pkcs11/pkcs11_hsm.h @@ -0,0 +1,84 @@ +/* libpki/drivers/pkcs11/pkcs11_hsm.h */ + +#ifndef _LIBPKI_HSM_PKCS11_H +#define _LIBPKI_HSM_PKCS11_H + +typedef struct pkcs11_handler { + + /* Pointer to the Shared Object (lib) */ + void *sh_lib; + + /* Info for the current HSM and Library */ + HSM_INFO hsm_info; + + /* Available Mechanisms (Algoritms) */ + CK_MECHANISM_TYPE_PTR mech_list; + + /* Number of available Mechanisms (Algorithms) */ + unsigned long mech_num; + + /* Current Algorithm */ + CK_MECHANISM_TYPE mech_curr; + + /* Callbacks - Easier to reference for PKCS11 drivers */ + CK_FUNCTION_LIST_PTR callbacks; + + /* Session Handler - Four Different handlers */ + CK_SESSION_HANDLE session; + /* + CK_SESSION_HANDLE encrypt; + CK_SESSION_HANDLE decrypt; + CK_SESSION_HANDLE sign; + CK_SESSION_HANDLE info; + */ + + /* Loging status */ + int logged_in; + + /* Current Slot ID */ + CK_SLOT_ID slot_id; + + /* Current Slot & Token (in slot_info.token) Info */ + HSM_SLOT_INFO slot_info; + + /* PKCS11 Operations Mutex */ + pthread_mutex_t pkcs11_mutex; + pthread_cond_t pkcs11_cond; + +} PKCS11_HANDLER; + +HSM * HSM_PKCS11_new( PKI_CONFIG *conf ); +int HSM_PKCS11_free ( HSM *driver, PKI_CONFIG *conf ); + +int HSM_PKCS11_login ( HSM *driver, PKI_CRED *cred ); +int HSM_PKCS11_logout ( HSM *driver ); + +int HSM_PKCS11_init ( HSM *driver, PKI_CONFIG *conf ); +int HSM_PKCS11_sign_algor_set (HSM *hsm, PKI_X509_ALGOR_VALUE *algor); + +int HSM_PKCS11_set_fips_mode ( const HSM *driver, int k); +int HSM_PKCS11_is_fips_mode( const HSM *driver ); + +/* +PKI_MEM * HSM_PKCS11_sign (PKI_MEM *der, PKI_X509_KEYPAIR *key, + PKI_DIGEST_ALG *digest); +int HSM_PKCS11_sign (PKI_OBJTYPE type, + void *x, + void *it_pp, + PKI_ALGOR *alg, + PKI_STRING *bit, + PKI_X509_KEYPAIR *key, + PKI_DIGEST_ALG *digest, + HSM *driver ); +*/ + +int HSM_PKCS11_verify ( PKI_OBJTYPE type, void *x, + PKI_X509_KEYPAIR *key, HSM *hsm ); + +unsigned long HSM_PKCS11_SLOT_num(HSM * hsm); +HSM_SLOT_INFO * HSM_PKCS11_SLOT_INFO_get ( unsigned long num, HSM *hsm ); +void HSM_PKCS11_SLOT_INFO_free ( HSM_SLOT_INFO *sl_info, HSM *hsm ); +int HSM_PKCS11_SLOT_select ( unsigned long num, PKI_CRED *cred, HSM *hsm); +int HSM_PKCS11_SLOT_clear (unsigned long slot_id, PKI_CRED *cred, HSM *driver); + +#endif diff --git a/include/libpki/crypto/hsm/pkcs11/pkcs11_hsm_obj.h b/include/libpki/crypto/hsm/pkcs11/pkcs11_hsm_obj.h new file mode 100644 index 00000000..bd6f4fe4 --- /dev/null +++ b/include/libpki/crypto/hsm/pkcs11/pkcs11_hsm_obj.h @@ -0,0 +1,46 @@ +/* PKCS#11 Object Management Functions */ + +#ifndef _LIBPKI_HEADERS_PKCS11_OBJSK_H +#define _LIBPKI_HEADERS_PKCS11_OBJSK_H + +/* ------------------- Retrieves a stack of objects ------------------- */ + +PKI_X509_STACK * HSM_PKCS11_OBJSK_get_url ( PKI_DATATYPE type, URL *url, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ); + +int HSM_PKCS11_OBJSK_add_url ( PKI_X509_STACK *sk, URL *url, + PKI_CRED *cred, HSM *hsm ); + +int HSM_PKCS11_OBJSK_del_url ( PKI_DATATYPE, URL *url, + PKI_CRED *cred, HSM *hsm); + +/* --------------------- Internal Functions --------------------------- */ + +PKI_X509_STACK *HSM_PKCS11_STACK_get_url( PKI_DATATYPE type, URL *url, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *driver ); + +int HSM_PKCS11_STACK_add_url( PKI_X509_STACK *sk, URL *url, + PKI_CRED *cred, HSM *hsm ); + +/* ------------------------ get Template(s) functions --------------------- */ +int HSM_PKCS11_X509_CERT_get_template (CK_ATTRIBUTE *templ, PKI_X509_CERT *x, + char *label, int label_len, + char *id, int id_len ); +/* ------------------------ get KEYPAIR functions ------------------------- */ +PKI_X509_KEYPAIR_STACK * HSM_PKCS11_KEYPAIR_get_url (URL *url, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm); +PKI_STACK * HSM_PKCS11_KEYPAIR_wrap_url ( URL *url, PKI_CRED *cred, + HSM *driver ); +PKI_STACK * HSM_PKCS11_KEYPAIR_STACK_wrap ( PKI_X509_KEYPAIR_STACK *sk, + PKI_CRED *cred, HSM *driver ); +/* ------------------------ add KEYPAIR functions ------------------------- */ +int HSM_PKCS11_KEYPAIR_add_url ( PKI_X509_KEYPAIR *pk, URL *url, PKI_CRED *cred, + HSM *driver ); +int HSM_PKCS11_KEYPAIR_STACK_add_url ( PKI_STACK *sk, URL *url, PKI_CRED *cred, + HSM *driver ); +/* ------------------------ Find functions ------------------------------ */ + +CK_OBJECT_HANDLE * HSM_PKCS11_X509_CERT_find_private_key ( PKI_X509_CERT *x, + CK_SESSION_HANDLE *hSession, PKCS11_HANDLER *lib ); +#endif + diff --git a/include/libpki/crypto/hsm/pkcs11/pkcs11_hsm_pkey.h b/include/libpki/crypto/hsm/pkcs11/pkcs11_hsm_pkey.h new file mode 100644 index 00000000..3b3a2e88 --- /dev/null +++ b/include/libpki/crypto/hsm/pkcs11/pkcs11_hsm_pkey.h @@ -0,0 +1,41 @@ +/* PKCS11 Object Management Functions */ + +#ifndef _LIBPKI_HEADERS_PKCS11_PKEY_H +#define _LIBPKI_HEADERS_PKCS11_PKEY_H + +#include + +#if OPENSSL_VERSION_NUMBER < 0x1010000fL + typedef ECDSA_METHOD EC_KEY_METHOD; +#endif + +/* ------------------------ Key Management Functions --------------------- */ +PKI_X509_KEYPAIR *HSM_PKCS11_KEYPAIR_new( PKI_KEYPARAMS *kp, + URL *url, PKI_CRED *cred, HSM *driver ); + +void HSM_PKCS11_KEYPAIR_free ( PKI_X509_KEYPAIR *pkey ); + +/* ------------------------------ RSA Callback Methods ------------------- */ + +const RSA_METHOD * HSM_PKCS11_get_rsa_method ( void ); + +const EC_KEY_METHOD * HSM_PKCS11_get_ecdsa_method ( void ); + +int HSM_PKCS11_rsa_sign ( int type, const unsigned char *m, unsigned int m_len, + unsigned char *sigret, unsigned int *siglen, const RSA *rsa ); + +#if OPENSSL_VERSION_NUMBER < 0x1010000fL + +ECDSA_SIG *HSM_PKCS11_ecdsa_sign(const unsigned char *dgst, int dgst_len, + const BIGNUM *inv, const BIGNUM *rp, EC_KEY *eckey); + +#else + +// int HSM_PKCS11_ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, BIGNUM **r); + +int HSM_PKCS11_ecdsa_sign ( int type, const unsigned char *dgst, int dlen, + unsigned char *sig, unsigned int *siglen, const BIGNUM *kinv, const BIGNUM *r, + EC_KEY *eckey ); +#endif +#endif + diff --git a/include/libpki/crypto/hsm/pkcs11/pkcs11_utils.h b/include/libpki/crypto/hsm/pkcs11/pkcs11_utils.h new file mode 100644 index 00000000..748f9b53 --- /dev/null +++ b/include/libpki/crypto/hsm/pkcs11/pkcs11_utils.h @@ -0,0 +1,86 @@ +/* PKCS11 Utils */ + +#ifndef _LIBPKI_HSM_PKCS11_UTILS_H +#define _LIBPKI_HSM_PKCS11_UTILS_H + +#define MAGIC 0xd00bed00 + +PKCS11_HANDLER * _hsm_get_pkcs11_handler ( void * hsm_void ); +PKCS11_HANDLER * _pki_pkcs11_load_module(const char *filename,PKI_CONFIG *conf); +int _hsm_pkcs11_get_token_info( unsigned long slot_id, + HSM_TOKEN_INFO *tk_info, PKCS11_HANDLER *lib ); + +int HSM_PKCS11_get_contents_info( unsigned long slot_id, PKI_CRED *cred, + void *driver ); + +int _strncpyClip( char *dst, char *orig, size_t size ); + +int HSM_PKCS11_check_mechanism ( PKCS11_HANDLER *lib, CK_MECHANISM_TYPE mech ); + +/* Session Handling */ +int HSM_PKCS11_session_new( unsigned long slot_id, CK_SESSION_HANDLE *hSession, + int flags, PKCS11_HANDLER *lib ); +int HSM_PKCS11_session_close( CK_SESSION_HANDLE *hSession, PKCS11_HANDLER *lib); + +/* Finds the first occurrence of an object */ +CK_OBJECT_HANDLE * HSM_PKCS11_get_obj( CK_ATTRIBUTE *templ, + int size, PKCS11_HANDLER *lib, CK_SESSION_HANDLE *s); + +/* Create an Object in a PKCS11 device */ +CK_OBJECT_HANDLE *HSM_PKCS11_create_obj ( CK_SESSION_HANDLE *hSession, + CK_ATTRIBUTE *templ, int size, PKCS11_HANDLER *lib ); + +/* Get attributes from the PKCS11 device */ +int HSM_PKCS11_get_attribute (CK_OBJECT_HANDLE *hPkey, + CK_SESSION_HANDLE *hSession, CK_ATTRIBUTE_TYPE attribute, + void **data, CK_ULONG *size, PKCS11_HANDLER *lib ); +int HSM_PKCS11_get_attr_bool ( CK_OBJECT_HANDLE *hObj, + CK_SESSION_HANDLE *hSession, CK_ATTRIBUTE_TYPE attribute, + CK_BBOOL *val, PKCS11_HANDLER *lib ); +int HSM_PKCS11_get_attr_ckulong ( CK_OBJECT_HANDLE *hObj, + CK_SESSION_HANDLE *hSession, CK_ATTRIBUTE_TYPE attribute, + CK_ULONG *val, PKCS11_HANDLER *lib ); +int HSM_PKCS11_get_attr_bn ( CK_OBJECT_HANDLE *hObj, + CK_SESSION_HANDLE *hSession, CK_ATTRIBUTE_TYPE attribute, + BIGNUM **val, PKCS11_HANDLER *lib ); +int HSM_PKCS11_get_attr_sn ( CK_OBJECT_HANDLE *hObj, + CK_SESSION_HANDLE *hSession, CK_ATTRIBUTE_TYPE attribute, + char **val, PKCS11_HANDLER *lib ); + +/* Set attributes for a PKCS11 object */ +int HSM_PKCS11_set_attribute (CK_OBJECT_HANDLE *hObj, + CK_SESSION_HANDLE *hSession, CK_ATTRIBUTE *attribute, + int size, PKCS11_HANDLER *lib ); + +/* Set a single attribute in the CK_ATTRIBUTE[] that is to be uses to + set/get the attribute in the PKCS#11 device */ +int HSM_PKCS11_set_attr_bool (CK_ATTRIBUTE_TYPE type, + CK_BBOOL value, CK_ATTRIBUTE *attribute ); +int HSM_PKCS11_set_attr_int ( CK_ATTRIBUTE_TYPE type, + CK_ULONG value, CK_ATTRIBUTE *attribute ); +int HSM_PKCS11_set_attr_sn ( CK_ATTRIBUTE_TYPE type, char *value, + size_t len,CK_ATTRIBUTE *attribute); +int HSM_PKCS11_set_attr_bn ( CK_ATTRIBUTE_TYPE type, const BIGNUM *bn, + CK_ATTRIBUTE *attribute); + +/* Save a single attribute to an existing object */ +int HSM_PKCS11_save_attribute (CK_OBJECT_HANDLE *obj, + CK_ATTRIBUTE *templ, int idx , CK_SESSION_HANDLE *hSession, + PKCS11_HANDLER *lib ); +int HSM_PKCS11_save_attr_bool (CK_OBJECT_HANDLE *obj, CK_ATTRIBUTE_TYPE type, + CK_BBOOL value, CK_SESSION_HANDLE *hSession, + PKCS11_HANDLER *lib ); +int HSM_PKCS11_save_attr_int ( CK_OBJECT_HANDLE *obj, CK_ATTRIBUTE_TYPE type, + int value, CK_SESSION_HANDLE *hSession, + PKCS11_HANDLER *lib ); +int HSM_PKCS11_save_attr_sn ( CK_OBJECT_HANDLE *obj, CK_ATTRIBUTE_TYPE type, + char *value, int len, CK_SESSION_HANDLE *hSession, + PKCS11_HANDLER *lib ); +int HSM_PKCS11_save_attr_bn ( CK_OBJECT_HANDLE *obj, CK_ATTRIBUTE_TYPE type, + BIGNUM *bn, CK_SESSION_HANDLE *hSession, + PKCS11_HANDLER *lib ); + +/* Clean a template (array of CK_ATTRIBUTE) */ +void HSM_PKCS11_clean_template ( CK_ATTRIBUTE *templ, int n ); + +#endif /* _LIBPKI_HSM_PKCS11_UTILS_H */ diff --git a/include/libpki/crypto/hsm/pkcs11/rsa/cryptoki.h b/include/libpki/crypto/hsm/pkcs11/rsa/cryptoki.h new file mode 100644 index 00000000..0514a575 --- /dev/null +++ b/include/libpki/crypto/hsm/pkcs11/rsa/cryptoki.h @@ -0,0 +1,112 @@ +/* Modified by Massimiliano Pala for LibPKI */ +/* ========================================================================= */ +/* cryptoki.h include file for PKCS #11. */ +/* $Revision: 1.1.1.1 $ */ + +/* License to copy and use this software is granted provided that it is + * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface + * (Cryptoki)" in all material mentioning or referencing this software. + + * License is also granted to make and use derivative works provided that + * such works are identified as "derived from the RSA Security Inc. PKCS #11 + * Cryptographic Token Interface (Cryptoki)" in all material mentioning or + * referencing the derived work. + + * RSA Security Inc. makes no representations concerning either the + * merchantability of this software or the suitability of this software for + * any particular purpose. It is provided "as is" without express or implied + * warranty of any kind. + */ + +/* This is a sample file containing the top level include directives + * for building Win32 Cryptoki libraries and applications. + */ + +#ifndef ___CRYPTOKI_H_INC___ +#define ___CRYPTOKI_H_INC___ + +#if defined(WIN16) || (defined(_WINDOWS) && !defined(_WIN32)) + #define CK_ENTRY _export _far _pascal + #define CK_POINTER far * + #pragma pack(1) +#elif defined(VXD) + #define CK_ENTRY + #define CK_POINTER * + #pragma pack(push, 1) +#elif defined(WIN32) || defined(_WINDOWS) + #define CK_ENTRY __declspec( dllexport ) + #define CK_POINTER * + #pragma pack(push, cryptoki, 1) +#else + #define CK_ENTRY + #define CK_POINTER * +#endif + +/* Specifies that the function is a DLL entry point. */ +#define CK_IMPORT_SPEC __declspec(dllimport) + +/* Define CRYPTOKI_EXPORTS during the build of cryptoki libraries. Do + * not define it in applications. + */ +#ifdef CRYPTOKI_EXPORTS +/* Specified that the function is an exported DLL entry point. */ +#define CK_EXPORT_SPEC __declspec(dllexport) +#else +#define CK_EXPORT_SPEC CK_IMPORT_SPEC +#endif + +/* Ensures the calling convention for Win32 builds */ +#define CK_CALL_SPEC __cdecl + +#define CK_PTR * + +#define CK_DEFINE_FUNCTION(returnType, name) \ + returnType name + +/* +#define CK_DEFINE_FUNCTION(returnType, name) \ + returnType CK_EXPORT_SPEC CK_CALL_SPEC name +*/ + +#define CK_DECLARE_FUNCTION(returnType, name) \ + returnType name + +/* +#define CK_DECLARE_FUNCTION(returnType, name) \ + returnType CK_EXPORT_SPEC CK_CALL_SPEC name +*/ + +#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \ + returnType (* name) + +/* +#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \ + returnType CK_IMPORT_SPEC (CK_CALL_SPEC CK_PTR name) +*/ + +#define CK_CALLBACK_FUNCTION(returnType, name) \ + returnType (* name) + +/* +#define CK_CALLBACK_FUNCTION(returnType, name) \ + returnType (CK_CALL_SPEC CK_PTR name) +*/ + +#ifndef NULL_PTR +#define NULL_PTR 0 +#endif + +#include +// #include +// #include + +#if defined(WIN16) || (defined(_WINDOWS) && !defined(_WIN32)) + #pragma pack() +#elif defined(VXD) + #pragma pack(pop) +#elif defined(WIN32) || defined(_WINDOWS) + #pragma pack(pop, cryptoki) +#endif + + +#endif /* ___CRYPTOKI_H_INC___ */ diff --git a/include/libpki/crypto/hsm/pkcs11/rsa/pkcs11.h b/include/libpki/crypto/hsm/pkcs11/rsa/pkcs11.h new file mode 100644 index 00000000..0d78dd71 --- /dev/null +++ b/include/libpki/crypto/hsm/pkcs11/rsa/pkcs11.h @@ -0,0 +1,265 @@ +/* Copyright (c) OASIS Open 2016. All Rights Reserved./ + * /Distributed under the terms of the OASIS IPR Policy, + * [http://www.oasis-open.org/policies-guidelines/ipr], AS-IS, WITHOUT ANY + * IMPLIED OR EXPRESS WARRANTY; there is no warranty of MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE or NONINFRINGEMENT of the rights of others. + */ + +/* Latest version of the specification: + * http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/pkcs11-base-v2.40.html + */ + +#ifndef _PKCS11_H_ +#define _PKCS11_H_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* Before including this file (pkcs11.h) (or pkcs11t.h by + * itself), 5 platform-specific macros must be defined. These + * macros are described below, and typical definitions for them + * are also given. Be advised that these definitions can depend + * on both the platform and the compiler used (and possibly also + * on whether a Cryptoki library is linked statically or + * dynamically). + * + * In addition to defining these 5 macros, the packing convention + * for Cryptoki structures should be set. The Cryptoki + * convention on packing is that structures should be 1-byte + * aligned. + * + * If you're using Microsoft Developer Studio 5.0 to produce + * Win32 stuff, this might be done by using the following + * preprocessor directive before including pkcs11.h or pkcs11t.h: + * + * #pragma pack(push, cryptoki, 1) + * + * and using the following preprocessor directive after including + * pkcs11.h or pkcs11t.h: + * + * #pragma pack(pop, cryptoki) + * + * If you're using an earlier version of Microsoft Developer + * Studio to produce Win16 stuff, this might be done by using + * the following preprocessor directive before including + * pkcs11.h or pkcs11t.h: + * + * #pragma pack(1) + * + * In a UNIX environment, you're on your own for this. You might + * not need to do (or be able to do!) anything. + * + * + * Now for the macros: + * + * + * 1. CK_PTR: The indirection string for making a pointer to an + * object. It can be used like this: + * + * typedef CK_BYTE CK_PTR CK_BYTE_PTR; + * + * If you're using Microsoft Developer Studio 5.0 to produce + * Win32 stuff, it might be defined by: + * + * #define CK_PTR * + * + * If you're using an earlier version of Microsoft Developer + * Studio to produce Win16 stuff, it might be defined by: + * + * #define CK_PTR far * + * + * In a typical UNIX environment, it might be defined by: + * + * #define CK_PTR * + * + * + * 2. CK_DECLARE_FUNCTION(returnType, name): A macro which makes + * an importable Cryptoki library function declaration out of a + * return type and a function name. It should be used in the + * following fashion: + * + * extern CK_DECLARE_FUNCTION(CK_RV, C_Initialize)( + * CK_VOID_PTR pReserved + * ); + * + * If you're using Microsoft Developer Studio 5.0 to declare a + * function in a Win32 Cryptoki .dll, it might be defined by: + * + * #define CK_DECLARE_FUNCTION(returnType, name) \ + * returnType __declspec(dllimport) name + * + * If you're using an earlier version of Microsoft Developer + * Studio to declare a function in a Win16 Cryptoki .dll, it + * might be defined by: + * + * #define CK_DECLARE_FUNCTION(returnType, name) \ + * returnType __export _far _pascal name + * + * In a UNIX environment, it might be defined by: + * + * #define CK_DECLARE_FUNCTION(returnType, name) \ + * returnType name + * + * + * 3. CK_DECLARE_FUNCTION_POINTER(returnType, name): A macro + * which makes a Cryptoki API function pointer declaration or + * function pointer type declaration out of a return type and a + * function name. It should be used in the following fashion: + * + * // Define funcPtr to be a pointer to a Cryptoki API function + * // taking arguments args and returning CK_RV. + * CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtr)(args); + * + * or + * + * // Define funcPtrType to be the type of a pointer to a + * // Cryptoki API function taking arguments args and returning + * // CK_RV, and then define funcPtr to be a variable of type + * // funcPtrType. + * typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtrType)(args); + * funcPtrType funcPtr; + * + * If you're using Microsoft Developer Studio 5.0 to access + * functions in a Win32 Cryptoki .dll, in might be defined by: + * + * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \ + * returnType __declspec(dllimport) (* name) + * + * If you're using an earlier version of Microsoft Developer + * Studio to access functions in a Win16 Cryptoki .dll, it might + * be defined by: + * + * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \ + * returnType __export _far _pascal (* name) + * + * In a UNIX environment, it might be defined by: + * + * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \ + * returnType (* name) + * + * + * 4. CK_CALLBACK_FUNCTION(returnType, name): A macro which makes + * a function pointer type for an application callback out of + * a return type for the callback and a name for the callback. + * It should be used in the following fashion: + * + * CK_CALLBACK_FUNCTION(CK_RV, myCallback)(args); + * + * to declare a function pointer, myCallback, to a callback + * which takes arguments args and returns a CK_RV. It can also + * be used like this: + * + * typedef CK_CALLBACK_FUNCTION(CK_RV, myCallbackType)(args); + * myCallbackType myCallback; + * + * If you're using Microsoft Developer Studio 5.0 to do Win32 + * Cryptoki development, it might be defined by: + * + * #define CK_CALLBACK_FUNCTION(returnType, name) \ + * returnType (* name) + * + * If you're using an earlier version of Microsoft Developer + * Studio to do Win16 development, it might be defined by: + * + * #define CK_CALLBACK_FUNCTION(returnType, name) \ + * returnType _far _pascal (* name) + * + * In a UNIX environment, it might be defined by: + * + * #define CK_CALLBACK_FUNCTION(returnType, name) \ + * returnType (* name) + * + * + * 5. NULL_PTR: This macro is the value of a NULL pointer. + * + * In any ANSI/ISO C environment (and in many others as well), + * this should best be defined by + * + * #ifndef NULL_PTR + * #define NULL_PTR 0 + * #endif + */ + + +/* All the various Cryptoki types and #define'd values are in the + * file pkcs11t.h. + */ +#include "pkcs11t.h" + +#define __PASTE(x,y) x##y + + +/* ============================================================== + * Define the "extern" form of all the entry points. + * ============================================================== + */ + +#define CK_NEED_ARG_LIST 1 +#define CK_PKCS11_FUNCTION_INFO(name) \ + extern CK_DECLARE_FUNCTION(CK_RV, name) + +/* pkcs11f.h has all the information about the Cryptoki + * function prototypes. + */ +#include "pkcs11f.h" + +#undef CK_NEED_ARG_LIST +#undef CK_PKCS11_FUNCTION_INFO + + +/* ============================================================== + * Define the typedef form of all the entry points. That is, for + * each Cryptoki function C_XXX, define a type CK_C_XXX which is + * a pointer to that kind of function. + * ============================================================== + */ + +#define CK_NEED_ARG_LIST 1 +#define CK_PKCS11_FUNCTION_INFO(name) \ + typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_,name)) + +/* pkcs11f.h has all the information about the Cryptoki + * function prototypes. + */ +#include "pkcs11f.h" + +#undef CK_NEED_ARG_LIST +#undef CK_PKCS11_FUNCTION_INFO + + +/* ============================================================== + * Define structed vector of entry points. A CK_FUNCTION_LIST + * contains a CK_VERSION indicating a library's Cryptoki version + * and then a whole slew of function pointers to the routines in + * the library. This type was declared, but not defined, in + * pkcs11t.h. + * ============================================================== + */ + +#define CK_PKCS11_FUNCTION_INFO(name) \ + __PASTE(CK_,name) name; + +struct CK_FUNCTION_LIST { + + CK_VERSION version; /* Cryptoki version */ + +/* Pile all the function pointers into the CK_FUNCTION_LIST. */ +/* pkcs11f.h has all the information about the Cryptoki + * function prototypes. + */ +#include "pkcs11f.h" + +}; + +#undef CK_PKCS11_FUNCTION_INFO + + +#undef __PASTE + +#ifdef __cplusplus +} +#endif + +#endif /* _PKCS11_H_ */ + diff --git a/include/libpki/crypto/hsm/pkcs11/rsa/pkcs11_func.h b/include/libpki/crypto/hsm/pkcs11/rsa/pkcs11_func.h new file mode 100644 index 00000000..322b5c4f --- /dev/null +++ b/include/libpki/crypto/hsm/pkcs11/rsa/pkcs11_func.h @@ -0,0 +1,152 @@ +/* This file prevents the compiler from warining about + * deferencing void pointers + */ + +CK_RV CK_ENTRY C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList); + +typedef CK_RV CK_ENTRY (CK_PTR CK_C_Initialize)(CK_VOID_PTR pReserved); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_Finalize)(CK_VOID_PTR pReserved); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_Terminate)(void); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_GetInfo)(CK_INFO_PTR pInfo); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_GetFunctionList)(CK_FUNCTION_LIST_PTR_PTR ppFunctionList); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_GetSlotList)(CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pusCount); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_GetSlotInfo)(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_GetTokenInfo)(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_GetMechanismList)(CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pusCount); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_GetMechanismInfo)(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_WaitForSlotEvent)(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, CK_VOID_PTR pReserved); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_InitToken)(CK_SLOT_ID slotID, CK_CHAR_PTR pPin, CK_ULONG usPinLen, CK_CHAR_PTR pLabel); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_InitPIN)(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pPin, CK_ULONG usPinLen); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_SetPIN)(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin, CK_ULONG usOldLen, CK_CHAR_PTR pNewPin, CK_ULONG usNewLen); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_OpenSession)(CK_SLOT_ID slotID, CK_FLAGS flags, CK_VOID_PTR pApplication, CK_NOTIFY Notify, CK_SESSION_HANDLE_PTR phSession); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_CloseSession)(CK_SESSION_HANDLE hSession); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_CloseAllSessions)(CK_SLOT_ID slotID); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_GetSessionInfo)(CK_SESSION_HANDLE hSession, CK_SESSION_INFO_PTR pInfo); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_GetOperationState)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState, CK_ULONG_PTR pulOperationStateLen); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_SetOperationState)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState, CK_ULONG ulOperationStateLen, CK_OBJECT_HANDLE hEncryptionKey, CK_OBJECT_HANDLE hAuthenticationKey); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_Login)(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK_CHAR_PTR pPin, CK_ULONG usPinLen); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_Logout)(CK_SESSION_HANDLE hSession); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_CreateObject)(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount, CK_OBJECT_HANDLE_PTR phObject); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_CopyObject)(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount, CK_OBJECT_HANDLE_PTR phNewObject); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_DestroyObject)(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_GetObjectSize)(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pusSize); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_GetAttributeValue)(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_SetAttributeValue)(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_FindObjectsInit)(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_FindObjects)(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE_PTR phObject, CK_ULONG usMaxObjectCount, CK_ULONG_PTR pusObjectCount); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_FindObjectsFinal)(CK_SESSION_HANDLE hSession); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_EncryptInit)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_Encrypt)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG usDataLen, CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pusEncryptedDataLen); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_EncryptUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG usPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pusEncryptedPartLen); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_EncryptFinal)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastEncryptedPart, CK_ULONG_PTR pusLastEncryptedPartLen); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_DecryptInit)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_Decrypt)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, CK_ULONG usEncryptedDataLen, CK_BYTE_PTR pData, CK_ULONG_PTR pusDataLen); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_DecryptUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG usEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pusPartLen); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_DecryptFinal)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastPart, CK_ULONG_PTR pusLastPartLen); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_DigestInit)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_Digest)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG usDataLen, CK_BYTE_PTR pDigest, CK_ULONG_PTR pusDigestLen); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_DigestUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG usPartLen); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_DigestKey)(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_DigestFinal)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest, CK_ULONG_PTR pusDigestLen); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_SignInit)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_Sign)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG usDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pusSignatureLen); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_SignUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG usPartLen); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_SignFinal)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG_PTR pusSignatureLen); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_SignRecoverInit)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_SignRecover)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG usDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pusSignatureLen); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_VerifyInit)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_Verify)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG usDataLen, CK_BYTE_PTR pSignature, CK_ULONG usSignatureLen); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_VerifyUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG usPartLen); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_VerifyFinal)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG usSignatureLen); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_VerifyRecoverInit)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_VerifyRecover)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG usSignatureLen, CK_BYTE_PTR pData, CK_ULONG_PTR pusDataLen); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_DigestEncryptUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_DecryptDigestUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_SignEncryptUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_DecryptVerifyUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_GenerateKey)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount, CK_OBJECT_HANDLE_PTR phKey); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_GenerateKeyPair)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG usPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG usPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPrivateKey, CK_OBJECT_HANDLE_PTR phPublicKey); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_WrapKey)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey, CK_ULONG_PTR pusWrappedKeyLen); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_UnwrapKey)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey, CK_BYTE_PTR pWrappedKey, CK_ULONG usWrappedKeyLen, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usAttributeCount, CK_OBJECT_HANDLE_PTR phKey); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_DeriveKey)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usAttributeCount, CK_OBJECT_HANDLE_PTR phKey); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_SeedRandom)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, CK_ULONG usSeedLen); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_GenerateRandom)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pRandomData, CK_ULONG usRandomLen); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_GetFunctionStatus)(CK_SESSION_HANDLE hSession); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_CancelFunction)(CK_SESSION_HANDLE hSession); +typedef CK_RV CK_ENTRY (CK_PTR CK_C_PerformSelfTest)(CK_SESSION_HANDLE hSession, CK_ULONG typeOfTest, CK_BYTE_PTR outputData, CK_ULONG sizeOfOutputData, CK_BYTE_PTR inputData, CK_ULONG_PTR sizeOfInputData); +typedef CK_RV CK_ENTRY (CK_PTR CK_Notify)(CK_SESSION_HANDLE hSession, CK_NOTIFICATION event, CK_VOID_PTR pApplication); + + +struct CK_FUNCTION_LIST { + CK_VERSION version; + CK_C_Initialize C_Initialize; + CK_C_Finalize C_Finalize; + CK_C_GetInfo C_GetInfo; + CK_C_GetFunctionList C_GetFunctionList; + CK_C_GetSlotList C_GetSlotList; + CK_C_GetSlotInfo C_GetSlotInfo; + CK_C_GetTokenInfo C_GetTokenInfo; + CK_C_GetMechanismList C_GetMechanismList; + CK_C_GetMechanismInfo C_GetMechanismInfo; + CK_C_InitToken C_InitToken; + CK_C_InitPIN C_InitPIN; + CK_C_SetPIN C_SetPIN; + CK_C_OpenSession C_OpenSession; + CK_C_CloseSession C_CloseSession; + CK_C_CloseAllSessions C_CloseAllSessions; + CK_C_GetSessionInfo C_GetSessionInfo; + CK_C_GetOperationState C_GetOperationState; + CK_C_SetOperationState C_SetOperationState; + CK_C_Login C_Login; + CK_C_Logout C_Logout; + CK_C_CreateObject C_CreateObject; + CK_C_CopyObject C_CopyObject; + CK_C_DestroyObject C_DestroyObject; + CK_C_GetObjectSize C_GetObjectSize; + CK_C_GetAttributeValue C_GetAttributeValue; + CK_C_SetAttributeValue C_SetAttributeValue; + CK_C_FindObjectsInit C_FindObjectsInit; + CK_C_FindObjects C_FindObjects; + CK_C_FindObjectsFinal C_FindObjectsFinal; + CK_C_EncryptInit C_EncryptInit; + CK_C_Encrypt C_Encrypt; + CK_C_EncryptUpdate C_EncryptUpdate; + CK_C_EncryptFinal C_EncryptFinal; + CK_C_DecryptInit C_DecryptInit; + CK_C_Decrypt C_Decrypt; + CK_C_DecryptUpdate C_DecryptUpdate; + CK_C_DecryptFinal C_DecryptFinal; + CK_C_DigestInit C_DigestInit; + CK_C_Digest C_Digest; + CK_C_DigestUpdate C_DigestUpdate; + CK_C_DigestKey C_DigestKey; + CK_C_DigestFinal C_DigestFinal; + CK_C_SignInit C_SignInit; + CK_C_Sign C_Sign; + CK_C_SignUpdate C_SignUpdate; + CK_C_SignFinal C_SignFinal; + CK_C_SignRecoverInit C_SignRecoverInit; + CK_C_SignRecover C_SignRecover; + CK_C_VerifyInit C_VerifyInit; + CK_C_Verify C_Verify; + CK_C_VerifyUpdate C_VerifyUpdate; + CK_C_VerifyFinal C_VerifyFinal; + CK_C_VerifyRecoverInit C_VerifyRecoverInit; + CK_C_VerifyRecover C_VerifyRecover; + CK_C_DigestEncryptUpdate C_DigestEncryptUpdate; + CK_C_DecryptDigestUpdate C_DecryptDigestUpdate; + CK_C_SignEncryptUpdate C_SignEncryptUpdate; + CK_C_DecryptVerifyUpdate C_DecryptVerifyUpdate; + CK_C_GenerateKey C_GenerateKey; + CK_C_GenerateKeyPair C_GenerateKeyPair; + CK_C_WrapKey C_WrapKey; + CK_C_UnwrapKey C_UnwrapKey; + CK_C_DeriveKey C_DeriveKey; + CK_C_SeedRandom C_SeedRandom; + CK_C_GenerateRandom C_GenerateRandom; + CK_C_GetFunctionStatus C_GetFunctionStatus; + CK_C_CancelFunction C_CancelFunction; + CK_C_WaitForSlotEvent C_WaitForSlotEvent; + CK_C_PerformSelfTest C_PerformSelfTest; +}; + diff --git a/include/libpki/crypto/hsm/pkcs11/rsa/pkcs11f.h b/include/libpki/crypto/hsm/pkcs11/rsa/pkcs11f.h new file mode 100644 index 00000000..ed90affc --- /dev/null +++ b/include/libpki/crypto/hsm/pkcs11/rsa/pkcs11f.h @@ -0,0 +1,939 @@ +/* Copyright (c) OASIS Open 2016. All Rights Reserved./ + * /Distributed under the terms of the OASIS IPR Policy, + * [http://www.oasis-open.org/policies-guidelines/ipr], AS-IS, WITHOUT ANY + * IMPLIED OR EXPRESS WARRANTY; there is no warranty of MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE or NONINFRINGEMENT of the rights of others. + */ + +/* Latest version of the specification: + * http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/pkcs11-base-v2.40.html + */ + +/* This header file contains pretty much everything about all the + * Cryptoki function prototypes. Because this information is + * used for more than just declaring function prototypes, the + * order of the functions appearing herein is important, and + * should not be altered. + */ + +/* General-purpose */ + +/* C_Initialize initializes the Cryptoki library. */ +CK_PKCS11_FUNCTION_INFO(C_Initialize) +#ifdef CK_NEED_ARG_LIST +( + CK_VOID_PTR pInitArgs /* if this is not NULL_PTR, it gets + * cast to CK_C_INITIALIZE_ARGS_PTR + * and dereferenced + */ +); +#endif + + +/* C_Finalize indicates that an application is done with the + * Cryptoki library. + */ +CK_PKCS11_FUNCTION_INFO(C_Finalize) +#ifdef CK_NEED_ARG_LIST +( + CK_VOID_PTR pReserved /* reserved. Should be NULL_PTR */ +); +#endif + + +/* C_GetInfo returns general information about Cryptoki. */ +CK_PKCS11_FUNCTION_INFO(C_GetInfo) +#ifdef CK_NEED_ARG_LIST +( + CK_INFO_PTR pInfo /* location that receives information */ +); +#endif + + +/* C_GetFunctionList returns the function list. */ +CK_PKCS11_FUNCTION_INFO(C_GetFunctionList) +#ifdef CK_NEED_ARG_LIST +( + CK_FUNCTION_LIST_PTR_PTR ppFunctionList /* receives pointer to + * function list + */ +); +#endif + + + +/* Slot and token management */ + +/* C_GetSlotList obtains a list of slots in the system. */ +CK_PKCS11_FUNCTION_INFO(C_GetSlotList) +#ifdef CK_NEED_ARG_LIST +( + CK_BBOOL tokenPresent, /* only slots with tokens */ + CK_SLOT_ID_PTR pSlotList, /* receives array of slot IDs */ + CK_ULONG_PTR pulCount /* receives number of slots */ +); +#endif + + +/* C_GetSlotInfo obtains information about a particular slot in + * the system. + */ +CK_PKCS11_FUNCTION_INFO(C_GetSlotInfo) +#ifdef CK_NEED_ARG_LIST +( + CK_SLOT_ID slotID, /* the ID of the slot */ + CK_SLOT_INFO_PTR pInfo /* receives the slot information */ +); +#endif + + +/* C_GetTokenInfo obtains information about a particular token + * in the system. + */ +CK_PKCS11_FUNCTION_INFO(C_GetTokenInfo) +#ifdef CK_NEED_ARG_LIST +( + CK_SLOT_ID slotID, /* ID of the token's slot */ + CK_TOKEN_INFO_PTR pInfo /* receives the token information */ +); +#endif + + +/* C_GetMechanismList obtains a list of mechanism types + * supported by a token. + */ +CK_PKCS11_FUNCTION_INFO(C_GetMechanismList) +#ifdef CK_NEED_ARG_LIST +( + CK_SLOT_ID slotID, /* ID of token's slot */ + CK_MECHANISM_TYPE_PTR pMechanismList, /* gets mech. array */ + CK_ULONG_PTR pulCount /* gets # of mechs. */ +); +#endif + + +/* C_GetMechanismInfo obtains information about a particular + * mechanism possibly supported by a token. + */ +CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo) +#ifdef CK_NEED_ARG_LIST +( + CK_SLOT_ID slotID, /* ID of the token's slot */ + CK_MECHANISM_TYPE type, /* type of mechanism */ + CK_MECHANISM_INFO_PTR pInfo /* receives mechanism info */ +); +#endif + + +/* C_InitToken initializes a token. */ +CK_PKCS11_FUNCTION_INFO(C_InitToken) +#ifdef CK_NEED_ARG_LIST +( + CK_SLOT_ID slotID, /* ID of the token's slot */ + CK_UTF8CHAR_PTR pPin, /* the SO's initial PIN */ + CK_ULONG ulPinLen, /* length in bytes of the PIN */ + CK_UTF8CHAR_PTR pLabel /* 32-byte token label (blank padded) */ +); +#endif + + +/* C_InitPIN initializes the normal user's PIN. */ +CK_PKCS11_FUNCTION_INFO(C_InitPIN) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_UTF8CHAR_PTR pPin, /* the normal user's PIN */ + CK_ULONG ulPinLen /* length in bytes of the PIN */ +); +#endif + + +/* C_SetPIN modifies the PIN of the user who is logged in. */ +CK_PKCS11_FUNCTION_INFO(C_SetPIN) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_UTF8CHAR_PTR pOldPin, /* the old PIN */ + CK_ULONG ulOldLen, /* length of the old PIN */ + CK_UTF8CHAR_PTR pNewPin, /* the new PIN */ + CK_ULONG ulNewLen /* length of the new PIN */ +); +#endif + + + +/* Session management */ + +/* C_OpenSession opens a session between an application and a + * token. + */ +CK_PKCS11_FUNCTION_INFO(C_OpenSession) +#ifdef CK_NEED_ARG_LIST +( + CK_SLOT_ID slotID, /* the slot's ID */ + CK_FLAGS flags, /* from CK_SESSION_INFO */ + CK_VOID_PTR pApplication, /* passed to callback */ + CK_NOTIFY Notify, /* callback function */ + CK_SESSION_HANDLE_PTR phSession /* gets session handle */ +); +#endif + + +/* C_CloseSession closes a session between an application and a + * token. + */ +CK_PKCS11_FUNCTION_INFO(C_CloseSession) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession /* the session's handle */ +); +#endif + + +/* C_CloseAllSessions closes all sessions with a token. */ +CK_PKCS11_FUNCTION_INFO(C_CloseAllSessions) +#ifdef CK_NEED_ARG_LIST +( + CK_SLOT_ID slotID /* the token's slot */ +); +#endif + + +/* C_GetSessionInfo obtains information about the session. */ +CK_PKCS11_FUNCTION_INFO(C_GetSessionInfo) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_SESSION_INFO_PTR pInfo /* receives session info */ +); +#endif + + +/* C_GetOperationState obtains the state of the cryptographic operation + * in a session. + */ +CK_PKCS11_FUNCTION_INFO(C_GetOperationState) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* session's handle */ + CK_BYTE_PTR pOperationState, /* gets state */ + CK_ULONG_PTR pulOperationStateLen /* gets state length */ +); +#endif + + +/* C_SetOperationState restores the state of the cryptographic + * operation in a session. + */ +CK_PKCS11_FUNCTION_INFO(C_SetOperationState) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* session's handle */ + CK_BYTE_PTR pOperationState, /* holds state */ + CK_ULONG ulOperationStateLen, /* holds state length */ + CK_OBJECT_HANDLE hEncryptionKey, /* en/decryption key */ + CK_OBJECT_HANDLE hAuthenticationKey /* sign/verify key */ +); +#endif + + +/* C_Login logs a user into a token. */ +CK_PKCS11_FUNCTION_INFO(C_Login) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_USER_TYPE userType, /* the user type */ + CK_UTF8CHAR_PTR pPin, /* the user's PIN */ + CK_ULONG ulPinLen /* the length of the PIN */ +); +#endif + + +/* C_Logout logs a user out from a token. */ +CK_PKCS11_FUNCTION_INFO(C_Logout) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession /* the session's handle */ +); +#endif + + + +/* Object management */ + +/* C_CreateObject creates a new object. */ +CK_PKCS11_FUNCTION_INFO(C_CreateObject) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_ATTRIBUTE_PTR pTemplate, /* the object's template */ + CK_ULONG ulCount, /* attributes in template */ + CK_OBJECT_HANDLE_PTR phObject /* gets new object's handle. */ +); +#endif + + +/* C_CopyObject copies an object, creating a new object for the + * copy. + */ +CK_PKCS11_FUNCTION_INFO(C_CopyObject) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_OBJECT_HANDLE hObject, /* the object's handle */ + CK_ATTRIBUTE_PTR pTemplate, /* template for new object */ + CK_ULONG ulCount, /* attributes in template */ + CK_OBJECT_HANDLE_PTR phNewObject /* receives handle of copy */ +); +#endif + + +/* C_DestroyObject destroys an object. */ +CK_PKCS11_FUNCTION_INFO(C_DestroyObject) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_OBJECT_HANDLE hObject /* the object's handle */ +); +#endif + + +/* C_GetObjectSize gets the size of an object in bytes. */ +CK_PKCS11_FUNCTION_INFO(C_GetObjectSize) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_OBJECT_HANDLE hObject, /* the object's handle */ + CK_ULONG_PTR pulSize /* receives size of object */ +); +#endif + + +/* C_GetAttributeValue obtains the value of one or more object + * attributes. + */ +CK_PKCS11_FUNCTION_INFO(C_GetAttributeValue) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_OBJECT_HANDLE hObject, /* the object's handle */ + CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs; gets vals */ + CK_ULONG ulCount /* attributes in template */ +); +#endif + + +/* C_SetAttributeValue modifies the value of one or more object + * attributes. + */ +CK_PKCS11_FUNCTION_INFO(C_SetAttributeValue) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_OBJECT_HANDLE hObject, /* the object's handle */ + CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs and values */ + CK_ULONG ulCount /* attributes in template */ +); +#endif + + +/* C_FindObjectsInit initializes a search for token and session + * objects that match a template. + */ +CK_PKCS11_FUNCTION_INFO(C_FindObjectsInit) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_ATTRIBUTE_PTR pTemplate, /* attribute values to match */ + CK_ULONG ulCount /* attrs in search template */ +); +#endif + + +/* C_FindObjects continues a search for token and session + * objects that match a template, obtaining additional object + * handles. + */ +CK_PKCS11_FUNCTION_INFO(C_FindObjects) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* session's handle */ + CK_OBJECT_HANDLE_PTR phObject, /* gets obj. handles */ + CK_ULONG ulMaxObjectCount, /* max handles to get */ + CK_ULONG_PTR pulObjectCount /* actual # returned */ +); +#endif + + +/* C_FindObjectsFinal finishes a search for token and session + * objects. + */ +CK_PKCS11_FUNCTION_INFO(C_FindObjectsFinal) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession /* the session's handle */ +); +#endif + + + +/* Encryption and decryption */ + +/* C_EncryptInit initializes an encryption operation. */ +CK_PKCS11_FUNCTION_INFO(C_EncryptInit) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism, /* the encryption mechanism */ + CK_OBJECT_HANDLE hKey /* handle of encryption key */ +); +#endif + + +/* C_Encrypt encrypts single-part data. */ +CK_PKCS11_FUNCTION_INFO(C_Encrypt) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* session's handle */ + CK_BYTE_PTR pData, /* the plaintext data */ + CK_ULONG ulDataLen, /* bytes of plaintext */ + CK_BYTE_PTR pEncryptedData, /* gets ciphertext */ + CK_ULONG_PTR pulEncryptedDataLen /* gets c-text size */ +); +#endif + + +/* C_EncryptUpdate continues a multiple-part encryption + * operation. + */ +CK_PKCS11_FUNCTION_INFO(C_EncryptUpdate) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* session's handle */ + CK_BYTE_PTR pPart, /* the plaintext data */ + CK_ULONG ulPartLen, /* plaintext data len */ + CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */ + CK_ULONG_PTR pulEncryptedPartLen /* gets c-text size */ +); +#endif + + +/* C_EncryptFinal finishes a multiple-part encryption + * operation. + */ +CK_PKCS11_FUNCTION_INFO(C_EncryptFinal) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* session handle */ + CK_BYTE_PTR pLastEncryptedPart, /* last c-text */ + CK_ULONG_PTR pulLastEncryptedPartLen /* gets last size */ +); +#endif + + +/* C_DecryptInit initializes a decryption operation. */ +CK_PKCS11_FUNCTION_INFO(C_DecryptInit) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism, /* the decryption mechanism */ + CK_OBJECT_HANDLE hKey /* handle of decryption key */ +); +#endif + + +/* C_Decrypt decrypts encrypted data in a single part. */ +CK_PKCS11_FUNCTION_INFO(C_Decrypt) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* session's handle */ + CK_BYTE_PTR pEncryptedData, /* ciphertext */ + CK_ULONG ulEncryptedDataLen, /* ciphertext length */ + CK_BYTE_PTR pData, /* gets plaintext */ + CK_ULONG_PTR pulDataLen /* gets p-text size */ +); +#endif + + +/* C_DecryptUpdate continues a multiple-part decryption + * operation. + */ +CK_PKCS11_FUNCTION_INFO(C_DecryptUpdate) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* session's handle */ + CK_BYTE_PTR pEncryptedPart, /* encrypted data */ + CK_ULONG ulEncryptedPartLen, /* input length */ + CK_BYTE_PTR pPart, /* gets plaintext */ + CK_ULONG_PTR pulPartLen /* p-text size */ +); +#endif + + +/* C_DecryptFinal finishes a multiple-part decryption + * operation. + */ +CK_PKCS11_FUNCTION_INFO(C_DecryptFinal) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pLastPart, /* gets plaintext */ + CK_ULONG_PTR pulLastPartLen /* p-text size */ +); +#endif + + + +/* Message digesting */ + +/* C_DigestInit initializes a message-digesting operation. */ +CK_PKCS11_FUNCTION_INFO(C_DigestInit) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism /* the digesting mechanism */ +); +#endif + + +/* C_Digest digests data in a single part. */ +CK_PKCS11_FUNCTION_INFO(C_Digest) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pData, /* data to be digested */ + CK_ULONG ulDataLen, /* bytes of data to digest */ + CK_BYTE_PTR pDigest, /* gets the message digest */ + CK_ULONG_PTR pulDigestLen /* gets digest length */ +); +#endif + + +/* C_DigestUpdate continues a multiple-part message-digesting + * operation. + */ +CK_PKCS11_FUNCTION_INFO(C_DigestUpdate) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pPart, /* data to be digested */ + CK_ULONG ulPartLen /* bytes of data to be digested */ +); +#endif + + +/* C_DigestKey continues a multi-part message-digesting + * operation, by digesting the value of a secret key as part of + * the data already digested. + */ +CK_PKCS11_FUNCTION_INFO(C_DigestKey) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_OBJECT_HANDLE hKey /* secret key to digest */ +); +#endif + + +/* C_DigestFinal finishes a multiple-part message-digesting + * operation. + */ +CK_PKCS11_FUNCTION_INFO(C_DigestFinal) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pDigest, /* gets the message digest */ + CK_ULONG_PTR pulDigestLen /* gets byte count of digest */ +); +#endif + + + +/* Signing and MACing */ + +/* C_SignInit initializes a signature (private key encryption) + * operation, where the signature is (will be) an appendix to + * the data, and plaintext cannot be recovered from the + * signature. + */ +CK_PKCS11_FUNCTION_INFO(C_SignInit) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism, /* the signature mechanism */ + CK_OBJECT_HANDLE hKey /* handle of signature key */ +); +#endif + + +/* C_Sign signs (encrypts with private key) data in a single + * part, where the signature is (will be) an appendix to the + * data, and plaintext cannot be recovered from the signature. + */ +CK_PKCS11_FUNCTION_INFO(C_Sign) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pData, /* the data to sign */ + CK_ULONG ulDataLen, /* count of bytes to sign */ + CK_BYTE_PTR pSignature, /* gets the signature */ + CK_ULONG_PTR pulSignatureLen /* gets signature length */ +); +#endif + + +/* C_SignUpdate continues a multiple-part signature operation, + * where the signature is (will be) an appendix to the data, + * and plaintext cannot be recovered from the signature. + */ +CK_PKCS11_FUNCTION_INFO(C_SignUpdate) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pPart, /* the data to sign */ + CK_ULONG ulPartLen /* count of bytes to sign */ +); +#endif + + +/* C_SignFinal finishes a multiple-part signature operation, + * returning the signature. + */ +CK_PKCS11_FUNCTION_INFO(C_SignFinal) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pSignature, /* gets the signature */ + CK_ULONG_PTR pulSignatureLen /* gets signature length */ +); +#endif + + +/* C_SignRecoverInit initializes a signature operation, where + * the data can be recovered from the signature. + */ +CK_PKCS11_FUNCTION_INFO(C_SignRecoverInit) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism, /* the signature mechanism */ + CK_OBJECT_HANDLE hKey /* handle of the signature key */ +); +#endif + + +/* C_SignRecover signs data in a single operation, where the + * data can be recovered from the signature. + */ +CK_PKCS11_FUNCTION_INFO(C_SignRecover) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pData, /* the data to sign */ + CK_ULONG ulDataLen, /* count of bytes to sign */ + CK_BYTE_PTR pSignature, /* gets the signature */ + CK_ULONG_PTR pulSignatureLen /* gets signature length */ +); +#endif + + + +/* Verifying signatures and MACs */ + +/* C_VerifyInit initializes a verification operation, where the + * signature is an appendix to the data, and plaintext cannot + * cannot be recovered from the signature (e.g. DSA). + */ +CK_PKCS11_FUNCTION_INFO(C_VerifyInit) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism, /* the verification mechanism */ + CK_OBJECT_HANDLE hKey /* verification key */ +); +#endif + + +/* C_Verify verifies a signature in a single-part operation, + * where the signature is an appendix to the data, and plaintext + * cannot be recovered from the signature. + */ +CK_PKCS11_FUNCTION_INFO(C_Verify) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pData, /* signed data */ + CK_ULONG ulDataLen, /* length of signed data */ + CK_BYTE_PTR pSignature, /* signature */ + CK_ULONG ulSignatureLen /* signature length*/ +); +#endif + + +/* C_VerifyUpdate continues a multiple-part verification + * operation, where the signature is an appendix to the data, + * and plaintext cannot be recovered from the signature. + */ +CK_PKCS11_FUNCTION_INFO(C_VerifyUpdate) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pPart, /* signed data */ + CK_ULONG ulPartLen /* length of signed data */ +); +#endif + + +/* C_VerifyFinal finishes a multiple-part verification + * operation, checking the signature. + */ +CK_PKCS11_FUNCTION_INFO(C_VerifyFinal) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pSignature, /* signature to verify */ + CK_ULONG ulSignatureLen /* signature length */ +); +#endif + + +/* C_VerifyRecoverInit initializes a signature verification + * operation, where the data is recovered from the signature. + */ +CK_PKCS11_FUNCTION_INFO(C_VerifyRecoverInit) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism, /* the verification mechanism */ + CK_OBJECT_HANDLE hKey /* verification key */ +); +#endif + + +/* C_VerifyRecover verifies a signature in a single-part + * operation, where the data is recovered from the signature. + */ +CK_PKCS11_FUNCTION_INFO(C_VerifyRecover) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pSignature, /* signature to verify */ + CK_ULONG ulSignatureLen, /* signature length */ + CK_BYTE_PTR pData, /* gets signed data */ + CK_ULONG_PTR pulDataLen /* gets signed data len */ +); +#endif + + + +/* Dual-function cryptographic operations */ + +/* C_DigestEncryptUpdate continues a multiple-part digesting + * and encryption operation. + */ +CK_PKCS11_FUNCTION_INFO(C_DigestEncryptUpdate) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* session's handle */ + CK_BYTE_PTR pPart, /* the plaintext data */ + CK_ULONG ulPartLen, /* plaintext length */ + CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */ + CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */ +); +#endif + + +/* C_DecryptDigestUpdate continues a multiple-part decryption and + * digesting operation. + */ +CK_PKCS11_FUNCTION_INFO(C_DecryptDigestUpdate) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* session's handle */ + CK_BYTE_PTR pEncryptedPart, /* ciphertext */ + CK_ULONG ulEncryptedPartLen, /* ciphertext length */ + CK_BYTE_PTR pPart, /* gets plaintext */ + CK_ULONG_PTR pulPartLen /* gets plaintext len */ +); +#endif + + +/* C_SignEncryptUpdate continues a multiple-part signing and + * encryption operation. + */ +CK_PKCS11_FUNCTION_INFO(C_SignEncryptUpdate) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* session's handle */ + CK_BYTE_PTR pPart, /* the plaintext data */ + CK_ULONG ulPartLen, /* plaintext length */ + CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */ + CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */ +); +#endif + + +/* C_DecryptVerifyUpdate continues a multiple-part decryption and + * verify operation. + */ +CK_PKCS11_FUNCTION_INFO(C_DecryptVerifyUpdate) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* session's handle */ + CK_BYTE_PTR pEncryptedPart, /* ciphertext */ + CK_ULONG ulEncryptedPartLen, /* ciphertext length */ + CK_BYTE_PTR pPart, /* gets plaintext */ + CK_ULONG_PTR pulPartLen /* gets p-text length */ +); +#endif + + + +/* Key management */ + +/* C_GenerateKey generates a secret key, creating a new key + * object. + */ +CK_PKCS11_FUNCTION_INFO(C_GenerateKey) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism, /* key generation mech. */ + CK_ATTRIBUTE_PTR pTemplate, /* template for new key */ + CK_ULONG ulCount, /* # of attrs in template */ + CK_OBJECT_HANDLE_PTR phKey /* gets handle of new key */ +); +#endif + + +/* C_GenerateKeyPair generates a public-key/private-key pair, + * creating new key objects. + */ +CK_PKCS11_FUNCTION_INFO(C_GenerateKeyPair) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* session handle */ + CK_MECHANISM_PTR pMechanism, /* key-gen mech. */ + CK_ATTRIBUTE_PTR pPublicKeyTemplate, /* template for pub. key */ + CK_ULONG ulPublicKeyAttributeCount, /* # pub. attrs. */ + CK_ATTRIBUTE_PTR pPrivateKeyTemplate, /* template for priv. key */ + CK_ULONG ulPrivateKeyAttributeCount, /* # priv. attrs. */ + CK_OBJECT_HANDLE_PTR phPublicKey, /* gets pub. key handle */ + CK_OBJECT_HANDLE_PTR phPrivateKey /* gets priv. key handle */ +); +#endif + + +/* C_WrapKey wraps (i.e., encrypts) a key. */ +CK_PKCS11_FUNCTION_INFO(C_WrapKey) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism, /* the wrapping mechanism */ + CK_OBJECT_HANDLE hWrappingKey, /* wrapping key */ + CK_OBJECT_HANDLE hKey, /* key to be wrapped */ + CK_BYTE_PTR pWrappedKey, /* gets wrapped key */ + CK_ULONG_PTR pulWrappedKeyLen /* gets wrapped key size */ +); +#endif + + +/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new + * key object. + */ +CK_PKCS11_FUNCTION_INFO(C_UnwrapKey) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* session's handle */ + CK_MECHANISM_PTR pMechanism, /* unwrapping mech. */ + CK_OBJECT_HANDLE hUnwrappingKey, /* unwrapping key */ + CK_BYTE_PTR pWrappedKey, /* the wrapped key */ + CK_ULONG ulWrappedKeyLen, /* wrapped key len */ + CK_ATTRIBUTE_PTR pTemplate, /* new key template */ + CK_ULONG ulAttributeCount, /* template length */ + CK_OBJECT_HANDLE_PTR phKey /* gets new handle */ +); +#endif + + +/* C_DeriveKey derives a key from a base key, creating a new key + * object. + */ +CK_PKCS11_FUNCTION_INFO(C_DeriveKey) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* session's handle */ + CK_MECHANISM_PTR pMechanism, /* key deriv. mech. */ + CK_OBJECT_HANDLE hBaseKey, /* base key */ + CK_ATTRIBUTE_PTR pTemplate, /* new key template */ + CK_ULONG ulAttributeCount, /* template length */ + CK_OBJECT_HANDLE_PTR phKey /* gets new handle */ +); +#endif + + + +/* Random number generation */ + +/* C_SeedRandom mixes additional seed material into the token's + * random number generator. + */ +CK_PKCS11_FUNCTION_INFO(C_SeedRandom) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pSeed, /* the seed material */ + CK_ULONG ulSeedLen /* length of seed material */ +); +#endif + + +/* C_GenerateRandom generates random data. */ +CK_PKCS11_FUNCTION_INFO(C_GenerateRandom) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR RandomData, /* receives the random data */ + CK_ULONG ulRandomLen /* # of bytes to generate */ +); +#endif + + + +/* Parallel function management */ + +/* C_GetFunctionStatus is a legacy function; it obtains an + * updated status of a function running in parallel with an + * application. + */ +CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession /* the session's handle */ +); +#endif + + +/* C_CancelFunction is a legacy function; it cancels a function + * running in parallel. + */ +CK_PKCS11_FUNCTION_INFO(C_CancelFunction) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession /* the session's handle */ +); +#endif + + +/* C_WaitForSlotEvent waits for a slot event (token insertion, + * removal, etc.) to occur. + */ +CK_PKCS11_FUNCTION_INFO(C_WaitForSlotEvent) +#ifdef CK_NEED_ARG_LIST +( + CK_FLAGS flags, /* blocking/nonblocking flag */ + CK_SLOT_ID_PTR pSlot, /* location that receives the slot ID */ + CK_VOID_PTR pRserved /* reserved. Should be NULL_PTR */ +); +#endif + diff --git a/include/libpki/crypto/hsm/pkcs11/rsa/pkcs11t.h b/include/libpki/crypto/hsm/pkcs11/rsa/pkcs11t.h new file mode 100644 index 00000000..c13e67cf --- /dev/null +++ b/include/libpki/crypto/hsm/pkcs11/rsa/pkcs11t.h @@ -0,0 +1,2003 @@ +/* Copyright (c) OASIS Open 2016. All Rights Reserved./ + * /Distributed under the terms of the OASIS IPR Policy, + * [http://www.oasis-open.org/policies-guidelines/ipr], AS-IS, WITHOUT ANY + * IMPLIED OR EXPRESS WARRANTY; there is no warranty of MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE or NONINFRINGEMENT of the rights of others. + */ + +/* Latest version of the specification: + * http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/pkcs11-base-v2.40.html + */ + +/* See top of pkcs11.h for information about the macros that + * must be defined and the structure-packing conventions that + * must be set before including this file. + */ + +#ifndef _PKCS11T_H_ +#define _PKCS11T_H_ 1 + +#define CRYPTOKI_VERSION_MAJOR 2 +#define CRYPTOKI_VERSION_MINOR 40 +#define CRYPTOKI_VERSION_AMENDMENT 0 + +#define CK_TRUE 1 +#define CK_FALSE 0 + +#ifndef CK_DISABLE_TRUE_FALSE +#ifndef FALSE +#define FALSE CK_FALSE +#endif +#ifndef TRUE +#define TRUE CK_TRUE +#endif +#endif + +/* an unsigned 8-bit value */ +typedef unsigned char CK_BYTE; + +/* an unsigned 8-bit character */ +typedef CK_BYTE CK_CHAR; + +/* an 8-bit UTF-8 character */ +typedef CK_BYTE CK_UTF8CHAR; + +/* a BYTE-sized Boolean flag */ +typedef CK_BYTE CK_BBOOL; + +/* an unsigned value, at least 32 bits long */ +typedef unsigned long int CK_ULONG; + +/* a signed value, the same size as a CK_ULONG */ +typedef long int CK_LONG; + +/* at least 32 bits; each bit is a Boolean flag */ +typedef CK_ULONG CK_FLAGS; + + +/* some special values for certain CK_ULONG variables */ +#define CK_UNAVAILABLE_INFORMATION (~0UL) +#define CK_EFFECTIVELY_INFINITE 0UL + + +typedef CK_BYTE CK_PTR CK_BYTE_PTR; +typedef CK_CHAR CK_PTR CK_CHAR_PTR; +typedef CK_UTF8CHAR CK_PTR CK_UTF8CHAR_PTR; +typedef CK_ULONG CK_PTR CK_ULONG_PTR; +typedef void CK_PTR CK_VOID_PTR; + +/* Pointer to a CK_VOID_PTR-- i.e., pointer to pointer to void */ +typedef CK_VOID_PTR CK_PTR CK_VOID_PTR_PTR; + + +/* The following value is always invalid if used as a session + * handle or object handle + */ +#define CK_INVALID_HANDLE 0UL + + +typedef struct CK_VERSION { + CK_BYTE major; /* integer portion of version number */ + CK_BYTE minor; /* 1/100ths portion of version number */ +} CK_VERSION; + +typedef CK_VERSION CK_PTR CK_VERSION_PTR; + + +typedef struct CK_INFO { + CK_VERSION cryptokiVersion; /* Cryptoki interface ver */ + CK_UTF8CHAR manufacturerID[32]; /* blank padded */ + CK_FLAGS flags; /* must be zero */ + CK_UTF8CHAR libraryDescription[32]; /* blank padded */ + CK_VERSION libraryVersion; /* version of library */ +} CK_INFO; + +typedef CK_INFO CK_PTR CK_INFO_PTR; + + +/* CK_NOTIFICATION enumerates the types of notifications that + * Cryptoki provides to an application + */ +typedef CK_ULONG CK_NOTIFICATION; +#define CKN_SURRENDER 0UL +#define CKN_OTP_CHANGED 1UL + +typedef CK_ULONG CK_SLOT_ID; + +typedef CK_SLOT_ID CK_PTR CK_SLOT_ID_PTR; + + +/* CK_SLOT_INFO provides information about a slot */ +typedef struct CK_SLOT_INFO { + CK_UTF8CHAR slotDescription[64]; /* blank padded */ + CK_UTF8CHAR manufacturerID[32]; /* blank padded */ + CK_FLAGS flags; + + CK_VERSION hardwareVersion; /* version of hardware */ + CK_VERSION firmwareVersion; /* version of firmware */ +} CK_SLOT_INFO; + +/* flags: bit flags that provide capabilities of the slot + * Bit Flag Mask Meaning + */ +#define CKF_TOKEN_PRESENT 0x00000001UL /* a token is there */ +#define CKF_REMOVABLE_DEVICE 0x00000002UL /* removable devices*/ +#define CKF_HW_SLOT 0x00000004UL /* hardware slot */ + +typedef CK_SLOT_INFO CK_PTR CK_SLOT_INFO_PTR; + + +/* CK_TOKEN_INFO provides information about a token */ +typedef struct CK_TOKEN_INFO { + CK_UTF8CHAR label[32]; /* blank padded */ + CK_UTF8CHAR manufacturerID[32]; /* blank padded */ + CK_UTF8CHAR model[16]; /* blank padded */ + CK_CHAR serialNumber[16]; /* blank padded */ + CK_FLAGS flags; /* see below */ + + CK_ULONG ulMaxSessionCount; /* max open sessions */ + CK_ULONG ulSessionCount; /* sess. now open */ + CK_ULONG ulMaxRwSessionCount; /* max R/W sessions */ + CK_ULONG ulRwSessionCount; /* R/W sess. now open */ + CK_ULONG ulMaxPinLen; /* in bytes */ + CK_ULONG ulMinPinLen; /* in bytes */ + CK_ULONG ulTotalPublicMemory; /* in bytes */ + CK_ULONG ulFreePublicMemory; /* in bytes */ + CK_ULONG ulTotalPrivateMemory; /* in bytes */ + CK_ULONG ulFreePrivateMemory; /* in bytes */ + CK_VERSION hardwareVersion; /* version of hardware */ + CK_VERSION firmwareVersion; /* version of firmware */ + CK_CHAR utcTime[16]; /* time */ +} CK_TOKEN_INFO; + +/* The flags parameter is defined as follows: + * Bit Flag Mask Meaning + */ +#define CKF_RNG 0x00000001UL /* has random # generator */ +#define CKF_WRITE_PROTECTED 0x00000002UL /* token is write-protected */ +#define CKF_LOGIN_REQUIRED 0x00000004UL /* user must login */ +#define CKF_USER_PIN_INITIALIZED 0x00000008UL /* normal user's PIN is set */ + +/* CKF_RESTORE_KEY_NOT_NEEDED. If it is set, + * that means that *every* time the state of cryptographic + * operations of a session is successfully saved, all keys + * needed to continue those operations are stored in the state + */ +#define CKF_RESTORE_KEY_NOT_NEEDED 0x00000020UL + +/* CKF_CLOCK_ON_TOKEN. If it is set, that means + * that the token has some sort of clock. The time on that + * clock is returned in the token info structure + */ +#define CKF_CLOCK_ON_TOKEN 0x00000040UL + +/* CKF_PROTECTED_AUTHENTICATION_PATH. If it is + * set, that means that there is some way for the user to login + * without sending a PIN through the Cryptoki library itself + */ +#define CKF_PROTECTED_AUTHENTICATION_PATH 0x00000100UL + +/* CKF_DUAL_CRYPTO_OPERATIONS. If it is true, + * that means that a single session with the token can perform + * dual simultaneous cryptographic operations (digest and + * encrypt; decrypt and digest; sign and encrypt; and decrypt + * and sign) + */ +#define CKF_DUAL_CRYPTO_OPERATIONS 0x00000200UL + +/* CKF_TOKEN_INITIALIZED. If it is true, the + * token has been initialized using C_InitializeToken or an + * equivalent mechanism outside the scope of PKCS #11. + * Calling C_InitializeToken when this flag is set will cause + * the token to be reinitialized. + */ +#define CKF_TOKEN_INITIALIZED 0x00000400UL + +/* CKF_SECONDARY_AUTHENTICATION. If it is + * true, the token supports secondary authentication for + * private key objects. + */ +#define CKF_SECONDARY_AUTHENTICATION 0x00000800UL + +/* CKF_USER_PIN_COUNT_LOW. If it is true, an + * incorrect user login PIN has been entered at least once + * since the last successful authentication. + */ +#define CKF_USER_PIN_COUNT_LOW 0x00010000UL + +/* CKF_USER_PIN_FINAL_TRY. If it is true, + * supplying an incorrect user PIN will it to become locked. + */ +#define CKF_USER_PIN_FINAL_TRY 0x00020000UL + +/* CKF_USER_PIN_LOCKED. If it is true, the + * user PIN has been locked. User login to the token is not + * possible. + */ +#define CKF_USER_PIN_LOCKED 0x00040000UL + +/* CKF_USER_PIN_TO_BE_CHANGED. If it is true, + * the user PIN value is the default value set by token + * initialization or manufacturing, or the PIN has been + * expired by the card. + */ +#define CKF_USER_PIN_TO_BE_CHANGED 0x00080000UL + +/* CKF_SO_PIN_COUNT_LOW. If it is true, an + * incorrect SO login PIN has been entered at least once since + * the last successful authentication. + */ +#define CKF_SO_PIN_COUNT_LOW 0x00100000UL + +/* CKF_SO_PIN_FINAL_TRY. If it is true, + * supplying an incorrect SO PIN will it to become locked. + */ +#define CKF_SO_PIN_FINAL_TRY 0x00200000UL + +/* CKF_SO_PIN_LOCKED. If it is true, the SO + * PIN has been locked. SO login to the token is not possible. + */ +#define CKF_SO_PIN_LOCKED 0x00400000UL + +/* CKF_SO_PIN_TO_BE_CHANGED. If it is true, + * the SO PIN value is the default value set by token + * initialization or manufacturing, or the PIN has been + * expired by the card. + */ +#define CKF_SO_PIN_TO_BE_CHANGED 0x00800000UL + +#define CKF_ERROR_STATE 0x01000000UL + +typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR; + + +/* CK_SESSION_HANDLE is a Cryptoki-assigned value that + * identifies a session + */ +typedef CK_ULONG CK_SESSION_HANDLE; + +typedef CK_SESSION_HANDLE CK_PTR CK_SESSION_HANDLE_PTR; + + +/* CK_USER_TYPE enumerates the types of Cryptoki users */ +typedef CK_ULONG CK_USER_TYPE; +/* Security Officer */ +#define CKU_SO 0UL +/* Normal user */ +#define CKU_USER 1UL +/* Context specific */ +#define CKU_CONTEXT_SPECIFIC 2UL + +/* CK_STATE enumerates the session states */ +typedef CK_ULONG CK_STATE; +#define CKS_RO_PUBLIC_SESSION 0UL +#define CKS_RO_USER_FUNCTIONS 1UL +#define CKS_RW_PUBLIC_SESSION 2UL +#define CKS_RW_USER_FUNCTIONS 3UL +#define CKS_RW_SO_FUNCTIONS 4UL + +/* CK_SESSION_INFO provides information about a session */ +typedef struct CK_SESSION_INFO { + CK_SLOT_ID slotID; + CK_STATE state; + CK_FLAGS flags; /* see below */ + CK_ULONG ulDeviceError; /* device-dependent error code */ +} CK_SESSION_INFO; + +/* The flags are defined in the following table: + * Bit Flag Mask Meaning + */ +#define CKF_RW_SESSION 0x00000002UL /* session is r/w */ +#define CKF_SERIAL_SESSION 0x00000004UL /* no parallel */ + +typedef CK_SESSION_INFO CK_PTR CK_SESSION_INFO_PTR; + + +/* CK_OBJECT_HANDLE is a token-specific identifier for an + * object + */ +typedef CK_ULONG CK_OBJECT_HANDLE; + +typedef CK_OBJECT_HANDLE CK_PTR CK_OBJECT_HANDLE_PTR; + + +/* CK_OBJECT_CLASS is a value that identifies the classes (or + * types) of objects that Cryptoki recognizes. It is defined + * as follows: + */ +typedef CK_ULONG CK_OBJECT_CLASS; + +/* The following classes of objects are defined: */ +#define CKO_DATA 0x00000000UL +#define CKO_CERTIFICATE 0x00000001UL +#define CKO_PUBLIC_KEY 0x00000002UL +#define CKO_PRIVATE_KEY 0x00000003UL +#define CKO_SECRET_KEY 0x00000004UL +#define CKO_HW_FEATURE 0x00000005UL +#define CKO_DOMAIN_PARAMETERS 0x00000006UL +#define CKO_MECHANISM 0x00000007UL +#define CKO_OTP_KEY 0x00000008UL + +#define CKO_VENDOR_DEFINED 0x80000000UL + +typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR; + +/* CK_HW_FEATURE_TYPE is a value that identifies the hardware feature type + * of an object with CK_OBJECT_CLASS equal to CKO_HW_FEATURE. + */ +typedef CK_ULONG CK_HW_FEATURE_TYPE; + +/* The following hardware feature types are defined */ +#define CKH_MONOTONIC_COUNTER 0x00000001UL +#define CKH_CLOCK 0x00000002UL +#define CKH_USER_INTERFACE 0x00000003UL +#define CKH_VENDOR_DEFINED 0x80000000UL + +/* CK_KEY_TYPE is a value that identifies a key type */ +typedef CK_ULONG CK_KEY_TYPE; + +/* the following key types are defined: */ +#define CKK_RSA 0x00000000UL +#define CKK_DSA 0x00000001UL +#define CKK_DH 0x00000002UL +#define CKK_ECDSA 0x00000003UL /* Deprecated */ +#define CKK_EC 0x00000003UL +#define CKK_X9_42_DH 0x00000004UL +#define CKK_KEA 0x00000005UL +#define CKK_GENERIC_SECRET 0x00000010UL +#define CKK_RC2 0x00000011UL +#define CKK_RC4 0x00000012UL +#define CKK_DES 0x00000013UL +#define CKK_DES2 0x00000014UL +#define CKK_DES3 0x00000015UL +#define CKK_CAST 0x00000016UL +#define CKK_CAST3 0x00000017UL +#define CKK_CAST5 0x00000018UL /* Deprecated */ +#define CKK_CAST128 0x00000018UL +#define CKK_RC5 0x00000019UL +#define CKK_IDEA 0x0000001AUL +#define CKK_SKIPJACK 0x0000001BUL +#define CKK_BATON 0x0000001CUL +#define CKK_JUNIPER 0x0000001DUL +#define CKK_CDMF 0x0000001EUL +#define CKK_AES 0x0000001FUL +#define CKK_BLOWFISH 0x00000020UL +#define CKK_TWOFISH 0x00000021UL +#define CKK_SECURID 0x00000022UL +#define CKK_HOTP 0x00000023UL +#define CKK_ACTI 0x00000024UL +#define CKK_CAMELLIA 0x00000025UL +#define CKK_ARIA 0x00000026UL + +#define CKK_MD5_HMAC 0x00000027UL +#define CKK_SHA_1_HMAC 0x00000028UL +#define CKK_RIPEMD128_HMAC 0x00000029UL +#define CKK_RIPEMD160_HMAC 0x0000002AUL +#define CKK_SHA256_HMAC 0x0000002BUL +#define CKK_SHA384_HMAC 0x0000002CUL +#define CKK_SHA512_HMAC 0x0000002DUL +#define CKK_SHA224_HMAC 0x0000002EUL + +#define CKK_SEED 0x0000002FUL +#define CKK_GOSTR3410 0x00000030UL +#define CKK_GOSTR3411 0x00000031UL +#define CKK_GOST28147 0x00000032UL + + + +#define CKK_VENDOR_DEFINED 0x80000000UL + + +/* CK_CERTIFICATE_TYPE is a value that identifies a certificate + * type + */ +typedef CK_ULONG CK_CERTIFICATE_TYPE; + +#define CK_CERTIFICATE_CATEGORY_UNSPECIFIED 0UL +#define CK_CERTIFICATE_CATEGORY_TOKEN_USER 1UL +#define CK_CERTIFICATE_CATEGORY_AUTHORITY 2UL +#define CK_CERTIFICATE_CATEGORY_OTHER_ENTITY 3UL + +#define CK_SECURITY_DOMAIN_UNSPECIFIED 0UL +#define CK_SECURITY_DOMAIN_MANUFACTURER 1UL +#define CK_SECURITY_DOMAIN_OPERATOR 2UL +#define CK_SECURITY_DOMAIN_THIRD_PARTY 3UL + + +/* The following certificate types are defined: */ +#define CKC_X_509 0x00000000UL +#define CKC_X_509_ATTR_CERT 0x00000001UL +#define CKC_WTLS 0x00000002UL +#define CKC_VENDOR_DEFINED 0x80000000UL + + +/* CK_ATTRIBUTE_TYPE is a value that identifies an attribute + * type + */ +typedef CK_ULONG CK_ATTRIBUTE_TYPE; + +/* The CKF_ARRAY_ATTRIBUTE flag identifies an attribute which + * consists of an array of values. + */ +#define CKF_ARRAY_ATTRIBUTE 0x40000000UL + +/* The following OTP-related defines relate to the CKA_OTP_FORMAT attribute */ +#define CK_OTP_FORMAT_DECIMAL 0UL +#define CK_OTP_FORMAT_HEXADECIMAL 1UL +#define CK_OTP_FORMAT_ALPHANUMERIC 2UL +#define CK_OTP_FORMAT_BINARY 3UL + +/* The following OTP-related defines relate to the CKA_OTP_..._REQUIREMENT + * attributes + */ +#define CK_OTP_PARAM_IGNORED 0UL +#define CK_OTP_PARAM_OPTIONAL 1UL +#define CK_OTP_PARAM_MANDATORY 2UL + +/* The following attribute types are defined: */ +#define CKA_CLASS 0x00000000UL +#define CKA_TOKEN 0x00000001UL +#define CKA_PRIVATE 0x00000002UL +#define CKA_LABEL 0x00000003UL +#define CKA_APPLICATION 0x00000010UL +#define CKA_VALUE 0x00000011UL +#define CKA_OBJECT_ID 0x00000012UL +#define CKA_CERTIFICATE_TYPE 0x00000080UL +#define CKA_ISSUER 0x00000081UL +#define CKA_SERIAL_NUMBER 0x00000082UL +#define CKA_AC_ISSUER 0x00000083UL +#define CKA_OWNER 0x00000084UL +#define CKA_ATTR_TYPES 0x00000085UL +#define CKA_TRUSTED 0x00000086UL +#define CKA_CERTIFICATE_CATEGORY 0x00000087UL +#define CKA_JAVA_MIDP_SECURITY_DOMAIN 0x00000088UL +#define CKA_URL 0x00000089UL +#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY 0x0000008AUL +#define CKA_HASH_OF_ISSUER_PUBLIC_KEY 0x0000008BUL +#define CKA_NAME_HASH_ALGORITHM 0x0000008CUL +#define CKA_CHECK_VALUE 0x00000090UL + +#define CKA_KEY_TYPE 0x00000100UL +#define CKA_SUBJECT 0x00000101UL +#define CKA_ID 0x00000102UL +#define CKA_SENSITIVE 0x00000103UL +#define CKA_ENCRYPT 0x00000104UL +#define CKA_DECRYPT 0x00000105UL +#define CKA_WRAP 0x00000106UL +#define CKA_UNWRAP 0x00000107UL +#define CKA_SIGN 0x00000108UL +#define CKA_SIGN_RECOVER 0x00000109UL +#define CKA_VERIFY 0x0000010AUL +#define CKA_VERIFY_RECOVER 0x0000010BUL +#define CKA_DERIVE 0x0000010CUL +#define CKA_START_DATE 0x00000110UL +#define CKA_END_DATE 0x00000111UL +#define CKA_MODULUS 0x00000120UL +#define CKA_MODULUS_BITS 0x00000121UL +#define CKA_PUBLIC_EXPONENT 0x00000122UL +#define CKA_PRIVATE_EXPONENT 0x00000123UL +#define CKA_PRIME_1 0x00000124UL +#define CKA_PRIME_2 0x00000125UL +#define CKA_EXPONENT_1 0x00000126UL +#define CKA_EXPONENT_2 0x00000127UL +#define CKA_COEFFICIENT 0x00000128UL +#define CKA_PUBLIC_KEY_INFO 0x00000129UL +#define CKA_PRIME 0x00000130UL +#define CKA_SUBPRIME 0x00000131UL +#define CKA_BASE 0x00000132UL + +#define CKA_PRIME_BITS 0x00000133UL +#define CKA_SUBPRIME_BITS 0x00000134UL +#define CKA_SUB_PRIME_BITS CKA_SUBPRIME_BITS + +#define CKA_VALUE_BITS 0x00000160UL +#define CKA_VALUE_LEN 0x00000161UL +#define CKA_EXTRACTABLE 0x00000162UL +#define CKA_LOCAL 0x00000163UL +#define CKA_NEVER_EXTRACTABLE 0x00000164UL +#define CKA_ALWAYS_SENSITIVE 0x00000165UL +#define CKA_KEY_GEN_MECHANISM 0x00000166UL + +#define CKA_MODIFIABLE 0x00000170UL +#define CKA_COPYABLE 0x00000171UL + +#define CKA_DESTROYABLE 0x00000172UL + +#define CKA_ECDSA_PARAMS 0x00000180UL /* Deprecated */ +#define CKA_EC_PARAMS 0x00000180UL + +#define CKA_EC_POINT 0x00000181UL + +#define CKA_SECONDARY_AUTH 0x00000200UL /* Deprecated */ +#define CKA_AUTH_PIN_FLAGS 0x00000201UL /* Deprecated */ + +#define CKA_ALWAYS_AUTHENTICATE 0x00000202UL + +#define CKA_WRAP_WITH_TRUSTED 0x00000210UL +#define CKA_WRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000211UL) +#define CKA_UNWRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000212UL) +#define CKA_DERIVE_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000213UL) + +#define CKA_OTP_FORMAT 0x00000220UL +#define CKA_OTP_LENGTH 0x00000221UL +#define CKA_OTP_TIME_INTERVAL 0x00000222UL +#define CKA_OTP_USER_FRIENDLY_MODE 0x00000223UL +#define CKA_OTP_CHALLENGE_REQUIREMENT 0x00000224UL +#define CKA_OTP_TIME_REQUIREMENT 0x00000225UL +#define CKA_OTP_COUNTER_REQUIREMENT 0x00000226UL +#define CKA_OTP_PIN_REQUIREMENT 0x00000227UL +#define CKA_OTP_COUNTER 0x0000022EUL +#define CKA_OTP_TIME 0x0000022FUL +#define CKA_OTP_USER_IDENTIFIER 0x0000022AUL +#define CKA_OTP_SERVICE_IDENTIFIER 0x0000022BUL +#define CKA_OTP_SERVICE_LOGO 0x0000022CUL +#define CKA_OTP_SERVICE_LOGO_TYPE 0x0000022DUL + +#define CKA_GOSTR3410_PARAMS 0x00000250UL +#define CKA_GOSTR3411_PARAMS 0x00000251UL +#define CKA_GOST28147_PARAMS 0x00000252UL + +#define CKA_HW_FEATURE_TYPE 0x00000300UL +#define CKA_RESET_ON_INIT 0x00000301UL +#define CKA_HAS_RESET 0x00000302UL + +#define CKA_PIXEL_X 0x00000400UL +#define CKA_PIXEL_Y 0x00000401UL +#define CKA_RESOLUTION 0x00000402UL +#define CKA_CHAR_ROWS 0x00000403UL +#define CKA_CHAR_COLUMNS 0x00000404UL +#define CKA_COLOR 0x00000405UL +#define CKA_BITS_PER_PIXEL 0x00000406UL +#define CKA_CHAR_SETS 0x00000480UL +#define CKA_ENCODING_METHODS 0x00000481UL +#define CKA_MIME_TYPES 0x00000482UL +#define CKA_MECHANISM_TYPE 0x00000500UL +#define CKA_REQUIRED_CMS_ATTRIBUTES 0x00000501UL +#define CKA_DEFAULT_CMS_ATTRIBUTES 0x00000502UL +#define CKA_SUPPORTED_CMS_ATTRIBUTES 0x00000503UL +#define CKA_ALLOWED_MECHANISMS (CKF_ARRAY_ATTRIBUTE|0x00000600UL) + +#define CKA_VENDOR_DEFINED 0x80000000UL + +/* CK_ATTRIBUTE is a structure that includes the type, length + * and value of an attribute + */ +typedef struct CK_ATTRIBUTE { + CK_ATTRIBUTE_TYPE type; + CK_VOID_PTR pValue; + CK_ULONG ulValueLen; /* in bytes */ +} CK_ATTRIBUTE; + +typedef CK_ATTRIBUTE CK_PTR CK_ATTRIBUTE_PTR; + +/* CK_DATE is a structure that defines a date */ +typedef struct CK_DATE{ + CK_CHAR year[4]; /* the year ("1900" - "9999") */ + CK_CHAR month[2]; /* the month ("01" - "12") */ + CK_CHAR day[2]; /* the day ("01" - "31") */ +} CK_DATE; + + +/* CK_MECHANISM_TYPE is a value that identifies a mechanism + * type + */ +typedef CK_ULONG CK_MECHANISM_TYPE; + +/* the following mechanism types are defined: */ +#define CKM_RSA_PKCS_KEY_PAIR_GEN 0x00000000UL +#define CKM_RSA_PKCS 0x00000001UL +#define CKM_RSA_9796 0x00000002UL +#define CKM_RSA_X_509 0x00000003UL + +#define CKM_MD2_RSA_PKCS 0x00000004UL +#define CKM_MD5_RSA_PKCS 0x00000005UL +#define CKM_SHA1_RSA_PKCS 0x00000006UL + +#define CKM_RIPEMD128_RSA_PKCS 0x00000007UL +#define CKM_RIPEMD160_RSA_PKCS 0x00000008UL +#define CKM_RSA_PKCS_OAEP 0x00000009UL + +#define CKM_RSA_X9_31_KEY_PAIR_GEN 0x0000000AUL +#define CKM_RSA_X9_31 0x0000000BUL +#define CKM_SHA1_RSA_X9_31 0x0000000CUL +#define CKM_RSA_PKCS_PSS 0x0000000DUL +#define CKM_SHA1_RSA_PKCS_PSS 0x0000000EUL + +#define CKM_DSA_KEY_PAIR_GEN 0x00000010UL +#define CKM_DSA 0x00000011UL +#define CKM_DSA_SHA1 0x00000012UL +#define CKM_DSA_SHA224 0x00000013UL +#define CKM_DSA_SHA256 0x00000014UL +#define CKM_DSA_SHA384 0x00000015UL +#define CKM_DSA_SHA512 0x00000016UL + +#define CKM_DH_PKCS_KEY_PAIR_GEN 0x00000020UL +#define CKM_DH_PKCS_DERIVE 0x00000021UL + +#define CKM_X9_42_DH_KEY_PAIR_GEN 0x00000030UL +#define CKM_X9_42_DH_DERIVE 0x00000031UL +#define CKM_X9_42_DH_HYBRID_DERIVE 0x00000032UL +#define CKM_X9_42_MQV_DERIVE 0x00000033UL + +#define CKM_SHA256_RSA_PKCS 0x00000040UL +#define CKM_SHA384_RSA_PKCS 0x00000041UL +#define CKM_SHA512_RSA_PKCS 0x00000042UL +#define CKM_SHA256_RSA_PKCS_PSS 0x00000043UL +#define CKM_SHA384_RSA_PKCS_PSS 0x00000044UL +#define CKM_SHA512_RSA_PKCS_PSS 0x00000045UL + +#define CKM_SHA224_RSA_PKCS 0x00000046UL +#define CKM_SHA224_RSA_PKCS_PSS 0x00000047UL + +#define CKM_SHA512_224 0x00000048UL +#define CKM_SHA512_224_HMAC 0x00000049UL +#define CKM_SHA512_224_HMAC_GENERAL 0x0000004AUL +#define CKM_SHA512_224_KEY_DERIVATION 0x0000004BUL +#define CKM_SHA512_256 0x0000004CUL +#define CKM_SHA512_256_HMAC 0x0000004DUL +#define CKM_SHA512_256_HMAC_GENERAL 0x0000004EUL +#define CKM_SHA512_256_KEY_DERIVATION 0x0000004FUL + +#define CKM_SHA512_T 0x00000050UL +#define CKM_SHA512_T_HMAC 0x00000051UL +#define CKM_SHA512_T_HMAC_GENERAL 0x00000052UL +#define CKM_SHA512_T_KEY_DERIVATION 0x00000053UL + +#define CKM_RC2_KEY_GEN 0x00000100UL +#define CKM_RC2_ECB 0x00000101UL +#define CKM_RC2_CBC 0x00000102UL +#define CKM_RC2_MAC 0x00000103UL + +#define CKM_RC2_MAC_GENERAL 0x00000104UL +#define CKM_RC2_CBC_PAD 0x00000105UL + +#define CKM_RC4_KEY_GEN 0x00000110UL +#define CKM_RC4 0x00000111UL +#define CKM_DES_KEY_GEN 0x00000120UL +#define CKM_DES_ECB 0x00000121UL +#define CKM_DES_CBC 0x00000122UL +#define CKM_DES_MAC 0x00000123UL + +#define CKM_DES_MAC_GENERAL 0x00000124UL +#define CKM_DES_CBC_PAD 0x00000125UL + +#define CKM_DES2_KEY_GEN 0x00000130UL +#define CKM_DES3_KEY_GEN 0x00000131UL +#define CKM_DES3_ECB 0x00000132UL +#define CKM_DES3_CBC 0x00000133UL +#define CKM_DES3_MAC 0x00000134UL + +#define CKM_DES3_MAC_GENERAL 0x00000135UL +#define CKM_DES3_CBC_PAD 0x00000136UL +#define CKM_DES3_CMAC_GENERAL 0x00000137UL +#define CKM_DES3_CMAC 0x00000138UL +#define CKM_CDMF_KEY_GEN 0x00000140UL +#define CKM_CDMF_ECB 0x00000141UL +#define CKM_CDMF_CBC 0x00000142UL +#define CKM_CDMF_MAC 0x00000143UL +#define CKM_CDMF_MAC_GENERAL 0x00000144UL +#define CKM_CDMF_CBC_PAD 0x00000145UL + +#define CKM_DES_OFB64 0x00000150UL +#define CKM_DES_OFB8 0x00000151UL +#define CKM_DES_CFB64 0x00000152UL +#define CKM_DES_CFB8 0x00000153UL + +#define CKM_MD2 0x00000200UL + +#define CKM_MD2_HMAC 0x00000201UL +#define CKM_MD2_HMAC_GENERAL 0x00000202UL + +#define CKM_MD5 0x00000210UL + +#define CKM_MD5_HMAC 0x00000211UL +#define CKM_MD5_HMAC_GENERAL 0x00000212UL + +#define CKM_SHA_1 0x00000220UL + +#define CKM_SHA_1_HMAC 0x00000221UL +#define CKM_SHA_1_HMAC_GENERAL 0x00000222UL + +#define CKM_RIPEMD128 0x00000230UL +#define CKM_RIPEMD128_HMAC 0x00000231UL +#define CKM_RIPEMD128_HMAC_GENERAL 0x00000232UL +#define CKM_RIPEMD160 0x00000240UL +#define CKM_RIPEMD160_HMAC 0x00000241UL +#define CKM_RIPEMD160_HMAC_GENERAL 0x00000242UL + +#define CKM_SHA256 0x00000250UL +#define CKM_SHA256_HMAC 0x00000251UL +#define CKM_SHA256_HMAC_GENERAL 0x00000252UL +#define CKM_SHA224 0x00000255UL +#define CKM_SHA224_HMAC 0x00000256UL +#define CKM_SHA224_HMAC_GENERAL 0x00000257UL +#define CKM_SHA384 0x00000260UL +#define CKM_SHA384_HMAC 0x00000261UL +#define CKM_SHA384_HMAC_GENERAL 0x00000262UL +#define CKM_SHA512 0x00000270UL +#define CKM_SHA512_HMAC 0x00000271UL +#define CKM_SHA512_HMAC_GENERAL 0x00000272UL +#define CKM_SECURID_KEY_GEN 0x00000280UL +#define CKM_SECURID 0x00000282UL +#define CKM_HOTP_KEY_GEN 0x00000290UL +#define CKM_HOTP 0x00000291UL +#define CKM_ACTI 0x000002A0UL +#define CKM_ACTI_KEY_GEN 0x000002A1UL + +#define CKM_CAST_KEY_GEN 0x00000300UL +#define CKM_CAST_ECB 0x00000301UL +#define CKM_CAST_CBC 0x00000302UL +#define CKM_CAST_MAC 0x00000303UL +#define CKM_CAST_MAC_GENERAL 0x00000304UL +#define CKM_CAST_CBC_PAD 0x00000305UL +#define CKM_CAST3_KEY_GEN 0x00000310UL +#define CKM_CAST3_ECB 0x00000311UL +#define CKM_CAST3_CBC 0x00000312UL +#define CKM_CAST3_MAC 0x00000313UL +#define CKM_CAST3_MAC_GENERAL 0x00000314UL +#define CKM_CAST3_CBC_PAD 0x00000315UL +/* Note that CAST128 and CAST5 are the same algorithm */ +#define CKM_CAST5_KEY_GEN 0x00000320UL +#define CKM_CAST128_KEY_GEN 0x00000320UL +#define CKM_CAST5_ECB 0x00000321UL +#define CKM_CAST128_ECB 0x00000321UL +#define CKM_CAST5_CBC 0x00000322UL /* Deprecated */ +#define CKM_CAST128_CBC 0x00000322UL +#define CKM_CAST5_MAC 0x00000323UL /* Deprecated */ +#define CKM_CAST128_MAC 0x00000323UL +#define CKM_CAST5_MAC_GENERAL 0x00000324UL /* Deprecated */ +#define CKM_CAST128_MAC_GENERAL 0x00000324UL +#define CKM_CAST5_CBC_PAD 0x00000325UL /* Deprecated */ +#define CKM_CAST128_CBC_PAD 0x00000325UL +#define CKM_RC5_KEY_GEN 0x00000330UL +#define CKM_RC5_ECB 0x00000331UL +#define CKM_RC5_CBC 0x00000332UL +#define CKM_RC5_MAC 0x00000333UL +#define CKM_RC5_MAC_GENERAL 0x00000334UL +#define CKM_RC5_CBC_PAD 0x00000335UL +#define CKM_IDEA_KEY_GEN 0x00000340UL +#define CKM_IDEA_ECB 0x00000341UL +#define CKM_IDEA_CBC 0x00000342UL +#define CKM_IDEA_MAC 0x00000343UL +#define CKM_IDEA_MAC_GENERAL 0x00000344UL +#define CKM_IDEA_CBC_PAD 0x00000345UL +#define CKM_GENERIC_SECRET_KEY_GEN 0x00000350UL +#define CKM_CONCATENATE_BASE_AND_KEY 0x00000360UL +#define CKM_CONCATENATE_BASE_AND_DATA 0x00000362UL +#define CKM_CONCATENATE_DATA_AND_BASE 0x00000363UL +#define CKM_XOR_BASE_AND_DATA 0x00000364UL +#define CKM_EXTRACT_KEY_FROM_KEY 0x00000365UL +#define CKM_SSL3_PRE_MASTER_KEY_GEN 0x00000370UL +#define CKM_SSL3_MASTER_KEY_DERIVE 0x00000371UL +#define CKM_SSL3_KEY_AND_MAC_DERIVE 0x00000372UL + +#define CKM_SSL3_MASTER_KEY_DERIVE_DH 0x00000373UL +#define CKM_TLS_PRE_MASTER_KEY_GEN 0x00000374UL +#define CKM_TLS_MASTER_KEY_DERIVE 0x00000375UL +#define CKM_TLS_KEY_AND_MAC_DERIVE 0x00000376UL +#define CKM_TLS_MASTER_KEY_DERIVE_DH 0x00000377UL + +#define CKM_TLS_PRF 0x00000378UL + +#define CKM_SSL3_MD5_MAC 0x00000380UL +#define CKM_SSL3_SHA1_MAC 0x00000381UL +#define CKM_MD5_KEY_DERIVATION 0x00000390UL +#define CKM_MD2_KEY_DERIVATION 0x00000391UL +#define CKM_SHA1_KEY_DERIVATION 0x00000392UL + +#define CKM_SHA256_KEY_DERIVATION 0x00000393UL +#define CKM_SHA384_KEY_DERIVATION 0x00000394UL +#define CKM_SHA512_KEY_DERIVATION 0x00000395UL +#define CKM_SHA224_KEY_DERIVATION 0x00000396UL + +#define CKM_PBE_MD2_DES_CBC 0x000003A0UL +#define CKM_PBE_MD5_DES_CBC 0x000003A1UL +#define CKM_PBE_MD5_CAST_CBC 0x000003A2UL +#define CKM_PBE_MD5_CAST3_CBC 0x000003A3UL +#define CKM_PBE_MD5_CAST5_CBC 0x000003A4UL /* Deprecated */ +#define CKM_PBE_MD5_CAST128_CBC 0x000003A4UL +#define CKM_PBE_SHA1_CAST5_CBC 0x000003A5UL /* Deprecated */ +#define CKM_PBE_SHA1_CAST128_CBC 0x000003A5UL +#define CKM_PBE_SHA1_RC4_128 0x000003A6UL +#define CKM_PBE_SHA1_RC4_40 0x000003A7UL +#define CKM_PBE_SHA1_DES3_EDE_CBC 0x000003A8UL +#define CKM_PBE_SHA1_DES2_EDE_CBC 0x000003A9UL +#define CKM_PBE_SHA1_RC2_128_CBC 0x000003AAUL +#define CKM_PBE_SHA1_RC2_40_CBC 0x000003ABUL + +#define CKM_PKCS5_PBKD2 0x000003B0UL + +#define CKM_PBA_SHA1_WITH_SHA1_HMAC 0x000003C0UL + +#define CKM_WTLS_PRE_MASTER_KEY_GEN 0x000003D0UL +#define CKM_WTLS_MASTER_KEY_DERIVE 0x000003D1UL +#define CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC 0x000003D2UL +#define CKM_WTLS_PRF 0x000003D3UL +#define CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE 0x000003D4UL +#define CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE 0x000003D5UL + +#define CKM_TLS10_MAC_SERVER 0x000003D6UL +#define CKM_TLS10_MAC_CLIENT 0x000003D7UL +#define CKM_TLS12_MAC 0x000003D8UL +#define CKM_TLS12_KDF 0x000003D9UL +#define CKM_TLS12_MASTER_KEY_DERIVE 0x000003E0UL +#define CKM_TLS12_KEY_AND_MAC_DERIVE 0x000003E1UL +#define CKM_TLS12_MASTER_KEY_DERIVE_DH 0x000003E2UL +#define CKM_TLS12_KEY_SAFE_DERIVE 0x000003E3UL +#define CKM_TLS_MAC 0x000003E4UL +#define CKM_TLS_KDF 0x000003E5UL + +#define CKM_KEY_WRAP_LYNKS 0x00000400UL +#define CKM_KEY_WRAP_SET_OAEP 0x00000401UL + +#define CKM_CMS_SIG 0x00000500UL +#define CKM_KIP_DERIVE 0x00000510UL +#define CKM_KIP_WRAP 0x00000511UL +#define CKM_KIP_MAC 0x00000512UL + +#define CKM_CAMELLIA_KEY_GEN 0x00000550UL +#define CKM_CAMELLIA_ECB 0x00000551UL +#define CKM_CAMELLIA_CBC 0x00000552UL +#define CKM_CAMELLIA_MAC 0x00000553UL +#define CKM_CAMELLIA_MAC_GENERAL 0x00000554UL +#define CKM_CAMELLIA_CBC_PAD 0x00000555UL +#define CKM_CAMELLIA_ECB_ENCRYPT_DATA 0x00000556UL +#define CKM_CAMELLIA_CBC_ENCRYPT_DATA 0x00000557UL +#define CKM_CAMELLIA_CTR 0x00000558UL + +#define CKM_ARIA_KEY_GEN 0x00000560UL +#define CKM_ARIA_ECB 0x00000561UL +#define CKM_ARIA_CBC 0x00000562UL +#define CKM_ARIA_MAC 0x00000563UL +#define CKM_ARIA_MAC_GENERAL 0x00000564UL +#define CKM_ARIA_CBC_PAD 0x00000565UL +#define CKM_ARIA_ECB_ENCRYPT_DATA 0x00000566UL +#define CKM_ARIA_CBC_ENCRYPT_DATA 0x00000567UL + +#define CKM_SEED_KEY_GEN 0x00000650UL +#define CKM_SEED_ECB 0x00000651UL +#define CKM_SEED_CBC 0x00000652UL +#define CKM_SEED_MAC 0x00000653UL +#define CKM_SEED_MAC_GENERAL 0x00000654UL +#define CKM_SEED_CBC_PAD 0x00000655UL +#define CKM_SEED_ECB_ENCRYPT_DATA 0x00000656UL +#define CKM_SEED_CBC_ENCRYPT_DATA 0x00000657UL + +#define CKM_SKIPJACK_KEY_GEN 0x00001000UL +#define CKM_SKIPJACK_ECB64 0x00001001UL +#define CKM_SKIPJACK_CBC64 0x00001002UL +#define CKM_SKIPJACK_OFB64 0x00001003UL +#define CKM_SKIPJACK_CFB64 0x00001004UL +#define CKM_SKIPJACK_CFB32 0x00001005UL +#define CKM_SKIPJACK_CFB16 0x00001006UL +#define CKM_SKIPJACK_CFB8 0x00001007UL +#define CKM_SKIPJACK_WRAP 0x00001008UL +#define CKM_SKIPJACK_PRIVATE_WRAP 0x00001009UL +#define CKM_SKIPJACK_RELAYX 0x0000100aUL +#define CKM_KEA_KEY_PAIR_GEN 0x00001010UL +#define CKM_KEA_KEY_DERIVE 0x00001011UL +#define CKM_KEA_DERIVE 0x00001012UL +#define CKM_FORTEZZA_TIMESTAMP 0x00001020UL +#define CKM_BATON_KEY_GEN 0x00001030UL +#define CKM_BATON_ECB128 0x00001031UL +#define CKM_BATON_ECB96 0x00001032UL +#define CKM_BATON_CBC128 0x00001033UL +#define CKM_BATON_COUNTER 0x00001034UL +#define CKM_BATON_SHUFFLE 0x00001035UL +#define CKM_BATON_WRAP 0x00001036UL + +#define CKM_ECDSA_KEY_PAIR_GEN 0x00001040UL /* Deprecated */ +#define CKM_EC_KEY_PAIR_GEN 0x00001040UL + +#define CKM_ECDSA 0x00001041UL +#define CKM_ECDSA_SHA1 0x00001042UL +#define CKM_ECDSA_SHA224 0x00001043UL +#define CKM_ECDSA_SHA256 0x00001044UL +#define CKM_ECDSA_SHA384 0x00001045UL +#define CKM_ECDSA_SHA512 0x00001046UL + +#define CKM_ECDH1_DERIVE 0x00001050UL +#define CKM_ECDH1_COFACTOR_DERIVE 0x00001051UL +#define CKM_ECMQV_DERIVE 0x00001052UL + +#define CKM_ECDH_AES_KEY_WRAP 0x00001053UL +#define CKM_RSA_AES_KEY_WRAP 0x00001054UL + +#define CKM_JUNIPER_KEY_GEN 0x00001060UL +#define CKM_JUNIPER_ECB128 0x00001061UL +#define CKM_JUNIPER_CBC128 0x00001062UL +#define CKM_JUNIPER_COUNTER 0x00001063UL +#define CKM_JUNIPER_SHUFFLE 0x00001064UL +#define CKM_JUNIPER_WRAP 0x00001065UL +#define CKM_FASTHASH 0x00001070UL + +#define CKM_AES_KEY_GEN 0x00001080UL +#define CKM_AES_ECB 0x00001081UL +#define CKM_AES_CBC 0x00001082UL +#define CKM_AES_MAC 0x00001083UL +#define CKM_AES_MAC_GENERAL 0x00001084UL +#define CKM_AES_CBC_PAD 0x00001085UL +#define CKM_AES_CTR 0x00001086UL +#define CKM_AES_GCM 0x00001087UL +#define CKM_AES_CCM 0x00001088UL +#define CKM_AES_CTS 0x00001089UL +#define CKM_AES_CMAC 0x0000108AUL +#define CKM_AES_CMAC_GENERAL 0x0000108BUL + +#define CKM_AES_XCBC_MAC 0x0000108CUL +#define CKM_AES_XCBC_MAC_96 0x0000108DUL +#define CKM_AES_GMAC 0x0000108EUL + +#define CKM_BLOWFISH_KEY_GEN 0x00001090UL +#define CKM_BLOWFISH_CBC 0x00001091UL +#define CKM_TWOFISH_KEY_GEN 0x00001092UL +#define CKM_TWOFISH_CBC 0x00001093UL +#define CKM_BLOWFISH_CBC_PAD 0x00001094UL +#define CKM_TWOFISH_CBC_PAD 0x00001095UL + +#define CKM_DES_ECB_ENCRYPT_DATA 0x00001100UL +#define CKM_DES_CBC_ENCRYPT_DATA 0x00001101UL +#define CKM_DES3_ECB_ENCRYPT_DATA 0x00001102UL +#define CKM_DES3_CBC_ENCRYPT_DATA 0x00001103UL +#define CKM_AES_ECB_ENCRYPT_DATA 0x00001104UL +#define CKM_AES_CBC_ENCRYPT_DATA 0x00001105UL + +#define CKM_GOSTR3410_KEY_PAIR_GEN 0x00001200UL +#define CKM_GOSTR3410 0x00001201UL +#define CKM_GOSTR3410_WITH_GOSTR3411 0x00001202UL +#define CKM_GOSTR3410_KEY_WRAP 0x00001203UL +#define CKM_GOSTR3410_DERIVE 0x00001204UL +#define CKM_GOSTR3411 0x00001210UL +#define CKM_GOSTR3411_HMAC 0x00001211UL +#define CKM_GOST28147_KEY_GEN 0x00001220UL +#define CKM_GOST28147_ECB 0x00001221UL +#define CKM_GOST28147 0x00001222UL +#define CKM_GOST28147_MAC 0x00001223UL +#define CKM_GOST28147_KEY_WRAP 0x00001224UL + +#define CKM_DSA_PARAMETER_GEN 0x00002000UL +#define CKM_DH_PKCS_PARAMETER_GEN 0x00002001UL +#define CKM_X9_42_DH_PARAMETER_GEN 0x00002002UL +#define CKM_DSA_PROBABLISTIC_PARAMETER_GEN 0x00002003UL +#define CKM_DSA_SHAWE_TAYLOR_PARAMETER_GEN 0x00002004UL + +#define CKM_AES_OFB 0x00002104UL +#define CKM_AES_CFB64 0x00002105UL +#define CKM_AES_CFB8 0x00002106UL +#define CKM_AES_CFB128 0x00002107UL + +#define CKM_AES_CFB1 0x00002108UL +#define CKM_AES_KEY_WRAP 0x00002109UL /* WAS: 0x00001090 */ +#define CKM_AES_KEY_WRAP_PAD 0x0000210AUL /* WAS: 0x00001091 */ + +#define CKM_RSA_PKCS_TPM_1_1 0x00004001UL +#define CKM_RSA_PKCS_OAEP_TPM_1_1 0x00004002UL + +#define CKM_VENDOR_DEFINED 0x80000000UL + +typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR; + + +/* CK_MECHANISM is a structure that specifies a particular + * mechanism + */ +typedef struct CK_MECHANISM { + CK_MECHANISM_TYPE mechanism; + CK_VOID_PTR pParameter; + CK_ULONG ulParameterLen; /* in bytes */ +} CK_MECHANISM; + +typedef CK_MECHANISM CK_PTR CK_MECHANISM_PTR; + + +/* CK_MECHANISM_INFO provides information about a particular + * mechanism + */ +typedef struct CK_MECHANISM_INFO { + CK_ULONG ulMinKeySize; + CK_ULONG ulMaxKeySize; + CK_FLAGS flags; +} CK_MECHANISM_INFO; + +/* The flags are defined as follows: + * Bit Flag Mask Meaning */ +#define CKF_HW 0x00000001UL /* performed by HW */ + +/* Specify whether or not a mechanism can be used for a particular task */ +#define CKF_ENCRYPT 0x00000100UL +#define CKF_DECRYPT 0x00000200UL +#define CKF_DIGEST 0x00000400UL +#define CKF_SIGN 0x00000800UL +#define CKF_SIGN_RECOVER 0x00001000UL +#define CKF_VERIFY 0x00002000UL +#define CKF_VERIFY_RECOVER 0x00004000UL +#define CKF_GENERATE 0x00008000UL +#define CKF_GENERATE_KEY_PAIR 0x00010000UL +#define CKF_WRAP 0x00020000UL +#define CKF_UNWRAP 0x00040000UL +#define CKF_DERIVE 0x00080000UL + +/* Describe a token's EC capabilities not available in mechanism + * information. + */ +#define CKF_EC_F_P 0x00100000UL +#define CKF_EC_F_2M 0x00200000UL +#define CKF_EC_ECPARAMETERS 0x00400000UL +#define CKF_EC_NAMEDCURVE 0x00800000UL +#define CKF_EC_UNCOMPRESS 0x01000000UL +#define CKF_EC_COMPRESS 0x02000000UL + +#define CKF_EXTENSION 0x80000000UL + +typedef CK_MECHANISM_INFO CK_PTR CK_MECHANISM_INFO_PTR; + +/* CK_RV is a value that identifies the return value of a + * Cryptoki function + */ +typedef CK_ULONG CK_RV; + +#define CKR_OK 0x00000000UL +#define CKR_CANCEL 0x00000001UL +#define CKR_HOST_MEMORY 0x00000002UL +#define CKR_SLOT_ID_INVALID 0x00000003UL + +#define CKR_GENERAL_ERROR 0x00000005UL +#define CKR_FUNCTION_FAILED 0x00000006UL + +#define CKR_ARGUMENTS_BAD 0x00000007UL +#define CKR_NO_EVENT 0x00000008UL +#define CKR_NEED_TO_CREATE_THREADS 0x00000009UL +#define CKR_CANT_LOCK 0x0000000AUL + +#define CKR_ATTRIBUTE_READ_ONLY 0x00000010UL +#define CKR_ATTRIBUTE_SENSITIVE 0x00000011UL +#define CKR_ATTRIBUTE_TYPE_INVALID 0x00000012UL +#define CKR_ATTRIBUTE_VALUE_INVALID 0x00000013UL + +#define CKR_ACTION_PROHIBITED 0x0000001BUL + +#define CKR_DATA_INVALID 0x00000020UL +#define CKR_DATA_LEN_RANGE 0x00000021UL +#define CKR_DEVICE_ERROR 0x00000030UL +#define CKR_DEVICE_MEMORY 0x00000031UL +#define CKR_DEVICE_REMOVED 0x00000032UL +#define CKR_ENCRYPTED_DATA_INVALID 0x00000040UL +#define CKR_ENCRYPTED_DATA_LEN_RANGE 0x00000041UL +#define CKR_FUNCTION_CANCELED 0x00000050UL +#define CKR_FUNCTION_NOT_PARALLEL 0x00000051UL + +#define CKR_FUNCTION_NOT_SUPPORTED 0x00000054UL + +#define CKR_KEY_HANDLE_INVALID 0x00000060UL + +#define CKR_KEY_SIZE_RANGE 0x00000062UL +#define CKR_KEY_TYPE_INCONSISTENT 0x00000063UL + +#define CKR_KEY_NOT_NEEDED 0x00000064UL +#define CKR_KEY_CHANGED 0x00000065UL +#define CKR_KEY_NEEDED 0x00000066UL +#define CKR_KEY_INDIGESTIBLE 0x00000067UL +#define CKR_KEY_FUNCTION_NOT_PERMITTED 0x00000068UL +#define CKR_KEY_NOT_WRAPPABLE 0x00000069UL +#define CKR_KEY_UNEXTRACTABLE 0x0000006AUL + +#define CKR_MECHANISM_INVALID 0x00000070UL +#define CKR_MECHANISM_PARAM_INVALID 0x00000071UL + +#define CKR_OBJECT_HANDLE_INVALID 0x00000082UL +#define CKR_OPERATION_ACTIVE 0x00000090UL +#define CKR_OPERATION_NOT_INITIALIZED 0x00000091UL +#define CKR_PIN_INCORRECT 0x000000A0UL +#define CKR_PIN_INVALID 0x000000A1UL +#define CKR_PIN_LEN_RANGE 0x000000A2UL + +#define CKR_PIN_EXPIRED 0x000000A3UL +#define CKR_PIN_LOCKED 0x000000A4UL + +#define CKR_SESSION_CLOSED 0x000000B0UL +#define CKR_SESSION_COUNT 0x000000B1UL +#define CKR_SESSION_HANDLE_INVALID 0x000000B3UL +#define CKR_SESSION_PARALLEL_NOT_SUPPORTED 0x000000B4UL +#define CKR_SESSION_READ_ONLY 0x000000B5UL +#define CKR_SESSION_EXISTS 0x000000B6UL + +#define CKR_SESSION_READ_ONLY_EXISTS 0x000000B7UL +#define CKR_SESSION_READ_WRITE_SO_EXISTS 0x000000B8UL + +#define CKR_SIGNATURE_INVALID 0x000000C0UL +#define CKR_SIGNATURE_LEN_RANGE 0x000000C1UL +#define CKR_TEMPLATE_INCOMPLETE 0x000000D0UL +#define CKR_TEMPLATE_INCONSISTENT 0x000000D1UL +#define CKR_TOKEN_NOT_PRESENT 0x000000E0UL +#define CKR_TOKEN_NOT_RECOGNIZED 0x000000E1UL +#define CKR_TOKEN_WRITE_PROTECTED 0x000000E2UL +#define CKR_UNWRAPPING_KEY_HANDLE_INVALID 0x000000F0UL +#define CKR_UNWRAPPING_KEY_SIZE_RANGE 0x000000F1UL +#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT 0x000000F2UL +#define CKR_USER_ALREADY_LOGGED_IN 0x00000100UL +#define CKR_USER_NOT_LOGGED_IN 0x00000101UL +#define CKR_USER_PIN_NOT_INITIALIZED 0x00000102UL +#define CKR_USER_TYPE_INVALID 0x00000103UL + +#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN 0x00000104UL +#define CKR_USER_TOO_MANY_TYPES 0x00000105UL + +#define CKR_WRAPPED_KEY_INVALID 0x00000110UL +#define CKR_WRAPPED_KEY_LEN_RANGE 0x00000112UL +#define CKR_WRAPPING_KEY_HANDLE_INVALID 0x00000113UL +#define CKR_WRAPPING_KEY_SIZE_RANGE 0x00000114UL +#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT 0x00000115UL +#define CKR_RANDOM_SEED_NOT_SUPPORTED 0x00000120UL + +#define CKR_RANDOM_NO_RNG 0x00000121UL + +#define CKR_DOMAIN_PARAMS_INVALID 0x00000130UL + +#define CKR_CURVE_NOT_SUPPORTED 0x00000140UL + +#define CKR_BUFFER_TOO_SMALL 0x00000150UL +#define CKR_SAVED_STATE_INVALID 0x00000160UL +#define CKR_INFORMATION_SENSITIVE 0x00000170UL +#define CKR_STATE_UNSAVEABLE 0x00000180UL + +#define CKR_CRYPTOKI_NOT_INITIALIZED 0x00000190UL +#define CKR_CRYPTOKI_ALREADY_INITIALIZED 0x00000191UL +#define CKR_MUTEX_BAD 0x000001A0UL +#define CKR_MUTEX_NOT_LOCKED 0x000001A1UL + +#define CKR_NEW_PIN_MODE 0x000001B0UL +#define CKR_NEXT_OTP 0x000001B1UL + +#define CKR_EXCEEDED_MAX_ITERATIONS 0x000001B5UL +#define CKR_FIPS_SELF_TEST_FAILED 0x000001B6UL +#define CKR_LIBRARY_LOAD_FAILED 0x000001B7UL +#define CKR_PIN_TOO_WEAK 0x000001B8UL +#define CKR_PUBLIC_KEY_INVALID 0x000001B9UL + +#define CKR_FUNCTION_REJECTED 0x00000200UL + +#define CKR_VENDOR_DEFINED 0x80000000UL + + +/* CK_NOTIFY is an application callback that processes events */ +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_NOTIFY)( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_NOTIFICATION event, + CK_VOID_PTR pApplication /* passed to C_OpenSession */ +); + + +/* CK_FUNCTION_LIST is a structure holding a Cryptoki spec + * version and pointers of appropriate types to all the + * Cryptoki functions + */ +typedef struct CK_FUNCTION_LIST CK_FUNCTION_LIST; + +typedef CK_FUNCTION_LIST CK_PTR CK_FUNCTION_LIST_PTR; + +typedef CK_FUNCTION_LIST_PTR CK_PTR CK_FUNCTION_LIST_PTR_PTR; + + +/* CK_CREATEMUTEX is an application callback for creating a + * mutex object + */ +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_CREATEMUTEX)( + CK_VOID_PTR_PTR ppMutex /* location to receive ptr to mutex */ +); + + +/* CK_DESTROYMUTEX is an application callback for destroying a + * mutex object + */ +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_DESTROYMUTEX)( + CK_VOID_PTR pMutex /* pointer to mutex */ +); + + +/* CK_LOCKMUTEX is an application callback for locking a mutex */ +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_LOCKMUTEX)( + CK_VOID_PTR pMutex /* pointer to mutex */ +); + + +/* CK_UNLOCKMUTEX is an application callback for unlocking a + * mutex + */ +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_UNLOCKMUTEX)( + CK_VOID_PTR pMutex /* pointer to mutex */ +); + + +/* CK_C_INITIALIZE_ARGS provides the optional arguments to + * C_Initialize + */ +typedef struct CK_C_INITIALIZE_ARGS { + CK_CREATEMUTEX CreateMutex; + CK_DESTROYMUTEX DestroyMutex; + CK_LOCKMUTEX LockMutex; + CK_UNLOCKMUTEX UnlockMutex; + CK_FLAGS flags; + CK_VOID_PTR pReserved; +} CK_C_INITIALIZE_ARGS; + +/* flags: bit flags that provide capabilities of the slot + * Bit Flag Mask Meaning + */ +#define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001UL +#define CKF_OS_LOCKING_OK 0x00000002UL + +typedef CK_C_INITIALIZE_ARGS CK_PTR CK_C_INITIALIZE_ARGS_PTR; + + +/* additional flags for parameters to functions */ + +/* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */ +#define CKF_DONT_BLOCK 1 + +/* CK_RSA_PKCS_MGF_TYPE is used to indicate the Message + * Generation Function (MGF) applied to a message block when + * formatting a message block for the PKCS #1 OAEP encryption + * scheme. + */ +typedef CK_ULONG CK_RSA_PKCS_MGF_TYPE; + +typedef CK_RSA_PKCS_MGF_TYPE CK_PTR CK_RSA_PKCS_MGF_TYPE_PTR; + +/* The following MGFs are defined */ +#define CKG_MGF1_SHA1 0x00000001UL +#define CKG_MGF1_SHA256 0x00000002UL +#define CKG_MGF1_SHA384 0x00000003UL +#define CKG_MGF1_SHA512 0x00000004UL +#define CKG_MGF1_SHA224 0x00000005UL + +/* CK_RSA_PKCS_OAEP_SOURCE_TYPE is used to indicate the source + * of the encoding parameter when formatting a message block + * for the PKCS #1 OAEP encryption scheme. + */ +typedef CK_ULONG CK_RSA_PKCS_OAEP_SOURCE_TYPE; + +typedef CK_RSA_PKCS_OAEP_SOURCE_TYPE CK_PTR CK_RSA_PKCS_OAEP_SOURCE_TYPE_PTR; + +/* The following encoding parameter sources are defined */ +#define CKZ_DATA_SPECIFIED 0x00000001UL + +/* CK_RSA_PKCS_OAEP_PARAMS provides the parameters to the + * CKM_RSA_PKCS_OAEP mechanism. + */ +typedef struct CK_RSA_PKCS_OAEP_PARAMS { + CK_MECHANISM_TYPE hashAlg; + CK_RSA_PKCS_MGF_TYPE mgf; + CK_RSA_PKCS_OAEP_SOURCE_TYPE source; + CK_VOID_PTR pSourceData; + CK_ULONG ulSourceDataLen; +} CK_RSA_PKCS_OAEP_PARAMS; + +typedef CK_RSA_PKCS_OAEP_PARAMS CK_PTR CK_RSA_PKCS_OAEP_PARAMS_PTR; + +/* CK_RSA_PKCS_PSS_PARAMS provides the parameters to the + * CKM_RSA_PKCS_PSS mechanism(s). + */ +typedef struct CK_RSA_PKCS_PSS_PARAMS { + CK_MECHANISM_TYPE hashAlg; + CK_RSA_PKCS_MGF_TYPE mgf; + CK_ULONG sLen; +} CK_RSA_PKCS_PSS_PARAMS; + +typedef CK_RSA_PKCS_PSS_PARAMS CK_PTR CK_RSA_PKCS_PSS_PARAMS_PTR; + +typedef CK_ULONG CK_EC_KDF_TYPE; + +/* The following EC Key Derivation Functions are defined */ +#define CKD_NULL 0x00000001UL +#define CKD_SHA1_KDF 0x00000002UL + +/* The following X9.42 DH key derivation functions are defined */ +#define CKD_SHA1_KDF_ASN1 0x00000003UL +#define CKD_SHA1_KDF_CONCATENATE 0x00000004UL +#define CKD_SHA224_KDF 0x00000005UL +#define CKD_SHA256_KDF 0x00000006UL +#define CKD_SHA384_KDF 0x00000007UL +#define CKD_SHA512_KDF 0x00000008UL +#define CKD_CPDIVERSIFY_KDF 0x00000009UL + + +/* CK_ECDH1_DERIVE_PARAMS provides the parameters to the + * CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE mechanisms, + * where each party contributes one key pair. + */ +typedef struct CK_ECDH1_DERIVE_PARAMS { + CK_EC_KDF_TYPE kdf; + CK_ULONG ulSharedDataLen; + CK_BYTE_PTR pSharedData; + CK_ULONG ulPublicDataLen; + CK_BYTE_PTR pPublicData; +} CK_ECDH1_DERIVE_PARAMS; + +typedef CK_ECDH1_DERIVE_PARAMS CK_PTR CK_ECDH1_DERIVE_PARAMS_PTR; + +/* + * CK_ECDH2_DERIVE_PARAMS provides the parameters to the + * CKM_ECMQV_DERIVE mechanism, where each party contributes two key pairs. + */ +typedef struct CK_ECDH2_DERIVE_PARAMS { + CK_EC_KDF_TYPE kdf; + CK_ULONG ulSharedDataLen; + CK_BYTE_PTR pSharedData; + CK_ULONG ulPublicDataLen; + CK_BYTE_PTR pPublicData; + CK_ULONG ulPrivateDataLen; + CK_OBJECT_HANDLE hPrivateData; + CK_ULONG ulPublicDataLen2; + CK_BYTE_PTR pPublicData2; +} CK_ECDH2_DERIVE_PARAMS; + +typedef CK_ECDH2_DERIVE_PARAMS CK_PTR CK_ECDH2_DERIVE_PARAMS_PTR; + +typedef struct CK_ECMQV_DERIVE_PARAMS { + CK_EC_KDF_TYPE kdf; + CK_ULONG ulSharedDataLen; + CK_BYTE_PTR pSharedData; + CK_ULONG ulPublicDataLen; + CK_BYTE_PTR pPublicData; + CK_ULONG ulPrivateDataLen; + CK_OBJECT_HANDLE hPrivateData; + CK_ULONG ulPublicDataLen2; + CK_BYTE_PTR pPublicData2; + CK_OBJECT_HANDLE publicKey; +} CK_ECMQV_DERIVE_PARAMS; + +typedef CK_ECMQV_DERIVE_PARAMS CK_PTR CK_ECMQV_DERIVE_PARAMS_PTR; + +/* Typedefs and defines for the CKM_X9_42_DH_KEY_PAIR_GEN and the + * CKM_X9_42_DH_PARAMETER_GEN mechanisms + */ +typedef CK_ULONG CK_X9_42_DH_KDF_TYPE; +typedef CK_X9_42_DH_KDF_TYPE CK_PTR CK_X9_42_DH_KDF_TYPE_PTR; + +/* CK_X9_42_DH1_DERIVE_PARAMS provides the parameters to the + * CKM_X9_42_DH_DERIVE key derivation mechanism, where each party + * contributes one key pair + */ +typedef struct CK_X9_42_DH1_DERIVE_PARAMS { + CK_X9_42_DH_KDF_TYPE kdf; + CK_ULONG ulOtherInfoLen; + CK_BYTE_PTR pOtherInfo; + CK_ULONG ulPublicDataLen; + CK_BYTE_PTR pPublicData; +} CK_X9_42_DH1_DERIVE_PARAMS; + +typedef struct CK_X9_42_DH1_DERIVE_PARAMS CK_PTR CK_X9_42_DH1_DERIVE_PARAMS_PTR; + +/* CK_X9_42_DH2_DERIVE_PARAMS provides the parameters to the + * CKM_X9_42_DH_HYBRID_DERIVE and CKM_X9_42_MQV_DERIVE key derivation + * mechanisms, where each party contributes two key pairs + */ +typedef struct CK_X9_42_DH2_DERIVE_PARAMS { + CK_X9_42_DH_KDF_TYPE kdf; + CK_ULONG ulOtherInfoLen; + CK_BYTE_PTR pOtherInfo; + CK_ULONG ulPublicDataLen; + CK_BYTE_PTR pPublicData; + CK_ULONG ulPrivateDataLen; + CK_OBJECT_HANDLE hPrivateData; + CK_ULONG ulPublicDataLen2; + CK_BYTE_PTR pPublicData2; +} CK_X9_42_DH2_DERIVE_PARAMS; + +typedef CK_X9_42_DH2_DERIVE_PARAMS CK_PTR CK_X9_42_DH2_DERIVE_PARAMS_PTR; + +typedef struct CK_X9_42_MQV_DERIVE_PARAMS { + CK_X9_42_DH_KDF_TYPE kdf; + CK_ULONG ulOtherInfoLen; + CK_BYTE_PTR pOtherInfo; + CK_ULONG ulPublicDataLen; + CK_BYTE_PTR pPublicData; + CK_ULONG ulPrivateDataLen; + CK_OBJECT_HANDLE hPrivateData; + CK_ULONG ulPublicDataLen2; + CK_BYTE_PTR pPublicData2; + CK_OBJECT_HANDLE publicKey; +} CK_X9_42_MQV_DERIVE_PARAMS; + +typedef CK_X9_42_MQV_DERIVE_PARAMS CK_PTR CK_X9_42_MQV_DERIVE_PARAMS_PTR; + +/* CK_KEA_DERIVE_PARAMS provides the parameters to the + * CKM_KEA_DERIVE mechanism + */ +typedef struct CK_KEA_DERIVE_PARAMS { + CK_BBOOL isSender; + CK_ULONG ulRandomLen; + CK_BYTE_PTR pRandomA; + CK_BYTE_PTR pRandomB; + CK_ULONG ulPublicDataLen; + CK_BYTE_PTR pPublicData; +} CK_KEA_DERIVE_PARAMS; + +typedef CK_KEA_DERIVE_PARAMS CK_PTR CK_KEA_DERIVE_PARAMS_PTR; + + +/* CK_RC2_PARAMS provides the parameters to the CKM_RC2_ECB and + * CKM_RC2_MAC mechanisms. An instance of CK_RC2_PARAMS just + * holds the effective keysize + */ +typedef CK_ULONG CK_RC2_PARAMS; + +typedef CK_RC2_PARAMS CK_PTR CK_RC2_PARAMS_PTR; + + +/* CK_RC2_CBC_PARAMS provides the parameters to the CKM_RC2_CBC + * mechanism + */ +typedef struct CK_RC2_CBC_PARAMS { + CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */ + CK_BYTE iv[8]; /* IV for CBC mode */ +} CK_RC2_CBC_PARAMS; + +typedef CK_RC2_CBC_PARAMS CK_PTR CK_RC2_CBC_PARAMS_PTR; + + +/* CK_RC2_MAC_GENERAL_PARAMS provides the parameters for the + * CKM_RC2_MAC_GENERAL mechanism + */ +typedef struct CK_RC2_MAC_GENERAL_PARAMS { + CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */ + CK_ULONG ulMacLength; /* Length of MAC in bytes */ +} CK_RC2_MAC_GENERAL_PARAMS; + +typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR \ + CK_RC2_MAC_GENERAL_PARAMS_PTR; + + +/* CK_RC5_PARAMS provides the parameters to the CKM_RC5_ECB and + * CKM_RC5_MAC mechanisms + */ +typedef struct CK_RC5_PARAMS { + CK_ULONG ulWordsize; /* wordsize in bits */ + CK_ULONG ulRounds; /* number of rounds */ +} CK_RC5_PARAMS; + +typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR; + + +/* CK_RC5_CBC_PARAMS provides the parameters to the CKM_RC5_CBC + * mechanism + */ +typedef struct CK_RC5_CBC_PARAMS { + CK_ULONG ulWordsize; /* wordsize in bits */ + CK_ULONG ulRounds; /* number of rounds */ + CK_BYTE_PTR pIv; /* pointer to IV */ + CK_ULONG ulIvLen; /* length of IV in bytes */ +} CK_RC5_CBC_PARAMS; + +typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR; + + +/* CK_RC5_MAC_GENERAL_PARAMS provides the parameters for the + * CKM_RC5_MAC_GENERAL mechanism + */ +typedef struct CK_RC5_MAC_GENERAL_PARAMS { + CK_ULONG ulWordsize; /* wordsize in bits */ + CK_ULONG ulRounds; /* number of rounds */ + CK_ULONG ulMacLength; /* Length of MAC in bytes */ +} CK_RC5_MAC_GENERAL_PARAMS; + +typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR \ + CK_RC5_MAC_GENERAL_PARAMS_PTR; + +/* CK_MAC_GENERAL_PARAMS provides the parameters to most block + * ciphers' MAC_GENERAL mechanisms. Its value is the length of + * the MAC + */ +typedef CK_ULONG CK_MAC_GENERAL_PARAMS; + +typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR; + +typedef struct CK_DES_CBC_ENCRYPT_DATA_PARAMS { + CK_BYTE iv[8]; + CK_BYTE_PTR pData; + CK_ULONG length; +} CK_DES_CBC_ENCRYPT_DATA_PARAMS; + +typedef CK_DES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR; + +typedef struct CK_AES_CBC_ENCRYPT_DATA_PARAMS { + CK_BYTE iv[16]; + CK_BYTE_PTR pData; + CK_ULONG length; +} CK_AES_CBC_ENCRYPT_DATA_PARAMS; + +typedef CK_AES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR; + +/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS provides the parameters to the + * CKM_SKIPJACK_PRIVATE_WRAP mechanism + */ +typedef struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS { + CK_ULONG ulPasswordLen; + CK_BYTE_PTR pPassword; + CK_ULONG ulPublicDataLen; + CK_BYTE_PTR pPublicData; + CK_ULONG ulPAndGLen; + CK_ULONG ulQLen; + CK_ULONG ulRandomLen; + CK_BYTE_PTR pRandomA; + CK_BYTE_PTR pPrimeP; + CK_BYTE_PTR pBaseG; + CK_BYTE_PTR pSubprimeQ; +} CK_SKIPJACK_PRIVATE_WRAP_PARAMS; + +typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR \ + CK_SKIPJACK_PRIVATE_WRAP_PARAMS_PTR; + + +/* CK_SKIPJACK_RELAYX_PARAMS provides the parameters to the + * CKM_SKIPJACK_RELAYX mechanism + */ +typedef struct CK_SKIPJACK_RELAYX_PARAMS { + CK_ULONG ulOldWrappedXLen; + CK_BYTE_PTR pOldWrappedX; + CK_ULONG ulOldPasswordLen; + CK_BYTE_PTR pOldPassword; + CK_ULONG ulOldPublicDataLen; + CK_BYTE_PTR pOldPublicData; + CK_ULONG ulOldRandomLen; + CK_BYTE_PTR pOldRandomA; + CK_ULONG ulNewPasswordLen; + CK_BYTE_PTR pNewPassword; + CK_ULONG ulNewPublicDataLen; + CK_BYTE_PTR pNewPublicData; + CK_ULONG ulNewRandomLen; + CK_BYTE_PTR pNewRandomA; +} CK_SKIPJACK_RELAYX_PARAMS; + +typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR \ + CK_SKIPJACK_RELAYX_PARAMS_PTR; + + +typedef struct CK_PBE_PARAMS { + CK_BYTE_PTR pInitVector; + CK_UTF8CHAR_PTR pPassword; + CK_ULONG ulPasswordLen; + CK_BYTE_PTR pSalt; + CK_ULONG ulSaltLen; + CK_ULONG ulIteration; +} CK_PBE_PARAMS; + +typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR; + + +/* CK_KEY_WRAP_SET_OAEP_PARAMS provides the parameters to the + * CKM_KEY_WRAP_SET_OAEP mechanism + */ +typedef struct CK_KEY_WRAP_SET_OAEP_PARAMS { + CK_BYTE bBC; /* block contents byte */ + CK_BYTE_PTR pX; /* extra data */ + CK_ULONG ulXLen; /* length of extra data in bytes */ +} CK_KEY_WRAP_SET_OAEP_PARAMS; + +typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR CK_KEY_WRAP_SET_OAEP_PARAMS_PTR; + +typedef struct CK_SSL3_RANDOM_DATA { + CK_BYTE_PTR pClientRandom; + CK_ULONG ulClientRandomLen; + CK_BYTE_PTR pServerRandom; + CK_ULONG ulServerRandomLen; +} CK_SSL3_RANDOM_DATA; + + +typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS { + CK_SSL3_RANDOM_DATA RandomInfo; + CK_VERSION_PTR pVersion; +} CK_SSL3_MASTER_KEY_DERIVE_PARAMS; + +typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR \ + CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR; + +typedef struct CK_SSL3_KEY_MAT_OUT { + CK_OBJECT_HANDLE hClientMacSecret; + CK_OBJECT_HANDLE hServerMacSecret; + CK_OBJECT_HANDLE hClientKey; + CK_OBJECT_HANDLE hServerKey; + CK_BYTE_PTR pIVClient; + CK_BYTE_PTR pIVServer; +} CK_SSL3_KEY_MAT_OUT; + +typedef CK_SSL3_KEY_MAT_OUT CK_PTR CK_SSL3_KEY_MAT_OUT_PTR; + + +typedef struct CK_SSL3_KEY_MAT_PARAMS { + CK_ULONG ulMacSizeInBits; + CK_ULONG ulKeySizeInBits; + CK_ULONG ulIVSizeInBits; + CK_BBOOL bIsExport; + CK_SSL3_RANDOM_DATA RandomInfo; + CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial; +} CK_SSL3_KEY_MAT_PARAMS; + +typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR; + +typedef struct CK_TLS_PRF_PARAMS { + CK_BYTE_PTR pSeed; + CK_ULONG ulSeedLen; + CK_BYTE_PTR pLabel; + CK_ULONG ulLabelLen; + CK_BYTE_PTR pOutput; + CK_ULONG_PTR pulOutputLen; +} CK_TLS_PRF_PARAMS; + +typedef CK_TLS_PRF_PARAMS CK_PTR CK_TLS_PRF_PARAMS_PTR; + +typedef struct CK_WTLS_RANDOM_DATA { + CK_BYTE_PTR pClientRandom; + CK_ULONG ulClientRandomLen; + CK_BYTE_PTR pServerRandom; + CK_ULONG ulServerRandomLen; +} CK_WTLS_RANDOM_DATA; + +typedef CK_WTLS_RANDOM_DATA CK_PTR CK_WTLS_RANDOM_DATA_PTR; + +typedef struct CK_WTLS_MASTER_KEY_DERIVE_PARAMS { + CK_MECHANISM_TYPE DigestMechanism; + CK_WTLS_RANDOM_DATA RandomInfo; + CK_BYTE_PTR pVersion; +} CK_WTLS_MASTER_KEY_DERIVE_PARAMS; + +typedef CK_WTLS_MASTER_KEY_DERIVE_PARAMS CK_PTR \ + CK_WTLS_MASTER_KEY_DERIVE_PARAMS_PTR; + +typedef struct CK_WTLS_PRF_PARAMS { + CK_MECHANISM_TYPE DigestMechanism; + CK_BYTE_PTR pSeed; + CK_ULONG ulSeedLen; + CK_BYTE_PTR pLabel; + CK_ULONG ulLabelLen; + CK_BYTE_PTR pOutput; + CK_ULONG_PTR pulOutputLen; +} CK_WTLS_PRF_PARAMS; + +typedef CK_WTLS_PRF_PARAMS CK_PTR CK_WTLS_PRF_PARAMS_PTR; + +typedef struct CK_WTLS_KEY_MAT_OUT { + CK_OBJECT_HANDLE hMacSecret; + CK_OBJECT_HANDLE hKey; + CK_BYTE_PTR pIV; +} CK_WTLS_KEY_MAT_OUT; + +typedef CK_WTLS_KEY_MAT_OUT CK_PTR CK_WTLS_KEY_MAT_OUT_PTR; + +typedef struct CK_WTLS_KEY_MAT_PARAMS { + CK_MECHANISM_TYPE DigestMechanism; + CK_ULONG ulMacSizeInBits; + CK_ULONG ulKeySizeInBits; + CK_ULONG ulIVSizeInBits; + CK_ULONG ulSequenceNumber; + CK_BBOOL bIsExport; + CK_WTLS_RANDOM_DATA RandomInfo; + CK_WTLS_KEY_MAT_OUT_PTR pReturnedKeyMaterial; +} CK_WTLS_KEY_MAT_PARAMS; + +typedef CK_WTLS_KEY_MAT_PARAMS CK_PTR CK_WTLS_KEY_MAT_PARAMS_PTR; + +typedef struct CK_CMS_SIG_PARAMS { + CK_OBJECT_HANDLE certificateHandle; + CK_MECHANISM_PTR pSigningMechanism; + CK_MECHANISM_PTR pDigestMechanism; + CK_UTF8CHAR_PTR pContentType; + CK_BYTE_PTR pRequestedAttributes; + CK_ULONG ulRequestedAttributesLen; + CK_BYTE_PTR pRequiredAttributes; + CK_ULONG ulRequiredAttributesLen; +} CK_CMS_SIG_PARAMS; + +typedef CK_CMS_SIG_PARAMS CK_PTR CK_CMS_SIG_PARAMS_PTR; + +typedef struct CK_KEY_DERIVATION_STRING_DATA { + CK_BYTE_PTR pData; + CK_ULONG ulLen; +} CK_KEY_DERIVATION_STRING_DATA; + +typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR \ + CK_KEY_DERIVATION_STRING_DATA_PTR; + + +/* The CK_EXTRACT_PARAMS is used for the + * CKM_EXTRACT_KEY_FROM_KEY mechanism. It specifies which bit + * of the base key should be used as the first bit of the + * derived key + */ +typedef CK_ULONG CK_EXTRACT_PARAMS; + +typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR; + +/* CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is used to + * indicate the Pseudo-Random Function (PRF) used to generate + * key bits using PKCS #5 PBKDF2. + */ +typedef CK_ULONG CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE; + +typedef CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE CK_PTR \ + CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE_PTR; + +#define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001UL +#define CKP_PKCS5_PBKD2_HMAC_GOSTR3411 0x00000002UL +#define CKP_PKCS5_PBKD2_HMAC_SHA224 0x00000003UL +#define CKP_PKCS5_PBKD2_HMAC_SHA256 0x00000004UL +#define CKP_PKCS5_PBKD2_HMAC_SHA384 0x00000005UL +#define CKP_PKCS5_PBKD2_HMAC_SHA512 0x00000006UL +#define CKP_PKCS5_PBKD2_HMAC_SHA512_224 0x00000007UL +#define CKP_PKCS5_PBKD2_HMAC_SHA512_256 0x00000008UL + +/* CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is used to indicate the + * source of the salt value when deriving a key using PKCS #5 + * PBKDF2. + */ +typedef CK_ULONG CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE; + +typedef CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE CK_PTR \ + CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE_PTR; + +/* The following salt value sources are defined in PKCS #5 v2.0. */ +#define CKZ_SALT_SPECIFIED 0x00000001UL + +/* CK_PKCS5_PBKD2_PARAMS is a structure that provides the + * parameters to the CKM_PKCS5_PBKD2 mechanism. + */ +typedef struct CK_PKCS5_PBKD2_PARAMS { + CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource; + CK_VOID_PTR pSaltSourceData; + CK_ULONG ulSaltSourceDataLen; + CK_ULONG iterations; + CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf; + CK_VOID_PTR pPrfData; + CK_ULONG ulPrfDataLen; + CK_UTF8CHAR_PTR pPassword; + CK_ULONG_PTR ulPasswordLen; +} CK_PKCS5_PBKD2_PARAMS; + +typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR; + +/* CK_PKCS5_PBKD2_PARAMS2 is a corrected version of the CK_PKCS5_PBKD2_PARAMS + * structure that provides the parameters to the CKM_PKCS5_PBKD2 mechanism + * noting that the ulPasswordLen field is a CK_ULONG and not a CK_ULONG_PTR. + */ +typedef struct CK_PKCS5_PBKD2_PARAMS2 { + CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource; + CK_VOID_PTR pSaltSourceData; + CK_ULONG ulSaltSourceDataLen; + CK_ULONG iterations; + CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf; + CK_VOID_PTR pPrfData; + CK_ULONG ulPrfDataLen; + CK_UTF8CHAR_PTR pPassword; + CK_ULONG ulPasswordLen; +} CK_PKCS5_PBKD2_PARAMS2; + +typedef CK_PKCS5_PBKD2_PARAMS2 CK_PTR CK_PKCS5_PBKD2_PARAMS2_PTR; + +typedef CK_ULONG CK_OTP_PARAM_TYPE; +typedef CK_OTP_PARAM_TYPE CK_PARAM_TYPE; /* backward compatibility */ + +typedef struct CK_OTP_PARAM { + CK_OTP_PARAM_TYPE type; + CK_VOID_PTR pValue; + CK_ULONG ulValueLen; +} CK_OTP_PARAM; + +typedef CK_OTP_PARAM CK_PTR CK_OTP_PARAM_PTR; + +typedef struct CK_OTP_PARAMS { + CK_OTP_PARAM_PTR pParams; + CK_ULONG ulCount; +} CK_OTP_PARAMS; + +typedef CK_OTP_PARAMS CK_PTR CK_OTP_PARAMS_PTR; + +typedef struct CK_OTP_SIGNATURE_INFO { + CK_OTP_PARAM_PTR pParams; + CK_ULONG ulCount; +} CK_OTP_SIGNATURE_INFO; + +typedef CK_OTP_SIGNATURE_INFO CK_PTR CK_OTP_SIGNATURE_INFO_PTR; + +#define CK_OTP_VALUE 0UL +#define CK_OTP_PIN 1UL +#define CK_OTP_CHALLENGE 2UL +#define CK_OTP_TIME 3UL +#define CK_OTP_COUNTER 4UL +#define CK_OTP_FLAGS 5UL +#define CK_OTP_OUTPUT_LENGTH 6UL +#define CK_OTP_OUTPUT_FORMAT 7UL + +#define CKF_NEXT_OTP 0x00000001UL +#define CKF_EXCLUDE_TIME 0x00000002UL +#define CKF_EXCLUDE_COUNTER 0x00000004UL +#define CKF_EXCLUDE_CHALLENGE 0x00000008UL +#define CKF_EXCLUDE_PIN 0x00000010UL +#define CKF_USER_FRIENDLY_OTP 0x00000020UL + +typedef struct CK_KIP_PARAMS { + CK_MECHANISM_PTR pMechanism; + CK_OBJECT_HANDLE hKey; + CK_BYTE_PTR pSeed; + CK_ULONG ulSeedLen; +} CK_KIP_PARAMS; + +typedef CK_KIP_PARAMS CK_PTR CK_KIP_PARAMS_PTR; + +typedef struct CK_AES_CTR_PARAMS { + CK_ULONG ulCounterBits; + CK_BYTE cb[16]; +} CK_AES_CTR_PARAMS; + +typedef CK_AES_CTR_PARAMS CK_PTR CK_AES_CTR_PARAMS_PTR; + +typedef struct CK_GCM_PARAMS { + CK_BYTE_PTR pIv; + CK_ULONG ulIvLen; + CK_ULONG ulIvBits; + CK_BYTE_PTR pAAD; + CK_ULONG ulAADLen; + CK_ULONG ulTagBits; +} CK_GCM_PARAMS; + +typedef CK_GCM_PARAMS CK_PTR CK_GCM_PARAMS_PTR; + +typedef struct CK_CCM_PARAMS { + CK_ULONG ulDataLen; + CK_BYTE_PTR pNonce; + CK_ULONG ulNonceLen; + CK_BYTE_PTR pAAD; + CK_ULONG ulAADLen; + CK_ULONG ulMACLen; +} CK_CCM_PARAMS; + +typedef CK_CCM_PARAMS CK_PTR CK_CCM_PARAMS_PTR; + +/* Deprecated. Use CK_GCM_PARAMS */ +typedef struct CK_AES_GCM_PARAMS { + CK_BYTE_PTR pIv; + CK_ULONG ulIvLen; + CK_ULONG ulIvBits; + CK_BYTE_PTR pAAD; + CK_ULONG ulAADLen; + CK_ULONG ulTagBits; +} CK_AES_GCM_PARAMS; + +typedef CK_AES_GCM_PARAMS CK_PTR CK_AES_GCM_PARAMS_PTR; + +/* Deprecated. Use CK_CCM_PARAMS */ +typedef struct CK_AES_CCM_PARAMS { + CK_ULONG ulDataLen; + CK_BYTE_PTR pNonce; + CK_ULONG ulNonceLen; + CK_BYTE_PTR pAAD; + CK_ULONG ulAADLen; + CK_ULONG ulMACLen; +} CK_AES_CCM_PARAMS; + +typedef CK_AES_CCM_PARAMS CK_PTR CK_AES_CCM_PARAMS_PTR; + +typedef struct CK_CAMELLIA_CTR_PARAMS { + CK_ULONG ulCounterBits; + CK_BYTE cb[16]; +} CK_CAMELLIA_CTR_PARAMS; + +typedef CK_CAMELLIA_CTR_PARAMS CK_PTR CK_CAMELLIA_CTR_PARAMS_PTR; + +typedef struct CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS { + CK_BYTE iv[16]; + CK_BYTE_PTR pData; + CK_ULONG length; +} CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS; + +typedef CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR \ + CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS_PTR; + +typedef struct CK_ARIA_CBC_ENCRYPT_DATA_PARAMS { + CK_BYTE iv[16]; + CK_BYTE_PTR pData; + CK_ULONG length; +} CK_ARIA_CBC_ENCRYPT_DATA_PARAMS; + +typedef CK_ARIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR \ + CK_ARIA_CBC_ENCRYPT_DATA_PARAMS_PTR; + +typedef struct CK_DSA_PARAMETER_GEN_PARAM { + CK_MECHANISM_TYPE hash; + CK_BYTE_PTR pSeed; + CK_ULONG ulSeedLen; + CK_ULONG ulIndex; +} CK_DSA_PARAMETER_GEN_PARAM; + +typedef CK_DSA_PARAMETER_GEN_PARAM CK_PTR CK_DSA_PARAMETER_GEN_PARAM_PTR; + +typedef struct CK_ECDH_AES_KEY_WRAP_PARAMS { + CK_ULONG ulAESKeyBits; + CK_EC_KDF_TYPE kdf; + CK_ULONG ulSharedDataLen; + CK_BYTE_PTR pSharedData; +} CK_ECDH_AES_KEY_WRAP_PARAMS; + +typedef CK_ECDH_AES_KEY_WRAP_PARAMS CK_PTR CK_ECDH_AES_KEY_WRAP_PARAMS_PTR; + +typedef CK_ULONG CK_JAVA_MIDP_SECURITY_DOMAIN; + +typedef CK_ULONG CK_CERTIFICATE_CATEGORY; + +typedef struct CK_RSA_AES_KEY_WRAP_PARAMS { + CK_ULONG ulAESKeyBits; + CK_RSA_PKCS_OAEP_PARAMS_PTR pOAEPParams; +} CK_RSA_AES_KEY_WRAP_PARAMS; + +typedef CK_RSA_AES_KEY_WRAP_PARAMS CK_PTR CK_RSA_AES_KEY_WRAP_PARAMS_PTR; + +typedef struct CK_TLS12_MASTER_KEY_DERIVE_PARAMS { + CK_SSL3_RANDOM_DATA RandomInfo; + CK_VERSION_PTR pVersion; + CK_MECHANISM_TYPE prfHashMechanism; +} CK_TLS12_MASTER_KEY_DERIVE_PARAMS; + +typedef CK_TLS12_MASTER_KEY_DERIVE_PARAMS CK_PTR \ + CK_TLS12_MASTER_KEY_DERIVE_PARAMS_PTR; + +typedef struct CK_TLS12_KEY_MAT_PARAMS { + CK_ULONG ulMacSizeInBits; + CK_ULONG ulKeySizeInBits; + CK_ULONG ulIVSizeInBits; + CK_BBOOL bIsExport; + CK_SSL3_RANDOM_DATA RandomInfo; + CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial; + CK_MECHANISM_TYPE prfHashMechanism; +} CK_TLS12_KEY_MAT_PARAMS; + +typedef CK_TLS12_KEY_MAT_PARAMS CK_PTR CK_TLS12_KEY_MAT_PARAMS_PTR; + +typedef struct CK_TLS_KDF_PARAMS { + CK_MECHANISM_TYPE prfMechanism; + CK_BYTE_PTR pLabel; + CK_ULONG ulLabelLength; + CK_SSL3_RANDOM_DATA RandomInfo; + CK_BYTE_PTR pContextData; + CK_ULONG ulContextDataLength; +} CK_TLS_KDF_PARAMS; + +typedef CK_TLS_KDF_PARAMS CK_PTR CK_TLS_KDF_PARAMS_PTR; + +typedef struct CK_TLS_MAC_PARAMS { + CK_MECHANISM_TYPE prfHashMechanism; + CK_ULONG ulMacLength; + CK_ULONG ulServerOrClient; +} CK_TLS_MAC_PARAMS; + +typedef CK_TLS_MAC_PARAMS CK_PTR CK_TLS_MAC_PARAMS_PTR; + +typedef struct CK_GOSTR3410_DERIVE_PARAMS { + CK_EC_KDF_TYPE kdf; + CK_BYTE_PTR pPublicData; + CK_ULONG ulPublicDataLen; + CK_BYTE_PTR pUKM; + CK_ULONG ulUKMLen; +} CK_GOSTR3410_DERIVE_PARAMS; + +typedef CK_GOSTR3410_DERIVE_PARAMS CK_PTR CK_GOSTR3410_DERIVE_PARAMS_PTR; + +typedef struct CK_GOSTR3410_KEY_WRAP_PARAMS { + CK_BYTE_PTR pWrapOID; + CK_ULONG ulWrapOIDLen; + CK_BYTE_PTR pUKM; + CK_ULONG ulUKMLen; + CK_OBJECT_HANDLE hKey; +} CK_GOSTR3410_KEY_WRAP_PARAMS; + +typedef CK_GOSTR3410_KEY_WRAP_PARAMS CK_PTR CK_GOSTR3410_KEY_WRAP_PARAMS_PTR; + +typedef struct CK_SEED_CBC_ENCRYPT_DATA_PARAMS { + CK_BYTE iv[16]; + CK_BYTE_PTR pData; + CK_ULONG length; +} CK_SEED_CBC_ENCRYPT_DATA_PARAMS; + +typedef CK_SEED_CBC_ENCRYPT_DATA_PARAMS CK_PTR \ + CK_SEED_CBC_ENCRYPT_DATA_PARAMS_PTR; + +#endif /* _PKCS11T_H_ */ + diff --git a/include/libpki/crypto/hsm/types.h b/include/libpki/crypto/hsm/types.h new file mode 100644 index 00000000..b9e74520 --- /dev/null +++ b/include/libpki/crypto/hsm/types.h @@ -0,0 +1,328 @@ +/* hsm/types.h */ + +/* Configuration options: + * + */ + + +#ifndef _LIBPKI_SYSTEM_H +#include +#endif + +#ifndef _LIBPKI_UTILS_TYPES_H +#include +#endif + +#ifndef HSM_TYPES_H +#define HSM_TYPES_H + +BEGIN_C_DECLS + +#ifndef typedef byte +typedef unsigned char byte; +#endif + +// Forward declaration for the HSM structure +typedef struct pki_config_st PKI_CONFIG; +typedef struct pki_cred_st PKI_CRED; +typedef struct pki_mem_st PKI_MEM; + +typedef struct crypto_keyparams_st CRYPTO_KEYPARAMS; +typedef struct crypto_keypair_st CRYPTO_KEYPAIR; + +/* \brief HSM Manufacturer ID Size */ +#define HSM_MANUFACTURER_ID_SIZE 32 + +/* \brief HSM Description Size */ +#define HSM_DESCRIPTION_SIZE 32 + +/* \brief HSM Slot Description Size */ +#define HSM_SLOT_DESCRIPTION_SIZE 64 + +/* \brief HSM Label Size */ +#define HSM_LABEL_SIZE 32 + +/* \brief HSM Model Size */ +#define HSM_MODEL_SIZE 16 + +/* \brief HSM Serial Number Size */ +#define HSM_SERIAL_NUMBER_SIZE 16 + +/* \brief HSM UTC Time Size */ +#define HSM_UTC_TIME_SIZE 16 + +/* \brief HSM Types */ +typedef enum { + HSM_TYPE_OTHER = 0, + HSM_TYPE_SOFTWARE, + HSM_TYPE_PKCS11 +} HSM_TYPE; + +/* \brief HSM Key Pair Handlers' Indexes */ +typedef enum hsm_keypair_handler_idx { + KEYPAIR_DRIVER_HANDLER_IDX = 0, + KEYPAIR_PRIVKEY_HANDLER_IDX, + KEYPAIR_PUBKEY_HANDLER_IDX +} HSM_KEYPAIR_HANDLER; + +/* \brief HSM Info Data Structure */ +typedef struct hsm_info_st { + + /* \brief HSM Version Major Number */ + unsigned short version_major; + + /* \brief HSM Version Minor Number */ + unsigned short version_minor; + + /* \brief HSM Manufacturer ID */ + char manufacturerID[HSM_MANUFACTURER_ID_SIZE]; + + /* \brief HSM Description */ + char description[HSM_DESCRIPTION_SIZE]; + + /* \brief HSM Library Version Major Number */ + unsigned short lib_version_major; + + /* \brief HSM Library Version Minor Number */ + unsigned short lib_version_minor; + + /* \brief HSM Fips Mode of Operation */ + int fips_mode; + +} HSM_INFO; + +/* \brief HSM Token Info Data Structure */ +typedef struct hsm_token_info_st { + + /* \brief Token Label */ + char label[HSM_LABEL_SIZE]; + + /* \brief Token Manufacturer ID */ + char manufacturerID[HSM_DESCRIPTION_SIZE]; + + /* \brief Token Model */ + char model[HSM_MODEL_SIZE]; + + /* \brief Serial Number */ + char serialNumber[HSM_SERIAL_NUMBER_SIZE]; + + /* \brief Max Supported Sessions */ + unsigned long max_sessions; + + /* \brief Current Number of Sessions */ + unsigned long curr_sessions; + + /* \brief Maximum Pin Length */ + unsigned long max_pin_len; + + /* \brief Minimum Supported Pin Length */ + unsigned long min_pin_len; + + /* \brief Public Memory Total Size */ + unsigned long memory_pub_tot; + + /* \brief Available Public Memory Size */ + unsigned long memory_pub_free; + + /* \brief Private Memory Total Size */ + unsigned long memory_priv_tot; + + /* \brief Available Private Memory Size */ + unsigned long memory_priv_free; + + /* \brief Hardware Version Major Number */ + unsigned short hw_version_major; + + /* \brief Hardware Version Minor Number */ + unsigned short hw_version_minor; + + /* \brief Firmware Version Major Number */ + unsigned short fw_version_major; + + /* \brief Firmware Version Minor Number */ + unsigned short fw_version_minor; + + /* \brief Requires Login */ + unsigned short login_required; + + /* \brief Provides Random Number Generation */ + unsigned short has_rng; + + /* \brief Provides Clock Time */ + unsigned short has_clock; + + /* \brief Token UTC Time */ + char utcTime[HSM_UTC_TIME_SIZE]; + +} HSM_TOKEN_INFO; + +/* \brief HSM Slot Info Data Structure */ +typedef struct hsm_slot_info_st { + + /* \brief Device Manufacturer ID */ + char manufacturerID[HSM_MANUFACTURER_ID_SIZE]; + + /* \brief Device Description */ + char description[HSM_SLOT_DESCRIPTION_SIZE]; + + /* \brief Hardware Version */ + unsigned short hw_version_major; + unsigned short hw_version_minor; + + /* \brief Firmware Version */ + unsigned short fw_version_major; + unsigned short fw_version_minor; + + /* \brief Is the Slot Initialized? */ + unsigned short initialized; + + /* \brief Does the Slot have a valid token? */ + unsigned short present; + + /* \brief Is the Slot removable? */ + unsigned short removable; + + /* \brief Is the Slot a hardware Slot? */ + unsigned short hardware; + + /* \brief Info for the current inserted token */ + HSM_TOKEN_INFO token_info; + +} HSM_SLOT_INFO; + +typedef struct callbacks_st { + + /* ------------- HSM Management functions --------------- */ + + /* Get Error number */ + unsigned long (*get_errno)( void ); + + /* Get Error Description */ + char * (*get_errdesc)( unsigned long err, char *str, size_t size ); + + /* HSM initialization function */ + int (*init) (struct hsm_st *driver, PKI_CONFIG *); + + /* HSM free function */ + int (*free) (struct hsm_st *driver, PKI_CONFIG *); + + /* HSM login */ + int (*login)(struct hsm_st *driver, PKI_CRED *cred); + + /* HSM logout */ + int (*logout)(struct hsm_st *driver); + + /* HSM set algor function */ + int (*sign_algor) (struct hsm_st *driver, unsigned char * oid); + + /* HSM set fips mode */ + int (*set_fips_mode) (const struct hsm_st *driver, int k); + + /* HSM gets fips operation mode */ + int (*is_fips_mode) (const struct hsm_st *driver); + + /* ----------------- Slot Management functions ----------------- */ + + /* Get the number of available Slots */ + unsigned long (*slot_num)(struct hsm_st *); + + /* Get Slot info */ + HSM_SLOT_INFO * (*slot_info_get)(unsigned long, struct hsm_st *); + + /* Free memory associated with an HSM_SLOT_INFO structure */ + void (*slot_info_free) (HSM_SLOT_INFO *, struct hsm_st *); + + /* Set the current slot */ + int (*select_slot)(unsigned long, PKI_CRED *cred, struct hsm_st *); + + /* Clear the current slot from any object present */ + int (*clear_slot)(unsigned long, PKI_CRED *cred, struct hsm_st *); + + /* -------------- Object Management functions -------------------- */ + + int (*get_objects)(PKI_STACK ** sk, PKI_TYPE type, byte * label, PKI_TYPE format, + const PKI_CRED *cred, void *driver); + + int (*add_objects)(const PKI_STACK * sk, PKI_TYPE type, byte * label, PKI_TYPE format, + const PKI_CRED * cred, void *driver); + + int (*del_objects)(PKI_TYPE type, byte * label, const PKI_CRED * cred, void *driver); + + /* ------------- Crypto functions --------------- */ + + /* \brief General Sign Function */ + int (*sign)(unsigned char * data, size_t size, unsigned char * sig, + size_t * sig_size, const char *digest_alg, CRYPTO_KEYPAIR *key); + + /* \brief General Verify Function */ + int (*verify)(unsigned char * data, size_t size, unsigned char * sig, size_t sig_size, + const char *digest_alg, CRYPTO_KEYPAIR *key); + + /* ------------- Key Management functions --------------- */ + + /* Create (new) Keypair */ + int (*keypair_new)(unsigned char * pub, size_t *pub_size, unsigned char * priv, size_t priv_size, + const CRYPTO_KEYPARAMS * params, const char * label, void * driver); + + /* Free memory associated with a keypair */ + void (*keypair_free)(CRYPTO_KEYPAIR *); + + /* Key Wrapping function */ + int (*key_wrap)(unsigned char * out, size_t *out_len, CRYPTO_KEYPAIR * key, const PKI_CRED * cred); + + /* Key Unwrapping function */ + int (*key_unwrap)(byte * wrapped_key, size_t wrapped_key_len, byte * label, + const PKI_CRED *, void * driver); + +} HSM_CALLBACKS; + +/* Structure for HSM definition */ +typedef struct hsm_st { + + /* ID of the driver - this is used to identify the driver + to be used, e.g., 'id://LunaCA' for loading the ENGINE + LunaCA extension */ + char * id_label; + + /* Version of the token */ + int version; + + /* Description of the HSM */ + char *description; + + /* Manufacturer */ + char *manufacturer; + + /* Pointer to the HSM config file and parsed structure*/ + PKI_CONFIG *config; + + /* One of PKI_HSM_TYPE value */ + HSM_TYPE type; + + /* Pointer to the internal structure for drivers */ + void *driver; + + /* Pointer to internal session handler */ + void *session; + + /* Credential for the HSM - usually used for the SO */ + PKI_CRED *cred; + + /* Is Logged In */ + uint8_t isLoggedIn; + + /* Is Cred Set */ + uint8_t isCredSet; + + /* Login Requirements */ + const uint8_t isLoginRequired; + + /* HSM Callbacks */ + const HSM_CALLBACKS *callbacks; + +} HSM; + +END_C_DECLS + +#endif + diff --git a/include/libpki/crypto/hsm/wolfssl/data_st.h b/include/libpki/crypto/hsm/wolfssl/data_st.h new file mode 100644 index 00000000..0d57f982 --- /dev/null +++ b/include/libpki/crypto/hsm/wolfssl/data_st.h @@ -0,0 +1,19 @@ +/* OpenCA libpki package +* (c) 2000-2006 by Massimiliano Pala and OpenCA Group +* All Rights Reserved +* +* =================================================================== +* Released under OpenCA LICENSE +*/ + +#ifndef _LIBPKI_HEADER_OPENSSL_DATA_ST_H +#define _LIBPKI_HEADER_OPENSSL_DATA_ST_H + +#include + +typedef struct pki_openssl_store_st { + void *store_ptr; +} PKI_OPENSSL_STORE; + +/* End of _LIBPKI_HEADER_OPENSSL_DATA_ST_H */ +#endif diff --git a/include/libpki/crypto/hsm/wolfssl/wolfssl_hsm.h b/include/libpki/crypto/hsm/wolfssl/wolfssl_hsm.h new file mode 100644 index 00000000..326f25d6 --- /dev/null +++ b/include/libpki/crypto/hsm/wolfssl/wolfssl_hsm.h @@ -0,0 +1,85 @@ +/* libpki/drivers/openssl/openssl_hsm.h */ + +#ifndef _LIBPKI_HSM_OPENSSL_H +#define _LIBPKI_HSM_OPENSSL_H + +#include + +#include + +#ifndef _LIBPKI_COMPAT_H +#include +#endif + +#ifndef _LIBPKI_HSM_ST_H +#include +#endif + +#ifndef _LIBPKI_OPENSSL_HSM_CB_H +#include +#endif + +#ifndef _LIBPKI_HEADERS_OPENSSL_PKEY_H +#include +#endif + +#ifndef _LIBPKI_ERRORS_H +#include +#endif + +#ifndef _LIBPKI_INIT_H +#include +#endif + +#ifndef _LIBPKI_PKI_X509_H +#include +#endif + +#ifndef _LIBPKI_LOG_H +#include +#endif + +#ifndef _LIBPKI_PKI_ID_H +#include +#endif + +#include + +BEGIN_C_DECLS + + // ==================== + // Functions Prototypes + // ==================== + +unsigned long HSM_OPENSSL_get_errno ( void ); +char * HSM_OPENSSL_get_errdesc ( unsigned long err, char *str, size_t size ); + +HSM * HSM_OPENSSL_new( PKI_CONFIG *conf ); +const HSM * HSM_OPENSSL_get_default( void ); + +int HSM_OPENSSL_free ( HSM *driver, PKI_CONFIG *conf ); +int HSM_OPENSSL_init ( HSM *driver, PKI_CONFIG *conf ); + +int HSM_OPENSSL_set_fips_mode(const HSM *driver, int k); +int HSM_OPENSSL_is_fips_mode(const HSM *driver); + +/* ---------------------- Sign/Verify functions ----------------------- */ + +/* + * int HSM_OPENSSL_sign ( PKI_MEM *der, PKI_X509_KEYPAIR *key, + * PKI_DIGEST_ALG *al); + */ + +PKI_MEM * HSM_OPENSSL_sign ( PKI_MEM *der, PKI_DIGEST_ALG *digest, + PKI_X509_KEYPAIR *key ); + +/* +int HSM_OPENSSL_verify ( PKI_X509 *x, PKI_X509_KEYPAIR *key ); +*/ + +/* ---------------------- OPENSSL Slot Management Functions ---------------- */ +HSM_SLOT_INFO * HSM_OPENSSL_SLOT_INFO_get ( unsigned long num, HSM *hsm_void); + +END_C_DECLS + +#endif diff --git a/include/libpki/crypto/hsm/wolfssl/wolfssl_hsm_cb.h b/include/libpki/crypto/hsm/wolfssl/wolfssl_hsm_cb.h new file mode 100644 index 00000000..16022fef --- /dev/null +++ b/include/libpki/crypto/hsm/wolfssl/wolfssl_hsm_cb.h @@ -0,0 +1,9 @@ +/* src/libpki/drivers/openssl_hsm_cb.h */ + +#ifndef _LIBPKI_OPENSSL_HSM_CB_H +#define _LIBPKI_OPENSSL_HSM_CB_H + +const PKI_X509_CALLBACKS *HSM_OPENSSL_X509_get_cb ( PKI_DATATYPE type ); + +#endif + diff --git a/include/libpki/crypto/hsm/wolfssl/wolfssl_hsm_obj.h b/include/libpki/crypto/hsm/wolfssl/wolfssl_hsm_obj.h new file mode 100644 index 00000000..07ea6ea9 --- /dev/null +++ b/include/libpki/crypto/hsm/wolfssl/wolfssl_hsm_obj.h @@ -0,0 +1,23 @@ +/* ENGINE Object Management Functions */ + +#ifndef _LIBPKI_HEADERS_OPENSSL_OBJSK_H +#define _LIBPKI_HEADERS_OPENSSL_OBJSK_H + +/* ------------------- Retrieves a stack of objects ------------------- */ +PKI_STACK * HSM_OPENSSL_OBJSK_get_url ( PKI_DATATYPE type, URL *url, + PKI_CRED *cred, void *hsm ); + +int HSM_OPENSSL_OBJSK_add_url ( PKI_STACK *sk, PKI_DATATYPE type, URL *url, + PKI_CRED *cred, void *hsm ); + +int HSM_OPENSSL_OBJSK_del_url ( PKI_STACK *sk, PKI_DATATYPE type, URL *url, + PKI_CRED *cred, void *hsm); + +PKI_MEM_STACK * HSM_OPENSSL_OBJSK_wrap_url ( PKI_STACK *, PKI_DATATYPE type, + URL *url, PKI_CRED *cred, void *hsm); + +/* --------------------- Internal Functions --------------------------- */ +PKI_X509_KEYPAIR_STACK * HSM_OPENSSL_KEYPAIR_get_url (URL *url, PKI_CRED *cred, + HSM *hsm); +#endif + diff --git a/include/libpki/crypto/hsm/wolfssl/wolfssl_hsm_pkey.h b/include/libpki/crypto/hsm/wolfssl/wolfssl_hsm_pkey.h new file mode 100644 index 00000000..1afdcd5f --- /dev/null +++ b/include/libpki/crypto/hsm/wolfssl/wolfssl_hsm_pkey.h @@ -0,0 +1,20 @@ +/* ENGINE Object Management Functions */ + +#ifndef _LIBPKI_HEADERS_OPENSSL_PKEY_H +#define _LIBPKI_HEADERS_OPENSSL_PKEY_H + + +/* ------------------- Keypair Functions --------------------- */ + +PKI_X509_KEYPAIR *HSM_OPENSSL_X509_KEYPAIR_new( PKI_KEYPARAMS *pk, + URL *url, PKI_CRED *cred, HSM *driver ); +void HSM_OPENSSL_X509_KEYPAIR_free ( PKI_X509_KEYPAIR *pkey ); + +int OPENSSL_HSM_write_bio_PrivateKey (BIO *bp, EVP_PKEY *x, + const EVP_CIPHER *enc, unsigned char *kstr, int klen, + pem_password_cb *cb, void *u); + +EVP_PKEY *OPENSSL_HSM_KEYPAIR_dup(EVP_PKEY *kVal); + +#endif + diff --git a/include/libpki/crypto/types.h b/include/libpki/crypto/types.h new file mode 100644 index 00000000..5eb74fcd --- /dev/null +++ b/include/libpki/crypto/types.h @@ -0,0 +1,239 @@ +/* crypto_types.h */ + +#ifndef _LIBPKI_SYSTEM_H +# include +#endif + +#ifdef ENABLE_OQS +# include +#endif + +#ifdef _LIBPKI_UTILS_TYPES_H +#include +#endif + +#ifndef _LIBPKI_HSM_TYPES_H +#include +#endif + +#ifndef CRYTO_NO_OPENSSL +#ifndef _LIBPKI_OPENSSL_TYPES_H +#include +#endif +#endif + +#ifndef _LIBPKI_CRYPTO_TYPES_H +#define _LIBPKI_CRYPTO_TYPES_H + +BEGIN_C_DECLS + +#define CRYPTO_BUFFER_TINY_SZ 128 +#define CRYPTO_BUFFER_SMALL_SZ 1024 +#define CRYPTO_BUFFER_MEDIUM_SZ 2048 +#define CRYPTO_BUFFER_LARGE_SZ 8192 +#define CRYPTO_BUFFER_DEF_SZ CRYPTO_BUFFER_MEDIUM_SZ +#define CRYPTO_BUFFER_MAX_SZ CRYPTO_BUFFER_LARGE_SZ + +typedef enum c_key_min_enum { + CRYPTO_RSA_KEY_MIN_SIZE = 1024, + CRYPTO_DSA_KEY_MIN_SIZE = 2048, + CRYPTO_EC_KEY_MIN_SIZE = 256, +} CRYPTO_MIN_SZ; + +typedef enum c_key_default_enum { + CRYPTO_RSA_DEFAULT_SZ = 2048, + CRYPTO_DSA_DEFAULT_SZ = 2048, + CRYPTO_EC_DEFAULT_SZ = 256 +} CRYPTO_DEFAULT_SZ; + +typedef enum crypto_type_enum { + /* Signature - Traditional */ + CRYPTO_TYPE_RSA = 1, + CRYPTO_TYPE_RSAPSS, + CRYPTO_TYPE_ECDSA, + CRYPTO_TYPE_ED25519, + CRYPTO_TYPE_ED448, + /* Signature - quantum-safe */ + CRYPTO_TYPE_MLDSA44, + CRYPTO_TYPE_MLDSA65, + CRYPTO_TYPE_MLDSA87, + /* Signature - Composite */ + CRYPTO_TYPE_MLDSA44_P256, + CRYPTO_TYPE_MLDSA44_ED25519, + /* Key Exchange - quantum-safe */ + CRYPTO_TYPE_MLKEM512, + CRYPTO_TYPE_MLKEM768, + CRYPTO_TYPE_MLKEM1024, + /* Key Exchange - Composite */ + CRYPTO_TYPE_MLKEM768_P256, + CRYPTO_TYPE_MLKEM768_CURVE25519, + CRYPTO_TYPE_MLKEM1024_CURVE448, + /* Hash Types */ + CRYPTO_TYPE_SHA1, + CRYPTO_TYPE_SHA224, + CRYPTO_TYPE_SHA256, + CRYPTO_TYPE_SHA384, + CRYPTO_TYPE_SHA512, + CRYPTO_TYPE_SHA512_224, + CRYPTO_TYPE_SHA512_256, + CRYPTO_TYPE_SHA3_224, + CRYPTO_TYPE_SHA3_256, + CRYPTO_TYPE_SHA3_384, + CRYPTO_TYPE_SHA3_512, + CRYPTO_TYPE_SHAKE128, + CRYPTO_TYPE_SHAKE256, + /* HMAC */ + CRYPTO_TYPE_HMAC_SHA1, + CRYPTO_TYPE_HMAC_SHA224, + CRYPTO_TYPE_HMAC_SHA256, + CRYPTO_TYPE_HMAC_SHA384, + CRYPTO_TYPE_HMAC_SHA512, + CRYPTO_TYPE_HMAC_SHA512_224, + CRYPTO_TYPE_HMAC_SHA512_256, + CRYPTO_TYPE_HMAC_SHA3_224, + CRYPTO_TYPE_HMAC_SHA3_256, + CRYPTO_TYPE_HMAC_SHA3_384, + CRYPTO_TYPE_HMAC_SHA3_512, + CRYPTO_TYPE_HMAC_SHAKE128, + CRYPTO_TYPE_HMAC_SHAKE256, + + /* Password Based Encryption */ + CRYPTO_TYPE_PBKDF2, + CRYPTO_TYPE_PKCS5_PBES2, + CRYPTO_TYPE_PKCS5_PBKDF2, + + /* Symmetric Encryption */ + CRYPTO_TYPE_AES128, + CRYPTO_TYPE_AES192, + CRYPTO_TYPE_AES256, + CRYPTO_TYPE_AES128_GCM, + CRYPTO_TYPE_AES192_GCM, + CRYPTO_TYPE_AES256_GCM, + CRYPTO_TYPE_AES128_CCM, + CRYPTO_TYPE_AES192_CCM, + CRYPTO_TYPE_AES256_CCM, + CRYPTO_TYPE_AES128_CFB, + CRYPTO_TYPE_AES192_CFB, + CRYPTO_TYPE_AES256_CFB, + CRYPTO_TYPE_AES128_OFB, + CRYPTO_TYPE_AES192_OFB, + CRYPTO_TYPE_AES256_OFB, + CRYPTO_TYPE_AES128_CTR, + CRYPTO_TYPE_AES192_CTR, + CRYPTO_TYPE_AES256_CTR, + CRYPTO_TYPE_AES128_CBC, + CRYPTO_TYPE_AES192_CBC, + CRYPTO_TYPE_AES256_CBC, + CRYPTO_TYPE_AES128_XTS, + CRYPTO_TYPE_AES256_XTS, + + /* Symmetric Encryption - Quantum Safe */ + CRYPTO_TYPE_KYBER512, + CRYPTO_TYPE_KYBER768, + CRYPTO_TYPE_KYBER1024, + + /* Symmetric Encryption - Composite */ + +} CRYPTO_TYPE; + +typedef struct c_keyparams_st { + + int pkey_type; + int is_postquantum; + int is_deprecated; + +#ifndef CRYPTO_NO_RSA + struct { + int exponent; + int bits; + } rsa; + + struct { + int exponent; + int bits; + int mfg1; + } rsapss; +#endif + +#ifndef CRYPTO_NO_EDDSA + struct { + const char * curve; + } eddsa; +#endif + +#ifndef CRYTPO_NO_DSA + // DSA scheme parameters + struct { + int bits; + } dsa; +#endif + +#ifndef CRYPTO_NO_ECDSA + struct { + const char * curve; + CRYPTO_EC_FORM form; + int asn1flags; + } ec; +#endif + +#if defined(ENABLE_OQS) || defined(ENABLE_OQSPROV) + struct { + const char * alg; + } oqs; +#endif // ENABLE_OQS + +#ifdef ENABLE_COMPOSITE + struct { + const char * alg; + int k_of_n; + } comp; +#endif + +} CRYPTO_KEYPARAMS; + +typedef struct c_keypair_st { + CRYPTO_TYPE type; + CRYPTO_KEYPARAMS params; + void * crypto_lib_value; +} CRYPTO_KEYPAIR; + +typedef struct c_pw_cb_st { + const void *password; + const char *prompt_info; +} CRYPRO_PW_CB_DATA; + +typedef struct c_buffer_tiny_st { + size_t size; + byte data[CRYPTO_BUFFER_TINY_SZ]; +} CRYPTO_BUFFER_TINY; + +typedef struct c_buffer_small_st { + size_t size; + byte data[CRYPTO_BUFFER_SMALL_SZ]; +} CRYPTO_BUFFER_SMALL; + +typedef struct c_buffer_medium_st { + size_t size; + byte data[CRYPTO_BUFFER_MEDIUM_SZ]; +} CRYPTO_BUFFER_MEDIUM; + +typedef struct c_buffer_large_st { + size_t size; + byte data[CRYPTO_BUFFER_LARGE_SZ]; +} CRYPTO_BUFFER_LARGE; + +typedef struct c_digest_st { + CRYPTO_TYPE type; + CRYPTO_BUFFER_TINY digest; +} CRYPTO_DIGEST; + +typedef struct crypto_hmac_st { + // Digest Algoritm to use. Default is SHA-1 + CRYPTO_TYPE type; + CRYPTO_BUFFER_TINY key; +} CRYPTO_HMAC; + +END_C_DECLS + +/* End of _LIBPKI_HEADER_DATA_ST_H */ +#endif diff --git a/include/libpki/libconf/compat.h b/include/libpki/libconf/compat.h new file mode 100644 index 00000000..13b77b03 --- /dev/null +++ b/include/libpki/libconf/compat.h @@ -0,0 +1,48 @@ +/* OpenCA libpki package +* (c) 2000-2007 by Massimiliano Pala and OpenCA Group +* All Rights Reserved +* +* =================================================================== +* Released under OpenCA LICENSE +*/ + +#ifndef _LIBPKI_COMPAT_H +#define _LIBPKI_COMPAT_H + +// Basic Definitions for return codes +#define PKI_ERR 0 +#define PKI_OK 1 + +/* BEGIN_C_DECLS should be used at the beginning of your declarations, +so that C++ compilers don't mangle their names. Use END_C_DECLS at +the end of C declarations. */ +#undef BEGIN_C_DECLS +#undef END_C_DECLS +#ifdef __cplusplus + # define BEGIN_C_DECLS extern "C" { + # define END_C_DECLS } +#else + # define BEGIN_C_DECLS /* empty */ + # define END_C_DECLS /* empty */ +#endif + +/* PARAMS is a macro used to wrap function prototypes, so that +compilers that don't understand ANSI C prototypes still work, +and ANSI C compilers can issue warnings about type mismatches. */ +#undef PARAMS +#if defined (__STDC__) || defined (_AIX) \ + || (defined (__mips) && defined (_SYSTYPE_SVR4)) \ + || defined(WIN32) || defined(__cplusplus) + # define PARAMS(protos) protos +#else + # define PARAMS(protos) () +#endif + +/* This is to enable support for -fsanitize=address extra checks */ +#if defined(__clang__) || defined (__GNUC__) +# define ATTRIBUTE_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address)) +#else +# define ATTRIBUTE_NO_SANITIZE_ADDRESS +#endif + +#endif // End of _LIBPKI_COMPAT_H diff --git a/include/libpki/libconf/defines.h b/include/libpki/libconf/defines.h new file mode 100644 index 00000000..3a8aa2cf --- /dev/null +++ b/include/libpki/libconf/defines.h @@ -0,0 +1,214 @@ +/* src/libpki/config.h.in. Generated from configure.ac by autoheader. */ + +/* Forces 32bits builds */ +#undef ENABLE_ARCH_32 + +/* Forces 64bits builds */ +#undef ENABLE_ARCH_64 + +/* Composite Crypto Native OpenSSL Support */ +#undef ENABLE_COMPOSITE + +/* ECC Support for OpenSSL */ +#undef ENABLE_ECDSA + +/* SUN CMS */ +#undef ENABLE_KMF + +/* OPENSSL */ +#undef ENABLE_OPENSSL + +/* Open Quantum Safe Library */ +#undef ENABLE_OQS + +/* Open Quantum Safe Library */ +#undef ENABLE_OQSPROV + +/* Define to 1 if you have the `bzero' function. */ +#undef HAVE_BZERO + +/* Calloc in C library */ +#undef HAVE_CALLOC + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* ENGINE */ +#undef HAVE_ENGINE + +/* Define to 1 if you have the `fork' function. */ +#undef HAVE_FORK + +/* GCC pragma ignored */ +#undef HAVE_GCC_PRAGMA_IGNORED + +/* GCC pragma pop */ +#undef HAVE_GCC_PRAGMA_POP + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* HAVE LDAP */ +#undef HAVE_LDAP + +/* PTHREAD Library */ +#undef HAVE_LIBPTHREAD + +/* DNS Library */ +#undef HAVE_LIBRESOLV + +/* Define to 1 if your system has a GNU libc compatible `malloc' function, and + to 0 otherwise. */ +#undef HAVE_MALLOC + +/* Define to 1 if you have the `memset' function. */ +#undef HAVE_MEMSET + +/* test "${enablemysql}" = "yes" */ +#undef HAVE_MYSQL + +/* test "${enablepg}" = "yes" */ +#undef HAVE_PG + +/* HAVE_PTHREAD_RWLOCK */ +#undef HAVE_PTHREAD_RWLOCK + +/* Define to 1 if you have the `setenv' function. */ +#undef HAVE_SETENV + +/* Define to 1 if you have the `socket' function. */ +#undef HAVE_SOCKET + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDIO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strcasecmp' function. */ +#undef HAVE_STRCASECMP + +/* Define to 1 if you have the `strchr' function. */ +#undef HAVE_STRCHR + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strrchr' function. */ +#undef HAVE_STRRCHR + +/* Define to 1 if you have the `strstr' function. */ +#undef HAVE_STRSTR + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYSLOG_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SELECT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SOCKET_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have that is POSIX.1 compatible. */ +#undef HAVE_SYS_WAIT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the `vfork' function. */ +#undef HAVE_VFORK + +/* Define to 1 if you have the header file. */ +#undef HAVE_VFORK_H + +/* Define to 1 if `fork' works. */ +#undef HAVE_WORKING_FORK + +/* Define to 1 if `vfork' works. */ +#undef HAVE_WORKING_VFORK + +/* LIBXML2 */ +#undef HAVE_XML2 + +/* HAVE OPENLDAP */ +#undef LDAP_VENDOR_OPENLDAP + +/* HAVE SUN LDAP */ +#undef LDAP_VENDOR_SUN + +/* BSD */ +#undef LIBPKI_TARGET_BSD + +/* HP-UX */ +#undef LIBPKI_TARGET_HPUX + +/* IPHONE */ +#undef LIBPKI_TARGET_IPHONE + +/* Linux */ +#undef LIBPKI_TARGET_LINUX + +/* OSX */ +#undef LIBPKI_TARGET_OSX + +/* Solaris */ +#undef LIBPKI_TARGET_SOLARIS + +/* Define to the sub-directory where libtool stores uninstalled libraries. */ +#undef LT_OBJDIR + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if all of the C90 standard headers exist (not just the ones + required in a freestanding environment). This macro is provided for + backward compatibility; new code need not use it. */ +#undef STDC_HEADERS + +/* Define to 1 if your declares `struct tm'. */ +#undef TM_IN_SYS_TIME + +/* Version number of package */ +#undef VERSION + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to rpl_malloc if the replacement function should be used. */ +#undef malloc + +/* Define as a signed integer type capable of holding a process identifier. */ +#undef pid_t + +/* Define as `fork' if `vfork' does not work. */ +#undef vfork diff --git a/include/libpki/libconf/defines.h.in b/include/libpki/libconf/defines.h.in new file mode 100644 index 00000000..3a8aa2cf --- /dev/null +++ b/include/libpki/libconf/defines.h.in @@ -0,0 +1,214 @@ +/* src/libpki/config.h.in. Generated from configure.ac by autoheader. */ + +/* Forces 32bits builds */ +#undef ENABLE_ARCH_32 + +/* Forces 64bits builds */ +#undef ENABLE_ARCH_64 + +/* Composite Crypto Native OpenSSL Support */ +#undef ENABLE_COMPOSITE + +/* ECC Support for OpenSSL */ +#undef ENABLE_ECDSA + +/* SUN CMS */ +#undef ENABLE_KMF + +/* OPENSSL */ +#undef ENABLE_OPENSSL + +/* Open Quantum Safe Library */ +#undef ENABLE_OQS + +/* Open Quantum Safe Library */ +#undef ENABLE_OQSPROV + +/* Define to 1 if you have the `bzero' function. */ +#undef HAVE_BZERO + +/* Calloc in C library */ +#undef HAVE_CALLOC + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* ENGINE */ +#undef HAVE_ENGINE + +/* Define to 1 if you have the `fork' function. */ +#undef HAVE_FORK + +/* GCC pragma ignored */ +#undef HAVE_GCC_PRAGMA_IGNORED + +/* GCC pragma pop */ +#undef HAVE_GCC_PRAGMA_POP + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* HAVE LDAP */ +#undef HAVE_LDAP + +/* PTHREAD Library */ +#undef HAVE_LIBPTHREAD + +/* DNS Library */ +#undef HAVE_LIBRESOLV + +/* Define to 1 if your system has a GNU libc compatible `malloc' function, and + to 0 otherwise. */ +#undef HAVE_MALLOC + +/* Define to 1 if you have the `memset' function. */ +#undef HAVE_MEMSET + +/* test "${enablemysql}" = "yes" */ +#undef HAVE_MYSQL + +/* test "${enablepg}" = "yes" */ +#undef HAVE_PG + +/* HAVE_PTHREAD_RWLOCK */ +#undef HAVE_PTHREAD_RWLOCK + +/* Define to 1 if you have the `setenv' function. */ +#undef HAVE_SETENV + +/* Define to 1 if you have the `socket' function. */ +#undef HAVE_SOCKET + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDIO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strcasecmp' function. */ +#undef HAVE_STRCASECMP + +/* Define to 1 if you have the `strchr' function. */ +#undef HAVE_STRCHR + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strrchr' function. */ +#undef HAVE_STRRCHR + +/* Define to 1 if you have the `strstr' function. */ +#undef HAVE_STRSTR + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYSLOG_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SELECT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SOCKET_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have that is POSIX.1 compatible. */ +#undef HAVE_SYS_WAIT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the `vfork' function. */ +#undef HAVE_VFORK + +/* Define to 1 if you have the header file. */ +#undef HAVE_VFORK_H + +/* Define to 1 if `fork' works. */ +#undef HAVE_WORKING_FORK + +/* Define to 1 if `vfork' works. */ +#undef HAVE_WORKING_VFORK + +/* LIBXML2 */ +#undef HAVE_XML2 + +/* HAVE OPENLDAP */ +#undef LDAP_VENDOR_OPENLDAP + +/* HAVE SUN LDAP */ +#undef LDAP_VENDOR_SUN + +/* BSD */ +#undef LIBPKI_TARGET_BSD + +/* HP-UX */ +#undef LIBPKI_TARGET_HPUX + +/* IPHONE */ +#undef LIBPKI_TARGET_IPHONE + +/* Linux */ +#undef LIBPKI_TARGET_LINUX + +/* OSX */ +#undef LIBPKI_TARGET_OSX + +/* Solaris */ +#undef LIBPKI_TARGET_SOLARIS + +/* Define to the sub-directory where libtool stores uninstalled libraries. */ +#undef LT_OBJDIR + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if all of the C90 standard headers exist (not just the ones + required in a freestanding environment). This macro is provided for + backward compatibility; new code need not use it. */ +#undef STDC_HEADERS + +/* Define to 1 if your declares `struct tm'. */ +#undef TM_IN_SYS_TIME + +/* Version number of package */ +#undef VERSION + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to rpl_malloc if the replacement function should be used. */ +#undef malloc + +/* Define as a signed integer type capable of holding a process identifier. */ +#undef pid_t + +/* Define as `fork' if `vfork' does not work. */ +#undef vfork diff --git a/include/libpki/libconf/features.h b/include/libpki/libconf/features.h new file mode 100644 index 00000000..f12e6e08 --- /dev/null +++ b/include/libpki/libconf/features.h @@ -0,0 +1,20 @@ + +#ifndef _LIBPKI_FEATURES_H +#define _LIBPKI_FEATURES_H + +/* ECC Support for OpenSSL */ +#undef ENABLE_ECDSA + +/* Open Quantum Safe Library */ +#undef ENABLE_OQS + +/* Open Quantum Safe Library */ +#undef ENABLE_OQSPROV + +/* Composite Crypto Native OpenSSL Support */ +#undef ENABLE_COMPOSITE + +/* Combined/Alt Crypto Native OpenSSL Support */ +#undef ENABLE_COMBINED + +#endif // End of _LIBPKI_FEATURES_H \ No newline at end of file diff --git a/include/libpki/libconf/features.h.in b/include/libpki/libconf/features.h.in new file mode 100644 index 00000000..0b5854bd --- /dev/null +++ b/include/libpki/libconf/features.h.in @@ -0,0 +1,21 @@ +/* features.h.in - enabled features definitions */ + +#ifndef _LIBPKI_FEATURES_H +#define _LIBPKI_FEATURES_H + +/* ECC Support for OpenSSL */ +#undef ENABLE_ECDSA + +/* Open Quantum Safe Library */ +#undef ENABLE_OQS + +/* Open Quantum Safe Library */ +#undef ENABLE_OQSPROV + +/* Composite Crypto Native OpenSSL Support */ +#undef ENABLE_COMPOSITE + +/* Combined/Alt Crypto Native OpenSSL Support */ +#undef ENABLE_COMBINED + +#endif // End of _LIBPKI_FEATURES_H \ No newline at end of file diff --git a/include/libpki/libconf/system.h b/include/libpki/libconf/system.h new file mode 100644 index 00000000..9b4a81f2 --- /dev/null +++ b/include/libpki/libconf/system.h @@ -0,0 +1,362 @@ +/* libconf/system.h - LibPKI operating system layer */ + +#ifndef _LIBPKI_SYSTEM_H +#define _LIBPKI_SYSTEM_H + +#ifdef __LIB_BUILD__ +#include +#endif + +#ifndef _LIBPKI_COMPAT_H +#include +#endif + +#ifndef _LIBPKI_FEATURES_H +#include +#endif + +#ifndef _LIBPKI_VERSION_H +#include +#endif + +#ifndef _LIBPKI_CORE_TYPES_H +#include +#endif + +# include +# include +# include +# include + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#define __XOPEN_OR_POSIX +#include +#undef __XOPEN_OR_POSIX + +#include +#include + +#ifdef LIBPKI_TARGET_SOLARIS +#include +#endif + +#ifndef _SYS_UTSNAME_H +#include +#endif + +#if defined (__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED) + /* Ok, Semafores are correctly supported */ +#elif defined (_SYS_SEM_H_) + /* OpenBSD is not a GNU_LIBRARY but knows semaphores */ +#else + /* We should define here the structure */ + union semun { + int val; /* value for SETVAL */ + struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */ + unsigned short *array; /* array for GETALL, SETALL */ + /* Linux specific part: */ + struct seminfo *__buf; /* buffer for IPC_INFO */ + }; + +#endif + +// ---------------------- ENDIANNESS defines ---------------------- + +#define LIBPKI_LITTLE_ENDIAN 1 +#define LIBPKI_BIG_ENDIAN 2 + +# ifdef __BYTE_ORDER +# if __BYTE_ORDER == __LITTLE_ENDIAN +# define LIBPKI_ENDIANNESS LIBPKI_LITTLE_ENDIAN +# else +# if __BYTE_ORDER == __BIG_ENDIAN +# define LIBPKI_ENDIANNESS LIBPKI_BIG_ENDIAN +# endif +# endif +# endif /* __BYTE_ORDER */ + +# ifdef BYTE_ORDER +# if BYTE_ORDER == LITTLE_ENDIAN +# define LIBPKI_ENDIANNESS LIBPKI_LITTLE_ENDIAN +# else +# if BYTE_ORDER == BIG_ENDIAN +# define LIBPKI_ENDIANNESS LIBPKI_BIG_ENDIAN +# endif +# endif +# endif /* _DARWIN_BYTE_ORDER */ + +# ifndef LIBPKI_ENDIANNESS +# if defined (i386) || defined (__i386__) || defined (_M_IX86) || \ + defined (vax) || defined (__alpha) +# define LIBPKI_ENDIANNESS LIBPKI_LITTLE_ENDIAN +# endif +# endif + +// ---------------------- OS and ARCH defines ---------------------- +// Bits +#define LIBPKI_OS32 1 +#define LIBPKI_OS64 2 +// Types of OSes +#define LIBPKI_OS_POSIX 4 +#define LIBPKI_OS_WIN 8 +// Specific OSes +#define LIBPKI_OS_BSD 16 +#define LIBPKI_OS_LINUX 32 +#define LIBPKI_OS_SOLARIS 64 +#define LIBPKI_OS_MACOS 128 +// Win +#define LIBPKI_OS_WINCE 256 +#define LIBPKI_OS_WINNT 512 +#define LIBPKI_OS_WINXP 1024 +#define LIBPKI_OS_WIN2003 2048 +#define LIBPKI_OS_VISTA 4096 +#define LIBPKI_OS_WIN7 8192 +// Mobile Env +#define LIBPKI_OS_IPHONE 16384 +#define LIBPKI_OS_SYMBIAN 32768 + + +# if defined(_WINCE) || defined(WINCE) +// Windows CE (WINCE and _WIN32 defined) +# define LIBPKI_WIN 1 +# define LIBPKI_OS_BITS LIBPKI_OS32 +# define LIBPKI_OS_CLASS LIBPKI_OS_WIN +# define LIBPKI_OS_VENDOR LIBPKI_OS_WINCE +# elif defined(_WIN64) || defined(WIN64) +// 64 bit Windows (_WIN64 and _WIN32 defined) +# define LIBPKI_WIN 1 +# define LIBPKI_OS_BITS LIBPKI_OS64 +# define LIBPKI_OS_CLASS LIBPKI_OS_WIN +# elif defined(_WIN32) || defined(WIN32) || defined(__WIN32_) || \ + defined (__WINDOW__) +// 32 bit Windows (only _WIN32 defined) +# define LIBPKI_WIN 1 +# define LIBPKI_OS_BITS LIBPKI_OS32 +# define LIBPKI_OS_CLASS LIBPKI_OS_WIN +# elif defined(__linux) || defined(linux) +// Generic Linux +# define LIBPKI_LINUX 1 +# define LIBPKI_UNIX 1 +# define LIBPKI_OS_VENDOR LIBPKI_OS_LINUX +# define LIBPKI_OS_CLASS LIBPKI_OS_POSIX +# elif defined(macintosh) || defined(Macintosh) || defined(MACOS) +// MACOS +# define LIBPKI_MACOS 1 +# define LIBPKI_UNIX 1 +# define LIBPKI_OS_CLASS LIBPKI_OS_POSIX +# define LIBPKI_OS_VENDOR LIBPKI_OS_MACOS +# elif defined(__bsdi__) || defined (BSD) +// BSD +# define LIBPKI_BSD 1 +# define LIBPKI_UNIX 1 +# define LIBPKI_OS_VENDOR LIBPKI_OS_BSD +# define LIBPKI_OS_CLASS LIBPKI_OS_POSIX +# elif defined(__IPHONE_OS) +// iPHONE +# define LIBPKI_IPHONE 1 +# define LIBPKI_UNIX 1 +# define LIBPKI_OS_BITS LIBPKI_OS64 +# define LIBPKI_OS_VENDOR LIBPKI_OS_IPHONE +# define LIBPKI_OS_CLASS LIBPKI_OS_POSIX +# elif defined(__sun) || defined(sun) +/* +# if defined(__SVR4) || defined(__svr4__) +// SOLARIS +*/ +# define LIBPKI_SOLARIS 1 +# define LIBPKI_UNIX 1 +# define LIBPKI_OS_CLASS LIBPKI_OS_POSIX +# define LIBPKI_OS_VENDOR LIBPKI_OS_SOLARIS +/* +# else +// SUN +#define LIBPKI_OS_CLASS LIBPKI_OS_POSIX +#define LIBPKI_OS_VENDOR LIBPKI_OS_SOLARIS +# endif +*/ +# elif defined(__SYMBIAN32__) +// SYMBIAN +# define LIBPKI_SYMBIAN 1 +# define LIBPKI_UNIX 1 +# define LIBPKI_OS_CLASS LIBPKI_OS_POSIX +# define LIBPKI_OS_VENDOR LIBPKI_OS_SYMBIAN +# endif + +# if (LIBPKI_OS_CLASS == LIBPKI_OS_WIN) +# if (_WIN32_WINNT == 0x500) +// Windows 2000 +# define LIBPKI_OS_VENDOR LIBPKI_OS_WINNT +# elif (_WIN32_WINNT == 0x501) +// Windows XP +# define LIBPKI_OS_VENDOR LIBPKI_OS_WINXP +# elif (_WIN32_WINNT == 0x502) +// Windows Server 2003 +# define LIBPKI_OS_VENDOR LIBPKI_OS_WIN2003 +# elif (_WIN32_WINNT == 0x600) +// Windows Vista or Server 2008 +# define LIBPKI_OS_VENDOR LIBPKI_OS_VISTA +# elif (_WIN32_WINNT == 0x601) +// Windows 7 +# define LIBPKI_OS_VENDOR LIBPKI_OS_WIN7 +# endif +# define LDAP_VENDOR_MICROSOFT 1 +# endif /* LIBPKI_OS_WIN */ + +/* Check for word size */ +# if (LIBPKI_OS_CLASS == LIBPKI_OS_POSIX) +# if defined(__x86_64__) || defined(__AMD64__) || defined(__amd64__) +# define LIBPKI_OS_BITS LIBPKI_OS64 +# else +# ifdef ENABLE_ARCH_64 +# define LIBPKI_OS_BITS LIBPKI_OS64 +# else +# define LIBPKI_OS_BITS LIBPKI_OS32 +# endif +# endif +# endif /* LIBPKI_OS_POSIX */ + +// ---------------------- OS Specific Includes ----------------------- + +# if (LIBPKI_OS_CLASS == LIBPKI_OS_WIN) +# include +# include +# include +typedef int pki_int32_t; +typedef unsigned int pki_uint32_t; +typedef __int64 pki_int64_t; +typedef unsigned __int64 pki_uint64_t; + +#define LIBPKI_PATH_SEPARATOR "\\" +#define LIBPKI_PATH_SEPARATOR_CHAR '\\' + +# else +# include +# if defined(LIBPKI_LINUX) || defined(LIBPKI_MACOS) +# include +# endif // LIBPKI_UNIX +# include +typedef int32_t pki_int32_t; +typedef uint32_t pki_uint32_t; +typedef int64_t pki_int64_t; +typedef uint64_t pki_uint64_t; + +#define LIBPKI_PATH_SEPARATOR "/" +#define LIBPKI_PATH_SEPARATOR_CHAR '/' + +#if (LIBPKI_OS_CLASS == LIBPKI_OS_WIN ) + // Do we need any includes for the threads on WIN (???) + typedef SRWLOCK PKI_RWLOCK; + typedef CONDITION_VARIABLE PKI_COND; + typedef CRITICAL_SECTION PKI_MUTEX; + + typedef struct timespec { + long long tv_sec; + long long tv_nsec; + }; + + typedef struct _thread_v { + void *ret_arg; + void *(* func)(void *); + _pthread_cleanup *clean; + HANDLE h; + int cancelled; + unsigned p_state; + int keymax; + void **keyval; + + jmp_buf jb; + }; + + typedef _thread_v PKI_THREAD; + + typedef struct pthread_attr_t { + unsigned p_state; + void *stack; + size_t s_size; + } PKI_PTHREAD_ATTR; + +#define PKI_THREAD_CREATE_JOINABLE 0 +#define PKI_THREAD_CREATE_DETACHED 0x04 + +#define PKI_THREAD_EXPLICT_SCHED 0 +#define PKI_THREAD_INHERIT_SCHED 0x08 + +#define PKI_THREAD_SCOPE_PROCESS 0 +#define PKI_THREAD_SCOPE_SYSTEM 0x10 + +#define PKI_THREAD_DESTRUCTOR_ITERATIONS 256 + +#define PKI_THREAD_PRIO_NONE 0 +#define PKI_THREAD_PRIO_INHERIT 8 +#define PKI_THREAD_PRIO_PROTECT 16 +#define PKI_THREAD_PRIO_MULT 32 + +#define PKI_THREAD_PROCESS_SHARED 0 +#define PKI_THREAD_PROCESS_PRIVATE 1 + +#else +/* Pthread lib include */ + #include + +#ifdef __LIB_BUILD__ +# ifndef HAVE_PTHREAD_RWLOCK + typedef struct pthread_rwlock_t + { + pthread_cond_t cond_var; + pthread_mutex_t lock_mutex; + pthread_mutex_t data_mutex; + + uint64_t n_readers; + uint64_t n_writers; + uint64_t n_writers_waiting; + } PKI_RWLOCK; +# else + typedef pthread_rwlock_t PKI_RWLOCK; +# endif +#else + typedef pthread_rwlock_t PKI_RWLOCK; +#endif + + typedef pthread_mutex_t PKI_MUTEX; + typedef pthread_cond_t PKI_COND; + + typedef pthread_t PKI_THREAD; + + typedef pthread_attr_t PKI_THREAD_ATTR; + typedef pthread_t PKI_THREAD_ID; + +#define PKI_THREAD_CREATE_JOINABLE PTHREAD_CREATE_JOINABLE +#define PKI_THREAD_CREATE_DETACHED PTHREAD_CREATE_DETACHED + +#define PKI_THREAD_EXPLICT_SCHED PTHREAD_EXPLICT_SCHED +#define PKI_THREAD_INHERIT_SCHED PTHREAD_INHERIT_SCHED + +#define PKI_THREAD_SCOPE_PROCESS PTHREAD_SCOPE_PROCESS +#define PKI_THREAD_SCOPE_SYSTEM PTHREAD_SCOPE_SYSTEM + +#define PKI_THREAD_DESTRUCTOR_ITERATIONS PTHREAD_DESTRUCTOR_ITERATIONS + +#define PKI_THREAD_PRIO_NONE PTHREAD_PRIO_NONE +#define PKI_THREAD_PRIO_INHERIT PTHREAD_PRIO_INHERIT +#define PKI_THREAD_PRIO_PROTECT PTHREAD_PRIO_PROTECT +#define PKI_THREAD_PRIO_MULT PTHREAD_PRIO_MULT + +#define PKI_THREAD_PROCESS_SHARED PTHREAD_PROCESS_SHARED +#define PKI_THREAD_PROCESS_PRIVATE PTHREAD_PROCESS_PRIVATE + +#endif /* LIBPKI_OS_WIN */ + +# endif /* LIBPKI_OS_WIN */ + +#endif /* _LIBPKI_SYSTEM_H */ diff --git a/include/libpki/libconf/types.h b/include/libpki/libconf/types.h new file mode 100644 index 00000000..4b17baea --- /dev/null +++ b/include/libpki/libconf/types.h @@ -0,0 +1,137 @@ +/* libconf/types.h */ + +#ifndef _LIBPKI_CORE_TYPES_H +#define _LIBPKI_CORE_TYPES_H + +/* PKI Datatypes */ +typedef enum { + + /* Crypto Datatype */ + PKI_TYPE_ANY = 0, + PKI_TYPE_PUBKEY, + PKI_TYPE_PRIVKEY, + PKI_TYPE_SECRET_KEY, + PKI_TYPE_CRED, + + /* X509 object types */ + PKI_TYPE_X509_PRIVKEY, + PKI_TYPE_X509_PUBKEY, + PKI_TYPE_X509_CERT, + PKI_TYPE_X509_CRL, + PKI_TYPE_X509_REQ, + PKI_TYPE_X509_PKCS7, + PKI_TYPE_X509_CMS, + PKI_TYPE_X509_PKCS12, + PKI_TYPE_X509_OCSP_REQ, + PKI_TYPE_X509_OCSP_RESP, + PKI_TYPE_X509_PRQP_REQ, + PKI_TYPE_X509_PRQP_RESP, + PKI_TYPE_X509_CMS_MSG, + PKI_TYPE_X509_XPAIR, + + /* Non-X509 Object types */ + PKI_TYPE_EST_MSG, + PKI_TYPE_SCEP_MSG, + + /* X509 Certificate Types */ + PKI_TYPE_X509_, + PKI_TYPE_X509_CERT_CA, + PKI_TYPE_X509_CERT_EE, + PKI_TYPE_X509_CERT_ROOT, + + /* Special Extensions */ + PKI_TYPE_X509_EXTENSIONS, + PKI_TYPE_X509_EXT_BASIC_CONSTRAINTS, + PKI_TYPE_X509_EXT_KEY_USAGE, + PKI_TYPE_X509_EXT_EXT_KEY_USAGE, + PKI_TYPE_X509_EXT_SUBJECT_KEY_ID, + PKI_TYPE_X509_EXT_AUTH_KEY_ID, + PKI_TYPE_X509_EXT_CRL_DIST_POINTS, + PKI_TYPE_X509_EXT_AUTH_INFO_ACCESS, + PKI_TYPE_X509_EXT_SUBJECT_ALT_NAME, + PKI_TYPE_X509_EXT_ISSUER_ALT_NAME, + PKI_TYPE_X509_EXT_NAME_CONSTRAINTS, + PKI_TYPE_X509_EXT_POLICY_CONSTRAINTS, + PKI_TYPE_X509_EXT_POLICY_MAPPINGS, + + /* Revocation */ + PKI_TYPE_X509_EXT_CRL_NUMBER, + PKI_TYPE_X509_EXT_REASON_CODE, + PKI_TYPE_X509_EXT_INVALIDITY_DATE, + PKI_TYPE_X509_EXT_DELTA_CRL_INDICATOR, + PKI_TYPE_X509_EXT_ISSUING_DIST_POINT, + PKI_TYPE_X509_EXT_FRESHEST_CRL, + + /* Policy */ + PKI_TYPE_X509_EXT_POLICY, + PKI_TYPE_X509_EXT_POLICY_CONSTRAINTS, + PKI_TYPE_X509_EXT_POLICY_MAPPINGS, + PKI_TYPE_X509_EXT_INHIBIT_ANY_POLICY, + + /* X509 data types */ + PKI_TYPE_X509_ALGOR, + PKI_TYPE_X509_SERIAL, + PKI_TYPE_X509_VERSION, + PKI_TYPE_X509_SUBJECT, + PKI_TYPE_X509_ISSUER, + PKI_TYPE_X509_VALIDITY, + PKI_TYPE_X509_SIGNATURE, + PKI_TYPE_X509_PUBKEY, + PKI_TYPE_X509_EXTENSION, + PKI_TYPE_X509_OBJECT, + PKI_TYPE_X509_NOTBEFORE, + PKI_TYPE_X509_NOTAFTER, + PKI_TYPE_X509_THISUPDATE, + PKI_TYPE_X509_LASTUPDATE, + PKI_TYPE_X509_NEXTUPDATE, + PKI_TYPE_X509_PRODUCEDAT, + PKI_TYPE_X509_ALGORITHM, + PKI_TYPE_X509_KEYSIZE, + PKI_TYPE_X509_KEYPAIR_VALUE, + PKI_TYPE_X509_X509_PUBKEY, + PKI_TYPE_X509_PUBKEY_BITSTRING, + PKI_TYPE_X509_PRIVKEY, + PKI_TYPE_X509_SIGNATURE, + PKI_TYPE_X509_SIGNATURE_ALG1, + PKI_TYPE_X509_SIGNATURE_ALG2, + PKI_TYPE_X509_NONCE, + + /* X500 Names */ + PKI_TYPE_X500_CN, + PKI_TYPE_X500_C, + PKI_TYPE_X500_L, + PKI_TYPE_X500_ST, + PKI_TYPE_X500_O, + PKI_TYPE_X500_OU, + PKI_TYPE_X500_EMAIL, + PKI_TYPE_X500_UID, + PKI_TYPE_X500_DC, + PKI_TYPE_X500_SN, + + /* Certificate Types */ + PKI_TYPE_X509_CA, + PKI_TYPE_X509_ROOT, + PKI_TYPE_X509_END_ENTITY, + + /* Trust Settings (PKCS#11 driver)*/ + PKI_TYPE_TRUST_ROOT, + PKI_TYPE_TRUST_OTHER, + PKI_TYPE_TRUST_DEPRECATED, + + /* Data Format */ + PKI_TYPE_FORMAT_RAW, + PKI_TYPE_FORMAT_B64, + PKI_TYPE_FORMAT_ASN1, + PKI_TYPE_FORMAT_PEM, + PKI_TYPE_FORMAT_TXT, + PKI_TYPE_FORMAT_XML, + PKI_TYPE_FORMAT_URL, + + /* Custom Type */ + PKI_TYPE_CUSTOM, +} PKI_TYPE; + +/* \brief Maximum value for PKI_TYPE */ +#define PKI_TYPE_MAX PKI_TYPE_CUSTOM + +#endif /* _LIBPKI_CORE_TYPES_H */ diff --git a/include/libpki/libconf/version.h b/include/libpki/libconf/version.h new file mode 100644 index 00000000..01501be2 --- /dev/null +++ b/include/libpki/libconf/version.h @@ -0,0 +1,55 @@ +/* libpkiv.h.in - LibPKI Version Header */ + +#ifndef _LIBPKI_COMPAT_H +#include +#endif + +#ifndef LIBPKI_VERSION_H +# define LIBPKI_VERSION_H + +BEGIN_C_DECLS + +// Shared Lib Major Version +# define LIBPKI_SHLIB_VERSION_HISTORY "@shlib_history@" +# define LIBPKI_SHLIB_VERSION_NUMBER "@shlib_version@" + +// Breakdown of version numbers +# define LIBPKI_VERSION_MAJOR 0x@lib_major@ +# define LIBPKI_VERSION_MINOR 0x@lib_minor@ +# define LIBPKI_VERSION_MICRO 0x@lib_micro@ +# define LIBPKI_VERSION_REVISION 0x@lib_revision@ + +// Generic value to use in pre-processing +# define LIBPKI_VERSION_NUMBER 0x@lib_major@@lib_minor@@lib_micro@@lib_revision@L + +// Useful for debugging/info purposes +# define LIBPKI_VERSION_TEXT "LibPKI v@PACKAGE_VERSION@@txt_revision@" + +// Build date +# define LIBPKI_BUILD_DATE_TEXT "@BUILD_DATE@" +# define LIBPKI_BUILD_DATE_TEXT_PRETTY "@BUILD_DATE_PRETTY@" +# define LIBPKI_BUILD_DATE_TEXT_FULL "@BUILD_DATE_FULL@" +# define LIBPKI_BUILD_DATE_NUMBER 0x@yr@@mon@@day@@hr@@min@@sec@ + +// Build Support Libraries Versions +# define LIBPKI_BUILD_OPENSSL_VERSION_TEXT OPENSSL_VERSION_TEXT +# define LIBPKI_BUILD_OPENSSL_VERSION_NUMBER OPENSSL_VERSION_NUMBER + +// Useful Build Dates +# define LIBPKI_BUILD_DATE_YEAR @yr@ +# define LIBPKI_BUILD_DATE_MONTH @mon@ +# define LIBPKI_BUILD_DATE_DAY @day@ +# define LIBPKI_BUILD_DATE_HOUR @hr@ +# define LIBPKI_BUILD_DATE_MIN @min@ +# define LIBPKI_BUILD_DATE_SEC @sec@ + +# define LIBPKI_BUILD_DATE_YEAR_TEXT "@yr@" +# define LIBPKI_BUILD_DATE_MONTH_TEXT "@mon@" +# define LIBPKI_BUILD_DATE_DAY_TEXT "@day@" +# define LIBPKI_BUILD_DATE_HOUR_TEXT "@hr@" +# define LIBPKI_BUILD_DATE_MIN_TEXT "@min@" +# define LIBPKI_BUILD_DATE_SEC_TEXT "@sec@" + +END_C_DECLS + +#endif // End of LIBPKI_VERSION_H diff --git a/include/libpki/libconf/version.h.in b/include/libpki/libconf/version.h.in new file mode 100644 index 00000000..01501be2 --- /dev/null +++ b/include/libpki/libconf/version.h.in @@ -0,0 +1,55 @@ +/* libpkiv.h.in - LibPKI Version Header */ + +#ifndef _LIBPKI_COMPAT_H +#include +#endif + +#ifndef LIBPKI_VERSION_H +# define LIBPKI_VERSION_H + +BEGIN_C_DECLS + +// Shared Lib Major Version +# define LIBPKI_SHLIB_VERSION_HISTORY "@shlib_history@" +# define LIBPKI_SHLIB_VERSION_NUMBER "@shlib_version@" + +// Breakdown of version numbers +# define LIBPKI_VERSION_MAJOR 0x@lib_major@ +# define LIBPKI_VERSION_MINOR 0x@lib_minor@ +# define LIBPKI_VERSION_MICRO 0x@lib_micro@ +# define LIBPKI_VERSION_REVISION 0x@lib_revision@ + +// Generic value to use in pre-processing +# define LIBPKI_VERSION_NUMBER 0x@lib_major@@lib_minor@@lib_micro@@lib_revision@L + +// Useful for debugging/info purposes +# define LIBPKI_VERSION_TEXT "LibPKI v@PACKAGE_VERSION@@txt_revision@" + +// Build date +# define LIBPKI_BUILD_DATE_TEXT "@BUILD_DATE@" +# define LIBPKI_BUILD_DATE_TEXT_PRETTY "@BUILD_DATE_PRETTY@" +# define LIBPKI_BUILD_DATE_TEXT_FULL "@BUILD_DATE_FULL@" +# define LIBPKI_BUILD_DATE_NUMBER 0x@yr@@mon@@day@@hr@@min@@sec@ + +// Build Support Libraries Versions +# define LIBPKI_BUILD_OPENSSL_VERSION_TEXT OPENSSL_VERSION_TEXT +# define LIBPKI_BUILD_OPENSSL_VERSION_NUMBER OPENSSL_VERSION_NUMBER + +// Useful Build Dates +# define LIBPKI_BUILD_DATE_YEAR @yr@ +# define LIBPKI_BUILD_DATE_MONTH @mon@ +# define LIBPKI_BUILD_DATE_DAY @day@ +# define LIBPKI_BUILD_DATE_HOUR @hr@ +# define LIBPKI_BUILD_DATE_MIN @min@ +# define LIBPKI_BUILD_DATE_SEC @sec@ + +# define LIBPKI_BUILD_DATE_YEAR_TEXT "@yr@" +# define LIBPKI_BUILD_DATE_MONTH_TEXT "@mon@" +# define LIBPKI_BUILD_DATE_DAY_TEXT "@day@" +# define LIBPKI_BUILD_DATE_HOUR_TEXT "@hr@" +# define LIBPKI_BUILD_DATE_MIN_TEXT "@min@" +# define LIBPKI_BUILD_DATE_SEC_TEXT "@sec@" + +END_C_DECLS + +#endif // End of LIBPKI_VERSION_H diff --git a/include/libpki/pki.h b/include/libpki/pki.h new file mode 100644 index 00000000..3e7c2aa5 --- /dev/null +++ b/include/libpki/pki.h @@ -0,0 +1,376 @@ +/* OpenCA libpki package +* (c) 2000-2007 by Massimiliano Pala and OpenCA Group +* All Rights Reserved +* +* =================================================================== +* Released under OpenCA LICENSE +*/ + +#ifndef _LIBPKI_PKI_H +#define _LIBPKI_PKI_H 1 + +#ifndef _LIBPKI_COMPAT_H +# include +#endif + +#ifndef LIBPKI_VERSION_H +# include +#endif + +// Library configuration +#ifdef __LIB_BUILD__ +#include +#else +#include +#endif + +#include + +#include +#include +#include +#include + +#include + +#define __XOPEN_OR_POSIX +#include +#undef __XOPEN_OR_POSIX + +#include +#include + +#include +#include + +#include +#include + +#ifdef LIBPKI_TARGET_SOLARIS +#include +#endif + +#include +#include +#include +#include +// #include + + +BEGIN_C_DECLS + +extern const long LIBPKI_OS_DETAILS; + +#define PKI_NAMESPACE_PREFIX "pki" +#define PKI_NAMESPACE_HREF "http://www.openca.org/openca/pki/1/0/0" + +#define PKI_SUBSCRIBER_REQ_TYPE "application/pki-subscriber-request" +#define PKI_SUBSCRIBER_RESP_TYPE "application/pki-subscriber-response" +#define PKI_MANAGEMENT_REQ_TYPE "application/pki-management-request" +#define PKI_MANAGEMENT_RESP_TYPE "application/pki-management-response" + +#ifdef HAVE_ENGINE +#define ENV_OPENCA_ENGINE "engine" +#define ENV_OPENCA_ENGINE_ID "engine_id" +#define ENV_OPENCA_ENGINE_PRE "engine_pre" +#define ENV_OPENCA_ENGINE_POST "engine_post" +#endif + +/* Imports the library's datatypes */ +#ifndef _LIBPKI_PKI_DATATYPES_H +# include +#endif + +#ifdef ENABLE_COMPOSITE +#include +#endif + +#define PKI_SCHEME_DEFAULT PKI_SCHEME_RSA + +#define PKI_DEFAULT_CLASSIC_SEC_BITS 128 +#define PKI_DEFAULT_QUANTUM_SEC_BITS 128 + +#define CRL_OK 1 +#define CRL_NOT_YET_VALID 2 +#define CRL_EXPIRED 3 +#define CRL_ERROR_NEXT_UPDATE 4 +#define CRL_ERROR_LAST_UPDATE 5 +#define CRL_ERROR_UNKNOWN 10 + +#define PKI_VALIDITY_ONE_HOUR 3600 +#define PKI_VALIDITY_ONE_DAY PKI_VALIDITY_ONE_HOUR*24 +#define PKI_VALIDITY_ONE_WEEK PKI_VALIDITY_ONE_DAY*7 +#define PKI_VALIDITY_ONE_MONTH PKI_VALIDITY_ONE_DAY*30 +#define PKI_VALIDITY_ONE_YEAR PKI_VALIDITY_ONE_DAY*365 + +typedef enum { + PKI_X509_CRL_REASON_ERROR = -1, + PKI_X509_CRL_REASON_UNSPECIFIED = 0, + PKI_X509_CRL_REASON_KEY_COMPROMISE = 1, + PKI_X509_CRL_REASON_CA_COMPROMISE = 2, + PKI_X509_CRL_REASON_AFFILIATION_CHANGED = 3, + PKI_X509_CRL_REASON_SUPERSEDED = 4, + PKI_X509_CRL_REASON_CESSATION_OF_OPERATION = 5, + PKI_X509_CRL_REASON_CERTIFICATE_HOLD = 6, + // Value #7 is not used + PKI_X509_CRL_REASON_REMOVE_FROM_CRL = 8, + PKI_X509_CRL_REASON_PRIVILEGE_WITHDRAWN = 9, + PKI_X509_CRL_REASON_AA_COMPROMISE = 10, + // Hold instructions + PKI_X509_CRL_REASON_HOLD_INSTRUCTION_REJECT = 0xA2, + PKI_X509_CRL_REASON_HOLD_INSTRUCTION_CALLISSUER = 0xA3, +} PKI_X509_CRL_REASON; + +typedef struct __pkiCrlReasonCodes_st { + int code; + const char *name; + const char *descr; +} PKI_X509_CRL_REASON_CODE; + +typedef enum { + PKI_MUTEX_READ = 0, + PKI_MUTEX_WRITE = 1, +} PKI_MUTEX_METHOD; + +#if (LIBPKI_OS_CLASS == LIBPKI_OS_WIN ) + // Do we need any includes for the threads on WIN (???) + typedef SRWLOCK PKI_RWLOCK; + typedef CONDITION_VARIABLE PKI_COND; + typedef CRITICAL_SECTION PKI_MUTEX; + + typedef struct timespec { + long long tv_sec; + long long tv_nsec; + }; + + typedef struct _thread_v { + void *ret_arg; + void *(* func)(void *); + _pthread_cleanup *clean; + HANDLE h; + int cancelled; + unsigned p_state; + int keymax; + void **keyval; + + jmp_buf jb; + }; + + typedef _thread_v PKI_THREAD; + + typedef struct pthread_attr_t { + unsigned p_state; + void *stack; + size_t s_size; + } PKI_PTHREAD_ATTR; + +#define PKI_THREAD_CREATE_JOINABLE 0 +#define PKI_THREAD_CREATE_DETACHED 0x04 + +#define PKI_THREAD_EXPLICT_SCHED 0 +#define PKI_THREAD_INHERIT_SCHED 0x08 + +#define PKI_THREAD_SCOPE_PROCESS 0 +#define PKI_THREAD_SCOPE_SYSTEM 0x10 + +#define PKI_THREAD_DESTRUCTOR_ITERATIONS 256 + +#define PKI_THREAD_PRIO_NONE 0 +#define PKI_THREAD_PRIO_INHERIT 8 +#define PKI_THREAD_PRIO_PROTECT 16 +#define PKI_THREAD_PRIO_MULT 32 + +#define PKI_THREAD_PROCESS_SHARED 0 +#define PKI_THREAD_PROCESS_PRIVATE 1 + +#else +/* Pthread lib include */ + #include + +#ifdef __LIB_BUILD__ +# ifndef HAVE_PTHREAD_RWLOCK + typedef struct pthread_rwlock_t + { + pthread_cond_t cond_var; + pthread_mutex_t lock_mutex; + pthread_mutex_t data_mutex; + + uint64_t n_readers; + uint64_t n_writers; + uint64_t n_writers_waiting; + } PKI_RWLOCK; +# else + typedef pthread_rwlock_t PKI_RWLOCK; +# endif +#else + typedef pthread_rwlock_t PKI_RWLOCK; +#endif + + typedef pthread_mutex_t PKI_MUTEX; + typedef pthread_cond_t PKI_COND; + + typedef pthread_t PKI_THREAD; + + typedef pthread_attr_t PKI_THREAD_ATTR; + typedef pthread_t PKI_THREAD_ID; + +#define PKI_THREAD_CREATE_JOINABLE PTHREAD_CREATE_JOINABLE +#define PKI_THREAD_CREATE_DETACHED PTHREAD_CREATE_DETACHED + +#define PKI_THREAD_EXPLICT_SCHED PTHREAD_EXPLICT_SCHED +#define PKI_THREAD_INHERIT_SCHED PTHREAD_INHERIT_SCHED + +#define PKI_THREAD_SCOPE_PROCESS PTHREAD_SCOPE_PROCESS +#define PKI_THREAD_SCOPE_SYSTEM PTHREAD_SCOPE_SYSTEM + +#define PKI_THREAD_DESTRUCTOR_ITERATIONS PTHREAD_DESTRUCTOR_ITERATIONS + +#define PKI_THREAD_PRIO_NONE PTHREAD_PRIO_NONE +#define PKI_THREAD_PRIO_INHERIT PTHREAD_PRIO_INHERIT +#define PKI_THREAD_PRIO_PROTECT PTHREAD_PRIO_PROTECT +#define PKI_THREAD_PRIO_MULT PTHREAD_PRIO_MULT + +#define PKI_THREAD_PROCESS_SHARED PTHREAD_PROCESS_SHARED +#define PKI_THREAD_PROCESS_PRIVATE PTHREAD_PROCESS_PRIVATE + +#endif + +#include +#include +#include + +/* Generic */ +#include + +/* Credentials */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* General X509 object */ +#include +#include +#include + +/* Forward declarations */ +#define PKI_X509_CERT PKI_X509 +#define PKI_X509_REQ PKI_X509 + +/* Libpki Includes */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +/* HSM Support */ +#include +#include +#include + +/* Software HSM Support */ +#include +#include +#include +#include + +#ifdef HAVE_ENGINE /* ENGINE Support */ +#include +#include +#include +#include +#endif + +/* PKCS11 Support */ +#include /* Updated to pkcs11t */ +#include +#include +#include +#include + +/* Profile and Config support */ +#include +#include +#include + +/* PKI_ID_INFO support */ +#include + +/* TOKEN interface */ +#include +#include +#include + +/* Log Subsystem Support */ +#include + +/* DBMS support */ +#ifdef __LIB_BUILD__ +#include +#include +#include +#endif /* END of __LIB_BUILD__ */ + +/* EST Interface */ +#include + +/* SCEP Interface */ +#include + +/* CMC Interface */ +#include + +/* General PKI Messaging System */ +#include +#include +#include + +/* PRQP Support */ +#include + +/* crossCertificatePair support */ +#include +#include + +/* I/O operations for PKIX objects */ +#include + +END_C_DECLS + +#endif diff --git a/include/libpki/pki_config.h.in b/include/libpki/pki_config.h.in new file mode 100644 index 00000000..a2db4ad2 --- /dev/null +++ b/include/libpki/pki_config.h.in @@ -0,0 +1,117 @@ +/* OpenCA libpki package +* (c) 2000-2007 by Massimiliano Pala and OpenCA Group +* All Rights Reserved +* +* =================================================================== +* Released under OpenCA LICENSE +*/ + +#ifndef _LIBPKI_XMLINCLUDES_H +# include +# include +# include +# include +#endif + +#ifndef _LIBPKI_STACK_H +# include +#endif + +#ifndef _LIBPKI_PKI_IO_H +# include +#endif + +#ifndef _LIBPKI_CONF_H +#define _LIBPKI_CONF_H + +#define PKI_CONFIG xmlDoc +#define PKI_CONFIG_ELEMENT xmlNode + +#define PKI_DEFAULT_ETC_DIR "@etc_dir@" + +#define PKI_DEFAULT_CONF_DIR "@conf_dir@/libpki" +#define PKI_DEFAULT_PROFILE_DIR "profile.d" +#define PKI_DEFAULT_TOKEN_DIR "token.d" +#define PKI_DEFAULT_HSM_DIR "hsm.d" +#define PKI_DEFAULT_STORE_DIR "store.d" +#define PKI_DEFAULT_CONF_OID_FILE "objectIdentifiers.xml" + +typedef enum { + PKI_CONF_PROFILE = 0, + PKI_CONF_TOKEN, + PKI_CONF_HSM, + PKI_CONF_STORE, + PKI_CONF_OID +} PKI_CONF_TYPE; + +int PKI_CONFIG_free ( PKI_CONFIG * doc ); +void PKI_CONFIG_free_void ( void * doc ); + +PKI_CONFIG * PKI_CONFIG_load(const char *urlPath); +PKI_CONFIG_STACK * PKI_CONFIG_load_dir (const char *dir, PKI_CONFIG_STACK *sk ); +PKI_CONFIG_STACK * PKI_CONFIG_load_all (const char * dir ); + +PKI_CONFIG * PKI_CONFIG_OID_load (const char *oidFile ); +PKI_OID * PKI_CONFIG_OID_search (const PKI_CONFIG *doc, + const char *searchName ); + +/* Config Options */ +char * PKI_CONFIG_get_value(const PKI_CONFIG *doc, + const char *search ); + +PKI_STACK * PKI_CONFIG_get_stack_value(const PKI_CONFIG *doc, + const char *search ); + +PKI_CONFIG_ELEMENT_STACK * PKI_CONFIG_get_element_stack(const PKI_CONFIG *doc, + const char *search ); + +char * PKI_CONFIG_get_element_name (PKI_CONFIG_ELEMENT *e); +char * PKI_CONFIG_get_element_value (PKI_CONFIG_ELEMENT *e); + +char * PKI_CONFIG_get_attribute_value (const PKI_CONFIG *doc, + const char *search, + const char *attr_name ); + +PKI_CONFIG_ELEMENT * PKI_CONFIG_get_root ( PKI_CONFIG *doc ); + +int PKI_CONFIG_get_elements_num ( const PKI_CONFIG *doc, + const char *search ); + +PKI_CONFIG_ELEMENT * PKI_CONFIG_get_element(const PKI_CONFIG *doc, + const char *search, + int num); + +PKI_CONFIG_ELEMENT * PKI_CONFIG_get_element_child (PKI_CONFIG_ELEMENT *e); +PKI_CONFIG_ELEMENT * PKI_CONFIG_get_element_next (PKI_CONFIG_ELEMENT *e); +PKI_CONFIG_ELEMENT * PKI_CONFIG_get_element_prev (PKI_CONFIG_ELEMENT *e); + +PKI_CONFIG_ELEMENT_STACK * PKI_CONFIG_get_element_children ( + PKI_CONFIG_ELEMENT *e); + +char * PKI_CONFIG_find ( const char *dir, + const char *name ); + +char * PKI_CONFIG_find_all ( const char *dir, + const char *name, + const char *subdir ); + +PKI_STACK *PKI_CONFIG_get_search_paths ( const char *dir ); + +PKI_CONFIG_ELEMENT *PKI_CONFIG_ELEMENT_new ( const char *name, + const char *value ); + +int PKI_CONFIG_ELEMENT_add_attribute ( PKI_CONFIG *doc, + PKI_CONFIG_ELEMENT *node, + const char *name, + const char *value ); + +PKI_CONFIG_ELEMENT *PKI_CONFIG_ELEMENT_add_child ( PKI_CONFIG *doc, + PKI_CONFIG_ELEMENT *node, + const char *name, + const char *value ); + +PKI_CONFIG_ELEMENT *PKI_CONFIG_ELEMENT_add_child_el ( PKI_CONFIG * doc, + PKI_CONFIG_ELEMENT *node, + PKI_CONFIG_ELEMENT *el); + +#endif diff --git a/include/libpki/pki_io.h b/include/libpki/pki_io.h new file mode 100644 index 00000000..2103242d --- /dev/null +++ b/include/libpki/pki_io.h @@ -0,0 +1,26 @@ +/* I/O headers */ + + +#include + +#ifndef _LIBPKI_IO_H +#define _LIBPKI_IO_H + +// Base definition for PKI_IO +#define PKI_IO BIO + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/include/libpki/pkix/cmc/cmc.h b/include/libpki/pkix/cmc/cmc.h new file mode 100644 index 00000000..c7399c67 --- /dev/null +++ b/include/libpki/pkix/cmc/cmc.h @@ -0,0 +1,443 @@ +/* CMS Includes for LibPKI */ + +#ifndef _LIBPKI_CMS_H +#define _LIBPKI_CMS_H + +#define CMS_REQ_SIMPLE_DATATYPE "application/pkcs10" +#define CMS_REQ_SIMPLE_EXTENSION "p10" + +#define CMS_REQ_FULL_DATATYPE "application/pkcs7-mime" +#define CMS_REQ_FULL_EXTENSION "p7m" + +#define CMS_RESP_SIMPLE_DATATYPE "application/pkcs7-mime" +#define CMS_RESP_SIMPLE_EXTENSION "p7c" + +#define CMS_RESP_FULL_DATATYPE "application/pkcs7-mime" +#define CMS_RESP_FULL_EXTENSION "p7m" + +#define PEM_STRING_CERT_REQ_MSG "CERTIFICATE REQUEST MESSAGE" +#define PKI_CONTENT_TYPE_CERT_REQ_MSG "application/pkcs7-mime" + +/* + PEND_INFO ::= SEQUENCE { + pendToken OCTET STRING, + pendTime GeneralizedTime + } +*/ + +typedef struct PendInfo_st { + ASN1_OCTET_STRING *pendInfo; + ASN1_GENERALIZEDTIME *pendTime; +} PEND_INFO; + +DECLARE_ASN1_FUNCTIONS(PEND_INFO) + +/* + BODY_PART_REFERENCE ::= SEQUENCE { + bodyPartID BodyPartID, + bodyPartPath SEQUENCE SIZE(1..MAX) OF BodyPartID + } +*/ + +typedef struct BodyPartReference_st { + ASN1_INTEGER * bodyPartID; + STACK_OF(ASN1_INTEGER) * bodyPartPath; +} BODY_PART_REFERENCE; + +DECLARE_ASN1_FUNCTIONS(BODY_PART_REFERENCE) + +DECLARE_STACK_OF(BODY_PART_REFERENCE) + +/* + CMC_STATUS_INFO ::= SEQUENCE { + cMCStatus CMCStatus, + bodyList SEQUENCE SIZE (1..MAX) OF BODY_PART_REFERENCE, + statusString UTF8String OPTIONAL, + otherInfo CHOICE { + failInfo CMCFailInfo, + pendInfo PEND_INFO, + extendedFailInfo SEQUENCE { + failInfoOID OBJECT_IDENTIFIER, + failInfoValue AttributeValue } + } OPTIONAL + } +*/ + +/* Watch out because the ASN1_ANY value could swallow everything else... */ + +typedef struct ExtendedFailInfo_st { + ASN1_OBJECT *failInfoOID; + /* Should be ASN1_ANY not void! */ + ASN1_TYPE * failInfoValue; +} EXTENDED_FAIL_INFO; + +DECLARE_ASN1_FUNCTIONS(EXTENDED_FAIL_INFO) + +typedef struct OtherInfoEx_st { + int type; + union { + ASN1_INTEGER *failInfo; + PEND_INFO *pendInfo; + EXTENDED_FAIL_INFO *extendedFailInfo; + } value; +} OTHER_INFO_EX; + +DECLARE_ASN1_FUNCTIONS(OTHER_INFO_EX) + +typedef struct CMCStatusInfoEx_st { + ASN1_INTEGER *cMCStatus; + STACK_OF(BODY_PART_REFERENCE) *bodyList; + ASN1_UTF8STRING *statusString; + OTHER_INFO_EX *otherInfo; +} CMC_STATUS_INFO_EX; + +DECLARE_ASN1_FUNCTIONS(CMC_STATUS_INFO_EX) + +/* + CMCStatusInfo ::= SEQUENCE { + cMCStatusInfo CMCStatus, + bodyList SEQUENCE SIZE (1..MAX) OF BodyPartID, + statusString UTF8String OPTIONAL, + otherInfo CHOICE { + failInfo CMCFailInfo, + pendInfo PendInfo + } OPTIONAL + } +*/ + +typedef struct OtherInfo_st { + int type; + union { + ASN1_INTEGER * failInfo; + PEND_INFO * pendInfo; + } value; +} OTHER_INFO; + + +DECLARE_ASN1_FUNCTIONS(OTHER_INFO) + +typedef struct CMCStatusInfo_st { + ASN1_INTEGER *cMCStatusInfo; + STACK_OF(ASN1_INTEGER) *bodyList; + ASN1_UTF8STRING *statusString; + OTHER_INFO *otherInfo; +} CMC_STATUS_INFO; + +DECLARE_ASN1_FUNCTIONS(CMC_STATUS_INFO) + +/* + TAGGED_ATTRIBUTE ::= SEQUENCE { + bodyPartID BodyPartID, + attrType OBJECT IDENTIFIER, + attrValues SET OF AttributeValue + } +*/ + +typedef struct TaggedAttribute_st { + ASN1_INTEGER *bodyPartID; + ASN1_OBJECT *attrType; + STACK_OF(X509_ATTRIBUTE) *attrValues; +} TAGGED_ATTRIBUTE; + +DECLARE_ASN1_FUNCTIONS(TAGGED_ATTRIBUTE) + +DECLARE_STACK_OF(TAGGED_ATTRIBUTE) + +/* + OTHER_MSG ::= SEQUENECE { + bodyPartID BodyPartID, + otherMsgType OBJECT IDENTIFIER, + otherMsgValue ANY DEFINED BY otherMsgType + } +*/ + +typedef struct OtherMsg_st { + ASN1_INTEGER * bodyPartID; + ASN1_OBJECT * otherMsgType; + ASN1_TYPE * otherMsgValue; +} OTHER_MSG; + +DECLARE_ASN1_FUNCTIONS( OTHER_MSG ) + +/* + CMC_UNSIGNED_DATA ::= SEQUENCE { + bodyPartPath SEQUENCE SIZE (1..MAX) OF BodyPartID, + identifier OBJECT IDENTIFIER, + content ANY DEFINED BY identifier +*/ + +typedef struct CMCUnsignedData_st { + STACK_OF(ASN1_INTEGER) * bodyPartPath; + ASN1_OBJECT * identifier; + ASN1_TYPE *content; +} CMC_UNSIGNED_DATA; + +DECLARE_ASN1_FUNCTIONS( CMC_UNSIGNED_DATA ) + +/* + ContentInfo ::= SEQUENCE { + bodyPartID BodyPartID, + contentInfo ContentInfo + } +*/ + +typedef struct ContentInfo_st { + ASN1_OBJECT * contentType; + ASN1_TYPE * content; +} CONTENT_INFO; + +DECLARE_ASN1_FUNCTIONS(CONTENT_INFO) + +/* + TaggedContentInfo ::= SEQUENCE { + bodyPartID BodyPartID, + contentInfo ContentInfo + } +*/ + +typedef struct TaggedContentInfo_st { + ASN1_INTEGER *bodyPartID; + CONTENT_INFO *contentInfo; +} TAGGED_CONTENT_INFO; + +DECLARE_ASN1_FUNCTIONS(TAGGED_CONTENT_INFO) + +/* + TaggedCertificationRequest ::= SEQUENCE { + bodyPartID BodyPartID, + certificationRequest CertificationRequest + } +*/ + +typedef struct TaggedCertificationRequest_st { + ASN1_INTEGER *bodyPartID; + X509_REQ *certificationRequest; +} TAGGED_CERTIFICATION_REQUEST; + +DECLARE_ASN1_FUNCTIONS(TAGGED_CERTIFICATION_REQUEST) + +/* + PKMACValue ::= SEQUENCE { + algId AlgorithmIdentifier, + -- the algorithm value shall be PasswordBasedMac + -- {1 2 840 113533 7 66 13} + -- the parameter value is PBMParameter + value BIT STRING } +*/ + +typedef struct PKMACValue_st { + X509_ALGOR *algID; + ASN1_BIT_STRING *value; +} PKMAC_VALUE; + +DECLARE_ASN1_FUNCTIONS(PKMAC_VALUE) + +/* + POPOSigningKeyInput ::= SEQUENCE { + authInfo CHOICE { + sender [0] GeneralName, + -- used only if an authenticated identity has been + -- established for the sender (e.g., a DN from a + -- previously-issued and currently-valid certificate) + publicKeyMAC PKMACValue }, + -- used if no authenticated GeneralName currently exists for + -- the sender; publicKeyMAC contains a password-based MAC + -- on the DER-encoded value of publicKey + publicKey SubjectPublicKeyInfo } -- from CertTemplate +*/ + +typedef struct AuthInfo_st { + int type; + union { + X509_NAME *sender; + PKMAC_VALUE *publicKeyMAC; + } value; +} AUTH_INFO; + +DECLARE_ASN1_FUNCTIONS(AUTH_INFO) + +typedef struct PubKeyInfo_st { + X509_ALGOR *algorithm; + ASN1_BIT_STRING *subjectPublicKey; +} PUBKEY_INFO; + +DECLARE_ASN1_FUNCTIONS(PUBKEY_INFO) + +typedef struct POPOSigningKeyInput { + AUTH_INFO *authInfo; + PUBKEY_INFO *publicKey; +} POP_O_SIGNING_KEY_INPUT; + +DECLARE_ASN1_FUNCTIONS(POP_O_SIGNING_KEY_INPUT) + +/* + POPOSigningKey ::= SEQUENCE { + poposkInput [0] POPOSigningKeyInput OPTIONAL, + algorithmIdentifier AlgorithmIdentifier, + signature BIT STRING } + -- The signature (using "algorithmIdentifier") is on the + -- DER-encoded value of poposkInput. NOTE: If the CertReqMsg + -- certReq CertTemplate contains the subject and publicKey values, + -- then poposkInput MUST be omitted and the signature MUST be + -- computed on the DER-encoded value of CertReqMsg certReq. If + -- the CertReqMsg certReq CertTemplate does not contain the public + -- key and subject values, then poposkInput MUST be present and + -- MUST be signed. This strategy ensures that the public key is + -- not present in both the poposkInput and CertReqMsg certReq + -- CertTemplate fields. +*/ + +typedef struct POPOSigningKey { + POP_O_SIGNING_KEY_INPUT *poposkInput; + X509_ALGOR *algorithmIdentifier; + ASN1_BIT_STRING *signature; +} POP_O_SIGNING_KEY; + +DECLARE_ASN1_FUNCTIONS(POP_O_SIGNING_KEY) + +/* + SubsequentMessage ::= INTEGER { + encrCert (0), + -- requests that resulting certificate be encrypted for the + -- end entity (following which, POP will be proven in a + -- confirmation message) + challengeResp (1) } + -- requests that CA/RA engage in challenge-response exchange with + -- end entity in order to prove private key possession + + POPOPrivKey ::= CHOICE { + thisMessage [0] BIT STRING, + -- posession is proven in this message (which contains the private + -- key itself (encrypted for the CA)) + subsequentMessage [1] SubsequentMessage, + -- possession will be proven in a subsequent message + dhMAC [2] BIT STRING } + -- for keyAgreement (only), possession is proven in this message + -- (which contains a MAC (over the DER-encoded value of the + -- certReq parameter in CertReqMsg, which must include both subject + -- and publicKey) based on a key derived from the end entity's + -- private DH key and the CA's public DH key); + -- the dhMAC value MUST be calculated as per the directions given + -- in Appendix A. +*/ + +typedef struct POPOPrivKey_st { + int type; + union { + ASN1_BIT_STRING *thisMessage; + ASN1_INTEGER *subsequentMessage; + ASN1_BIT_STRING *dhMAC; + } value; +} POP_O_PRIVKEY; + +DECLARE_ASN1_FUNCTIONS(POP_O_PRIVKEY) + +/* + ProofOfPossession ::= CHOICE { + raVerified [0] NULL, + -- used if the RA has already verified that the requester is in + -- possession of the private key + signature [1] POPOSigningKey, + keyEncipherment [2] POPOPrivKey, + keyAgreement [3] POPOPrivKey } +*/ + +typedef struct ProofOfPossession_st { + /* This should be type NULL - What type is this ? */ + int type; + union { + ASN1_INTEGER *raVerified; + POP_O_SIGNING_KEY *signature; + POP_O_PRIVKEY *keyEncipherment; + POP_O_PRIVKEY *keyAgreement; + } value; +} X509_POP; + +DECLARE_ASN1_FUNCTIONS(X509_POP) + +/* + CertReqMsg ::= SEQUENCE { + certReq CertificateRequest, + pop ProofOfPossession OPTIONAL, + regInfo SEQUENCE SIZE (1..MAX) OF AttributeTypeAndValue OPTIONAL + } +*/ + +typedef struct CertReqMsg_st { + X509_REQ *certReq; + X509_POP *pop; + STACK_OF(X509_ATTRIBUTE) *regInfo; +} CERT_REQ_MSG; + +DECLARE_ASN1_FUNCTIONS(CERT_REQ_MSG) + +/* + TaggedRequest ::= CHOICE { + tcr [0] TaggedCertificationRequest, + crm [1] CertReqMsg, + orm [2] SEQUENCE { + bodyPartID BodyPartID, + requestMessageType OBJECT IDENTIFIER, + requestMessageValue ANY DEFINED BY requestMessageType + } + } +*/ + +typedef struct OtherReqMsg_st { + ASN1_INTEGER *bodyPartID; + ASN1_OBJECT *requestMessageType; + ASN1_TYPE *requestMessageValue; +} OTHER_REQ_MSG; + +DECLARE_ASN1_FUNCTIONS(OTHER_REQ_MSG) + +typedef struct TaggedRequest_st { + int type; + union { + TAGGED_CERTIFICATION_REQUEST *tcr; + CERT_REQ_MSG *crm; + OTHER_REQ_MSG *orm; + } value; +} TAGGED_REQUEST; + +DECLARE_ASN1_FUNCTIONS(TAGGED_REQUEST) + + +/* + PKI_DATA ::= SEQUENCE { + controlSequence SEQUENCE SIZE(0..MAX) OF TAGGED_ATTRIBUTE, + reqSequence SEQUENCE SIZE(0..MAX) OF TaggedRequest, + cmsSequence SEQUENCE SIZE(0..MAX) OF TaggedContentInfo, + otherMsgSequence SEQUENCE SIZE(0..MAX) OF OTHER_MSG + } +*/ + +typedef struct PKIData_st { + STACK_OF(TAGGED_ATTRIBUTE) *controlSequence; + STACK_OF(TAGGED_REQUEST) * reqSequence; + STACK_OF(TAGGED_CONTENT_INFO) *cmsSequence; + STACK_OF(OTHER_MSG) *otherMsgSequence; +} PKI_DATA; + +DECLARE_ASN1_FUNCTIONS(PKI_DATA) + +/* + RESPONSE_BODY ::= SEQUENCE { + controlSequence SEQUENCE SIZE(0..MAX) OF TAGGED_ATTRIBUTE, + cmsSequence SEQUENCE SIZE(0..MAX) OF TaggedContentInfo, + otherMsgSequence SEQUENCE SIZE(0..MAX) OF OTHER_MSG + } +*/ + +typedef struct ResponseBody_st { + STACK_OF(TAGGED_ATTRIBUTE) *controlSequence; + STACK_OF(TAGGED_CONTENT_INFO) *cmsSequence; + STACK_OF(OTHER_MSG) *otherMsgSequence; +} RESPONSE_BODY; + +DECLARE_ASN1_FUNCTIONS(RESPONSE_BODY) + +#include + +/* End _LIBPKI_CMS_H */ +#endif diff --git a/include/libpki/pkix/cmc/cmc_cert_req.h b/include/libpki/pkix/cmc/cmc_cert_req.h new file mode 100644 index 00000000..ec13c6a6 --- /dev/null +++ b/include/libpki/pkix/cmc/cmc_cert_req.h @@ -0,0 +1,31 @@ +/* CMS Support for LibPKI + * (c) 2008 by Massimiliano Pala and OpenCA Group + * All Rights Reserved + * + * This software is released under the GPL2 License included + * in the archive. You can not remove this copyright notice. + */ + +CERT_REQ_MSG *d2i_CERT_REQ_MSG_bio ( BIO *bp, CERT_REQ_MSG *p ); +int i2d_CERT_REQ_MSG_bio(BIO *bp, CERT_REQ_MSG *o ); + +CERT_REQ_MSG *PEM_read_bio_CERT_REQ_MSG( BIO *bp ); +int PEM_write_bio_CERT_REQ_MSG( BIO *bp, CERT_REQ_MSG *o ); + +/* ======================== REQ get API ========================== */ + +CERT_REQ_MSG *CERT_REQ_MSG_get( char *url_s ); +CERT_REQ_MSG *CERT_REQ_MSG_get_url( URL *url ); +CERT_REQ_MSG *CERT_REQ_MSG_get_fd( int fd ); +CERT_REQ_MSG *CERT_REQ_MSG_get_mem( PKI_MEM *mem ); + +/* ====================== CERT_REQ_MSG REQ put API ====================== */ + +int CERT_REQ_MSG_put( CERT_REQ_MSG *req, char *url_s, + int format, PKI_MEM_STACK **ret_sk ); +int CERT_REQ_MSG_put_url( CERT_REQ_MSG *req, URL *url, + int format, PKI_MEM_STACK **ret_sk ); + +int CERT_REQ_MSG_put_fp( CERT_REQ_MSG *req, FILE * file, int format); +int CERT_REQ_MSG_put_mem( CERT_REQ_MSG *req, PKI_MEM *mem, int format); + diff --git a/include/libpki/pkix/est/est.h b/include/libpki/pkix/est/est.h new file mode 100644 index 00000000..bbd31ab6 --- /dev/null +++ b/include/libpki/pkix/est/est.h @@ -0,0 +1,252 @@ +/* + * OpenCA EST + * + * (c) 2019 by Massimiliano Pala and OpenCA Labs + * + */ + +#ifndef _LIBPKI_EST_H_ +#define _LIBPKI_EST_H_ + +/* +#include +#include +#include +#include +#include + +#include +#include +#include +#include +*/ + +/* +#define EST_ATTRIBUTE_OID_MESSAGE_TYPE "2.16.840.1.113733.1.9.2" +#define EST_ATTRIBUTE_STRING_MESSAGE_TYPE "messageType" +#define EST_ATTRIBUTE_OID_PKI_STATUS "2.16.840.1.113733.1.9.3" +#define EST_ATTRIBUTE_STRING_PKI_STATUS "pkiStatus" +#define EST_ATTRIBUTE_OID_FAIL_INFO "2.16.840.1.113733.1.9.4" +#define EST_ATTRIBUTE_STRING_FAIL_INFO "failInfo" +#define EST_ATTRIBUTE_OID_SENDER_NONCE "2.16.840.1.113733.1.9.5" +#define EST_ATTRIBUTE_STRING_SENDER_NONCE "senderNonce" +#define EST_ATTRIBUTE_OID_RECIPIENT_NONCE "2.16.840.1.113733.1.9.6" +#define EST_ATTRIBUTE_STRING_RECIPIENT_NONCE "recipientNonce" +#define EST_ATTRIBUTE_OID_TRANS_ID "2.16.840.1.113733.1.9.7" +#define EST_ATTRIBUTE_STRING_TRANS_ID "transId" +#define EST_ATTRIBUTE_OID_EXTENSION_REQ "2.16.840.1.113733.1.9.8" +#define EST_ATTRIBUTE_STRING_EXTENSION_REQ "extensionReq" +#define EST_ATTRIBUTE_OID_PROXY_AUTHENTICATOR "1.3.6.1.4.1.4263.5.5" +#define EST_ATTRIBUTE_STRING_PROXY_AUTHENTICATOR "proxyAuthenticator" +*/ + +#define TRANS_ID_SIZE 16 + +typedef struct est_oid_st { + int attr_type; + char *oid_s; + char *descr; + char *long_descr; + int nid; +} EST_CONF_ATTRIBUTE; + +/* These should be in the same order than the EST_ATTRIBUTE_list in est_attrs.c */ +typedef enum { + EST_ATTRIBUTE_TYPE_UNKNOWN = -1, + EST_ATTRIBUTE_MESSAGE_TYPE = 0, + EST_ATTRIBUTE_PKI_STATUS, + EST_ATTRIBUTE_FAIL_INFO, + EST_ATTRIBUTE_SENDER_NONCE, + EST_ATTRIBUTE_RECIPIENT_NONCE, + EST_ATTRIBUTE_TRANS_ID, + EST_ATTRIBUTE_EXTENSION_REQ, + EST_ATTRIBUTE_PROXY_AUTH +} EST_ATTRIBUTE_TYPE; + +typedef enum { + PKI_X509_EST_MSG_UNKNOWN = -1, + PKI_X509_EST_MSG_V2REQUEST = 17, + PKI_X509_EST_MSG_V2PROXY = 18, + PKI_X509_EST_MSG_PKCSREQ = 19, + PKI_X509_EST_MSG_CERTREP = 3, + PKI_X509_EST_MSG_GETCERTINITIAL = 20, + PKI_X509_EST_MSG_GETCERT = 21, + PKI_X509_EST_MSG_GETCRL = 22 +} EST_MESSAGE_TYPE; + +typedef enum { + EST_STATUS_SUCCESS = 0, + EST_STATUS_FAILURE = 2, + EST_STATUS_PENDING = 3 +} EST_STATUS; + +typedef enum { + EST_FAILURE_BADALG = 0, + EST_FAILURE_BADMESSAGECHECK = 1, + EST_FAILURE_BADREQUEST = 2, + EST_FAILURE_BADTIME = 3, + EST_FAILURE_BADCERTID = 4 +} EST_FAILURE; + +#define EST_NONCE PKI_MEM +#define NONCE_SIZE 16 + +#define PKI_X509_EST_MSG_VALUE PKCS7 +#define PKI_X509_EST_DATA PKI_X509_PKCS7 +#define PKI_X509_EST_MSG PKI_X509_PKCS7 + +#include +#include +#include +#include + + +#endif + + +/* +typedef struct est_recip_info { + STACK_OF(PKCS7_RECIP_INFO) *sk_recip_info; + STACK_OF(X509) *sk_recip_certs; + + PKCS7_ISSUER_AND_SERIAL *ias; + +} EST_RECIP_INFO; +*/ + +/* +typedef struct { + int NID_p7data; + + // enc p7 enveloped data + PKCS7 *p7env; + PKCS7 *p7; + + // Info about the recipient of the message + EST_RECIP_INFO recip_info; + EVP_PKEY *pkey; + X509 *cacert; + + union { + // PKCSReq Content + X509_REQ *req; + // CertResp Content + X509 *issued_cert; + // CertReq Content + X509 *self_signed_cert; + // GetCertInitial Content + EST_ISSUER_AND_SUBJECT *init_certinfo; + // GetCert && GetCrl Content + PKCS7_ISSUER_AND_SERIAL *ias; + } content; + + X509_CRL *crl; + +} EST_ENVELOPED_DATA; + +typedef struct { + int messageType; + + STACK_OF(PKCS7_SIGNER_INFO) *sk_signer_info; + PKCS7_ISSUER_AND_SERIAL *signer_ias; + X509 *signer_cert; + EVP_PKEY *signer_pkey; + + STACK_OF(X509_ATTRIBUTE) *attrs; + + EST_ENVELOPED_DATA env_data; + + STACK_OF(X509) *sk_others; + +} EST_MSG; +*/ + +/* +#define EST_MESSAGE_is(a, b) (!strcmp(a, b)) +#define EST_PKISTATUS_is(a, b) (!strcmp(a, b)) +#define EST_FAILURE_is(a, b) (!strcmp(a, b)) + +#define EST_type2str(a) ( \ +(0 == a ) ? "(not set)" : ( \ +(EST_MSG_PKCSREQ == a ) ? "PKCSReq" : ( \ +(EST_MSG_V2REQUEST == a ) ? "v2Request" : ( \ +(EST_MSG_V2PROXY == a ) ? "v2Proxy" : ( \ +(EST_MSG_CERTREP == a ) ? "CertRep" : ( \ +(EST_MSG_GETCERTINITIAL == a ) ? "GetCertInitial" : ( \ +(EST_MSG_GETCERT == a ) ? "GetCert" : ( \ +(EST_MSG_GETCRL == a ) ? "GetCRL" : "unknown")))))))) + +#define EST_str2type( a ) ( \ +(NULL == a) ? -1 : ( \ +(0 == strcmp("PKCSReq", a)) ? EST_MSG_PKCSREQ : ( \ +(0 == strcmp("v2Request", a)) ? EST_MSG_V2REQUEST : ( \ +(0 == strcmp("v2Proxy", a)) ? EST_MSG_V2PROXY : ( \ +(0 == strcmp("CertRep", a)) ? EST_MSG_CERTREP : ( \ +(0 == strcmp("GetCertInitial", a)) ? EST_MSG_GETCERTINITIAL : (\ +(0 == strcmp("GetCert", a)) ? EST_MSG_GETCERT : ( \ +(0 == strcmp("GetCRL", a)) ? EST_MSG_GETCRL : -1 )))))))) + +#define EST_TYPE(a) ( \ +(NULL == a) ? "(not set)" : ( \ +(0 == strcmp(EST_MESSAGE_TYPE_PKCSREQ, a)) ? "PKCSReq" : ( \ +(0 == strcmp(EST_MESSAGE_TYPE_V2REQUEST, a)) ? "v2Request" : ( \ +(0 == strcmp(EST_MESSAGE_TYPE_V2PROXY, a)) ? "v2Proxy" : ( \ +(0 == strcmp(EST_MESSAGE_TYPE_CERTREP, a)) ? "CertRep" : ( \ +(0 == strcmp(EST_MESSAGE_TYPE_GETCERTINITIAL, a)) ? "GetCertInitial" : (\ +(0 == strcmp(EST_MESSAGE_TYPE_GETCERT, a)) ? "GetCert" : ( \ +(0 == strcmp(EST_MESSAGE_TYPE_GETCRL, a)) ? "GetCRL" : "unknown")))))))) + +#define EST_status2str(a) ( \ +(PKI_SUCCESS == a ) ? "Success" : ( \ +(PKI_FAILURE == a ) ? "Failure" : ( \ +(PKI_PENDING == a ) ? "Pending" : "(unknown)"))) + +#define EST_str2status(a) ( \ +(NULL == a) ? -1 : ( \ +(0 == strcmp("SUCCESS", a)) ? PKI_SUCCESS : ( \ +(0 == strcmp("FAILURE", a)) ? PKI_FAILURE : ( \ +(0 == strcmp("PENDING", a)) ? PKI_PENDING : -1 )))) + +#define EST_STATUS(a) ( \ +(NULL == a) ? "(not set)" : ( \ +(0 == strcmp(EST_PKISTATUS_SUCCESS, a)) ? "SUCCESS" : ( \ +(0 == strcmp(EST_PKISTATUS_FAILURE, a)) ? "FAILURE" : ( \ +(0 == strcmp(EST_PKISTATUS_PENDING, a)) ? "PENDING" : "(unknown)")))) + +#define EST_failure2str(a) ( \ +(FAIL_BADALG == a ) ? "BadAlg" : ( \ +(FAIL_BADMESSAGECHECK == a ) ? "BadMessageCheck" : ( \ +(FAIL_BADREQUEST == a ) ? "BadRequest" : ( \ +(FAIL_BADTIME == a ) ? "BadTime" : ( \ +(FAIL_BADCERTID == a ) ? "BadCertID" : "(unknown)"))))) + +#define EST_str2failure(a) ( \ +(NULL == a) ? -1 : ( \ +(0 == strcmp("badAlg", a)) ? FAIL_BADALG : ( \ +(0 == strcmp("badMessageCheck", a)) ? FAIL_BADMESSAGECHECK : ( \ +(0 == strcmp("badRequest", a)) ? FAIL_BADREQUEST : ( \ +(0 == strcmp("badTime", a)) ? FAIL_BADTIME : ( \ +(0 == strcmp("badCertId", a)) ? FAIL_BADCERTID : -1 )))))) + +#define EST_FAILURE(a) ( \ +(NULL == a) ? "(not set)" : ( \ +(0 == strcmp(EST_FAILURE_BADALG, a)) ? "BadAlg" : ( \ +(0 == strcmp(EST_FAILURE_BADMESSAGECHECK, a)) ? "BadMessageCheck" : ( \ +(0 == strcmp(EST_FAILURE_BADREQUEST, a)) ? "BadRequest" : ( \ +(0 == strcmp(EST_FAILURE_BADTIME, a)) ? "BadTime" : ( \ +(0 == strcmp(EST_FAILURE_BADCERTID, a)) ? "BadCertID" : "(unknown)")))))) +*/ + +/* +#define EST_str2attribute(a) ( \ +(NULL == a) ? -1 : ( \ +(0 == strcmp(MESSAGE_TYPE_OID_STRING, a)) ? EST_MESSAGE_TYPE_ATTRIBUTE : (\ +(0 == strcmp(PKI_STATUS_OID_STRING, a)) ? EST_PKI_STATUS_ATTRIBUTE : (\ +(0 == strcmp(FAIL_INFO_OID_STRING, a)) ? EST_FAIL_INFO_ATTRIBUTE : (\ +(0 == strcmp(SENDER_NONCE_OID_STRING, a)) ? EST_SENDER_NONCE_ATTRIBUTE : (\ +(0 == strcmp(RECIPIENT_NONCE_OID_STRING, a)) ? EST_RECIPIENT_NONCE_ATTRIBUTE : (\ +(0 == strcmp(TRANS_ID_OID_STRING, a)) ? EST_TRANS_ID_ATTRIBUTE : (\ +(0 == strcmp(EXTENSION_REQ_OID_STRING, a)) ? EST_EXTENSION_REQ_ATTRIBUTE : (\ +(0 == strcmp(PROXY_AUTHENTICATOR_OID_STRING, a)) ? EST_PROXY_AUTHENTICATOR_ATTRIBUTE : -1 ))))))))) +*/ + diff --git a/include/libpki/pkix/est/pki_x509_est_asn1.h b/include/libpki/pkix/est/pki_x509_est_asn1.h new file mode 100644 index 00000000..17235eb7 --- /dev/null +++ b/include/libpki/pkix/est/pki_x509_est_asn1.h @@ -0,0 +1,15 @@ +/* + * EST - ASN1 Functions + */ + +#ifndef _LIBPKI_PKI_X509_EST_ASN1_H +#define _LIBPKI_PKI_X509_EST_ASN1_H + +typedef struct est_issuer_and_subject_st { + X509_NAME *issuer; + X509_NAME *subject; +} EST_ISSUER_AND_SUBJECT; + +DECLARE_ASN1_FUNCTIONS(EST_ISSUER_AND_SUBJECT) + +#endif diff --git a/include/libpki/pkix/est/pki_x509_est_attrs.h b/include/libpki/pkix/est/pki_x509_est_attrs.h new file mode 100644 index 00000000..ba388fa6 --- /dev/null +++ b/include/libpki/pkix/est/pki_x509_est_attrs.h @@ -0,0 +1,108 @@ +/* + * OpenCA EST -- signed attributes handling routines + * (c) 2003-2019 by Massimiliano Pala and OpenCA Group + */ + +#ifndef _LIBPKI_EST_SIGNED_ATTRS_H +#define _LIBPKI_EST_SIGNED_ATTRS_H + +void PKI_X509_EST_init(void); + +EST_ATTRIBUTE_TYPE PKI_X509_EST_ATTRIBUTE_get_txt(const char * const txt); + +PKI_ID PKI_X509_EST_ATTRIBUTE_get_nid(EST_ATTRIBUTE_TYPE num); + +PKI_OID *PKI_X509_EST_MSG_get_oid(EST_ATTRIBUTE_TYPE est_attribute); + +int PKI_X509_EST_MSG_set_attribute(PKI_X509_EST_MSG * msg, + EST_ATTRIBUTE_TYPE type, + const unsigned char * const data, + size_t size); + +int PKI_X509_EST_MSG_set_attribute_by_name(PKI_X509_EST_MSG * msg, + const char * const name, + const unsigned char * const data, + size_t size); + +int PKI_X509_EST_MSG_set_attribute_int(PKI_X509_EST_MSG * msg, + PKI_ID id, + int val); + +PKI_MEM * PKI_X509_EST_MSG_get_attr_value(const PKI_X509_EST_MSG * const msg, + EST_ATTRIBUTE_TYPE type); + +int PKI_X509_EST_MSG_get_attr_value_int(const PKI_X509_EST_MSG * const msg, + EST_ATTRIBUTE_TYPE type); + +/* ------------------------ Specific Attributes ------------------------ */ + +PKI_MEM *PKI_X509_EST_MSG_new_trans_id(const PKI_X509_KEYPAIR * key); + +int PKI_X509_EST_MSG_set_trans_id(PKI_X509_EST_MSG * msg, + const PKI_MEM * mem); + +char * PKI_X509_EST_MSG_get_trans_id(const PKI_X509_EST_MSG * const msg); + + +int PKI_X509_EST_MSG_set_sender_nonce(PKI_X509_EST_MSG * msg, + const PKI_MEM * const mem); + + +int PKI_X509_EST_MSG_set_recipient_nonce(PKI_X509_EST_MSG * msg, + const PKI_MEM * const mem); + +/*! \brief Sets the messageType attribute in a EST message */ + +int PKI_X509_EST_MSG_set_type(PKI_X509_EST_MSG * msg, + EST_MESSAGE_TYPE type); + + +/*! \brief Returns the messageType attribute from a EST message */ + +EST_MESSAGE_TYPE PKI_X509_EST_MSG_get_type(const PKI_X509_EST_MSG * const msg); + + +/*! \brief Sets the pkiStatus attribute in a EST message */ + +int PKI_X509_EST_MSG_set_status(PKI_X509_EST_MSG * msg, + EST_STATUS status); + + +/*! \brief Returns the pkiStatus attribute from a EST message */ + +EST_STATUS PKI_X509_EST_MSG_get_status(const PKI_X509_EST_MSG * const msg); + + +/*! \brief Sets the failInfo attribute in a EST message */ + +int PKI_X509_EST_MSG_set_failinfo(PKI_X509_EST_MSG * msg, + int fail); + + +/*! \brief Returns the failInfo attribute from a EST message */ + +EST_FAILURE PKI_X509_EST_MSG_get_failinfo(const PKI_X509_EST_MSG * const msg); + + +/*! \brief Returns the senderNonce attribute from a EST message */ + +PKI_MEM *PKI_X509_EST_MSG_get_sender_nonce(const PKI_X509_EST_MSG * const msg); + + +/*! \brief Returns the recipientNonce attribute from a EST message */ + +PKI_MEM *PKI_X509_EST_MSG_get_recipient_nonce(PKI_X509_EST_MSG * const msg); + + +/*! \brief Sets the proxyAuthenticator attribute from a EST message */ + +int PKI_X509_EST_MSG_set_proxy(PKI_X509_EST_MSG * msg, + int auth); + + +/*! \brief Returns the proxyAuthenticator attribute from a EST message */ + +int PKI_X509_EST_MSG_get_proxy(const PKI_X509_EST_MSG * const msg); + + +#endif diff --git a/include/libpki/pkix/est/pki_x509_est_data.h b/include/libpki/pkix/est/pki_x509_est_data.h new file mode 100644 index 00000000..4ceaa210 --- /dev/null +++ b/include/libpki/pkix/est/pki_x509_est_data.h @@ -0,0 +1,28 @@ +/* EST msg handling + * (c) 2009 by Massimiliano Pala and OpenCA Labs + * All Rights Reserved + */ + +#ifndef _LIBPKI_X509_EST_DATA_H +#define _LIBPKI_X509_EST_DATA_H + +PKI_X509_EST_DATA * PKI_X509_EST_DATA_new ( void ); + +void PKI_X509_EST_DATA_free ( PKI_X509_EST_DATA *data ); + +int PKI_X509_EST_DATA_add_recipient ( PKI_X509_EST_DATA *data, + PKI_X509_CERT *recipient ); + +int PKI_X509_EST_DATA_set_recipients ( PKI_X509_EST_DATA *data, + PKI_X509_CERT_STACK *sk ); + +int PKI_X509_EST_DATA_set_x509_obj ( PKI_X509_EST_DATA *data, + PKI_X509 *obj ); + +int PKI_X509_EST_DATA_set_ias ( PKI_X509_EST_DATA *data, + EST_ISSUER_AND_SUBJECT *ias ); + +int PKI_X509_EST_DATA_set_raw_data ( PKI_X509_EST_DATA *data, + unsigned char *raw_val, ssize_t size ); + +#endif diff --git a/include/libpki/pkix/est/pki_x509_est_msg.h b/include/libpki/pkix/est/pki_x509_est_msg.h new file mode 100644 index 00000000..e05517d4 --- /dev/null +++ b/include/libpki/pkix/est/pki_x509_est_msg.h @@ -0,0 +1,39 @@ +/* EST msg handling + * (c) 2009-2019 by Massimiliano Pala and OpenCA Labs + * All Rights Reserved + */ + +#ifndef _LIBPKI_X509_EST_MSG_H +#define _LIBPKI_X509_EST_MSG_H + +PKI_X509_EST_MSG *PKI_X509_EST_MSG_new ( EST_MESSAGE_TYPE type ); +void PKI_X509_EST_MSG_free ( PKI_X509_EST_MSG *msg ); + +/* ----------------------------- Signer ------------------------------- */ + +int PKI_X509_EST_MSG_add_signer ( PKI_X509_EST_MSG *msg, + PKI_X509_CERT *signer, PKI_X509_KEYPAIR *key, + PKI_DIGEST_ALG *md ); + +int PKI_X509_EST_MSG_add_signer_sk ( PKI_X509_EST_MSG *msg, + PKI_TOKEN *tk, PKI_DIGEST_ALG *md ); + +/* ---------------------------- Encode / Decode ------------------------ */ + +int PKI_X509_EST_MSG_encode ( PKI_X509_EST_MSG *msg, + PKI_X509_EST_DATA *data ); + +PKI_MEM *PKI_X509_EST_MSG_decode ( PKI_X509_EST_MSG *msg, + PKI_X509_KEYPAIR * key, PKI_X509_CERT *x ); + +/* ---------------------------- EST helper Funcs ---------------------- */ + +PKI_X509_EST_MSG * PKI_X509_EST_MSG_new_certreq ( PKI_X509_KEYPAIR *key, + PKI_X509_REQ *req, PKI_X509_CERT *signer, + PKI_X509_CERT_STACK *recipients, PKI_DIGEST_ALG *md ); + +PKI_X509 *PKI_X509_EST_MSG_get_x509_obj ( PKI_X509_EST_MSG *msg, + PKI_DATATYPE type, PKI_DATA_FORMAT format, + PKI_X509_KEYPAIR *key, PKI_X509_CERT *x ); + +#endif diff --git a/include/libpki/pkix/ocsp/pki_ocsp_req.h b/include/libpki/pkix/ocsp/pki_ocsp_req.h new file mode 100644 index 00000000..17bb24b4 --- /dev/null +++ b/include/libpki/pkix/ocsp/pki_ocsp_req.h @@ -0,0 +1,89 @@ +/* PKI_X509_OCSP_REQ object management */ + +#ifndef _LIBPKI_X509_OCSP_REQ_H +#define _LIBPKI_X509_OCSP_REQ_H + +/* Macros for PKI_MEM conversion */ +#define PKI_X509_OCSP_REQ_mem_der(a) \ + PKI_MEM_new_func( (void *) a, i2d_OCSP_REQ_bio ) +#define PKI_X509_OCSP_REQ_mem_pem(a) \ + PKI_MEM_new_func( (void *) a, PEM_write_bio_OCSP_REQ ) + +/* --------------------------------- Memory Allocation ------------------ */ +PKI_X509_OCSP_REQ *PKI_X509_OCSP_REQ_new ( void ); +void PKI_X509_OCSP_REQ_free_void( void *x ); +void PKI_X509_OCSP_REQ_free( PKI_X509_OCSP_REQ *x ); + +/* --------------------------------- Request Generation ----------------- */ +int PKI_X509_OCSP_REQ_add_nonce ( PKI_X509_OCSP_REQ *req, size_t size ); + +int PKI_X509_OCSP_REQ_add_serial ( PKI_X509_OCSP_REQ *req, PKI_INTEGER *serial, + PKI_X509_CERT *issuer, PKI_DIGEST_ALG *digest ); +int PKI_X509_OCSP_REQ_add_cert ( PKI_X509_OCSP_REQ *req, PKI_X509_CERT *cert, + PKI_X509_CERT *issuer, PKI_DIGEST_ALG *digest ); +int PKI_X509_OCSP_REQ_add_txt ( PKI_X509_OCSP_REQ *req, char *serial, + PKI_X509_CERT *issuer, PKI_DIGEST_ALG *digest ); +int PKI_X509_OCSP_REQ_add_longlong ( PKI_X509_OCSP_REQ *req, long long serial, + PKI_X509_CERT *issuer, PKI_DIGEST_ALG *digest ); + +/* --------------------------------- Signature -------------------------- */ +int PKI_X509_OCSP_REQ_DATA_sign (PKI_X509_OCSP_REQ *req, + PKI_X509_KEYPAIR *k, PKI_DIGEST_ALG *md ); + +int PKI_X509_OCSP_REQ_sign ( PKI_X509_OCSP_REQ *req, PKI_X509_KEYPAIR *keypair, + PKI_X509_CERT *cert, PKI_X509_CERT *issuer, + PKI_X509_CERT_STACK * otherCerts, PKI_DIGEST_ALG *digest ); + +int PKI_X509_OCSP_REQ_sign_tk ( PKI_X509_OCSP_REQ *req, PKI_TOKEN *tk ); + +/* --------------------------------- Parsing ---------------------------- */ +int PKI_X509_OCSP_REQ_has_nonce ( PKI_X509_OCSP_REQ *req ); + +int PKI_X509_OCSP_REQ_elements ( PKI_X509_OCSP_REQ *req ); + +PKI_OCSP_CERTID * PKI_X509_OCSP_REQ_get_cid ( PKI_X509_OCSP_REQ *req, int num); + +void * PKI_X509_OCSP_REQ_get_data ( PKI_X509_OCSP_REQ *req, PKI_X509_DATA type ); + +char * PKI_X509_OCSP_REQ_get_parsed ( PKI_X509_OCSP_REQ *req, PKI_X509_DATA type ); + +int PKI_X509_OCSP_REQ_print_parsed ( PKI_X509_OCSP_REQ *req, + PKI_X509_DATA type, int fd ); + +/* -------------------------------- CertID --------------------------------*/ + +PKI_STRING * PKI_OCSP_CERTID_get_issuerNameHash(PKI_OCSP_CERTID * c_id); + +PKI_STRING * PKI_OCSP_CERTID_get_issuerKeyHash(PKI_OCSP_CERTID * c_id); + +PKI_INTEGER * PKI_OCSP_CERTID_get_serialNumber(PKI_OCSP_CERTID * c_id); + +const PKI_DIGEST_ALG * PKI_OCSP_CERTID_get_hashAlgorithm(PKI_OCSP_CERTID * c_id); + +/* ---------------------------- Request Tools ---------------------------- */ + +PKI_INTEGER * PKI_X509_OCSP_REQ_get_serial ( PKI_X509_OCSP_REQ *req, int num); + +const PKI_DIGEST_ALG * PKI_X509_OCSP_REQ_get_hashAlgorithm(PKI_X509_OCSP_REQ * req, + int num); +PKI_STRING * PKI_X509_OCSP_REQ_get_issuerNameHash(PKI_X509_OCSP_REQ * req, + int num); + +PKI_STRING * PKI_X509_OCSP_REQ_get_issuerKeyHash (PKI_X509_OCSP_REQ * req, + int num); + +/* --------------------------------- Tools ------------------------------ */ + +int PKI_OCSP_nonce_check ( PKI_X509_OCSP_REQ *req, PKI_X509_OCSP_RESP *resp ); + +/* ------------------------------- Basic I/O ---------------------------- */ + +PKI_X509_OCSP_REQ_VALUE *PEM_read_bio_OCSP_REQ( PKI_IO *bp, void *, + void *, void * ); +int PEM_write_bio_OCSP_REQ( PKI_IO *bp, PKI_X509_OCSP_REQ_VALUE *o ); +int i2d_OCSP_REQ_bio ( PKI_IO *bio, PKI_X509_OCSP_REQ_VALUE *val ); +PKI_X509_OCSP_REQ_VALUE * d2i_OCSP_REQ_bio ( PKI_IO *bio, + PKI_X509_OCSP_REQ_VALUE *buf ); + +#endif + diff --git a/include/libpki/pkix/ocsp/pki_ocsp_resp.h b/include/libpki/pkix/ocsp/pki_ocsp_resp.h new file mode 100644 index 00000000..eb1bd7c7 --- /dev/null +++ b/include/libpki/pkix/ocsp/pki_ocsp_resp.h @@ -0,0 +1,135 @@ +/* PKI_X509_OCSP_RESP object management */ + +#ifndef _LIBPKI_X509_OCSP_RESP_H +#define _LIBPKI_X509_OCSP_RESP_H + +/* Macros for PKI_MEM conversion */ +#define PKI_X509_OCSP_RESP_mem_der(a) \ + PKI_MEM_new_func( (void *) a, i2d_OCSP_RESP_bio ) +#define PKI_X509_OCSP_RESP_mem_pem(a) \ + PKI_MEM_new_func( (void *) a, PEM_write_bio_OCSP_RESP ) + +/* ---------------------------- Memory Management ----------------------- */ + +PKI_OCSP_RESP *PKI_OCSP_RESP_new ( void ); +void PKI_OCSP_RESP_free( PKI_OCSP_RESP *x ); + +PKI_X509_OCSP_RESP *PKI_X509_OCSP_RESP_new_null( void ); +PKI_X509_OCSP_RESP *PKI_X509_OCSP_RESP_new ( void ); + +void PKI_X509_OCSP_RESP_free_void( void *x ); +void PKI_X509_OCSP_RESP_free( PKI_X509_OCSP_RESP *x ); + +// int PKI_X509_OCSP_RESP_set_keytype_by_key(PKI_X509_OCSP_RESP * x, +// const PKI_X509_KEYPAIR * const key); + +// int PKI_X509_OCSP_RESP_set_keytype_by_cert(PKI_X509_OCSP_RESP * x, +// const PKI_X509_CERT * const cert); + +// int PKI_X509_OCSP_RESP_set_nametype_by_cert(PKI_X509_OCSP_RESP * x, +// const PKI_X509 * const cert); + +// int PKI_X509_OCSP_RESP_set_nametype_by_name(PKI_X509_OCSP_RESP * x, +// const PKI_X509_NAME * const name); + +// int PKI_X509_OCSP_RESP_set_createdAt(PKI_X509_OCSP_RESP * x, int offset); + +/* ---------------------------- Response Manipulation ------------------- */ + +/*! + * @brief Sets the status of the OCSP response + * @param x The OCSP response to which the status should be set + * @param status The status to set + * @return PKI_OK if the status was set successfully, PKI_ERR otherwise + */ +int PKI_X509_OCSP_RESP_set_status (PKI_X509_OCSP_RESP *x, + PKI_X509_OCSP_RESP_STATUS status ); + +/*! + * @brief Adds a single response to the OCSP response + * @param r The OCSP response to which the response should be added + * @param cid The certificate ID of the certificate to which the response + * @param status The status of the certificate + * @param revokeTime The time at which the certificate was revoked + * @param thisUpdate The time at which the source of the revocation information was updated + * @param nextUpdate The time at which the revocation information will be updated again + * @param reason The reason code for the revocation + * @param invalidityDate The date at which the certificate was invalidated + * @return PKI_OK if the response was added successfully, PKI_ERR otherwise + */ +int PKI_X509_OCSP_RESP_add (PKI_X509_OCSP_RESP * r, + PKI_OCSP_CERTID * cid, + PKI_OCSP_CERTSTATUS status, + const PKI_TIME * revokeTime, + const PKI_TIME * thisUpdate, + const PKI_TIME * nextUpdate, + PKI_X509_CRL_REASON reason, + PKI_X509_EXTENSION * invalidityDate); + +/*! + * \brief Copies the NONCE from a PKI_OCSP_RESP into the response + */ +int PKI_X509_OCSP_RESP_copy_nonce (PKI_X509_OCSP_RESP *r, + PKI_X509_OCSP_REQ *req); + +int PKI_X509_OCSP_RESP_set_extendedRevoke(PKI_X509_OCSP_RESP * resp); + +int PKI_X509_OCSP_RESP_bytes_encode ( PKI_X509_OCSP_RESP * resp); + +/* ------------------------------ Signature ----------------------------- */ + +// int PKI_X509_OCSP_RESP_DATA_sign (PKI_X509_OCSP_RESP *r, PKI_X509_KEYPAIR *pkey, +// PKI_DIGEST_ALG *md ); + +/*! + * \brief Signs a PKI_X509_OCSP_RESP + * + * For a simpler API use PKI_X509_OCSP_RESP_sign_tk + */ + +int PKI_X509_OCSP_RESP_sign ( PKI_X509_OCSP_RESP *r, PKI_X509_KEYPAIR *keypair, + PKI_X509_CERT *cert, PKI_X509_CERT *issuer, + PKI_X509_CERT_STACK * otherCerts, PKI_DIGEST_ALG *digest, + PKI_X509_OCSP_RESPID_TYPE respidType); + +/*! + * \brief Signs a PKI_X509_OCSP_RESP object by using a token + */ +int PKI_X509_OCSP_RESP_sign_tk ( PKI_X509_OCSP_RESP *r, PKI_TOKEN *tk, + PKI_DIGEST_ALG *digest, PKI_X509_OCSP_RESPID_TYPE respidType); + +/* ------------------------------ Data Parsing --------------------------- */ + +/*! + * \brief Returns a pointer to the data present in the OCSP request + */ +const void * PKI_X509_OCSP_RESP_get_data ( PKI_X509_OCSP_RESP *r, PKI_X509_DATA type ); + +/*! + * \brief Returns a char * representation of the data present in the + * OCSP request + */ +char * PKI_X509_OCSP_RESP_get_parsed ( PKI_X509_OCSP_RESP *r, PKI_X509_DATA type ); + +/*! + * \brief Prints the requested data from the OCSP request to the file + * descriptor passed as an argument + */ +int PKI_X509_OCSP_RESP_print_parsed ( PKI_X509_OCSP_RESP *r, + PKI_X509_DATA type, int fd ); + +/* ----------------------------- Basic I/O ------------------------------- */ + +/* + *! \brief PEM <-> INTERNAL Macros --- fix for errors in OpenSSL + */ + +PKI_X509_OCSP_RESP_VALUE *PEM_read_bio_PKI_X509_OCSP_RESP_VALUE( PKI_IO *bp, void *a, + void *b, void *c ); +int PEM_write_bio_PKI_X509_OCSP_RESP_VALUE( PKI_IO *bp, PKI_X509_OCSP_RESP_VALUE *o ); + +PKI_OCSP_RESP *d2i_PKI_X509_OCSP_RESP_VALUE_bio ( PKI_IO *bp, PKI_X509_OCSP_RESP_VALUE **p ); + +int i2d_PKI_X509_OCSP_RESP_VALUE_bio(PKI_IO *bp, PKI_X509_OCSP_RESP_VALUE *o ); + +#endif diff --git a/include/libpki/pkix/pki_msg.h b/include/libpki/pkix/pki_msg.h new file mode 100644 index 00000000..a3e90dd2 --- /dev/null +++ b/include/libpki/pkix/pki_msg.h @@ -0,0 +1,71 @@ +/* src/libpki/pki_msg.h - General PKI message */ + +#ifndef _LIBPKI_PKI_MSG_H +#define _LIBPKI_PKI_MSG_H + +/* --------------------------- Enums -------------------------- */ + +typedef enum { + PKI_MSG_PROTO_UNKNOWN = 0, + PKI_MSG_PROTO_SCEP, + PKI_MSG_PROTO_CMC, + PKI_MSG_PROTO_XKMS +} PKI_MSG_PROTO; + +typedef enum { + PKI_MSG_REQ_ACTION_UNKNOWN = 0, + PKI_MSG_REQ_ACTION_CERTREQ, + PKI_MSG_REQ_ACTION_CHECK_CERTREQ, + PKI_MSG_REQ_ACTION_GETCERT, + PKI_MSG_REQ_ACTION_GETCACERT, + PKI_MSG_REQ_ACTION_GETCRL +} PKI_MSG_REQ_ACTION; + +typedef enum { + PKI_MSG_RESP_ACTION_UNKNOWN = 0, + PKI_MSG_RESP_ACTION_CERTREQ, + PKI_MSG_RESP_ACTION_CHECK_CERTREQ, + PKI_MSG_RESP_ACTION_GETCERT, + PKI_MSG_RESP_ACTION_GETCACERT, + PKI_MSG_RESP_ACTION_GETCRL +} PKI_MSG_RESP_ACTION; + +typedef enum { + PKI_MSG_STATUS_UNKNOWN = 0, + PKI_MSG_STATUS_OK, + PKI_MSG_STATUS_FAIL, + PKI_MSG_STATUS_PENDING +} PKI_MSG_STATUS; + +/* ------------------------ Data Structures ------------------- */ + +typedef struct pki_req_msg_st { + PKI_MSG_PROTO proto; + PKI_MSG_REQ_ACTION action; + PKI_X509_CERT *cacert; + PKI_X509_CERT_STACK *recipients; + PKI_X509_KEYPAIR *sign_key; + PKI_X509_CERT *sign_cert; + PKI_DIGEST_ALG *sign_md; + PKI_CRED *cred; + char * subject; + char * template_name; + char * loa; + PKI_MEM * data; + PKI_X509 *msg_data; +} PKI_MSG_REQ; + +typedef struct pki_resp_msg_st { + PKI_MSG_PROTO proto; + PKI_MSG_STATUS status; + PKI_MSG_RESP_ACTION action; + PKI_X509_CERT *cacert; + PKI_X509_KEYPAIR *sign_key; + PKI_X509_CERT *sign_cert; + PKI_X509_CERT_STACK *recipients; + PKI_X509_CERT *issued_cert; + PKI_MEM *data; + PKI_X509 *msg_data; +} PKI_MSG_RESP; + +#endif diff --git a/include/libpki/pkix/pki_msg_req.h b/include/libpki/pkix/pki_msg_req.h new file mode 100644 index 00000000..9599eea4 --- /dev/null +++ b/include/libpki/pkix/pki_msg_req.h @@ -0,0 +1,113 @@ +/* src/libpki/pki_msg_req.h - General PKI message */ + +#ifndef _LIBPKI_PKI_MSG_REQ_H +#define _LIBPKI_PKI_MSG_REQ_H + +/* --------------------------- Functions -------------------------- */ + +/*! \brief Returns an empty generic PKI request message */ +PKI_MSG_REQ *PKI_MSG_REQ_new_null ( void ); + +/*! \brief Free a PKI_MSG_REQ data structure */ +void PKI_MSG_REQ_free ( PKI_MSG_REQ *msg ); + +/*! \brief Adds data to the Message body */ +int PKI_MSG_REQ_add_data ( PKI_MSG_REQ *msg, unsigned char *data, size_t size ); + +/*! \brief Replaces data in a PKI_MSG_REQ message */ +int PKI_MSG_REQ_replace_data ( PKI_MSG_REQ *msg, unsigned char *data, + size_t size ); + +/*! \brief Clears the data of the Message body */ +int PKI_MSG_REQ_clear_data ( PKI_MSG_REQ *msg ); + +/*! \brief Sets the messaging protocol to be used */ +int PKI_MSG_REQ_set_proto ( PKI_MSG_REQ *msg, PKI_MSG_PROTO proto ); + +/*! \brief Returns the PKI_MSG_PROTO from a PKI_MSG_REQUEST object */ +PKI_MSG_PROTO PKI_MSG_REQ_get_proto ( PKI_MSG_REQ *msg ); + +/*! \brief Sets the Certificate of the CA the request is intended for */ +int PKI_MSG_REQ_set_cacert ( PKI_MSG_REQ *msg, PKI_X509_CERT *cacert ); + +/*! \brief Gets the Certificate of the CA the request is intended for */ +PKI_X509_CERT *PKI_MSG_REQ_get_cacert ( PKI_MSG_REQ *msg ); + +/*! \brief Sets the Subject to be used in the certificate request */ +int PKI_MSG_REQ_set_subject ( PKI_MSG_REQ *msg, char *subject ); + +/*! \brief Gets the Subject to be used in the certificate request */ +char * PKI_MSG_REQ_get_subject ( PKI_MSG_REQ *msg ); + +/*! \brief Sets the requested template */ +int PKI_MSG_REQ_set_template ( PKI_MSG_REQ *msg, char *name ); + +/*! \brief Gets the requested template */ +char *PKI_MSG_REQ_get_template ( PKI_MSG_REQ *msg ); + +/*! \brief Sets the requested Level of Assurance (LOA) */ +int PKI_MSG_REQ_set_loa ( PKI_MSG_REQ *msg, char * loa ); + +/*! \brief Gets the requested Level Of Assurance (LOA) */ +char * PKI_MSG_REQ_get_loa ( PKI_MSG_REQ *msg ); + +/*! \brief Sets the basic action in a PKI_MSG_REQ message */ +int PKI_MSG_REQ_set_action ( PKI_MSG_REQ *msg, PKI_MSG_REQ_ACTION action ); + +/*! \brief Gets the basic action in a PKI_MSG_REQ message */ +PKI_MSG_REQ_ACTION PKI_MSG_REQ_get_action ( PKI_MSG_REQ *msg ); + +/*! \brief Sets the Keypair to be used when generating the request */ +int PKI_MSG_REQ_set_keypair ( PKI_MSG_REQ *msg, PKI_X509_KEYPAIR * pkey ); + +/*! \brief Sets the Signer Certificate */ +int PKI_MSG_REQ_set_signer ( PKI_MSG_REQ *msg, PKI_X509_CERT *signer, + PKI_DIGEST_ALG *md ); + +/*! \brief Gets the Signer Certificate */ +PKI_X509_CERT * PKI_MSG_REQ_get_signer ( PKI_MSG_REQ *msg ); + +/*! \brief Gets the Keypair to be used when generating the request */ +PKI_X509_KEYPAIR * PKI_MSG_REQ_get_keypair ( PKI_MSG_REQ *msg ); + +/*! \brief Adds a certificate to the list of recipients */ +int PKI_MSG_REQ_add_recipient ( PKI_MSG_REQ *msg, PKI_X509_CERT *x ); + +/*! \brief Clears the list of recipients in a PKI_MSG_REQ */ +int PKI_MSG_REQ_clear_recipients( PKI_MSG_REQ *msg ); + +/*! \brief Gets the list of recipients in a PKI_MSG_REQ */ +PKI_X509_CERT_STACK *PKI_MSG_REQ_get_recipients( PKI_MSG_REQ *msg ); + +/*! \brief Sets the list of recipients in a PKI_MSG_REQ */ +int PKI_MSG_REQ_set_recipients ( PKI_MSG_REQ *msg, PKI_X509_CERT_STACK *x_sk); + +/*! \brief Gets the encoded version of the message */ +void *PKI_MSG_REQ_get_encoded ( PKI_MSG_REQ *msg ); + +/*! \brief Encodes the message according to the selected PKI_MSG_PROTO */ +int PKI_MSG_REQ_encode ( PKI_MSG_REQ *msg, PKI_MSG_PROTO proto ); + +/*! Builds a new PKI message by using a PKI_TOKEN */ +PKI_MSG_REQ *PKI_MSG_REQ_new_tk( PKI_MSG_REQ_ACTION action, char *subject, + char *template_name, PKI_TOKEN *tk, PKI_DIGEST_ALG *md ); + +/*! Builds a new PKI message */ +PKI_MSG_REQ * PKI_MSG_REQ_new( PKI_MSG_REQ_ACTION action, char * subject, + char *template_name, PKI_X509_KEYPAIR *sign_key, + PKI_X509_CERT *signer, PKI_X509_CERT *cacert, + PKI_DIGEST_ALG *md); + +/*! Sends a message and retrieves the response */ +PKI_MSG_RESP * PKI_MSG_REQ_send ( PKI_MSG_REQ *msg, PKI_TOKEN *tk, + char *url ); + +/*! Returns a SCEP_MSG from the passed PKI_MSG_REQ */ +int PKI_MSG_REQ_SCEP_new ( PKI_MSG_REQ *msg ); + +/* ---------------------------------- SCEP Specific --------------------- */ + +PKI_MSG_RESP *PKI_MSG_REQ_SCEP_send ( PKI_MSG_REQ *msg, PKI_STACK *sk, + PKI_TOKEN *tk ); + +#endif diff --git a/include/libpki/pkix/pki_msg_resp.h b/include/libpki/pkix/pki_msg_resp.h new file mode 100644 index 00000000..fa254134 --- /dev/null +++ b/include/libpki/pkix/pki_msg_resp.h @@ -0,0 +1,96 @@ +/* src/libpki/pki_msg_resp.h - General PKI message (responses) */ + +#ifndef _LIBPKI_PKI_MSG_RESP_H +#define _LIBPKI_PKI_MSG_RESP_H + +/* --------------------------- Functions -------------------------- */ + +/*! \brief Returns an empty generic PKI response message */ +PKI_MSG_RESP *PKI_MSG_RESP_new_null ( void ); + +/*! \brief Free a PKI_MSG_RESP data structure */ +void PKI_MSG_RESP_free ( PKI_MSG_RESP *msg ); + +/*! \brief Adds data to the Message body */ +int PKI_MSG_RESP_add_data (PKI_MSG_RESP *msg, unsigned char *data, size_t size); + +/*! \brief Replaces data in a PKI_MSG_RESP message */ +int PKI_MSG_RESP_replace_data ( PKI_MSG_RESP *msg, unsigned char *data, + size_t size ); + +/*! \brief Clears the data of the Message body */ +int PKI_MSG_RESP_clear_data ( PKI_MSG_RESP *msg ); + +/*! \brief Sets the messaging protocol to be used */ +int PKI_MSG_RESP_set_proto ( PKI_MSG_RESP *msg, PKI_MSG_PROTO proto ); + +/*! \brief Returns the PKI_MSG_PROTO from a PKI_MSG_RESP object */ +PKI_MSG_PROTO PKI_MSG_RESP_get_proto ( PKI_MSG_RESP *msg ); + +/*! \brief Gets the certificate from the Response */ +PKI_X509_CERT *PKI_MSG_RESP_get_issued_cert ( PKI_MSG_RESP *msg ); + +/*! \brief Sets the certificate from the Response */ +int PKI_MSG_RESP_set_issued_cert ( PKI_MSG_RESP *msg, PKI_X509_CERT *x ); + +/*! \brief Gets the CA certificate from the Response */ +PKI_X509_CERT *PKI_MSG_RESP_get_cacert ( PKI_MSG_RESP *msg ); + +/*! \brief Sets the CA certificate in the Response */ +int PKI_MSG_RESP_set_cacert ( PKI_MSG_RESP *msg, PKI_X509_CERT *x ); + +/*! \brief Sets the basic action in a PKI_MSG_RESP message */ +int PKI_MSG_RESP_set_status ( PKI_MSG_RESP *msg, PKI_MSG_STATUS status ); + +/*! \brief Gets the basic action in a PKI_MSG_RESP message */ +PKI_MSG_STATUS PKI_MSG_RESP_get_status ( PKI_MSG_RESP *msg ); + +/*! \brief Sets the basic action in a PKI_MSG_RESP message */ +int PKI_MSG_RESP_set_action ( PKI_MSG_RESP *msg, PKI_MSG_RESP_ACTION action ); + +/*! \brief Gets the basic action in a PKI_MSG_RESP message */ +PKI_MSG_RESP_ACTION PKI_MSG_RESP_get_action ( PKI_MSG_RESP *msg ); + +/*! \brief Sets the Keypair to be used when generating the response */ +int PKI_MSG_RESP_set_keypair ( PKI_MSG_RESP *msg, PKI_X509_KEYPAIR * pkey ); + +/*! \brief Gets the Keypair to be used when generating the response */ +PKI_X509_KEYPAIR * PKI_MSG_RESP_get_keypair ( PKI_MSG_RESP *msg ); + +/*! \brief Sets the Signer Certificate */ +int PKI_MSG_RESP_set_signer ( PKI_MSG_RESP *msg, PKI_X509_CERT *signer ); + +/*! \brief Gets the Signer Certificate */ +PKI_X509_CERT * PKI_MSG_RESP_get_signer ( PKI_MSG_RESP *msg ); + +/*! \brief Adds a certificate to the list of recipients */ +int PKI_MSG_RESP_add_recipient ( PKI_MSG_RESP *msg, PKI_X509_CERT *x ); + +/*! \brief Clears the list of recipients in a PKI_MSG_RESP */ +int PKI_MSG_RESP_clear_recipients( PKI_MSG_RESP *msg ); + +/*! \brief Gets the list of recipients in a PKI_MSG_RESP */ +PKI_X509_CERT_STACK *PKI_MSG_RESP_get_recipients( PKI_MSG_RESP *msg ); + +/*! \brief Sets the list of recipients in a PKI_MSG_RESP */ +int PKI_MSG_RESP_set_recipients( PKI_MSG_RESP *msg, PKI_X509_CERT_STACK *x_sk); + +/*! \brief Gets the encoded version of the Response message */ +void *PKI_MSG_RESP_get_encoded ( PKI_MSG_RESP *msg ); + +/*! \brief Encodes the message according to the selected PKI_MSG_PROTO */ +void *PKI_MSG_RESP_encode ( PKI_MSG_RESP *msg, PKI_MSG_PROTO proto ); + +/*! Builds a new PKI Response message by using a PKI_TOKEN */ +PKI_MSG_RESP *PKI_MSG_RESP_new_tk( PKI_MSG_RESP_ACTION action, + PKI_MSG_STATUS status, PKI_TOKEN *tk ); + +/*! \brief Builds a new message */ +PKI_MSG_RESP * PKI_MSG_RESP_new( PKI_MSG_RESP_ACTION action, + PKI_MSG_STATUS status, PKI_X509_KEYPAIR *sign_key, + PKI_X509_CERT *signer, PKI_X509_CERT *cacert ); + +/*! Returns a SCEP_MSG from the passed PKI_MSG_RESP */ +PKI_X509_SCEP_MSG *PKI_MSG_RESP_SCEP_new ( PKI_MSG_RESP *msg ); + +#endif diff --git a/include/libpki/pkix/prqp/http_client.h b/include/libpki/pkix/prqp/http_client.h new file mode 100644 index 00000000..1d5e73a0 --- /dev/null +++ b/include/libpki/pkix/prqp/http_client.h @@ -0,0 +1,31 @@ +/* + * PRQP Library - HTTP client functions + * by Massimiliano Pala (madwolf@openca.org) + * OpenCA project 2007 + * + * Copyright (c) 2007 The OpenCA Project. All rights reserved. + * + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef _LIBPKI_PRQP_HTTP_CLIENT_H +#define _LIBPKI_PRQP_HTTP_CLIENT_H + +/* Functions */ +/* +BIO *http_connect( URL *url ); +BUF_MEM *http_get_data ( BIO *in, ssize_t max_size ); +PKI_PRQP_RESP *PRQP_http_get_resp ( URL *url, PKI_PRQP_REQ *req, unsigned long max_size ); +BUF_MEM *http_get ( URL *url, unsigned long max_size, char *version ); +int parse_http_headers ( BIO *in ); +*/ + +PKI_X509_PRQP_RESP *PKI_X509_PRQP_RESP_get_http ( URL *url, + PKI_X509_PRQP_REQ *req, unsigned long max_size ); + +#endif diff --git a/include/libpki/pkix/prqp/prqp.h b/include/libpki/pkix/prqp/prqp.h new file mode 100644 index 00000000..52274d07 --- /dev/null +++ b/include/libpki/pkix/prqp/prqp.h @@ -0,0 +1,194 @@ +/* PRQP Implementation + * (c) 2007 by Massimiliano Pala and OpenCA Group + * All Rights Reserved + * + * This software is released under the GPL2 License included + * in the archive. You can not remove this copyright notice. + */ + +#ifndef _LIBPKI_PRQP_H +#define _LIBPKI_PRQP_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#define PKI_PRQP_LIB_CONF_FILE PKI_DEFAULT_ETC_DIR"/pki.conf" +#define PKI_PRQP_LIB_CONF_ENTRY_LONG "queryauthority" +#define PKI_PRQP_LIB_CONF_ENTRY_SHORT "rqa" + +#define PKI_PRQP_DEFAULT_PORT 830 +#define PKI_PRQP_REQ_CONTENT_TYPE "application/prqp-request" +#define PKI_PRQP_RESP_CONTENT_TYPE "application/prqp-response" + +/* +#define PRQP_KP_PRQP_SIGNING_OID "" +#define PRQP_KP_PRQP_SIGNING_OID_TEXT "" + +#define SERVICE_TYPE__OID "1.3.6." +#define SERVICE_TYPE__OID_STRING "" + +#define SERVICE_TYPE_OCSP_OID "1.3.6.1.113733.9.1.1" +#define SERVICE_TYPE_OCSP_OID_STRING "OCSP" +#define SERVICE_TYPE_CRL_OID "1.3.6.1.113733.9.1.2" +#define SERVICE_TYPE_CRL_OID_STRING "CRL" +#define SERVICE_TYPE_TIMESTAMPING_OID "1.3.6.1.113733.9.1.3" +#define SERVICE_TYPE_TIMESTAMPING_OID_STRING "TS" +#define SERVICE_TYPE_DVCS_OID "1.3.6.1.113733.9.1.4" +#define SERVICE_TYPE_DVCS_OID_STRING "DVCS" +#define SERVICE_TYPE_SCVP_OID "1.3.6.1.113733.9.1.5" +#define SERVICE_TYPE_SCVP_OID_STRING "SCVP" +#define SERVICE_TYPE_REVOKE_OID "1.3.6.1.113733.9.1.6" +#define SERVICE_TYPE_REVOKE_OID_STRING "REVOKE" +#define SERVICE_TYPE_SUBSCRIBE_OID "1.3.6.1.113733.9.1.7" +#define SERVICE_TYPE_SUBSCRIBE_OID_STRING "SUBSCRIBE" +*/ + +#define PKI_RESOURCE_TYPE_UNKNOWN 0 +#define PKI_RESOURCE_TYPE_OCSP 1 +#define PKI_RESOURCE_TYPE_CA_ISSUERS 2 +#define PKI_RESOURCE_TYPE_TIMESTAMPING 3 +#define PKI_RESOURCE_TYPE_SCVP 4 +#define PKI_RESOURCE_TYPE_CA_REPOSITORY 5 +#define PKI_RESOURCE_TYPE_HTTP_CERTS 6 +#define PKI_RESOURCE_TYPE_HTTP_CRL 7 +#define PKI_RESOURCE_TYPE_CROSS_CERTS 8 +#define PKI_RESOURCE_TYPE_XKMS_GATEWAY 9 +#define PKI_RESOURCE_TYPE_CMS_GATEWAY 10 +#define PKI_RESOURCE_TYPE_SCEP_GATEWAY 11 +#define PKI_RESOURCE_TYPE_CERT_POLICY 12 +#define PKI_RESOURCE_TYPE_CPS 13 +#define PKI_RESOURCE_TYPE_LOA_POLICY 14 +#define PKI_RESOURCE_TYPE_LOA_LEVEL 15 +#define PKI_RESOURCE_TYPE_HTML_REVOKE 16 +#define PKI_RESOURCE_TYPE_HTML_REQUEST 17 +#define PKI_RESOURCE_TYPE_HTML_RENEW 18 +#define PKI_RESOURCE_TYPE_HTML_SUSPEND 19 +#define PKI_RESOURCE_TYPE_WEBDAV_CERT 20 +#define PKI_RESOURCE_TYPE_WEBDAV_REV 21 + +#define PKI_RESOURCE_TYPE_GRID_ACCREDITATION_BODY 22 +#define PKI_RESOURCE_TYPE_GRID_ACCREDITATION_POLICY 23 +#define PKI_RESOURCE_TYPE_GRID_ACCREDITATION_STATUS 24 +#define PKI_RESOURCE_TYPE_GRID_DISTRIBUTION_UPDATE 25 +#define PKI_RESOURCE_TYPE_GRID_ACCREDITED_CA_CERTS 26 + +#define PKI_RESOURCE_TYPE_TAMP_UPDATE 27 +#define PKI_RESOURCE_TYPE_PRQP 28 + +#define PKI_RESOURCE_TYPE_DELTA_CRL_REPOSITORY 29 +#define PKI_RESOURCE_TYPE_CRL_REPOSITORY 30 + +/* PRQP STATUS INFO STRING and VALUES */ + +#define PKI_X509_PRQP_STATUS_STRING_OK "Ok" +#define PKI_X509_PRQP_STATUS_STRING_BAD_REQUEST "Bad Request" +#define PKI_X509_PRQP_STATUS_STRING_CA_NOT_PRESENT "CA Not Present" +#define PKI_X509_PRQP_STATUS_STRING_SYS_FAILURE "System Failure" +#define PKI_X509_PRQP_STATUS_STRING_UNKNOWN "Unknown" + +#define PKI_X509_PRQP_STATUS_STRING_NUM 4 + +typedef enum { + PKI_X509_PRQP_STATUS_UNKNOWN = -1, + PKI_X509_PRQP_STATUS_OK = 0, + PKI_X509_PRQP_STATUS_BAD_REQUEST = 1, + PKI_X509_PRQP_STATUS_CA_NOT_PRESENT = 2, + PKI_X509_PRQP_STATUS_SYS_FAILURE = 3 +} PKI_X509_PRQP_STATUS; + + +#ifdef __PKI_PRQP_LIB_C__ + +static char *prqp_exts_services[] = { + "1.3.6.1.5.5.7.48.12.0", "rqa", "PRQP RQA Server", + "1.3.6.1.5.5.7.48.12.1", "ocspServer", "OCSP Server", + "1.3.6.1.5.5.7.48.12.2", "subjectCert", "Subject Certificate Retieval URI", + "1.3.6.1.5.5.7.48.12.3", "issuerCert", "Issuer's Certificate Retieval URI", + "1.3.6.1.5.5.7.48.12.4", "timeStamp", "TimeStamping Service", + /* PKIX - not yet defined */ + "1.3.6.1.5.5.7.48.12.5", "scvp", "SCVP Service", + "1.3.6.1.5.5.7.48.12.6", "crlDistribution", "Latest CRL URI", + "1.3.6.1.5.5.7.48.12.7", "certRepository", "CMS Certificate Repository", + "1.3.6.1.5.5.7.48.12.8", "crlRepository", "CMS CRL Repository", + "1.3.6.1.5.5.7.48.12.9", "crossCertRepository", "CMS Cross Certificate Repository", + /* Gateways */ + "1.3.6.1.5.5.7.48.12.10", "cmcGateway", "CMC Gateway", + "1.3.6.1.5.5.7.48.12.11", "scepGateway", "SCEP Gateway", + "1.3.6.1.5.5.7.48.12.12", "htmlGateway", "HTML Gateway", + "1.3.6.1.5.5.7.48.12.13", "xkmsGateway", "XKMS Gateway", + /* Certificate Policies */ + "1.3.6.1.5.5.7.48.12.20", "certPolicy", "Certificate Policy (CP) URL", + "1.3.6.1.5.5.7.48.12.21", "certPracticeStatement", "Certificate Practices Statement (CPS) URL", + "1.3.6.1.5.5.7.48.12.22", "endorsedTA", "CMS Endorsed Trust Anchors", + /* Level of Assurance (LOA) */ + "1.3.6.1.5.5.7.48.12.25", "loaPolicy", "LOA Policy URL", + "1.3.6.1.5.5.7.48.12.26", "certLOALevel", "Certificate LOA Modifier URL", + /* HTTP (Browsers) based services */ + "1.3.6.1.5.5.7.48.12.30", "htmlRequest", "HTML Certificate Request Service URL", + "1.3.6.1.5.5.7.48.12.31", "htmlRevoke", "HTML Based Certificate Revocation Service URL", + "1.3.6.1.5.5.7.48.12.32", "htmlRenew", "HTML Certificate Renewal Service URL", + "1.3.6.1.5.5.7.48.12.33", "htmlSuspend", "HTML Certificate Suspension Service", + /* Webdav Services */ +/* + "1.3.6.1.5.5.7.48.12.40", "webdavCert", "Webdav Certificate Validation URL", + "1.3.6.1.5.5.7.48.12.41", "webdavRev", "Webdav Certificate Revocation URL", +*/ + + /* Grid Specific Services */ + "1.3.6.1.5.5.7.48.12.50", "gridAccreditationBody", "CA Accreditation Bodies", + "1.3.6.1.5.5.7.48.12.51", "gridAccreditationPolicy", "CA Accreditation Policy Document(s) URL", + "1.3.6.1.5.5.7.48.12.52", "gridAccreditationStatus", "CA Accreditation Status Document(s) URL", + "1.3.6.1.5.5.7.48.12.53", "gridDistributionUpdate", "Grid Distribution Package(s) URL", + "1.3.6.1.5.5.7.48.12.54", "gridAccreditedCACerts", "Certificates of Currently Accredited CAs", + /* Trust Anchors Publishing */ + "1.3.6.1.5.5.7.48.71", "apexTampUpdate", "APEX Trust Anchors Update URL", + "1.3.6.1.5.5.7.48.70", "tampUpdate", "Trust Anchors Update URL", + /* CA Incident report URL */ + "1.3.6.1.5.5.7.48.90", "caIncidentReport", "CA Incident Report URL", + /* Private Services */ + "1.3.6.1.5.5.7.48.12.100", "privateSvc", "Private Service", + /* Other PKI */ + // "2.5.29.27", "deltaCrl", "Delta CRL Base Address", + // "2.5.29.31", "crl", "CRL Repository", + /* End of the List */ + NULL, NULL, NULL +}; + +static char *prqp_exts[] = { + /* PRQP extended key usage - id-kp-PRQPSigning ::= { id-kp 10 }*/ + "1.3.6.1.5.5.7.3.11", "prqpSigning", "PRQP Signing", + /* PRQP PKIX identifier - id-prqp ::= { id-pkix 23 } */ + "1.3.6.1.5.5.7.23", "PRQP", "PKI Resource Query Protocol", + /* PRQP PKIX - PTA identifier - { id-prqp 1 } */ + "1.3.6.1.5.5.7.23.1", "PTA", "PRQP Trusted Authority", + /* PRQP AD id-ad-prqp ::= { id-ad 12 } */ + "1.3.6.1.5.5.7.48.12", "prqp", "PRQP Service", + /* End of the List */ + NULL, NULL, NULL +}; +#endif /* __PKI_PRQP_LIB_C__ */ + +#include +#include +#include +#include +#include +#include +#include +#include + + +/* Macros for PKI_MEM conversion */ +#define PKI_PRQP_REQ_mem_der(a) \ + PKI_MEM_new_func( (void *) a, i2d_PKI_PRQP_REQ ) +#define PKI_PRQP_REQ_mem_pem(a) \ + PKI_MEM_new_func_bio( (void *) a, PEM_write_bio_PRQP_REQ ) + +#ifdef __cplusplus +} +#endif +#endif + +/* end */ + diff --git a/include/libpki/pkix/prqp/prqp_asn1.h b/include/libpki/pkix/prqp/prqp_asn1.h new file mode 100644 index 00000000..1f8304ee --- /dev/null +++ b/include/libpki/pkix/prqp/prqp_asn1.h @@ -0,0 +1,275 @@ +/* PRQP Message implementation + * (c) 2006 by Massimiliano Pala and OpenCA Group + * All Rights Reserved + * + * This software is released under the GPL2 License included + * in the archive. You can not remove this copyright notice. + */ + +#ifndef _LIBPK_PRQP_ASN1_H +#define _LIBPK_PRQP_ASN1_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* PRQPSignature ::= SEQUENCE { + * signatureAlgorithm AlgorithmIdentifier, + * signature BIT STRING, + * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL } + */ + +typedef struct PRQPSignature_st { + X509_ALGOR *signatureAlgorithm; + ASN1_BIT_STRING *signature; + X509 *signerCert; + STACK_OF(X509) *otherCerts; +} PRQP_SIGNATURE; + +DECLARE_ASN1_FUNCTIONS(PRQP_SIGNATURE) + +/* BasicCertIdentifier ::= SEQUENCE { + * issuerNameHash OCTET STRING, + * serialNumber CertificateSerialNumber } + */ + +typedef struct BasicCertIdentifier_st { + ASN1_INTEGER *serialNumber; + ASN1_OCTET_STRING * issuerNameHash; +} BASIC_CERT_IDENTIFIER; + +DECLARE_ASN1_FUNCTIONS( BASIC_CERT_IDENTIFIER ) + +/* ExtendedCertInfo ::= SEQUENCE { + * certificateHash OCTET STRING, + * subjectKeyHash OCTET STRING, + * subjectKeyIdentifier [0] KeyIdentifier OPTIONAL, + * issuerKeyIdentifier [1] KeyIdentifier OPTIONAL } + */ + +typedef struct ExtendedCertInfo_st { + ASN1_OCTET_STRING * certificateHash; + ASN1_OCTET_STRING * subjectKeyHash; + ASN1_OCTET_STRING * subjectKeyId; + ASN1_OCTET_STRING * issuerKeyId; +} EXTENDED_CERT_INFO; + +DECLARE_ASN1_FUNCTIONS( EXTENDED_CERT_INFO ) + +/* CertIdentifier ::= SET { + * hashAlgorithm AlgorithmIdentifier, + * basicCertId BasicCertIdentifier, + * extInfo [0] ExtendedCertInfo OPTIONAL } + */ + +typedef struct CertIdentifier_st { + X509_ALGOR * hashAlgorithm; + BASIC_CERT_IDENTIFIER * basicCertId; + EXTENDED_CERT_INFO * extInfo; + X509 * caCert; + X509 * issuedCert; +} CERT_IDENTIFIER; + +// DECLARE_ASN1_SET_OF(CERT_IDENTIFIER) + +DECLARE_ASN1_FUNCTIONS(CERT_IDENTIFIER) + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +CERT_IDENTIFIER *CERT_IDENTIFIER_dup ( const CERT_IDENTIFIER *cid ); +#else +CERT_IDENTIFIER *CERT_IDENTIFIER_dup ( CERT_IDENTIFIER *cid ); +#endif + +/* ResourceIdentifier ::= SEQUENCE { + * resourceId OBJECT IDENTIFIER, + * version [0] INTEGER OPTIONAL } + */ + +typedef struct ResourceIdentifier_st { + ASN1_OBJECT *resourceId; + ASN1_INTEGER *version; + ASN1_OBJECT *oid; +} RESOURCE_IDENTIFIER; + +DECLARE_ASN1_FUNCTIONS(RESOURCE_IDENTIFIER) +DECLARE_STACK_OF(RESOURCE_IDENTIFIER) + +/* ResourceRequestToken ::= SEQUENCE { + * ca certIdentifier, + * serviceList [1] SET OF ResourceIdentifier OPTIONAL } + */ +typedef struct ResourceRequestToken_st { + CERT_IDENTIFIER *ca; + STACK_OF(RESOURCE_IDENTIFIER) *resourceList; +} RESOURCE_REQUEST_TOKEN; + +DECLARE_ASN1_FUNCTIONS(RESOURCE_REQUEST_TOKEN) + +/* TBSReqData ::= SEQUENCE { + * version INTEGER {v(1)}, + * nonce [0] INTEGER OPTIONAL, + * serviceToken ResourceRequestToken, + * extensions [1] IMPLICIT Extensions OPTIONAL } +*/ +typedef struct TBSReqData_st { + ASN1_INTEGER * version; + ASN1_INTEGER * nonce; + ASN1_GENERALIZEDTIME * producedAt; + RESOURCE_REQUEST_TOKEN * serviceToken; + STACK_OF(X509_EXTENSION)* extensions; +} PRQP_TBS_REQ_DATA; + +DECLARE_ASN1_FUNCTIONS(PRQP_TBS_REQ_DATA) + +/* PRQPReq ::= SEQUENCE { + * requestData TBSReqData, + * signature [0] Signature OPTIONAL } + */ + +typedef struct PRQPReq_st { + PRQP_TBS_REQ_DATA *requestData; + PRQP_SIGNATURE * prqpSignature; +} PKI_PRQP_REQ; + +DECLARE_ASN1_FUNCTIONS(PKI_PRQP_REQ) + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +PKI_PRQP_REQ * PKI_PRQP_REQ_dup ( const PKI_PRQP_REQ *x ); +#else +PKI_PRQP_REQ * PKI_PRQP_REQ_dup ( PKI_PRQP_REQ *x ); +#endif + +/* PKIStatus ::= INTEGER { + * ok {0}, + * badRequest {1}, + * caNotPresent {2}, + * systemFailure {3} } + */ + +/* PKIFailureInfo ::= BIT STRING { + * -- since we can fail in more than one way! + * -- More codes may be added in the future if/when required. + * badAlg (0), + * -- unrecognized or unsupported Algorithm Identifier + * badMessageCheck (1), + * -- integrity check failed (e.g., signature did not verify) + * badRequest (2), + * -- transaction not permitted or supported + * badTime (3), + * -- messageTime was not sufficiently close to the system time, + * -- as defined by local policy + * badCertId (4), + * -- no certificate could be found matching the provided criteria + * badDataFormat (5), + * -- the data submitted has the wrong format + * wrongAuthority (6), + * -- the authority indicated in the request is different from the + * -- one creating the response token + * incorrectData (7), + * -- the requester's data is incorrect (for notary services) + * missingTimeStamp (8), + * -- when the timestamp is missing but should be there (by policy) + */ + +/* PKIStatusInfo ::= SEQUENCE { + * status PKIStatus, + * statusString PKIFreeText OPTIONAL, + * failInfo PKIFailureInfo OPTIONAL } + */ + +typedef struct PKIStatusInfo_st { + ASN1_INTEGER *status; + ASN1_UTF8STRING *statusString; + ASN1_BIT_STRING *failInfo; + STACK_OF(ASN1_IA5STRING) *referrals; +} PKI_STATUS_INFO; + +DECLARE_ASN1_FUNCTIONS(PKI_STATUS_INFO) + +/* ResourceInfo ::= { + * resourceUri IA5String, + * version [0] INTEGER OPTIONAL } + */ + +/* +typedef struct ResourceInfo_st { + ASN1_IA5STRING * resourceUri; +} RESOURCE_INFO; + +DECLARE_STACK_OF(RESOURCE_INFO) +DECLARE_ASN1_FUNCTIONS(RESOURCE_INFO) +*/ + +/* ResourceResponseToken ::= { + * serviceId OBJECT IDENTIFIER, + * resLocatorList [0] EXPLICIT SEQUENCE OF ResourceInfo } + */ + +typedef struct ResourceResponseToken_st { + ASN1_OBJECT *resourceId; + STACK_OF(ASN1_IA5STRING) *resLocatorList; + ASN1_INTEGER *version; + ASN1_OBJECT *oid; + ASN1_UTF8STRING *textInfo; +} RESOURCE_RESPONSE_TOKEN; + +DECLARE_ASN1_FUNCTIONS(RESOURCE_RESPONSE_TOKEN) +DECLARE_STACK_OF(RESOURCE_RESPONSE_TOKEN) + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +RESOURCE_RESPONSE_TOKEN * RESOURCE_RESPONSE_TOKEN_dup ( const RESOURCE_RESPONSE_TOKEN * p ); +#else +RESOURCE_RESPONSE_TOKEN * RESOURCE_RESPONSE_TOKEN_dup ( RESOURCE_RESPONSE_TOKEN * p ); +#endif + +/* TBSRespData ::= { + * version INTEGER { v(1) }, + * nonce [0] INTEGER OPTIONAL, + * producedAt GeneralizedTime, + * nextUpdate [1] GeneralizedTime OPTIONAL, + * pkiStatus PKIStatusInfo, + * responseToken [2] SEQUENCE OF ResourceResponseToken OPTIONAL, + * extensions [3] EXPLICIT Extensions OPTIONAL } + */ + +typedef struct TBSRespData_st { + ASN1_INTEGER *version; + ASN1_INTEGER *nonce; + PKI_STATUS_INFO *pkiStatus; + ASN1_GENERALIZEDTIME *producedAt; + ASN1_GENERALIZEDTIME *nextUpdate; + CERT_IDENTIFIER *caCertId; + STACK_OF(RESOURCE_RESPONSE_TOKEN) *responseToken; + STACK_OF(X509_EXTENSION) *extensions; +} PRQP_TBS_RESP_DATA; + +DECLARE_ASN1_FUNCTIONS(PRQP_TBS_RESP_DATA) + +typedef struct PRQPResponse_st { + PRQP_TBS_RESP_DATA *respData; + PRQP_SIGNATURE *prqpSignature; +} PKI_PRQP_RESP; + +DECLARE_ASN1_FUNCTIONS(PKI_PRQP_RESP) + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +PKI_PRQP_RESP * PKI_PRQP_RESP_dup ( const PKI_PRQP_RESP *x ); +#else +PKI_PRQP_RESP * PKI_PRQP_RESP_dup ( PKI_PRQP_RESP *x ); +#endif + +/* Crypto Functionality */ +/* +char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method, + ASN1_IA5STRING *ia5); +ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, char *str); +*/ + +#ifdef __cplusplus +} +#endif +#endif + +/* end */ + diff --git a/include/libpki/pkix/prqp/prqp_bio.h b/include/libpki/pkix/prqp/prqp_bio.h new file mode 100644 index 00000000..dab3a6f8 --- /dev/null +++ b/include/libpki/pkix/prqp/prqp_bio.h @@ -0,0 +1,58 @@ +/* PKI Resource Query Protocol Message implementation + * (c) 2007 by Massimiliano Pala and OpenCA Group + * All Rights Reserved + * + * This software is released under the GPL2 License included + * in the archive. You can not remove this copyright notice. + */ + + +#ifndef _LIBPKI_PRQP_BIO_H +#define _LIBPKI_PRQP_BIO_H + +#define PEM_STRING_PKI_PRQP_REQ "PRQP REQUEST" +#define PEM_STRING_PKI_PRQP_RESP "PRQP RESPONSE" + +#define PKI_CONTENT_TYPE_PKI_PRQP_REQ "application/prqp-request" +#define PKI_CONTENT_TYPE_PKI_PRQP_RESP "application/prqp-response" + +/* Request BIO */ +PKI_PRQP_REQ * d2i_PRQP_REQ_bio ( BIO *bp, PKI_PRQP_REQ *p ); +PKI_PRQP_REQ * PEM_read_bio_PRQP_REQ( BIO *bp ); +int i2d_PRQP_REQ_bio(BIO *bp, PKI_PRQP_REQ *o ); +int PEM_write_bio_PRQP_REQ( BIO *bp, PKI_PRQP_REQ *o ); + +PKI_PRQP_RESP * d2i_PRQP_RESP_bio( BIO *bp, PKI_PRQP_RESP *p ); +PKI_PRQP_RESP * PEM_read_bio_PRQP_RESP( BIO *bp ); +int i2d_PRQP_RESP_bio( BIO *bp, PKI_PRQP_RESP *o ); +int PEM_write_bio_PRQP_RESP( BIO *bp, PKI_PRQP_RESP *o ); + +/* PRQP REQ get/put interface */ +/* +PKI_PRQP_REQ *PKI_PRQP_REQ_get( char *url_s ); +PKI_PRQP_REQ *PKI_PRQP_REQ_get_url( URL *url ); +PKI_PRQP_REQ *PKI_PRQP_REQ_get_fd( int fd ); +PKI_PRQP_REQ *PKI_PRQP_REQ_get_mem( PKI_MEM *mem ); + +int PKI_PRQP_REQ_put( PKI_PRQP_REQ *req, char *url_s, int format ); +int PKI_PRQP_REQ_put_url( PKI_PRQP_REQ *req, URL *url, int format ); +int PKI_PRQP_REQ_put_mem( PKI_PRQP_REQ *req, PKI_MEM *mem, int format ); +int PKI_PRQP_REQ_put_fp( PKI_PRQP_REQ *req, FILE * file, int format ); +*/ + +/* PRQP RESP get/put interface */ +/* +PKI_PRQP_RESP *PKI_PRQP_RESP_get( char *url_s, int timeout ); +PKI_PRQP_RESP *PKI_PRQP_RESP_get_url( URL *url, int timeout ); +PKI_PRQP_RESP *PKI_PRQP_RESP_get_fd( int fd ); +PKI_PRQP_RESP *PKI_PRQP_RESP_get_mem( PKI_MEM *mem ); + +int PKI_PRQP_RESP_put(PKI_PRQP_RESP *res, char *url_s, PKI_DATA_FORMAT format); +int PKI_PRQP_RESP_put_url(PKI_PRQP_RESP *res, URL *url, PKI_DATA_FORMAT format); +int PKI_PRQP_RESP_put_fp( PKI_PRQP_RESP *res, FILE *file, + PKI_DATA_FORMAT format); +int PKI_PRQP_RESP_put_mem( PKI_PRQP_RESP *res, PKI_MEM *mem, + PKI_DATA_FORMAT format); +*/ + +#endif diff --git a/include/libpki/pkix/prqp/prqp_lib.h b/include/libpki/pkix/prqp/prqp_lib.h new file mode 100644 index 00000000..3352c334 --- /dev/null +++ b/include/libpki/pkix/prqp/prqp_lib.h @@ -0,0 +1,129 @@ +/* PKI Resource Query Protocol (PRQP) - Main Lib file + * (c) 2006-2010 by Massimiliano Pala and OpenCA Labs + * All Rights Reserved + * + */ + +#ifndef _LIBPKI_X509_PRQP_LIB_H +#define _LIBPKI_X509_PRQP_LIB_H + +int CERT_IDENTIFIER_cmp ( CERT_IDENTIFIER *a, CERT_IDENTIFIER *b); + +void *PKI_X509_PRQP_REQ_new_null( void ); +void PKI_X509_PRQP_REQ_free_void( void *x ); +void PKI_X509_PRQP_REQ_free ( PKI_X509_PRQP_REQ *x ); + +void *PKI_X509_PRQP_RESP_new_null( void ); +void PKI_X509_PRQP_RESP_free_void( void *x ); +void PKI_X509_PRQP_RESP_free ( PKI_X509_PRQP_RESP *x ); + +/* Service Objects conversion functions */ +int PRQP_init_all_services ( void ); + +/* Certificate Identifier */ +CERT_IDENTIFIER * PKI_PRQP_CERTID_new_cert( + PKI_X509_CERT * caCert, + PKI_X509_CERT * issuerCert, + PKI_X509_CERT * issuedCert, + char * subject_s, + char * serial_s, + PKI_DIGEST_ALG * dgst ); + +CERT_IDENTIFIER *PKI_PRQP_CERTID_new( + const PKI_X509_NAME * caName, + const PKI_X509_NAME * caIssuerName, + const PKI_INTEGER * serial, + const PKI_STRING * caCertHash, + const PKI_STRING * caKeyHash, + const PKI_STRING * caKeyId, + const PKI_STRING * issKeyId, + const PKI_DIGEST_ALG *dgst); + +/* Certificate Identifier */ +/* +CERT_IDENTIFIER * PKI_PRQP_CERTID_new_cert( + const PKI_X509_CERT * caCert, + const PKI_X509_CERT * issuerCert, + const PKI_X509_CERT * issuedCert, + const char * subject_s, + const char * serial_s, + const PKI_DIGEST_ALG * dgst ); + +CERT_IDENTIFIER *PKI_PRQP_CERTID_new( + const PKI_X509_NAME * caName, + const PKI_X509_NAME * caIssuerName, + const PKI_INTEGER * serial, + const PKI_STRING * caCertHash, + const PKI_STRING * caKeyHash, + const PKI_STRING * caKeyId, + const PKI_STRING * issKeyId, + const PKI_DIGEST_ALG *dgst); +*/ + +/* General Signature Function for req or resp */ +int PKI_X509_PRQP_sign( PKI_X509 *obj, PKI_X509_KEYPAIR *k, + PKI_X509_CERT *x, PKI_DIGEST_ALG *dgst, + PKI_X509_CERT_STACK * certs ); +int PKI_X509_PRQP_sign_tk ( PKI_X509 *obj, PKI_TOKEN *tk, PKI_DIGEST_ALG *dgst ); + +// ***************** REQUEST ******************* + +PKI_X509_PRQP_REQ *PKI_X509_PRQP_REQ_new_cert(PKI_X509_CERT *x, PKI_X509_CERT *issuer, + PKI_X509_CERT *issued, char *issuer_s, char *serial_s, PKI_DIGEST_ALG *md ); + +PKI_X509_PRQP_REQ *PKI_X509_PRQP_REQ_new_url( char * cert_s, char *issuer_cert_s, + char *issued_cert_s, char *issuer_s, char *serial_s, PKI_DIGEST_ALG *md ); + +PKI_X509_PRQP_REQ *PKI_X509_PRQP_REQ_new_file( char * file, PKI_DATA_FORMAT format); + +PKI_X509_PRQP_REQ * PKI_X509_PRQP_REQ_new_certs_res( PKI_X509_CERT *caCert, + PKI_X509_CERT *caIssuerCert, PKI_X509_CERT *issuedCert, PKI_STACK *sk_srv ); + +PKI_INTEGER *PKI_X509_PRQP_NONCE_new (int size); + +/* Helper functions to add services to requests */ +int PKI_X509_PRQP_REQ_add_service_stack ( PKI_X509_PRQP_REQ *p, PKI_STACK *sk_services ); +int PKI_X509_PRQP_REQ_add_service ( PKI_X509_PRQP_REQ *p, char *ss ); + +int PKI_X509_PRQP_REQ_is_signed( PKI_X509_PRQP_REQ *r ); +int PKI_X509_PRQP_REQ_verify ( PKI_X509_PRQP_REQ *r ); + +void * PKI_X509_PRQP_REQ_get_data ( PKI_X509_PRQP_REQ *r, PKI_X509_DATA type ); + +// ***************** RESPONSE ****************** + +int PKI_X509_PRQP_RESP_version_set ( PKI_X509_PRQP_RESP *resp, int ver ); + +int PKI_X509_PRQP_RESP_nonce_dup ( PKI_X509_PRQP_RESP *resp, PKI_X509_PRQP_REQ *req ); +int PKI_X509_PRQP_RESP_pkistatus_set ( PKI_X509_PRQP_RESP *resp, long v, char *info ); +int PKI_X509_PRQP_RESP_add_referrals ( PKI_X509_PRQP_RESP *r, PKI_STACK *referrals); +int PKI_X509_PRQP_RESP_add_service ( PKI_X509_PRQP_RESP *r, PKI_OID * resId, char * url, + long long version, char *comment, PKI_OID *oid ); +int PKI_X509_PRQP_RESP_add_service_stack ( PKI_X509_PRQP_RESP *r, PKI_OID *resId, + PKI_STACK *url_stack, long long version, char *comment, + PKI_OID *oid ); + +PKI_X509_PRQP_RESP *PKI_X509_PRQP_RESP_new_req ( PKI_X509_PRQP_RESP **resp_pnt, + PKI_X509_PRQP_REQ *req, int status, long secs ); +PKI_STACK * PKI_X509_PRQP_RESP_url_sk ( PKI_X509_PRQP_RESP *r ); + +int PKI_X509_PRQP_RESP_is_signed( PKI_X509_PRQP_RESP *r ); +int PKI_X509_PRQP_RESP_verify ( PKI_X509_PRQP_RESP *r ); + +void * PKI_X509_PRQP_RESP_get_data ( PKI_X509_PRQP_RESP *r, PKI_X509_DATA type ); +PKI_OID *PRQP_RESOURCE_RESPONSE_TOKEN_get_oid ( RESOURCE_RESPONSE_TOKEN *rrt ); +PKI_STACK *PRQP_RESOURCE_RESPONSE_TOKEN_get_services( RESOURCE_RESPONSE_TOKEN *rrt ); +int PKI_X509_PRQP_RESP_get_status ( PKI_X509_PRQP_RESP *r ); + +// ******************** Print facilities ******************* + +int PKI_X509_PRQP_REQ_print ( PKI_X509_PRQP_REQ *req ); +int PKI_X509_PRQP_REQ_print_fp ( FILE *fp, PKI_X509_PRQP_REQ *req); +int PKI_X509_PRQP_REQ_VALUE_print_bio ( PKI_X509_PRQP_REQ_VALUE *req, BIO *bio); + +int PKI_X509_PRQP_RESP_print ( PKI_X509_PRQP_RESP *resp ); +int PKI_X509_PRQP_RESP_print_fp ( FILE *fp, PKI_X509_PRQP_RESP *resp ); +int PKI_X509_PRQP_RESP_VALUE_print_bio ( PKI_X509_PRQP_RESP_VALUE *resp, BIO *bio ); + + +#endif diff --git a/include/libpki/pkix/prqp/prqp_req_io.h b/include/libpki/pkix/prqp/prqp_req_io.h new file mode 100644 index 00000000..0d33a47a --- /dev/null +++ b/include/libpki/pkix/prqp/prqp_req_io.h @@ -0,0 +1,43 @@ +/* PKI_X509_PRQP_REQ I/O management */ + +#ifndef _LIBPKI_X509_PRQP_REQ_IO_H +#define _LIBPKI_X509_PRQP_REQ_IO_H + +#define PKI_X509_PRQP_REQ_BEGIN_ARMOUR "-----BEGIN PRQP REQUEST-----" +#define PKI_X509_PRQP_REQ_END_ARMOUR "-----END PRQP REQUEST-----" + +/* --------------------- PRQP REQ get (load) functions ------------------- */ +PKI_X509_PRQP_REQ *PKI_X509_PRQP_REQ_get ( char *url_s, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ); +PKI_X509_PRQP_REQ *PKI_X509_PRQP_REQ_get_url ( URL *url, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ); +PKI_X509_PRQP_REQ_STACK *PKI_X509_PRQP_REQ_STACK_get ( char *url_s, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ); +PKI_X509_PRQP_REQ_STACK *PKI_X509_PRQP_REQ_STACK_get_url ( URL *url, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm); + +/* -------------------- PRQP REQ put (write) functions ------------------- */ +int PKI_X509_PRQP_REQ_put ( PKI_X509_PRQP_REQ *x, PKI_DATA_FORMAT format, + char *url_string, char *mime, PKI_CRED *cred, HSM *hsm ); +int PKI_X509_PRQP_REQ_put_url ( PKI_X509_PRQP_REQ *x, PKI_DATA_FORMAT format, URL *url, + char *mime, PKI_CRED *cred, HSM *hsm ); +int PKI_X509_PRQP_REQ_STACK_put (PKI_X509_PRQP_REQ_STACK *sk, PKI_DATA_FORMAT format, + char *url_string, char *mime, PKI_CRED *cred, HSM *hsm ); +int PKI_X509_PRQP_REQ_STACK_put_url (PKI_X509_PRQP_REQ_STACK *sk, PKI_DATA_FORMAT format, + URL *url, char *mime, PKI_CRED *cred, HSM *hsm ); + +/* ---------------------- PRQP_REQ mem Operations ------------------------ */ + +PKI_X509_PRQP_REQ * PKI_X509_PRQP_REQ_get_mem ( PKI_MEM *mem, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ); + +PKI_X509_PRQP_REQ_STACK *PKI_X509_PRQP_REQ_STACK_get_mem(PKI_MEM *mem, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm); + +PKI_MEM * PKI_X509_PRQP_REQ_put_mem ( PKI_X509_PRQP_REQ *req, + PKI_DATA_FORMAT format, PKI_MEM **pki_mem, PKI_CRED *cred, HSM *hsm ); + +PKI_MEM *PKI_X509_PRQP_REQ_STACK_put_mem (PKI_X509_PRQP_REQ_STACK *sk, PKI_DATA_FORMAT format, + PKI_MEM **mem, PKI_CRED *cred, HSM *hsm); + +#endif diff --git a/include/libpki/pkix/prqp/prqp_resp_io.h b/include/libpki/pkix/prqp/prqp_resp_io.h new file mode 100644 index 00000000..af83f719 --- /dev/null +++ b/include/libpki/pkix/prqp/prqp_resp_io.h @@ -0,0 +1,43 @@ +/* PKI_X509_PRQP_RESP I/O management */ + +#ifndef _LIBPKI_X509_PRQP_RESP_IO_H +#define _LIBPKI_X509_PRQP_RESP_IO_H + +#define PKI_X509_PRQP_RESP_BEGIN_ARMOUR "-----BEGIN PRQP RESPUEST-----" +#define PKI_X509_PRQP_RESP_END_ARMOUR "-----END PRQP RESPUEST-----" + +/* --------------------- PRQP RESP get (load) functions ------------------- */ +PKI_X509_PRQP_RESP *PKI_X509_PRQP_RESP_get ( char *url_s, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ); +PKI_X509_PRQP_RESP *PKI_X509_PRQP_RESP_get_url ( URL *url, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ); +PKI_X509_PRQP_RESP_STACK *PKI_X509_PRQP_RESP_STACK_get ( char *url_s, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ); +PKI_X509_PRQP_RESP_STACK *PKI_X509_PRQP_RESP_STACK_get_url ( URL *url, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm); + +/* -------------------- PRQP RESP put (write) functions ------------------- */ +int PKI_X509_PRQP_RESP_put ( PKI_X509_PRQP_RESP *x, PKI_DATA_FORMAT format, + char *url_string, char *mime, PKI_CRED *cred, HSM *hsm ); +int PKI_X509_PRQP_RESP_put_url ( PKI_X509_PRQP_RESP *x, PKI_DATA_FORMAT format, URL *url, + char *mime, PKI_CRED *cred, HSM *hsm ); +int PKI_X509_PRQP_RESP_STACK_put (PKI_X509_PRQP_RESP_STACK *sk, PKI_DATA_FORMAT format, + char *url_string, char *mime, PKI_CRED *cred, HSM *hsm ); +int PKI_X509_PRQP_RESP_STACK_put_url (PKI_X509_PRQP_RESP_STACK *sk, PKI_DATA_FORMAT format, + URL *url, char *mime, PKI_CRED *cred, HSM *hsm ); + +/* ---------------------- PRQP_RESP mem Operations ------------------------ */ + +PKI_X509_PRQP_RESP * PKI_X509_PRQP_RESP_get_mem ( PKI_MEM *mem, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ); + +PKI_X509_PRQP_RESP_STACK *PKI_X509_PRQP_RESP_STACK_get_mem(PKI_MEM *mem, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm); + +PKI_MEM * PKI_X509_PRQP_RESP_put_mem ( PKI_X509_PRQP_RESP *x, + PKI_DATA_FORMAT format, PKI_MEM **pki_mem, PKI_CRED *cred, HSM *hsm ); + +PKI_MEM *PKI_X509_PRQP_RESP_STACK_put_mem (PKI_X509_PRQP_RESP_STACK *sk, + PKI_DATA_FORMAT format, PKI_MEM **mem, PKI_CRED *cred, HSM *hsm); + +#endif diff --git a/include/libpki/pkix/prqp/prqp_srv.h b/include/libpki/pkix/prqp/prqp_srv.h new file mode 100644 index 00000000..9412784f --- /dev/null +++ b/include/libpki/pkix/prqp/prqp_srv.h @@ -0,0 +1,25 @@ +/* + * PKI Resource Query Protocol Message implementation + * (c) 2006-2007 by Massimiliano Pala and OpenCA Group + * All Rights Reserved + */ + +#ifndef _LIBPKI_X509_PRQP_SRV_H +#define _LIBPKI_X509_PRQP_SRV_H + +PKI_STACK * PKI_get_ca_resources(PKI_X509_CERT *caCert, + PKI_X509_CERT *caIssuerCert, PKI_X509_CERT *issuedCert, + PKI_STACK *sk_services, char *url_s ); + +PKI_STACK * PKI_get_ca_service_sk( PKI_X509_CERT *caCert, + char *srv, char *url_s ); +PKI_STACK * PKI_get_cert_service_sk( PKI_X509_CERT *cert, + char *srv, char *url_s ); +char * PKI_get_ca_service( PKI_X509_CERT *caCert, char *srv, char *url_s ); + +PKI_X509_PRQP_RESP * PKI_DISCOVER_get_resp ( PKI_X509_PRQP_REQ *p, char *url_s ); +PKI_X509_PRQP_RESP * PKI_DISCOVER_get_resp_url ( PKI_X509_PRQP_REQ *p, URL *url ); + +#endif + + diff --git a/include/libpki/pkix/prqp/prqp_stack.h b/include/libpki/pkix/prqp/prqp_stack.h new file mode 100644 index 00000000..ddfd8b74 --- /dev/null +++ b/include/libpki/pkix/prqp/prqp_stack.h @@ -0,0 +1,135 @@ +/* PRQP Message implementation + * (c) 2006 by Massimiliano Pala and OpenCA Group + * All Rights Reserved + * + * This software is released under the GPL2 License included + * in the archive. You can not remove this copyright notice. + */ + +#ifndef _LIBPK_PRQP_STACK_H +#define _LIBPK_PRQP_STACK_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define PKI_X509_PRQP_REQ_STACK PKI_STACK +#define PKI_X509_PRQP_RESP_STACK PKI_STACK +#define PKI_RESOURCE_IDENTIFIER_STACK PKI_STACK +#define PKI_RESOURCE_RESPONSE_TOKEN_STACK PKI_STACK + +/* Define Stacks for RESOURCE_IDENTIFIER, RESOURCE_RESPONSE_TOKEN and + ASN1_IA5STRING */ + +/* RESOURCE_IDENTIFIER stack definitions */ +#if OPENSSL_VERSION_NUMBER < 0x1010000fL +# define sk_RESOURCE_IDENTIFIER_new(st) SKM_sk_new(RESOURCE_IDENTIFIER, (st)) +# define sk_RESOURCE_IDENTIFIER_new_null() SKM_sk_new(RESOURCE_IDENTIFIER, NULL) +# define sk_RESOURCE_IDENTIFIER_free(st) SKM_sk_free(RESOURCE_IDENTIFIER, (st)) +# define sk_RESOURCE_IDENTIFIER_num(st) SKM_sk_num(RESOURCE_IDENTIFIER, (st)) +# define sk_RESOURCE_IDENTIFIER_value(st, i) SKM_sk_value(RESOURCE_IDENTIFIER, (st), (i)) +# define sk_RESOURCE_IDENTIFIER_push(st, val) SKM_sk_push(RESOURCE_IDENTIFIER, (st), (val)) +# define sk_RESOURCE_IDENTIFIER_dup(st) SKM_sk_dup(RESOURCE_IDENTIFIER, st) +# define sk_RESOURCE_IDENTIFIER_pop_free(st, free_func) SKM_sk_pop_free(RESOURCE_IDENTIFIER, (st), (free_func)) +# define sk_RESOURCE_IDENTIFIER_pop(st) SKM_sk_pop(RESOURCE_IDENTIFIER, (st)) +#endif + +/* define for PRQP's RESOURCE_IDENTIFIER stacks - implement object type + * casting */ +#define PKI_STACK_RESOURCE_IDENTIFIER_new_null() (PKI_RESOURCE_IDENTIFIER_STACK *) PKI_STACK_new( NULL ) +#define PKI_STACK_RESOURCE_IDENTIFIER_new() (PKI_RESOURCE_IDENTIFIER_STACK *) PKI_STACK_new(PKI_RESOURCE_IDENTIFIER_free_void) +#define PKI_STACK_RESOURCE_IDENTIFIER_free( p ) PKI_STACK_free ( (PKI_STACK *) p) +#define PKI_STACK_RESOURCE_IDENTIFIER_free_all( p ) PKI_STACK_free_all ( (PKI_STACK *) p) +#define PKI_STACK_RESOURCE_IDENTIFIER_push(p, obj) PKI_STACK_push((PKI_STACK *)p, (void *)obj) +#define PKI_STACK_RESOURCE_IDENTIFIER_pop(p) (RESOURCE_IDENTIFIER *) PKI_STACK_pop( (PKI_STACK *) p ) +#define PKI_STACK_RESOURCE_IDENTIFIER_get_num(p,n) (RESOURCE_IDENTIFIER *) PKI_STACK_get_num( (PKI_STACK *)p, n) +#define PKI_STACK_RESOURCE_IDENTIFIER_ins_num(p,n,obj) PKI_STACK_ins_num((PKI_STACK *)p,n,(void *)obj) +#define PKI_STACK_RESOURCE_IDENTIFIER_del_num(p,n) PKI_STACK_del_num((PKI_STACK *)p, n) +#define PKI_STACK_RESOURCE_IDENTIFIER_elements(p) PKI_STACK_elements((PKI_STACK *)p) + +/* RESOURCE_RESPONSE_TOKEN stack definitions */ +#if OPENSSL_VERSION_NUMBER < 0x1010000fL +# define sk_RESOURCE_RESPONSE_TOKEN_new(st) SKM_sk_new(RESOURCE_RESPONSE_TOKEN, (st)) +# define sk_RESOURCE_RESPONSE_TOKEN_new_null() SKM_sk_new_null(RESOURCE_RESPONSE_TOKEN) +# define sk_RESOURCE_RESPONSE_TOKEN_free(st) SKM_sk_free(RESOURCE_RESPONSE_TOKEN, (st)) +# define sk_RESOURCE_RESPONSE_TOKEN_num(st) SKM_sk_num(RESOURCE_RESPONSE_TOKEN, (st)) +# define sk_RESOURCE_RESPONSE_TOKEN_value(st, i) SKM_sk_value(RESOURCE_RESPONSE_TOKEN, (st), (i)) +# define sk_RESOURCE_RESPONSE_TOKEN_push(st, val) SKM_sk_push(RESOURCE_RESPONSE_TOKEN, (st), (val)) +# define sk_RESOURCE_RESPONSE_TOKEN_dup(st) SKM_sk_dup(RESOURCE_RESPONSE_TOKEN, st) +# define sk_RESOURCE_RESPONSE_TOKEN_pop_free(st, free_func) SKM_sk_pop_free(RESOURCE_RESPONSE_TOKEN, (st), (free_func)) +# define sk_RESOURCE_RESPONSE_TOKEN_pop(st) SKM_sk_pop(RESOURCE_RESPONSE_TOKEN, (st)) +#endif + +/* define for PRQP's RESOURCE_RESPONSE_TOKEN stacks - implement object type + * casting */ +#define PKI_STACK_RESOURCE_RESPONSE_TOKEN_new_null() (PKI_RESOURCE_RESPONSE_TOKEN_STACK *) PKI_STACK_new( NULL ) +#define PKI_STACK_RESOURCE_RESPONSE_TOKEN_new() (PKI_RESOURCE_RESPONSE_TOKEN_STACK *) PKI_STACK_new(PKI_RESOURCE_RESPONSE_TOKEN_free_void) +#define PKI_STACK_RESOURCE_RESPONSE_TOKEN_free( p ) PKI_STACK_free ( (PKI_STACK *) p) +#define PKI_STACK_RESOURCE_RESPONSE_TOKEN_free_all( p ) PKI_STACK_free_all ( (PKI_STACK *) p) +#define PKI_STACK_RESOURCE_RESPONSE_TOKEN_push(p, obj) PKI_STACK_push((PKI_STACK *)p, (void *)obj) +#define PKI_STACK_RESOURCE_RESPONSE_TOKEN_pop(p) (RESOURCE_RESPONSE_TOKEN *) PKI_STACK_pop( (PKI_STACK *) p ) +#define PKI_STACK_RESOURCE_RESPONSE_TOKEN_get_num(p,n) (RESOURCE_RESPONSE_TOKEN *) PKI_STACK_get_num( (PKI_STACK *)p, n) +#define PKI_STACK_RESOURCE_RESPONSE_TOKEN_ins_num(p,n,obj) PKI_STACK_ins_num((PKI_STACK *)p,n,(void *)obj) +#define PKI_STACK_RESOURCE_RESPONSE_TOKEN_del_num(p,n) PKI_STACK_del_num((PKI_STACK *)p, n) +#define PKI_STACK_RESOURCE_RESPONSE_TOKEN_elements(p) PKI_STACK_elements((PKI_STACK *)p) + +/* RESOURCE_INFO stack definitions */ +/* @DEPRECATED/REMOVED +# define sk_RESOURCE_INFO_new(st) SKM_sk_new(RESOURCE_INFO, (st)) +# define sk_RESOURCE_INFO_new_null() SKM_sk_new_null(RESOURCE_INFO) +# define sk_RESOURCE_INFO_free(st) SKM_sk_free(RESOURCE_INFO, (st)) +# define sk_RESOURCE_INFO_num(st) SKM_sk_num(RESOURCE_INFO, (st)) +# define sk_RESOURCE_INFO_value(st, i) SKM_sk_value(RESOURCE_INFO, (st), (i)) +# define sk_RESOURCE_INFO_push(st, val) SKM_sk_push(RESOURCE_INFO, (st), (val)) +# define sk_RESOURCE_INFO_dup(st) SKM_sk_dup(RESOURCE_INFO, st) +# define sk_RESOURCE_INFO_pop_free(st, free_func) SKM_sk_pop_free(RESOURCE_INFO, (st), (free_func)) +# define sk_RESOURCE_INFO_pop(st) SKM_sk_pop(RESOURCE_INFO, (st)) +*/ + +/* ASN1_IA5STRING stack definitions */ +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL +DEFINE_STACK_OF(ASN1_IA5STRING) +#else +# define sk_ASN1_IA5STRING_new(st) SKM_sk_new(ASN1_IA5STRING, (st)) +# define sk_ASN1_IA5STRING_new_null() SKM_sk_new_null(ASN1_IA5STRING) +# define sk_ASN1_IA5STRING_free(st) SKM_sk_free(ASN1_IA5STRING, (st)) +# define sk_ASN1_IA5STRING_num(st) SKM_sk_num(ASN1_IA5STRING, (st)) +# define sk_ASN1_IA5STRING_value(st, i) SKM_sk_value(ASN1_IA5STRING, (st), (i)) +# define sk_ASN1_IA5STRING_push(st, val) SKM_sk_push(ASN1_IA5STRING, (st), (val)) +# define sk_ASN1_IA5STRING_dup(st) SKM_sk_dup(ASN1_IA5STRING, st) +# define sk_ASN1_IA5STRING_pop_free(st, free_func) SKM_sk_pop_free(ASN1_IA5STRING, (st), (free_func)) +# define sk_ASN1_IA5STRING_pop(st) SKM_sk_pop(ASN1_IA5STRING, (st)) +#endif + +/* define for PRQP's REQUESTS stacks - implement object type casting */ +#define PKI_STACK_X509_PRQP_REQ_new_null() (PKI_X509_PRQP_REQ_STACK *) PKI_STACK_new( NULL ) +#define PKI_STACK_X509_PRQP_REQ_new() (PKI_X509_PRQP_REQ_STACK *) PKI_STACK_new(PKI_X509_PRQP_REQ_free_void) +#define PKI_STACK_X509_PRQP_REQ_free( p ) PKI_STACK_free ( (PKI_STACK *) p) +#define PKI_STACK_X509_PRQP_REQ_free_all( p ) PKI_STACK_free_all ( (PKI_STACK *) p) +#define PKI_STACK_X509_PRQP_REQ_push(p, obj) PKI_STACK_push((PKI_STACK *)p, (void *)obj) +#define PKI_STACK_X509_PRQP_REQ_pop(p) (PKI_X509_PRQP_REQ *) PKI_STACK_pop( (PKI_STACK *) p ) +#define PKI_STACK_X509_PRQP_REQ_get_num(p,n) (PKI_X509_PRQP_REQ *) PKI_STACK_get_num( (PKI_STACK *)p, n) +#define PKI_STACK_X509_PRQP_REQ_ins_num(p,n,obj) PKI_STACK_ins_num((PKI_STACK *)p,n,(void *)obj) +#define PKI_STACK_X509_PRQP_REQ_del_num(p,n) PKI_STACK_del_num((PKI_STACK *)p, n) +#define PKI_STACK_X509_PRQP_REQ_elements(p) PKI_STACK_elements((PKI_STACK *)p) + +/* define for PRQP's RESPONSE stacks - implement object type casting */ +#define PKI_STACK_X509_PRQP_RESP_new_null() (PKI_X509_PRQP_RESP_STACK *) PKI_STACK_new( NULL ) +#define PKI_STACK_X509_PRQP_RESP_new() (PKI_X509_PRQP_RESP_STACK *) PKI_STACK_new(PKI_X509_PRQP_RESP_free_void) +#define PKI_STACK_X509_PRQP_RESP_free( p ) PKI_STACK_free ( (PKI_STACK *) p) +#define PKI_STACK_X509_PRQP_RESP_free_all( p ) PKI_STACK_free_all ( (PKI_STACK *) p) +#define PKI_STACK_X509_PRQP_RESP_push(p, obj) PKI_STACK_push((PKI_STACK *)p, (void *)obj) +#define PKI_STACK_X509_PRQP_RESP_pop(p) (PKI_X509_PRQP_RESP *) PKI_STACK_pop( (PKI_STACK *) p ) +#define PKI_STACK_X509_PRQP_RESP_get_num(p,n) (PKI_X509_PRQP_RESP *) PKI_STACK_get_num( (PKI_STACK *)p, n) +#define PKI_STACK_X509_PRQP_RESP_ins_num(p,n,obj) PKI_STACK_ins_num((PKI_STACK *)p,n,(void *)obj) +#define PKI_STACK_X509_PRQP_RESP_del_num(p,n) PKI_STACK_del_num((PKI_STACK *)p, n) +#define PKI_STACK_X509_PRQP_RESP_elements(p) PKI_STACK_elements((PKI_STACK *)p) + + +#ifdef __cplusplus +} +#endif +#endif + +/* end */ + diff --git a/include/libpki/pkix/scep/pki_x509_scep_asn1.h b/include/libpki/pkix/scep/pki_x509_scep_asn1.h new file mode 100644 index 00000000..1f9407c5 --- /dev/null +++ b/include/libpki/pkix/scep/pki_x509_scep_asn1.h @@ -0,0 +1,15 @@ +/* + * SCEP - ASN1 Functions + */ + +#ifndef _LIBPKI_PKI_X509_SCEP_ASN1_H +#define _LIBPKI_PKI_X509_SCEP_ASN1_H + +typedef struct scep_issuer_and_subject_st { + X509_NAME *issuer; + X509_NAME *subject; +} SCEP_ISSUER_AND_SUBJECT; + +DECLARE_ASN1_FUNCTIONS(SCEP_ISSUER_AND_SUBJECT) + +#endif diff --git a/include/libpki/pkix/scep/pki_x509_scep_attrs.h b/include/libpki/pkix/scep/pki_x509_scep_attrs.h new file mode 100644 index 00000000..a74b725b --- /dev/null +++ b/include/libpki/pkix/scep/pki_x509_scep_attrs.h @@ -0,0 +1,108 @@ +/* + * OpenCA SCEP -- signed attributes handling routines + * (c) 2003-2009 by Massimiliano Pala and OpenCA Group + */ + +#ifndef _LIBPKI_SCEP_SIGNED_ATTRS_H +#define _LIBPKI_SCEP_SIGNED_ATTRS_H + +void PKI_X509_SCEP_init(void); + +SCEP_ATTRIBUTE_TYPE PKI_X509_SCEP_ATTRIBUTE_get_txt(const char * const txt); + +PKI_ID PKI_X509_SCEP_ATTRIBUTE_get_nid(SCEP_ATTRIBUTE_TYPE num); + +PKI_OID *PKI_X509_SCEP_MSG_get_oid(SCEP_ATTRIBUTE_TYPE scep_attribute); + +int PKI_X509_SCEP_MSG_set_attribute(PKI_X509_SCEP_MSG * msg, + SCEP_ATTRIBUTE_TYPE type, + const unsigned char * const data, + size_t size); + +int PKI_X509_SCEP_MSG_set_attribute_by_name(PKI_X509_SCEP_MSG * msg, + const char * const name, + const unsigned char * const data, + size_t size); + +int PKI_X509_SCEP_MSG_set_attribute_int(PKI_X509_SCEP_MSG * msg, + PKI_ID id, + int val); + +PKI_MEM * PKI_X509_SCEP_MSG_get_attr_value(const PKI_X509_SCEP_MSG * const msg, + SCEP_ATTRIBUTE_TYPE type); + +int PKI_X509_SCEP_MSG_get_attr_value_int(const PKI_X509_SCEP_MSG * const msg, + SCEP_ATTRIBUTE_TYPE type); + +/* ------------------------ Specific Attributes ------------------------ */ + +PKI_MEM *PKI_X509_SCEP_MSG_new_trans_id(const PKI_X509_KEYPAIR * key); + +int PKI_X509_SCEP_MSG_set_trans_id(PKI_X509_SCEP_MSG * msg, + const PKI_MEM * mem); + +char * PKI_X509_SCEP_MSG_get_trans_id(const PKI_X509_SCEP_MSG * const msg); + + +int PKI_X509_SCEP_MSG_set_sender_nonce(PKI_X509_SCEP_MSG * msg, + const PKI_MEM * const mem); + + +int PKI_X509_SCEP_MSG_set_recipient_nonce(PKI_X509_SCEP_MSG * msg, + const PKI_MEM * const mem); + +/*! \brief Sets the messageType attribute in a SCEP message */ + +int PKI_X509_SCEP_MSG_set_type(PKI_X509_SCEP_MSG * msg, + SCEP_MESSAGE_TYPE type); + + +/*! \brief Returns the messageType attribute from a SCEP message */ + +SCEP_MESSAGE_TYPE PKI_X509_SCEP_MSG_get_type(const PKI_X509_SCEP_MSG * const msg); + + +/*! \brief Sets the pkiStatus attribute in a SCEP message */ + +int PKI_X509_SCEP_MSG_set_status(PKI_X509_SCEP_MSG * msg, + SCEP_STATUS status); + + +/*! \brief Returns the pkiStatus attribute from a SCEP message */ + +SCEP_STATUS PKI_X509_SCEP_MSG_get_status(const PKI_X509_SCEP_MSG * const msg); + + +/*! \brief Sets the failInfo attribute in a SCEP message */ + +int PKI_X509_SCEP_MSG_set_failinfo(PKI_X509_SCEP_MSG * msg, + int fail); + + +/*! \brief Returns the failInfo attribute from a SCEP message */ + +SCEP_FAILURE PKI_X509_SCEP_MSG_get_failinfo(const PKI_X509_SCEP_MSG * const msg); + + +/*! \brief Returns the senderNonce attribute from a SCEP message */ + +PKI_MEM *PKI_X509_SCEP_MSG_get_sender_nonce(const PKI_X509_SCEP_MSG * const msg); + + +/*! \brief Returns the recipientNonce attribute from a SCEP message */ + +PKI_MEM *PKI_X509_SCEP_MSG_get_recipient_nonce(PKI_X509_SCEP_MSG * const msg); + + +/*! \brief Sets the proxyAuthenticator attribute from a SCEP message */ + +int PKI_X509_SCEP_MSG_set_proxy(PKI_X509_SCEP_MSG * msg, + int auth); + + +/*! \brief Returns the proxyAuthenticator attribute from a SCEP message */ + +int PKI_X509_SCEP_MSG_get_proxy(const PKI_X509_SCEP_MSG * const msg); + + +#endif diff --git a/include/libpki/pkix/scep/pki_x509_scep_data.h b/include/libpki/pkix/scep/pki_x509_scep_data.h new file mode 100644 index 00000000..0c237829 --- /dev/null +++ b/include/libpki/pkix/scep/pki_x509_scep_data.h @@ -0,0 +1,28 @@ +/* SCEP msg handling + * (c) 2009 by Massimiliano Pala and OpenCA Labs + * All Rights Reserved + */ + +#ifndef _LIBPKI_X509_SCEP_DATA_H +#define _LIBPKI_X509_SCEP_DATA_H + +PKI_X509_SCEP_DATA * PKI_X509_SCEP_DATA_new ( void ); + +void PKI_X509_SCEP_DATA_free ( PKI_X509_SCEP_DATA *data ); + +int PKI_X509_SCEP_DATA_add_recipient ( PKI_X509_SCEP_DATA *data, + PKI_X509_CERT *recipient ); + +int PKI_X509_SCEP_DATA_set_recipients ( PKI_X509_SCEP_DATA *data, + PKI_X509_CERT_STACK *sk ); + +int PKI_X509_SCEP_DATA_set_x509_obj ( PKI_X509_SCEP_DATA *data, + PKI_X509 *obj ); + +int PKI_X509_SCEP_DATA_set_ias ( PKI_X509_SCEP_DATA *data, + SCEP_ISSUER_AND_SUBJECT *ias ); + +int PKI_X509_SCEP_DATA_set_raw_data ( PKI_X509_SCEP_DATA *data, + unsigned char *raw_val, ssize_t size ); + +#endif diff --git a/include/libpki/pkix/scep/pki_x509_scep_msg.h b/include/libpki/pkix/scep/pki_x509_scep_msg.h new file mode 100644 index 00000000..58f3db46 --- /dev/null +++ b/include/libpki/pkix/scep/pki_x509_scep_msg.h @@ -0,0 +1,39 @@ +/* SCEP msg handling + * (c) 2009 by Massimiliano Pala and OpenCA Labs + * All Rights Reserved + */ + +#ifndef _LIBPKI_X509_SCEP_MSG_H +#define _LIBPKI_X509_SCEP_MSG_H + +PKI_X509_SCEP_MSG *PKI_X509_SCEP_MSG_new ( SCEP_MESSAGE_TYPE type ); +void PKI_X509_SCEP_MSG_free ( PKI_X509_SCEP_MSG *msg ); + +/* ----------------------------- Signer ------------------------------- */ + +int PKI_X509_SCEP_MSG_add_signer ( PKI_X509_SCEP_MSG *msg, + PKI_X509_CERT *signer, PKI_X509_KEYPAIR *key, + PKI_DIGEST_ALG *md ); + +int PKI_X509_SCEP_MSG_add_signer_sk ( PKI_X509_SCEP_MSG *msg, + PKI_TOKEN *tk, PKI_DIGEST_ALG *md ); + +/* ---------------------------- Encode / Decode ------------------------ */ + +int PKI_X509_SCEP_MSG_encode ( PKI_X509_SCEP_MSG *msg, + PKI_X509_SCEP_DATA *data ); + +PKI_MEM *PKI_X509_SCEP_MSG_decode ( PKI_X509_SCEP_MSG *msg, + PKI_X509_KEYPAIR * key, PKI_X509_CERT *x ); + +/* ---------------------------- SCEP helper Funcs ---------------------- */ + +PKI_X509_SCEP_MSG * PKI_X509_SCEP_MSG_new_certreq ( PKI_X509_KEYPAIR *key, + PKI_X509_REQ *req, PKI_X509_CERT *signer, + PKI_X509_CERT_STACK *recipients, PKI_DIGEST_ALG *md ); + +PKI_X509 *PKI_X509_SCEP_MSG_get_x509_obj ( PKI_X509_SCEP_MSG *msg, + PKI_DATATYPE type, PKI_DATA_FORMAT format, + PKI_X509_KEYPAIR *key, PKI_X509_CERT *x ); + +#endif diff --git a/include/libpki/pkix/scep/scep.h b/include/libpki/pkix/scep/scep.h new file mode 100644 index 00000000..084d22b1 --- /dev/null +++ b/include/libpki/pkix/scep/scep.h @@ -0,0 +1,254 @@ +/* + * OpenCA SCEP + * + * (c) 2002-2009 by Massimiliano Pala and OpenCA Labs + * + * Thanks to the OpenSCEP group for their work and help + * + */ + +#ifndef _LIBPKI_SCEP_H_ +#define _LIBPKI_SCEP_H_ + +/* +#include +#include +#include +#include +#include + +#include +#include +#include +#include +*/ + +/* +#define SCEP_ATTRIBUTE_OID_MESSAGE_TYPE "2.16.840.1.113733.1.9.2" +#define SCEP_ATTRIBUTE_STRING_MESSAGE_TYPE "messageType" +#define SCEP_ATTRIBUTE_OID_PKI_STATUS "2.16.840.1.113733.1.9.3" +#define SCEP_ATTRIBUTE_STRING_PKI_STATUS "pkiStatus" +#define SCEP_ATTRIBUTE_OID_FAIL_INFO "2.16.840.1.113733.1.9.4" +#define SCEP_ATTRIBUTE_STRING_FAIL_INFO "failInfo" +#define SCEP_ATTRIBUTE_OID_SENDER_NONCE "2.16.840.1.113733.1.9.5" +#define SCEP_ATTRIBUTE_STRING_SENDER_NONCE "senderNonce" +#define SCEP_ATTRIBUTE_OID_RECIPIENT_NONCE "2.16.840.1.113733.1.9.6" +#define SCEP_ATTRIBUTE_STRING_RECIPIENT_NONCE "recipientNonce" +#define SCEP_ATTRIBUTE_OID_TRANS_ID "2.16.840.1.113733.1.9.7" +#define SCEP_ATTRIBUTE_STRING_TRANS_ID "transId" +#define SCEP_ATTRIBUTE_OID_EXTENSION_REQ "2.16.840.1.113733.1.9.8" +#define SCEP_ATTRIBUTE_STRING_EXTENSION_REQ "extensionReq" +#define SCEP_ATTRIBUTE_OID_PROXY_AUTHENTICATOR "1.3.6.1.4.1.4263.5.5" +#define SCEP_ATTRIBUTE_STRING_PROXY_AUTHENTICATOR "proxyAuthenticator" +*/ + +#define TRANS_ID_SIZE 16 + +typedef struct scep_oid_st { + int attr_type; + char *oid_s; + char *descr; + char *long_descr; + int nid; +} SCEP_CONF_ATTRIBUTE; + +/* These should be in the same order than the SCEP_ATTRIBUTE_list in scep_attrs.c */ +typedef enum { + SCEP_ATTRIBUTE_TYPE_UNKNOWN = -1, + SCEP_ATTRIBUTE_MESSAGE_TYPE = 0, + SCEP_ATTRIBUTE_PKI_STATUS, + SCEP_ATTRIBUTE_FAIL_INFO, + SCEP_ATTRIBUTE_SENDER_NONCE, + SCEP_ATTRIBUTE_RECIPIENT_NONCE, + SCEP_ATTRIBUTE_TRANS_ID, + SCEP_ATTRIBUTE_EXTENSION_REQ, + SCEP_ATTRIBUTE_PROXY_AUTH +} SCEP_ATTRIBUTE_TYPE; + +typedef enum { + PKI_X509_SCEP_MSG_UNKNOWN = -1, + PKI_X509_SCEP_MSG_V2REQUEST = 17, + PKI_X509_SCEP_MSG_V2PROXY = 18, + PKI_X509_SCEP_MSG_PKCSREQ = 19, + PKI_X509_SCEP_MSG_CERTREP = 3, + PKI_X509_SCEP_MSG_GETCERTINITIAL = 20, + PKI_X509_SCEP_MSG_GETCERT = 21, + PKI_X509_SCEP_MSG_GETCRL = 22 +} SCEP_MESSAGE_TYPE; + +typedef enum { + SCEP_STATUS_SUCCESS = 0, + SCEP_STATUS_FAILURE = 2, + SCEP_STATUS_PENDING = 3 +} SCEP_STATUS; + +typedef enum { + SCEP_FAILURE_BADALG = 0, + SCEP_FAILURE_BADMESSAGECHECK = 1, + SCEP_FAILURE_BADREQUEST = 2, + SCEP_FAILURE_BADTIME = 3, + SCEP_FAILURE_BADCERTID = 4 +} SCEP_FAILURE; + +#define SCEP_NONCE PKI_MEM +#define NONCE_SIZE 16 + +#define PKI_X509_SCEP_MSG_VALUE PKCS7 +#define PKI_X509_SCEP_DATA PKI_X509_PKCS7 +#define PKI_X509_SCEP_MSG PKI_X509_PKCS7 + +#include +#include +#include +#include + + +#endif + + +/* +typedef struct scep_recip_info { + STACK_OF(PKCS7_RECIP_INFO) *sk_recip_info; + STACK_OF(X509) *sk_recip_certs; + + PKCS7_ISSUER_AND_SERIAL *ias; + +} SCEP_RECIP_INFO; +*/ + +/* +typedef struct { + int NID_p7data; + + // enc p7 enveloped data + PKCS7 *p7env; + PKCS7 *p7; + + // Info about the recipient of the message + SCEP_RECIP_INFO recip_info; + EVP_PKEY *pkey; + X509 *cacert; + + union { + // PKCSReq Content + X509_REQ *req; + // CertResp Content + X509 *issued_cert; + // CertReq Content + X509 *self_signed_cert; + // GetCertInitial Content + SCEP_ISSUER_AND_SUBJECT *init_certinfo; + // GetCert && GetCrl Content + PKCS7_ISSUER_AND_SERIAL *ias; + } content; + + X509_CRL *crl; + +} SCEP_ENVELOPED_DATA; + +typedef struct { + int messageType; + + STACK_OF(PKCS7_SIGNER_INFO) *sk_signer_info; + PKCS7_ISSUER_AND_SERIAL *signer_ias; + X509 *signer_cert; + EVP_PKEY *signer_pkey; + + STACK_OF(X509_ATTRIBUTE) *attrs; + + SCEP_ENVELOPED_DATA env_data; + + STACK_OF(X509) *sk_others; + +} SCEP_MSG; +*/ + +/* +#define SCEP_MESSAGE_is(a, b) (!strcmp(a, b)) +#define SCEP_PKISTATUS_is(a, b) (!strcmp(a, b)) +#define SCEP_FAILURE_is(a, b) (!strcmp(a, b)) + +#define SCEP_type2str(a) ( \ +(0 == a ) ? "(not set)" : ( \ +(SCEP_MSG_PKCSREQ == a ) ? "PKCSReq" : ( \ +(SCEP_MSG_V2REQUEST == a ) ? "v2Request" : ( \ +(SCEP_MSG_V2PROXY == a ) ? "v2Proxy" : ( \ +(SCEP_MSG_CERTREP == a ) ? "CertRep" : ( \ +(SCEP_MSG_GETCERTINITIAL == a ) ? "GetCertInitial" : ( \ +(SCEP_MSG_GETCERT == a ) ? "GetCert" : ( \ +(SCEP_MSG_GETCRL == a ) ? "GetCRL" : "unknown")))))))) + +#define SCEP_str2type( a ) ( \ +(NULL == a) ? -1 : ( \ +(0 == strcmp("PKCSReq", a)) ? SCEP_MSG_PKCSREQ : ( \ +(0 == strcmp("v2Request", a)) ? SCEP_MSG_V2REQUEST : ( \ +(0 == strcmp("v2Proxy", a)) ? SCEP_MSG_V2PROXY : ( \ +(0 == strcmp("CertRep", a)) ? SCEP_MSG_CERTREP : ( \ +(0 == strcmp("GetCertInitial", a)) ? SCEP_MSG_GETCERTINITIAL : (\ +(0 == strcmp("GetCert", a)) ? SCEP_MSG_GETCERT : ( \ +(0 == strcmp("GetCRL", a)) ? SCEP_MSG_GETCRL : -1 )))))))) + +#define SCEP_TYPE(a) ( \ +(NULL == a) ? "(not set)" : ( \ +(0 == strcmp(SCEP_MESSAGE_TYPE_PKCSREQ, a)) ? "PKCSReq" : ( \ +(0 == strcmp(SCEP_MESSAGE_TYPE_V2REQUEST, a)) ? "v2Request" : ( \ +(0 == strcmp(SCEP_MESSAGE_TYPE_V2PROXY, a)) ? "v2Proxy" : ( \ +(0 == strcmp(SCEP_MESSAGE_TYPE_CERTREP, a)) ? "CertRep" : ( \ +(0 == strcmp(SCEP_MESSAGE_TYPE_GETCERTINITIAL, a)) ? "GetCertInitial" : (\ +(0 == strcmp(SCEP_MESSAGE_TYPE_GETCERT, a)) ? "GetCert" : ( \ +(0 == strcmp(SCEP_MESSAGE_TYPE_GETCRL, a)) ? "GetCRL" : "unknown")))))))) + +#define SCEP_status2str(a) ( \ +(PKI_SUCCESS == a ) ? "Success" : ( \ +(PKI_FAILURE == a ) ? "Failure" : ( \ +(PKI_PENDING == a ) ? "Pending" : "(unknown)"))) + +#define SCEP_str2status(a) ( \ +(NULL == a) ? -1 : ( \ +(0 == strcmp("SUCCESS", a)) ? PKI_SUCCESS : ( \ +(0 == strcmp("FAILURE", a)) ? PKI_FAILURE : ( \ +(0 == strcmp("PENDING", a)) ? PKI_PENDING : -1 )))) + +#define SCEP_STATUS(a) ( \ +(NULL == a) ? "(not set)" : ( \ +(0 == strcmp(SCEP_PKISTATUS_SUCCESS, a)) ? "SUCCESS" : ( \ +(0 == strcmp(SCEP_PKISTATUS_FAILURE, a)) ? "FAILURE" : ( \ +(0 == strcmp(SCEP_PKISTATUS_PENDING, a)) ? "PENDING" : "(unknown)")))) + +#define SCEP_failure2str(a) ( \ +(FAIL_BADALG == a ) ? "BadAlg" : ( \ +(FAIL_BADMESSAGECHECK == a ) ? "BadMessageCheck" : ( \ +(FAIL_BADREQUEST == a ) ? "BadRequest" : ( \ +(FAIL_BADTIME == a ) ? "BadTime" : ( \ +(FAIL_BADCERTID == a ) ? "BadCertID" : "(unknown)"))))) + +#define SCEP_str2failure(a) ( \ +(NULL == a) ? -1 : ( \ +(0 == strcmp("badAlg", a)) ? FAIL_BADALG : ( \ +(0 == strcmp("badMessageCheck", a)) ? FAIL_BADMESSAGECHECK : ( \ +(0 == strcmp("badRequest", a)) ? FAIL_BADREQUEST : ( \ +(0 == strcmp("badTime", a)) ? FAIL_BADTIME : ( \ +(0 == strcmp("badCertId", a)) ? FAIL_BADCERTID : -1 )))))) + +#define SCEP_FAILURE(a) ( \ +(NULL == a) ? "(not set)" : ( \ +(0 == strcmp(SCEP_FAILURE_BADALG, a)) ? "BadAlg" : ( \ +(0 == strcmp(SCEP_FAILURE_BADMESSAGECHECK, a)) ? "BadMessageCheck" : ( \ +(0 == strcmp(SCEP_FAILURE_BADREQUEST, a)) ? "BadRequest" : ( \ +(0 == strcmp(SCEP_FAILURE_BADTIME, a)) ? "BadTime" : ( \ +(0 == strcmp(SCEP_FAILURE_BADCERTID, a)) ? "BadCertID" : "(unknown)")))))) +*/ + +/* +#define SCEP_str2attribute(a) ( \ +(NULL == a) ? -1 : ( \ +(0 == strcmp(MESSAGE_TYPE_OID_STRING, a)) ? SCEP_MESSAGE_TYPE_ATTRIBUTE : (\ +(0 == strcmp(PKI_STATUS_OID_STRING, a)) ? SCEP_PKI_STATUS_ATTRIBUTE : (\ +(0 == strcmp(FAIL_INFO_OID_STRING, a)) ? SCEP_FAIL_INFO_ATTRIBUTE : (\ +(0 == strcmp(SENDER_NONCE_OID_STRING, a)) ? SCEP_SENDER_NONCE_ATTRIBUTE : (\ +(0 == strcmp(RECIPIENT_NONCE_OID_STRING, a)) ? SCEP_RECIPIENT_NONCE_ATTRIBUTE : (\ +(0 == strcmp(TRANS_ID_OID_STRING, a)) ? SCEP_TRANS_ID_ATTRIBUTE : (\ +(0 == strcmp(EXTENSION_REQ_OID_STRING, a)) ? SCEP_EXTENSION_REQ_ATTRIBUTE : (\ +(0 == strcmp(PROXY_AUTHENTICATOR_OID_STRING, a)) ? SCEP_PROXY_AUTHENTICATOR_ATTRIBUTE : -1 ))))))))) +*/ + diff --git a/include/libpki/pkix/types.h b/include/libpki/pkix/types.h new file mode 100644 index 00000000..3a945fa7 --- /dev/null +++ b/include/libpki/pkix/types.h @@ -0,0 +1,35 @@ +/* OpenCA libpki package +* (c) 2000-2007 by Massimiliano Pala and OpenCA Group +* All Rights Reserved +* +* =================================================================== +* Released under OpenCA LICENSE +*/ + +// Library configuration +#ifndef _LIBPKI_SYSTEM_H +#include +#endif + +#ifdef ENABLE_OQS +# include +#endif + +#ifndef _LIBPKI_PKIX_TYPES_H +#define _LIBPKI_PKIX_TYPES_H + +BEGIN_C_DECLS + +#define PKI_DATA_FORMAT_MIN PKI_DATA_FORMAT_RAW +#define PKI_DATA_FORMAT_MAX PKI_DATA_FORMAT_URL + +typedef enum pki_data_format_flag { + PKI_DATA_FORMAT_FLAG_NONE = 0, + PKI_DATA_FORMAT_FLAG_B64_SKIPNEWLINES = 1, +} PKI_DATA_FORMAT_FLAG; + +#define PKI_DATA_FORMAT_FLAG_SIZE 2 + +END_C_DECLS + +#endif diff --git a/include/libpki/token/token.h b/include/libpki/token/token.h new file mode 100644 index 00000000..081331e6 --- /dev/null +++ b/include/libpki/token/token.h @@ -0,0 +1,184 @@ +/* token.h */ + +#ifndef _LIBPKI_X509_PROFILE_H +# include +#endif + +#ifndef _LIBPKI_TOKEN_HEADERS_H +#define _LIBPKI_TOKEN_HEADERS_H + +#include + +/* Memory related functions */ +PKI_TOKEN *PKI_TOKEN_new_null( void ); +PKI_TOKEN *PKI_TOKEN_new( const char * const confDir, const char * const name ); +PKI_TOKEN *PKI_TOKEN_new_p12 ( char *url, char *config_dir, PKI_CRED *cred ); +// PKI_TOKEN *PKI_TOKEN_new_p12_hsm ( char *url, char *config_dir, PKI_CRED *cred, HSM * hsm ); +// PKI_TOKEN *PKI_TOKEN_new_p12_ex ( char *url, char *config_dir, PKI_CRED *cred, const char * hsmName); + +int PKI_TOKEN_free( PKI_TOKEN *tk ); +void PKI_TOKEN_free_void ( void *tk ); + +/* Token Initialization */ +int PKI_TOKEN_set_config_dir ( PKI_TOKEN *tk, char *dir ); +char * PKI_TOKEN_get_config_dir ( PKI_TOKEN *tk ); +int PKI_TOKEN_load_config ( PKI_TOKEN * const tk, const char * const tk_name ); + +/// @brief Login into the token (triggers keypair loading) +/// @param tk [in,out] The token to login into (PKI_TOKEN *) +/// @return PKI_OK if successful or an error code otherwise (PKI_ERR_) +int PKI_TOKEN_login(PKI_TOKEN * const tk); + +// Sets the login status for the token +int PKI_TOKEN_set_login_success(PKI_TOKEN * const tk); +int PKI_TOKEN_is_logged_in(const PKI_TOKEN * const tk); +int PKI_TOKEN_is_creds_set(const PKI_TOKEN * const tk); +int PKI_TOKEN_status_clear_errors(PKI_TOKEN * const tk); +int PKI_TOKEN_status_set(PKI_TOKEN * const tk, const PKI_TOKEN_STATUS status); +int PKI_TOKEN_status_del_error(PKI_TOKEN * const tk, const PKI_TOKEN_STATUS status); +int PKI_TOKEN_status_add_error(PKI_TOKEN * const tk, const PKI_TOKEN_STATUS status); +PKI_TOKEN_STATUS PKI_TOKEN_status_get(const PKI_TOKEN * const tk); + +int PKI_TOKEN_init (PKI_TOKEN * const tk, const char * const conf_url, const char * const name); +PKI_OID *PKI_TOKEN_OID_new ( PKI_TOKEN *tk, char *oid_s ); +int PKI_TOKEN_check ( PKI_TOKEN *tk ); + +// X509 Algorithm +PKI_X509_ALGOR_VALUE *PKI_TOKEN_get_algor( PKI_TOKEN *tk ); +int PKI_TOKEN_get_algor_id( PKI_TOKEN *tk ); +int PKI_TOKEN_set_algor( PKI_TOKEN *tk, PKI_ALGOR_ID algor ); +int PKI_TOKEN_set_algor_by_name( PKI_TOKEN *tk, const char *algName ); +int PKI_TOKEN_X509_REQ_profile_set( PKI_TOKEN *tk, PKI_X509_PROFILE *req_prof ); +int PKI_TOKEN_X509_CERT_profile_set( PKI_TOKEN *tk, PKI_X509_PROFILE *cert_prof ); + +// Algorithm Digest +int PKI_TOKEN_set_digest(PKI_TOKEN * tk, const PKI_DIGEST_ALG * digest); +int PKI_TOKEN_set_digest_id(PKI_TOKEN * tk, PKI_ALGOR_ID digest_id); +int PKI_TOKEN_set_digest_by_name(PKI_TOKEN * tk, const char * digest_name); +const PKI_DIGEST_ALG * PKI_TOKEN_get_digest(PKI_TOKEN * tk); +int PKI_TOKEN_get_digest_id(PKI_TOKEN * tk); +const char * PKI_TOKEN_get_digest_name(PKI_TOKEN * tk); + + +/// @brief Sets the HSM in a token +/// @param tk is the token to update +/// @param hsm is the pointer to an initialized HSM structure +/// @return PKI_OK if successful, PKI_ERR otherwise +int PKI_TOKEN_set_hsm(PKI_TOKEN * tk, HSM * hsm ); + +/// @brief Sets the HSM in a token via the token name +/// @param tk is the token to update +/// @param config_dir is the configuration dir (e.g., ~/.libpki) +/// @param hsmName is the name of the HSM to instantiate for the token +/// @return PKI_OK if successful, PKI_ERR otherwise +int PKI_TOKEN_set_hsm_name(PKI_TOKEN * tk, const char * const config_dir, const char * const hsmName); + +/* Token Credential Callback functions */ +PKI_CRED *PKI_TOKEN_cred_cb_stdin ( char * prompt ); +PKI_CRED *PKI_TOKEN_cred_cb_env ( char * env ); +int PKI_TOKEN_cred_set_cb ( PKI_TOKEN *tk, PKI_CRED * (*cb)(char *), + char *prompt); +/* Basic functions: add data to the TOKEN structure */ +int PKI_TOKEN_set_cert ( PKI_TOKEN *tk, PKI_X509_CERT *x ); +int PKI_TOKEN_set_cacert ( PKI_TOKEN *tk, PKI_X509_CERT *x ); +int PKI_TOKEN_set_keypair ( PKI_TOKEN *tk, PKI_X509_KEYPAIR *pkey ); +int PKI_TOKEN_set_otherCerts ( PKI_TOKEN *tk, PKI_X509_CERT_STACK *stack ); +int PKI_TOKEN_set_trustedCerts ( PKI_TOKEN *tk, PKI_X509_CERT_STACK *stack ); +int PKI_TOKEN_set_crls ( PKI_TOKEN *tk, PKI_X509_CRL_STACK *stack ); +int PKI_TOKEN_set_cred ( PKI_TOKEN *tk, PKI_CRED *cred ); +int PKI_TOKEN_set_req( PKI_TOKEN *tk, PKI_X509_REQ *req ); + +/* Load data from URL pointers */ +int PKI_TOKEN_load_cert( PKI_TOKEN *tk, char *url_string ); +int PKI_TOKEN_load_req ( PKI_TOKEN *tk, char *url_string ); +int PKI_TOKEN_load_cacert( PKI_TOKEN *tk, char *url_string ); +int PKI_TOKEN_load_keypair( PKI_TOKEN *tk, char *url_string ); +int PKI_TOKEN_load_otherCerts( PKI_TOKEN *tk, char *url_string ); +int PKI_TOKEN_load_trustedCerts( PKI_TOKEN *tk, char *url_string ); +int PKI_TOKEN_load_crls( PKI_TOKEN *tk, char *url_string ); + +/* Retrieve pointers to PKI_TOKEN data */ +PKI_X509_KEYPAIR *PKI_TOKEN_get_keypair ( PKI_TOKEN *tk ); +PKI_X509_CERT *PKI_TOKEN_get_cert ( PKI_TOKEN *tk ); +PKI_X509_CERT *PKI_TOKEN_get_cacert ( PKI_TOKEN *tk ); +PKI_X509_CERT_STACK * PKI_TOKEN_get_otherCerts ( PKI_TOKEN *tk); +PKI_X509_CERT_STACK * PKI_TOKEN_get_trustedCerts ( PKI_TOKEN *tk); +PKI_X509_CRL_STACK * PKI_TOKEN_get_crls ( PKI_TOKEN *tk ); +const PKI_CRED * PKI_TOKEN_cred_get(const PKI_TOKEN * const tk); +char * PKI_TOKEN_get_name ( PKI_TOKEN *tk ); + +PKI_X509_PKCS12 *PKI_TOKEN_get_p12 ( PKI_TOKEN *tk, PKI_CRED *cred ); + +/* Save data to URL pointers */ +int PKI_TOKEN_export_p12 ( PKI_TOKEN *tk, PKI_DATA_FORMAT format, + char *url_s, PKI_CRED *cred ); +int PKI_TOKEN_export_cert ( PKI_TOKEN *tk, char *url_string, PKI_DATA_FORMAT format ); +int PKI_TOKEN_export_req ( PKI_TOKEN *tk, char *url_string, PKI_DATA_FORMAT format ); +int PKI_TOKEN_export_keypair ( PKI_TOKEN *tk, char *url_string, PKI_DATA_FORMAT format ); +int PKI_TOKEN_export_keypair_url( PKI_TOKEN *tk, URL *url, PKI_DATA_FORMAT format ); +int PKI_TOKEN_export_otherCerts ( PKI_TOKEN *tk, char *url_string, PKI_DATA_FORMAT format ); +int PKI_TOKEN_export_trustedCerts (PKI_TOKEN *tk, char *url_string, PKI_DATA_FORMAT format); + +/* Import data into the token (add) */ +int PKI_TOKEN_import_cert ( PKI_TOKEN *tk, PKI_X509_CERT *cert, + PKI_DATATYPE type, char *url_s); +int PKI_TOKEN_import_cert_stack ( PKI_TOKEN *tk, PKI_X509_CERT_STACK *sk, + PKI_DATATYPE type, char *url_s ); + +/* Delete an object from the token (del) */ +int PKI_TOKEN_del_url ( PKI_TOKEN *tk, URL *url, PKI_DATATYPE datatype ); + +/* TOKEN operations */ +int PKI_TOKEN_new_keypair ( PKI_TOKEN *tk, int bits, char *label ); +int PKI_TOKEN_new_keypair_ex ( PKI_TOKEN *tk, PKI_KEYPARAMS *kp, char *label, char * profile_s); +int PKI_TOKEN_new_keypair_url ( PKI_TOKEN *tk, int bits, URL *label ); +int PKI_TOKEN_new_keypair_url_ex ( PKI_TOKEN *tk, PKI_KEYPARAMS *kp, URL *label, char *profile_s ); +int PKI_TOKEN_import_keypair ( PKI_TOKEN *tk, PKI_X509_KEYPAIR *key, char * url_s ); +int PKI_TOKEN_new_req(PKI_TOKEN *tk, char *subject, char *profile_s ); +int PKI_TOKEN_self_sign (PKI_TOKEN *tk, char *subject, char *serial, + unsigned long validity, char *profile_s ); +PKI_X509_CERT* PKI_TOKEN_issue_cert(PKI_TOKEN *tk, char *subject, char *serial, + unsigned long validity, PKI_X509_REQ *req, char *profile_s); + +/// @brief Generate a new CRL from a stack of revoked entries +/// @details Generates a new signed CRL from a stack of revoked entries. If a profile +/// passed, it is used to set the right extensions in the CRL. To generate a +/// new revoked entry the PKI_X509_CRL_ENTRY_new() function has to be used. +/// @param tk is the signing token (PKI_TOKEN) +/// @param serial is the text representation of the crl number (char *) +/// @param thisUpdate offset from 'now', in seconds, for thisUpdate date (long long) +/// @param nextUpdate offset from 'now', in seconds, for nextUpdate date (long long) +/// @param sk is the stack of revoked entries (PKI_STACK_X509_CRL_ENTRY *) +/// @param exts is the stack of extensions for the CRL (PKI_STACK_X509_EXTENSION *) +/// @param profile_s is the name of the profile for CRL extensions (char *) +/// @return The newly issued (and signed) CRL (PKI_X509_CRL *) +PKI_X509_CRL * PKI_TOKEN_issue_crl (const PKI_TOKEN * tk, /* signing token */ + const char * const serial, /* crlNumber */ + const long long thisUpdate /* offset */, + const long long nextUpdate /* offset */, + const PKI_X509_CRL_ENTRY_STACK * const sk, /* stack of rev */ + const PKI_X509_EXTENSION_STACK * const exts, /* stack of crl exts */ + const char * profile_s ); + +PKI_TOKEN *PKI_TOKEN_issue_proxy (PKI_TOKEN *tk, char *subject, + char *serial, unsigned long validity, + char *profile_s, PKI_TOKEN *px_tk ); + +/* TOKEN profile ops */ +int PKI_TOKEN_load_profiles(PKI_TOKEN *tk, char *urlStr); +int PKI_TOKEN_clear_profiles(PKI_TOKEN * tk); +int PKI_TOKEN_add_profile( PKI_TOKEN *tk, PKI_X509_PROFILE *profile ); + +/// @brief Returns a named profile from the loaded ones +/// @param tk is the token where the profiles have been loaded (PKI_TOKEN *) +/// @param profile_s is the name of the requested profile (char *) +/// @return the searched profile or NULL if none was found (PKI_X509_PROFILE *) +PKI_X509_PROFILE *PKI_TOKEN_search_profile(const PKI_TOKEN * const tk, + const char * const profile_s); + +/* TOKEN Slot */ +int PKI_TOKEN_use_slot(PKI_TOKEN *tk, long num); +int PKI_TOKEN_print_info(PKI_TOKEN *tk); + +#endif + diff --git a/include/libpki/token/token_data.h b/include/libpki/token/token_data.h new file mode 100644 index 00000000..a61a29e2 --- /dev/null +++ b/include/libpki/token/token_data.h @@ -0,0 +1,29 @@ +/* TOKEN Object Management Functions */ + +#ifndef _LIBPKI_TOKEN_DATA_HEADERS_H +#define _LIBPKI_TOKEN_DATA_HEADERS_H + +/* Key data Retrieval */ +PKI_MEM *PKI_TOKEN_get_keypair_data ( PKI_TOKEN *tk, PKI_DATA_FORMAT format ); +PKI_MEM *PKI_TOKEN_get_pubkey_data ( PKI_TOKEN *tk, PKI_DATA_FORMAT format ); +PKI_MEM *PKI_TOKEN_get_privkey_data ( PKI_TOKEN *tk, PKI_DATA_FORMAT format ); + +/* Certificate data Retrieval */ +PKI_MEM *PKI_TOKEN_get_cert_data ( PKI_TOKEN *tk, PKI_DATA_FORMAT format ); + +/* Identities data Retrieval */ +PKI_MEM *PKI_TOKEN_get_identity_data ( PKI_TOKEN *tk, PKI_DATA_FORMAT format ); + +/* CA Certificate Data Retrieval */ +PKI_MEM *PKI_TOKEN_get_cacert_data ( PKI_TOKEN *tk, PKI_DATA_FORMAT format ); + +/* Trusted Certs Stack Retrieval */ +PKI_MEM_STACK *PKI_TOKEN_get_trustedCerts_data ( PKI_TOKEN *tk, + PKI_DATA_FORMAT format ); + +/* Other Certs Stack Retrieval */ +PKI_MEM_STACK *PKI_TOKEN_get_otherCerts_data ( PKI_TOKEN *tk, + PKI_DATA_FORMAT format ); + +#endif + diff --git a/include/libpki/token/token_id.h b/include/libpki/token/token_id.h new file mode 100644 index 00000000..a1e6a4ae --- /dev/null +++ b/include/libpki/token/token_id.h @@ -0,0 +1,19 @@ +/* TOKEN ID Object Management Functions */ + +#ifndef _LIBPKI_TOKEN_ID_HEADERS_H +#define _LIBPKI_TOKEN_ID_HEADERS_H + +/* Set the ID to be used for current operations */ +int PKI_TOKEN_ID_set ( PKI_TOKEN *tk, int id ); + +/* Get the number of available IDs from the current token */ +int PKI_TOKEN_ID_num ( PKI_TOKEN *tk ); + +/* Get the list of IDs from the Token */ +PKI_ID_INFO_STACK *PKI_TOKEN_ID_INFO_list ( PKI_TOKEN *tk ); + +/* Get the PKI_ID_INFO from the TOKEN */ +PKI_ID_INFO * PKI_TOKEN_ID_INFO_get ( PKI_TOKEN *tk, int num ); + +#endif + diff --git a/include/libpki/token/types.h b/include/libpki/token/types.h new file mode 100644 index 00000000..f8dd106e --- /dev/null +++ b/include/libpki/token/types.h @@ -0,0 +1,115 @@ + +#ifndef _LIBPKI_SYSTEM_H +# include +#endif + +#ifndef _LIBPKI_CRYPTO_TYPES_H +#include +#endif + +#ifndef _LIBPKI_TOKEN_TYPES_H +#define _LIBPKI_TOKEN_TYPES_H + +typedef enum pki_token_status_flags { + PKI_READY = 0x0, + PKI_INIT_ERR = 0x1, + PKI_LOGIN_ERR = 0x2, + PKI_KEYPAIR_ERR = 0x3, + PKI_EE_CERT_ERR = 0x4, + PKI_CA_CERT_ERR = 0x5, + PKI_OTHER_CERTS_ERR = 0x6, + PKI_TRUSTED_CERTS_ERR = 0x7, +} PKI_STATUS_FLAG; + +#define PKI_TOKEN_STATUS_SZ 8 + +/* Structure for PKI_TOKEN definition */ +typedef struct pki_token_st { + /*! Pointer to the HSM if one is configured for the + specific PKI_TOKEN */ + HSM *hsm; + + /*! Scheme used when generating KEYPAIR */ + int scheme; + + /*! Type of TOKEN (software, engine, kmf, etc... ) */ + int type; + + /*! Signature Algorithm used by the PKI_TOKEN */ + void * algor; + + /*! Digest Algorithm used by the PKI_TOKEN */ + PKI_DIGEST_ALG * digest; + + /*! Pointer to the CA certificate */ + PKI_X509_CERT * cacert; + + /*! Pointer to the certificate */ + PKI_X509_CERT * cert; + + /*! Pointer to the certificate request */ + PKI_X509_REQ * req; + + /*! Pointer to the key */ + PKI_X509_KEYPAIR * keypair; + + /*! Pointer to CRED structure to be used when the PKI_KEYPAIR + is to be loaded */ + PKI_CRED * cred; + + PKI_CRED * (*cred_cb)(char *); + char * cred_prompt; + + /*! Pointer to the stack of chain of certs */ + PKI_X509_CERT_STACK * otherCerts; + + /*! Pointer to the stack of trusted certs */ + PKI_X509_CERT_STACK * trustedCerts; + + /*! Pointer to the stack of CRLs certs */ + PKI_X509_CRL_STACK * crls; + + /*! Pointer to the certificate profile to be used when issuing + a certificate */ + PKI_X509_PROFILE_STACK * profiles; + + /*! Pointer to OIDs configuration profile */ + PKI_CONFIG * oids; + + /*! Pointer to the PKI_CONFIG data */ + PKI_CONFIG * config; + + /*! Config directory */ + char * config_dir; + + /*! Token Name */ + char * name; + + /*! For General Device Support */ + long slot_id; + + /*! Identifier for selected Key */ + char * key_id; + + /*! Identifier for selected Certificate */ + char * cert_id; + + /*! Identifier for selected CA Certificate */ + char * cacert_id; + + /*! Identifier for selected Certificate Request */ + char * req_id; + + /*! Token Status Flags */ + uint32_t status; + + /*! Login Status */ + uint8_t isLoggedIn; + + /*! Credentials Status */ + uint8_t isCredSet; + +} PKI_TOKEN; + +/* End of _LIBPKI_HEADER_DATA_ST_H */ +#endif diff --git a/include/libpki/utils/asn1.h b/include/libpki/utils/asn1.h new file mode 100644 index 00000000..44b0ae5b --- /dev/null +++ b/include/libpki/utils/asn1.h @@ -0,0 +1,33 @@ + + +#ifndef _LIBPKI_SYSTEM_H +#include +#endif + +#ifndef _LIBPKI_UTILS_TYPES_H +#include +#endif + +#ifndef _LIBPKI_CRYPTO_TYPES_H +#include +#endif + +#ifndef _LIBPKI_ASN1_UTILS_H +#define _LIBPKI_ASN1_UTILS_H + +BEGIN_C_DECLS + +int i2d(unsigned char **out, size_t *size, void *in, int type); +int d2i(void *out, unsigned char **in, size_t size, int type); + +int i2d_PKI_X509(unsigned char **out, size_t *size, PKI_X509 *in); +int d2i_PKI_X509(PKI_X509 *out, unsigned char **in, size_t size); + +int i2d_PKI_X509_sk(unsigned char **out, size_t *size, PKI_X509_STACK *in); + +int i2d_PKI_STACK(unsigned char **out, size_t *size, PKI_STACK *sk, int sk_type); +int d2i_PKI_STACK(PKI_STACK **sk, unsigned char *in, size_t size, int sk_type); + +END_C_DECLS + +#endif /* _LIBPKI_ASN1_UTILS_H */ diff --git a/include/libpki/utils/banners.h b/include/libpki/utils/banners.h new file mode 100644 index 00000000..3ebf1ad0 --- /dev/null +++ b/include/libpki/utils/banners.h @@ -0,0 +1,50 @@ +// file: libpki/banners.h + +#ifndef LIBPKI_VERSION_H +#include +#endif + +#ifndef HEADER_OPENSSLV_H +#include +#endif + +#ifndef LIBPKI_HEADER_BANNERS_H +#define LIBPKI_HEADER_BANNERS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define BOLD "\x1B[1m" +#define NORM "\x1B[0m" +#define BLACK "\x1B[30m" +#define RED "\x1B[31m" +#define GREEN "\x1B[32m" +#define BLUE "\x1B[34m" + +#define BG "\x1B[47m" +#define BG_BOLD "\x1B[31;47m" +#define BG_NORM "\x1B[30;47m" +#define BG_RED "\x1B[31;47m" +#define BG_GREEN "\x1B[32;47m" +#define BG_BLUE "\x1B[34;47m" + +extern const char * libpki_banner; +extern const char * prog_banner; + +#define LIBPKI_BANNER_PRINT(a) \ + fprintf(a, libpki_banner) + +#define LIBPKI_BANNER_PRINT_STDOUT() fprintf(stdout, libpki_banner) + +#define PROGRAM_BANNER_PRINT(filePointer, progName, version, year, copyright) \ + fprintf(filePointer, prog_banner, progName, version, year, copyright) + +#define PROGRAM_BANNER_PRINT_STDOUT(progName, version, year, copyright) \ + fprintf(stdout, prog_banner, progName, version, year, copyright) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/libpki/utils/encoder.h b/include/libpki/utils/encoder.h new file mode 100644 index 00000000..6de9f288 --- /dev/null +++ b/include/libpki/utils/encoder.h @@ -0,0 +1,16 @@ +/* PKI Data Encoder */ + + +#ifndef _LIBPKI_PKI_DATA_ENCODER_H +#define _LIBPKI_PKI_DATA_ENCODER_H + +#include + +/* \brief Data Formats + * + * Encodes the data from one format to another + */ +int PKI_DATA_encode ( const void *data, const size_t size, + const PKI_TYPE data_format, void **out, size_t *out_size, int out_format ); + +#endif /* _LIBPKI_PKI_DATA_ENCODER_H */ diff --git a/include/libpki/utils/net/dns.h b/include/libpki/utils/net/dns.h new file mode 100644 index 00000000..0cb1b120 --- /dev/null +++ b/include/libpki/utils/net/dns.h @@ -0,0 +1,39 @@ +/* + * LIBPKI - Easy PKI Library + * by Massimiliano Pala (madwolf@openca.org) + * + * Copyright (c) 2007-2012 by Massimiliano Pala and OpenCA Labs. + * All rights reserved. + * + * ==================================================================== + * + */ + +#ifndef _LIBPKI_DNS_H +#define _LIBPKI_DNS_H + +#ifdef HAVE_LIBRESOLV +#include +#include +#include +#include +#ifndef T_AAAA +#include +#endif +#include +#endif + +enum pki_dns { + pki_ns_t_address = 300 +}; + +#ifndef T_CERT +#define T_CERT 36 +#endif + +PKI_MEM_STACK *URL_get_data_dns_url(const URL * url, + ssize_t size); + +int URL_get_dns_type(const char *str); + +#endif diff --git a/include/libpki/utils/net/http_s.h b/include/libpki/utils/net/http_s.h new file mode 100644 index 00000000..63930a88 --- /dev/null +++ b/include/libpki/utils/net/http_s.h @@ -0,0 +1,113 @@ +/* openca/pkicrypto/url.h */ +/* + * LIBPKI - OpenSource PKI library + * by Massimiliano Pala (madwolf@openca.org) and OpenCA project + * + * Copyright (c) 2001-2007 The OpenCA Project. All rights reserved. + * + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + + +#ifndef _LIBPKI_PKI_HTTP_H +#define _LIBPKI_PKI_HTTP_H + +#include +#include +#include + +#include + +#define LIBPKI_HTTP_BUF_SIZE 8192 +#define LIBPKI_HTTPS_BUF_SIZE 8192 + +/* ----------------------------- HTTP HELP Functions -------------------- */ + +void PKI_HTTP_free(PKI_HTTP *rv); + +PKI_HTTP * PKI_HTTP_new(void); + +char * PKI_HTTP_get_header_txt(const char * data, + const char * header); + +char * PKI_HTTP_get_header(const PKI_HTTP * http, + const char * header); + +PKI_HTTP *PKI_HTTP_get_message(const PKI_SOCKET * sock, + int timeout, + size_t max_size); + +/* --------------------- HTTP Generic GET/POST Functions ---------------- */ + +int PKI_HTTP_get_url (const URL * url, + const char * data, + size_t data_size, + const char * content_type, + int method, + int timeout, + size_t max_size, + PKI_MEM_STACK ** sk, + PKI_SSL * ssl ); + +int PKI_HTTP_get_socket (const PKI_SOCKET * sock, + const char * data, + size_t data_size, + const char * content_type, + int method, + int timeout, + size_t max_size, + PKI_MEM_STACK ** sk ); + +/* ------------------------------ HTTP Get Functions -------------------- */ + +int PKI_HTTP_GET_data(const char * url_s, + int timeout, + size_t max_size, + PKI_MEM_STACK ** ret, + PKI_SSL * ssl); + +int PKI_HTTP_GET_data_url(const URL * url, + int timeout, + size_t max_size, + PKI_MEM_STACK ** ret, + PKI_SSL * ssl); + +int PKI_HTTP_GET_data_socket(const PKI_SOCKET * url, + int timeout, + size_t max_size, + PKI_MEM_STACK ** ret); + +/* ------------------------------HTTP Put Functions -------------------- */ + +int PKI_HTTP_POST_data(const char * url_s, + const char * data, + size_t size, + const char * content_type, + int timeout, + size_t max_size, + PKI_MEM_STACK ** ret_sk, + PKI_SSL * ssl); + +int PKI_HTTP_POST_data_url(const URL * url, + const char * data, + size_t size, + const char * content_type, + int timeout, + size_t max_size, + PKI_MEM_STACK ** ret_sk, + PKI_SSL * ssl); + +int PKI_HTTP_POST_data_socket(const PKI_SOCKET *sock, + const char * data, + size_t size, + const char * content_type, + int timeout, + size_t max_size, + PKI_MEM_STACK ** ret_sk ); + +#endif diff --git a/include/libpki/utils/net/ldap.h b/include/libpki/utils/net/ldap.h new file mode 100644 index 00000000..0fdbec48 --- /dev/null +++ b/include/libpki/utils/net/ldap.h @@ -0,0 +1,28 @@ +/* + * LIBPKI - Easy PKI Library + * by Massimiliano Pala (madwolf@openca.org) + * OpenCA project 2007 + * + * Copyright (c) 2007 The OpenCA Project. All rights reserved. + * + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef _LIBPKI_LDAP_H +#define _LIBPKI_LDAP_H + +#if defined(LDAP_VENDOR_SUN) || defined (LDAP_VENDOR_OPENLDAP) || \ + defined(LDAP_VENDOR_MICROSOFT) +#include + +LDAP *URL_LDAP_connect(const URL *url, int timeout ); +PKI_MEM_STACK *URL_get_data_ldap_url(const URL *url, int timeout, ssize_t size); + +#endif + +#endif diff --git a/include/libpki/utils/net/pkcs11.h b/include/libpki/utils/net/pkcs11.h new file mode 100644 index 00000000..24ec094f --- /dev/null +++ b/include/libpki/utils/net/pkcs11.h @@ -0,0 +1,20 @@ +/* libpki/net/pki_pg.h */ + +#ifndef _LIBPKI_URL_PKCS11_H +#define _LIBPKI_URL_PKCS11_H + +#ifdef HAVE_P11 + +#include + +#endif /* HAVE_P11 */ + +char *pkcs11_parse_url_libpath(const URL * url); + +PKI_MEM_STACK *URL_get_data_pkcs11(const char * url_s, + ssize_t size ); + +PKI_MEM_STACK *URL_get_data_pkcs11_url(const URL * url, + ssize_t size ); + +#endif /* _LIBPKI_URL_PKCS11_H */ diff --git a/include/libpki/utils/net/pki_mysql.h b/include/libpki/utils/net/pki_mysql.h new file mode 100644 index 00000000..24691a57 --- /dev/null +++ b/include/libpki/utils/net/pki_mysql.h @@ -0,0 +1,24 @@ +/* libpki/net/mysql.h */ + +#ifndef _LIBPKI_URL_MYSQL_H +#define _LIBPKI_URL_MYSQL_H + +#ifdef HAVE_MYSQL + +#include + +MYSQL *db_connect ( const URL *url ); +int db_close ( MYSQL *sql ); + +#endif /* HAVE_MYSQL */ + +char *parse_url_table ( const URL * url ); +char *parse_url_dbname ( const URL *url ); + +PKI_MEM_STACK *URL_get_data_mysql ( const char *url_s, ssize_t size ); +PKI_MEM_STACK *URL_get_data_mysql_url ( const URL *url, ssize_t size ); + +int URL_put_data_mysql ( const char *url_s, const PKI_MEM *data ); +int URL_put_data_mysql_url ( const URL *url, const PKI_MEM *data ); + +#endif /* _LIBPKI_URL_MYSQL_H */ diff --git a/include/libpki/utils/net/pki_pg.h b/include/libpki/utils/net/pki_pg.h new file mode 100644 index 00000000..79ea2692 --- /dev/null +++ b/include/libpki/utils/net/pki_pg.h @@ -0,0 +1,24 @@ +/* libpki/net/pki_pg.h */ + +#ifndef _LIBPKI_URL_PG_H +#define _LIBPKI_URL_PG_H + +#ifdef HAVE_PG + +#include + +PGconn *pg_db_connect ( const URL *url ); +int pg_db_close ( PGconn *sql ); + +#endif /* HAVE_PG */ + +char *pg_parse_url_table ( const URL * url ); +char *pg_parse_url_dbname ( const URL *url ); + +PKI_MEM_STACK *URL_get_data_pg ( const char *url_s, ssize_t size ); +PKI_MEM_STACK *URL_get_data_pg_url ( const URL *url, ssize_t size ); + +int URL_put_data_pg ( const char *url_s, const PKI_MEM *data ); +int URL_put_data_pg_url ( const URL *url, const PKI_MEM *data ); + +#endif /* _LIBPKI_URL_PG_H */ diff --git a/include/libpki/utils/net/pki_socket.h b/include/libpki/utils/net/pki_socket.h new file mode 100644 index 00000000..38f3f6b0 --- /dev/null +++ b/include/libpki/utils/net/pki_socket.h @@ -0,0 +1,97 @@ +/* + * LIBPKI - OpenSource PKI library + * by Massimiliano Pala (madwolf@openca.org) and OpenCA project + * + * Copyright (c) 2001-2007 The OpenCA Project. All rights reserved. + * + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef _LIBPKI_PKI_SOCKET_H_ +#define _LIBPKI_PKI_SOCKET_H_ + +#include + +typedef enum { + PKI_SOCKET_TYPE_UNKNOWN = -1, + PKI_SOCKET_FD = 0, + PKI_SOCKET_SSL = 1, +} PKI_SOCKET_TYPE; + +typedef enum { + PKI_SOCKET_DISCONNECTED = 0, + PKI_SOCKET_CONNECTED = 1, +} PKI_SOCKET_STATUS; + +typedef struct pki_socket_st { + PKI_SOCKET_TYPE type; + int status; + + int fd; + PKI_SSL *ssl; + + URL *url; + +} PKI_SOCKET; + +// #include + +/* PKI_SOCKET management functions */ +PKI_SOCKET *PKI_SOCKET_new ( void ); +PKI_SOCKET *PKI_SOCKET_new_ssl ( PKI_SSL *ssl ); +PKI_SOCKET *PKI_SOCKET_new_fd ( int fd ); +void PKI_SOCKET_free ( PKI_SOCKET *sock); + +int PKI_SOCKET_set_flags(PKI_SOCKET * sock, + int flags); + +int PKI_SOCKET_set_trusted(PKI_SOCKET * sock, + PKI_X509_CERT_STACK * sk); + +int PKI_SOCKET_open(PKI_SOCKET * sock, + const char * url_s, + int timeout); + +int PKI_SOCKET_open_url(PKI_SOCKET * sock, + const URL * url_s, + int timeout); + +int PKI_SOCKET_connect(PKI_SOCKET * sock, + const URL * url, + int timeout ); + +int PKI_SOCKET_connect_ssl(PKI_SOCKET * sock, + const URL * url, + int timeout ); + +int PKI_SOCKET_close(PKI_SOCKET *sock); + +int PKI_SOCKET_set_ssl(PKI_SOCKET * sock, + PKI_SSL * ssl ); + +PKI_SSL * PKI_SOCKET_get_ssl(const PKI_SOCKET *sock); + +int PKI_SOCKET_set_fd(PKI_SOCKET * sock, + int fd ); + +int PKI_SOCKET_get_fd(const PKI_SOCKET * sock); + +int PKI_SOCKET_start_ssl(PKI_SOCKET * sock); + +ssize_t PKI_SOCKET_read(const PKI_SOCKET * sock, + const char * buf, + size_t n, + int timeout ); + +ssize_t PKI_SOCKET_write(const PKI_SOCKET * sock, + const char * buf, + size_t n); + +const URL * PKI_SOCKET_get_url(const PKI_SOCKET * sock); + +#endif diff --git a/include/libpki/utils/net/sock.h b/include/libpki/utils/net/sock.h new file mode 100644 index 00000000..54c8f357 --- /dev/null +++ b/include/libpki/utils/net/sock.h @@ -0,0 +1,71 @@ +/* + * LIBPKI - OpenSource PKI library + * by Massimiliano Pala (madwolf@openca.org) and OpenCA project + * + * Copyright (c) 2001-2007 The OpenCA Project. All rights reserved. + * + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef __OPENCA_SOCK_WRAP_H +#define __OPENCA_SOCK_WRAP_H + +#ifdef HAVE_SYS_SOCKET_H +# include +# include +#else +# include +#endif + +#include + +#include +#include + +#include +#include +#include + +#include + +#define INTERRUPTED_BY_SIGNAL (errno == EINTR || errno == ECHILD) + +#define SA struct sockaddr + +typedef enum { + PKI_NET_SOCK_STREAM = SOCK_STREAM, + PKI_NET_SOCK_DGRAM = SOCK_DGRAM, +} PKI_NET_SOCK_TYPE; + +/* Public Functions */ +int PKI_NET_socket(int family, int type, int protocol); +int PKI_NET_listen(const char *host, int port, PKI_NET_SOCK_TYPE socktype); +int PKI_NET_accept(int sock, int timeout); +int PKI_NET_open(const URL *url, int timeout); +int PKI_NET_close(int sock); +ssize_t PKI_NET_write (int fd, const void *bufptr, size_t nbytes); +ssize_t PKI_NET_read (int fd, const void *bufptr, size_t nbytes, int timeout); +PKI_MEM *PKI_NET_get_data ( int fd, int timeout, size_t max_size ); + +/* Datagrams functions */ +ssize_t PKI_NET_recvfrom (int fd, const void *bufptr, size_t nbytes, const struct sockaddr_in *cli, socklen_t size); +ssize_t PKI_NET_sendto (int sock, const char *host, int port, const void *data, size_t len); + +/* Internal Socket Wrapping functions */ +int _Listen (const char *hostname, int port, PKI_NET_SOCK_TYPE socktype); +int _Accept (int listen_sockfd, const SA *cliaddr, const socklen_t *addrlenp); +ssize_t _Read (int fd, const void *bufptr, size_t nbytes); +ssize_t _Write (int fd, const void *bufptr, size_t nbytes); +int _Select (int maxfdp1, fd_set *readset, fd_set *writeset, + fd_set *exceptset, struct timeval *timeout); + +/* Externally available functions */ +int inet_connect ( const URL *url ); +int inet_close ( int fd ); + +#endif diff --git a/include/libpki/utils/net/ssl.h b/include/libpki/utils/net/ssl.h new file mode 100644 index 00000000..ec6e525a --- /dev/null +++ b/include/libpki/utils/net/ssl.h @@ -0,0 +1,390 @@ +/* openca/pkicrypto/url.h */ +/* + * LIBPKI - OpenSource PKI library + * by Massimiliano Pala (madwolf@openca.org) and OpenCA project + * + * Copyright (c) 2001-2007 The OpenCA Project. All rights reserved. + * + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + + +#ifndef _LIBPKI_PKI_SSL_H +#define _LIBPKI_PKI_SSL_H + +#include +#include + +/*! \brief Algorithms for PKI_SSL connections */ +typedef SSL_METHOD PKI_SSL_ALGOR; + +/* Client Algorithms */ +#define PKI_SSL_CLIENT_ALGOR_UNKNOWN 0 + +#ifdef SSL2_VERSION +#define PKI_SSL_CLIENT_ALGOR_SSL2 SSLv2_client_method() +#else +#define PKI_SSL_CLIENT_ALGOR_SSL2 PKI_SSL_CLIENT_ALGOR_UNKNOWN +#endif + +#ifndef OPENSSL_NO_SSL3 +# ifdef SSL3_VERSION +# define PKI_SSL_CLIENT_ALGOR_SSL3 SSLv3_client_method() +# else +# define PKI_SSL_CLIENT_ALGOR_SSL3 PKI_SSL_CLIENT_ALGOR_UNKNOWN +# endif +#else +# define PKI_SSL_CLIENT_ALGOR_SSL3 PKI_SSL_CLIENT_ALGOR_UNKNOWN +#endif + +#ifndef OPENSSL_NO_TLS1 +# ifdef TLS1_VERSION +# define PKI_SSL_CLIENT_ALGOR_TLS1 TLSv1_client_method() +# else +# define PKI_SSL_CLIENT_ALGOR_TLS1 PKI_SSL_CLIENT_ALGOR_UNKNOWN +# endif +#else +# define PKI_SSL_CLIENT_ALGOR_TLS1 PKI_SSL_CLIENT_ALGOR_UNKNOWN +#endif + +#ifndef OPENSSL_NO_TLS1_1 +# ifdef TLS1_1_VERSION +# define PKI_SSL_CLIENT_ALGOR_TLS1_1 TLSv1_1_client_method() +# else +# define PKI_SSL_CLIENT_ALGOR_TLS1_1 PKI_SSL_CLIENT_ALGOR_UNKNOWN +# endif +#else +# define PKI_SSL_CLIENT_ALGOR_TLS1_1 PKI_SSL_CLIENT_ALGOR_UNKNOWN +#endif + +#ifndef OPENSSL_NO_TLS1_2 +# ifdef TLS1_2_VERSION +# define PKI_SSL_CLIENT_ALGOR_TLS1_2 TLSv1_2_client_method() +# else +# define PKI_SSL_CLIENT_ALGOR_TLS1_2 PKI_SSL_CLIENT_ALGOR_UNKNOWN +# endif +#else +# define PKI_SSL_CLIENT_ALGOR_TLS1_2 PKI_SSL_CLIENT_ALGOR_UNKNOWN +#endif + +#ifndef OPENSSL_NO_DTLS1 +# ifdef DTLSv1_client_method +# define PKI_SSL_CLIENT_ALGOR_DTLS1 DTLSv1_client_method() +# else +# define PKI_SSL_CLIENT_ALGOR_DTLS1 PKI_SSL_CLIENT_ALGOR_UNKNOWN +# endif +#else +# define PKI_SSL_CLIENT_ALGOR_DTLS1 PKI_SSL_CLIENT_ALGOR_UNKNOWN +#endif + +/* Generic method that implements all SSLv2, SSLv3, TLSv1.0, + * TLSv1.1, and TLSv1.2 */ +#define PKI_SSL_CLIENT_ALGOR_ALL TLS_client_method() + +/* Default Client Method */ +#define PKI_SSL_CLIENT_ALGOR_DEFAULT PKI_SSL_CLIENT_ALGOR_ALL + +/* Server Algorithms */ +#define PKI_SSL_SERVER_ALGOR_UNKNOWN 0 + +#ifndef OPENSSL_NO_SSL2 +# ifdef SSL2_VERSION +# define PKI_SSL_SERVER_ALGOR_SSL2 SSLv2_server_method() +# else +# define PKI_SSL_SERVER_ALGOR_SSL2 PKI_SSL_SERVER_ALGOR_UNKNOWN +# endif +#else +# define PKI_SSL_SERVER_ALGOR_SSL2 PKI_SSL_SERVER_ALGOR_UNKNOWN +#endif + +#ifndef OPENSSL_NO_SSL3 +# ifdef SSL3_VERSION +# define PKI_SSL_SERVER_ALGOR_SSL3 SSLv3_server_method() +# else +# define PKI_SSL_SERVER_ALGOR_SSL3 PKI_SSL_SERVER_ALGOR_UNKNOWN +# endif +#else +# define PKI_SSL_SERVER_ALGOR_SSL3 PKI_SSL_SERVER_ALGOR_UNKNOWN +#endif + +#ifndef OPENSSL_NO_TLS1 +# ifdef TLS1_VERSION +# define PKI_SSL_SERVER_ALGOR_TLS1 TLSv1_server_method() +# else +# define PKI_SSL_SERVER_ALGOR_TLS1 PKI_SSL_SERVER_ALGOR_UNKNOWN +# endif +#else +# define PKI_SSL_SERVER_ALGOR_TLS1 PKI_SSL_SERVER_ALGOR_UNKNOWN +#endif + +#ifndef OPENSSL_NO_TLS1_1 +# ifdef TLS1_1_VERSION +# define PKI_SSL_SERVER_ALGOR_TLS1_1 TLSv1_1_server_method() +# else +# define PKI_SSL_SERVER_ALGOR_TLS1_1 PKI_SSL_SERVER_ALGOR_UNKNOWN +# endif +#else +# define PKI_SSL_SERVER_ALGOR_TLS1_1 PKI_SSL_SERVER_ALGOR_UNKNOWN +#endif + +#ifndef OPENSSL_NO_TLS1_2 +# ifdef TLS1_2_VERSION +# define PKI_SSL_SERVER_ALGOR_TLS1_2 TLSv1_2_server_method() +# else +# define PKI_SSL_SERVER_ALGOR_TLS1_2 PKI_SSL_SERVER_ALGOR_UNKNOWN +# endif +#else +# define PKI_SSL_SERVER_ALGOR_TLS1_2 PKI_SSL_SERVER_ALGOR_UNKNOWN +#endif + +#ifndef OPENSSL_NO_TLS1_3 +# ifdef TLS1_3_VERSION +# define PKI_SSL_SERVER_ALGOR_TLS1_3 TLSv1_3_server_method() +# else +# define PKI_SSL_SERVER_ALGOR_TLS1_3 PKI_SSL_SERVER_ALGOR_UNKNOWN +# endif +#else +# define PKI_SSL_SERVER_ALGOR_TLS1_3 PKI_SSL_SERVER_ALGOR_UNKNOWN +#endif + +#ifndef OPENSSL_NO_DTLS1 +# define PKI_SSL_SERVER_ALGOR_DTLS1 DTLSv1_server_method() +# else +# define PKI_SSL_SERVER_ALGOR_DTLS1 PKI_SSL_SERVER_ALGOR_UNKNOWN +# endif + +#ifndef OPENSSL_NO_DTLS1_2 +# define PKI_SSL_SERVER_ALGOR_DTLS1_2 DTLSv1_2_server_method() +# else +# define PKI_SSL_SERVER_ALGOR_DTLS1 PKI_SSL_SERVER_ALGOR_UNKNOWN +# endif + +/* Generic method that implements all SSLv2, SSLv3, TLSv1.0, + * TLSv1.1, and TLSv1.2 */ +#define PKI_SSL_SERVER_ALGOR_ALL TLS_server_method() + +/* Default Server Method */ +#define PKI_SSL_SERVER_ALGOR_DEFAULT PKI_SSL_SERVER_ALGOR_TLS1_3 + +/*! \brief Flags for algorithm exclusion in PKI_SSL connections */ + +typedef enum { +#ifdef SSL_OP_NO_SSLv2 + PKI_SSL_FLAGS_NO_SSL2 = SSL_OP_NO_SSLv2, +#else + PKI_SSL_FLAGS_NO_SSL2 = 0, +#endif +#ifdef SSL_OP_NO_SSLv3 + PKI_SSL_FLAGS_NO_SSL3 = SSL_OP_NO_SSLv3, +#else + PKI_SSL_FLAGS_NO_SSL3 = 0, +#endif +#ifdef SSL_OP_NO_TLSv1 + PKI_SSL_FLAGS_NO_TLS1 = SSL_OP_NO_TLSv1, +#else + PKI_SSL_FLAGS_NO_TLS1 = 0, +#endif +#ifdef SSL_OP_NO_TLSv1_1 + PKI_SSL_FLAGS_NO_TLS1_1 = SSL_OP_NO_TLSv1_1, +#else + PKI_SSL_FLAGS_NO_TLS1_1 = 0, +#endif +#ifdef SSL_OP_NO_TLSv1_2 + PKI_SSL_FLAGS_NO_TLS1_2 = SSL_OP_NO_TLSv1_2, +#else + PKI_SSL_FLAGS_NO_TLS1_2 = 0, +#endif +#ifdef SSL_OP_NO_TLSv1_3 + PKI_SSL_FLAGS_NO_TLS1_3 = SSL_OP_NO_TLSv1_3, +#else + PKI_SSL_FLAGS_NO_TLS1_3 = 0, +#endif +#ifdef SSL_OP_NO_DTLSv1 + PKI_SSL_FLAGS_NO_DTLS1 = SSL_OP_NO_DTLSv1, +#else + PKI_SSL_FLAGS_NO_DTLS1 = 0, +#endif + +} PKI_SSL_FLAGS; + +#define PKI_SSL_FLAGS_DEFAULT \ + (PKI_SSL_FLAGS_NO_SSL2 | PKI_SSL_FLAGS_NO_SSL3) + +/*! \brief Flags for Verify Behavior: PRQP, CRL, OCSP */ + +typedef enum { + PKI_SSL_VERIFY_NONE = 0, + PKI_SSL_VERIFY_PEER = 1, + PKI_SSL_VERIFY_PEER_REQUIRE = 2, + PKI_SSL_VERIFY_CRL = 4, + PKI_SSL_VERIFY_CRL_REQUIRE = 8, + PKI_SSL_VERIFY_OCSP = 16, + PKI_SSL_VERIFY_OCSP_REQUIRE = 32, + PKI_SSL_VERIFY_NO_SELFSIGNED = 64, + PKI_SSL_VERIFY_ENABLE_PRQP = 128, +} PKI_SSL_VERIFY; + +#define PKI_SSL_VERIFY_NORMAL \ + PKI_SSL_VERIFY_CRL | \ + PKI_SSL_VERIFY_OCSP | \ + PKI_SSL_VERIFY_ENABLE_PRQP + +#define PKI_SSL_VERIFY_REQUIRE \ + PKI_SSL_VERIFY_CRL_REQUIRE | \ + PKI_SSL_VERIFY_OCSP_REQUIRE | \ + PKI_SSL_VERIFY_ENABLE_PRQP + +/* Ciphers for the different protocols */ +#define PKI_SSL_CIPHERS_SSL3 \ + "HIGH:MEDIUM:!NULL" + +#define PKI_SSL_CIPHERS_TLS1 \ + "ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA" \ + ":DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA" \ + ":ECDH-RSA-AES256-SHA:ECDH-ECDSA-AES256-SHA" \ + ":ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA" \ + ":DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA" \ + ":PSK-AES128-CBC-SHA" + +#define PKI_SSL_CIPHERS_TLS1_1 \ + ":TLS_RSA_WITH_IDEA_CBC_SHA:TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA:" \ + ":TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:" \ + ":ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA" \ + ":DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA" \ + ":ECDH-RSA-AES256-SHA:ECDH-ECDSA-AES256-SHA" \ + ":ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA" \ + ":DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA" \ + ":PSK-AES128-CBC-SHA" + +#define PKI_SSL_CIPHERS_TLS1_2 \ + "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384" \ + ":ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384" \ + ":DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256" \ + ":ECDH-RSA-AES256-GCM-SHA384:ECDH-ECDSA-AES256-GCM-SHA384" \ + ":ECDH-RSA-AES256-SHA384:ECDH-ECDSA-AES256-SHA384" \ + ":ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256" \ + ":ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256" \ + ":DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256" \ + ":ECDH-RSA-AES128-GCM-SHA256:ECDH-ECDSA-AES128-GCM-SHA256" \ + ":ECDH-RSA-AES128-SHA256:ECDH-ECDSA-AES128-SHA256" \ + ":AES256-GCM-SHA384:AES256-SHA256" \ + ":AES128-GCM-SHA256:AES128-SHA256" + +#define PKI_SSL_CIPHERS_ALL \ + PKI_SSL_CIPHERS_TLS1_2 \ + PKI_SSL_CIPHERS_TLS1_1 \ + PKI_SSL_CIPHERS_TLS1 \ + PKI_SSL_CIPHERS_SSL3 + +/* Default SSL/TLS Ciphers */ +#define PKI_SSL_CIPHERS_DEFAULT \ + PKI_SSL_CIPHERS_TLS1_2 + +/*! \brief PKI_SSL data structure for SSL/TLS */ + +typedef struct pki_ssl_t { + + /* Connection flags -> to disable specific SSL/TLS versions */ + int flags; + + /* Authentication -> none, client, server, all */ + int auth; + + /* Pointers to the OpenSSL data structures */ + SSL *ssl; + SSL_CTX *ssl_ctx; + char *cipher; + const PKI_SSL_ALGOR *algor; + + /* Pointer to the PKI_TOKEN to be used for the communication */ + struct pki_token_st *tk; + + /* PKI_X509_CERT_STACK of trusted certificates */ + PKI_X509_CERT_STACK *trusted_certs; + + /* PKI_X509_CERT_STACK of other certificates (e.g., SubCAs to facilitate + * the certificate's chain building) */ + PKI_X509_CERT_STACK *other_certs; + + /* Set to 1 while the socket is connected, 0 otherwise */ + int connected; + + /* Server name - used to set the TLS extension */ + char *servername; + + /* Not Used, yet */ + char *session; + + /* After authentication, if set to 1 we continue */ + int verify_ok; + + /* Enabling certificate validation flags */ + unsigned int verify_flags; + + /* Peer Certificates Chain */ + PKI_X509_CERT_STACK *peer_chain; + +} PKI_SSL; + +#ifndef _LIBPKI_PKI_X509_DATA_ST_H + + /* Forward Declaration for PKI_X509 structure */ + struct pki_x509_st; +// typedef struct pki_x509_st PKI_X509; + + /* Forward Definition for PKI_X509_CERT */ +#define PKI_X509_CERT PKI_X509 + +#endif + +#include + +/* SSL helper functions */ +PKI_SSL * PKI_SSL_new ( const PKI_SSL_ALGOR *algor ); +PKI_SSL *PKI_SSL_dup ( PKI_SSL *ssl ); +void PKI_SSL_free ( PKI_SSL *ssl ); + +int PKI_SSL_set_algor ( PKI_SSL *ssl, PKI_SSL_ALGOR *algor ); +int PKI_SSL_set_flags ( PKI_SSL *ssl, PKI_SSL_FLAGS flags ); +int PKI_SSL_set_cipher ( PKI_SSL *ssl, char *cipher ); + +int PKI_SSL_set_token ( PKI_SSL *ssl, struct pki_token_st *tk ); + +int PKI_SSL_set_trusted ( PKI_SSL *ssl, PKI_X509_CERT_STACK *sk ); +int PKI_SSL_add_trusted ( PKI_SSL *ssl, PKI_X509_CERT *cert ); +int PKI_SSL_set_others ( PKI_SSL *ssl, PKI_X509_CERT_STACK *sk ); +int PKI_SSL_add_other ( PKI_SSL *ssl, PKI_X509_CERT *cert ); + +int PKI_SSL_set_fd ( PKI_SSL *ssl, int fd ); +int PKI_SSL_get_fd ( PKI_SSL *ssl ); + +int PKI_SSL_set_host_name ( PKI_SSL *ssl, const char * hostname ); + +int PKI_SSL_set_verify ( PKI_SSL *ssl, PKI_SSL_VERIFY vflags ); +int PKI_SSL_check_verify ( PKI_SSL *ssl, PKI_SSL_VERIFY flag ); + +int PKI_SSL_connect_url ( PKI_SSL *ssl, URL *url, int timeout ); +int PKI_SSL_connect ( PKI_SSL *ssl, char *url_s, int timeout ); + +int PKI_SSL_start_ssl ( PKI_SSL *ssl, int fd ); +int PKI_SSL_close ( PKI_SSL *ssl ); + +ssize_t PKI_SSL_write(const PKI_SSL * ssl, + const char * buf, + ssize_t size); + +ssize_t PKI_SSL_read(const PKI_SSL * ssl, + const char * buf, + ssize_t size ); + +struct pki_x509_st * PKI_SSL_get_peer_cert ( PKI_SSL *ssl ); +PKI_X509_CERT_STACK * PKI_SSL_get_peer_chain ( PKI_SSL *ssl ); + +const char *PKI_SSL_get_servername ( PKI_SSL *ssl ); + +#endif diff --git a/include/libpki/utils/net/types.h b/include/libpki/utils/net/types.h new file mode 100644 index 00000000..0d44f3fc --- /dev/null +++ b/include/libpki/utils/net/types.h @@ -0,0 +1,125 @@ +/* net/types.h */ + + +#ifndef _LIBPKI_OS_H +#include +#endif + +#ifndef _LIBPKI_NET_TYPES_H +#define _LIBPKI_NET_TYPES_H + +BEGIN_C_DECLS + +/* Forward Declarations */ +typedef struct pki_stack_st PKI_STACK; +typedef struct pki_mem_st PKI_MEM; + +typedef enum pki_http_method_enum { + PKI_HTTP_METHOD_UNKNOWN = 0, + PKI_HTTP_METHOD_GET, + PKI_HTTP_METHOD_POST, + PKI_HTTP_METHOD_HTTP +} PKI_HTTP_METHOD; + +#define PKI_HTTP_METHOD_POST_TXT "POST" +#define PKI_HTTP_METHOD_GET_TXT "GET" +#define PKI_HTTP_METHOD_HTTP_TXT "HTTP" + +typedef enum { + URI_PROTO_FILE = 0, + URI_PROTO_LDAP = 1, + URI_PROTO_HTTP = 2, + URI_PROTO_HTTPS = 3, + URI_PROTO_FTP = 4, + URI_PROTO_ID = 5, + URI_PROTO_FD = 6, + URI_PROTO_MYSQL = 10, + URI_PROTO_PG = 20, + URI_PROTO_PKCS11 = 30, + URI_PROTO_SOCK = 40, + URI_PROTO_DNS = 50, +} URI_PROTO; + +#define DEFAULT_LDAP_PORT 389 +#define DEFAULT_HTTP_PORT 80 +#define DEFAULT_HTTPS_PORT 443 +#define DEFAULT_FTP_PORT 21 +#define DEFAULT_MYSQL_PORT 3306 +#define DEFAULT_PG_PORT 3456 +#define DEFAULT_PKCS11_PORT -1 +#define DEFAULT_DNS_PORT -1 + +#define LIBPKI_URL_BUF_SIZE 8192 + +typedef struct url_data_st { + + /* Original URL string */ + char * url_s; + + /* Protocol, currently supported LDAP and FILE */ + URI_PROTO proto; + + /* URL requires SSL/TLS :: 0 = NO, 1 = YES */ + int ssl; + + /* Address or filename */ + char *addr; + + /* Communication Port (where supported by the protocol) */ + int port; + + /* Authentication (where supported by the protocol) */ + char *usr; + char *pwd; + + /* Search facility - for LDAP the DN is in the path, while + the attributes for filtering the responses are here in + the attrs stack. The same for mysql:// or postgres:// + urls */ + char *attrs; + + /* Path - Used by HTTP/LDAP/ID/etc... */ + char *path; + + /* Object Number - Used to identify a specific object + when multiple objects are matched */ + int object_num; +} URL; + +typedef struct http_headers { + + /* Method */ + PKI_HTTP_METHOD method; + + /* HTTP version as float number */ + float version; + + /* Returned Code */ + int code; + + /* Returned Location - in case a 30X is found */ + char *location; + + /* Content Type */ + char *type; + + /* URL for GET methods */ + // URL *url; + + /* Path */ + char *path; + + /* Protocol */ + int proto; + + /* Headers Data */ + PKI_MEM *head; + + /* HTTP body data */ + PKI_MEM *body; + +} PKI_HTTP; + +END_C_DECLS + +#endif diff --git a/include/libpki/utils/net/url.h b/include/libpki/utils/net/url.h new file mode 100644 index 00000000..d7ffa2bc --- /dev/null +++ b/include/libpki/utils/net/url.h @@ -0,0 +1,101 @@ +/* net/url.h */ +/* + * LIBPKI - OpenSource PKI library + * by Massimiliano Pala (madwolf@openca.org) and OpenCA project + * + * Copyright (c) 2001-2008 The OpenCA Project. All rights reserved. + * + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef _LIBPKI_NET_TYPES_H +#include +#endif + +#ifndef _LIBPKI_URL_H +#define _LIBPKI_URL_H + +/* ----------------------- URL Function prototypes --------------------- */ + +void URL_free(URL *url); + +URL * URL_new(const char * url); + +const char * URL_get_parsed(const URL *url); + +const char * URL_proto_to_string(URI_PROTO proto); + +char * URL_get_local_addr(void); + +/* ----------------------- URL wrapping functions ---------------------- */ + +PKI_MEM_STACK * URL_get_data(const char *url_s, + int timeout, + ssize_t max_size, + PKI_SSL *ssl); + +PKI_MEM_STACK * URL_get_data_url(const URL * url, + int timeout, + ssize_t max_size, + PKI_SSL *ssl); + +PKI_MEM_STACK * URL_get_data_socket(const PKI_SOCKET *sock, + int timeout, + ssize_t size); + +int URL_put_data(const char * url_s, + const PKI_MEM * data, + const char * contType, + PKI_MEM_STACK ** ret_sk, + int timeout, + ssize_t max_size, + PKI_SSL * ssl); + +int URL_put_data_raw(const char * url_s, + const unsigned char * data, + const size_t size, + const char * contType, + PKI_MEM_STACK ** ret_sk, + int timeout, + ssize_t max_size, + PKI_SSL * ssl); + +int URL_put_data_url(const URL * url, + const PKI_MEM * data, + const char * contType, + PKI_MEM_STACK ** ret_sk, + int timeout, + ssize_t max_size, + PKI_SSL * ssl); + +int URL_put_data_socket(const PKI_SOCKET * sock, + const PKI_MEM * data, + const char * contType, + PKI_MEM_STACK ** ret_sk, + int timeout, + ssize_t max_size); + +/* ------------------------ Actual I/O implementation ------------------- */ + +PKI_MEM_STACK *URL_get_data_fd(const URL * url, + ssize_t size); + +PKI_MEM_STACK *URL_get_data_file(const URL * url, + ssize_t size); + +int URL_put_data_fd(const URL * url, + const PKI_MEM * data); + +int URL_put_data_file(const URL * url, + const PKI_MEM * data); + +/* ---------------------------- URL macros ------------------------------ */ + +#define getParsedUrl(a) URL_new(a) + +#endif diff --git a/include/libpki/utils/pki_cred.h b/include/libpki/utils/pki_cred.h new file mode 100644 index 00000000..956696ba --- /dev/null +++ b/include/libpki/utils/pki_cred.h @@ -0,0 +1,30 @@ +/* src/pki_cred.c */ + + +#ifndef _LIBPKI_PKI_CRED_H +#define _LIBPKI_PKI_CRED_H + +#include + +// typedef pki_ssl_st; + +typedef struct pki_cred_st { + const char *username; + const char *password; + const char *prompt_info; + ssize_t len; + + // struct pki_ssl_st *ssl; + struct pki_ssl_t *ssl; +} PKI_CRED; + +PKI_CRED *PKI_CRED_new_null ( void ); +PKI_CRED *PKI_CRED_new ( const char * const user, const char * const pwd ); + +void PKI_CRED_free(PKI_CRED *cred); +PKI_CRED *PKI_CRED_dup ( const PKI_CRED * const cred ); + +const struct pki_ssl_t * PKI_CRED_get_ssl(const PKI_CRED * const cred); +int PKI_CRED_set_ssl(PKI_CRED *cred, struct pki_ssl_t * const ssl); + +#endif diff --git a/include/libpki/utils/pki_err.h b/include/libpki/utils/pki_err.h new file mode 100644 index 00000000..b09e83e6 --- /dev/null +++ b/include/libpki/utils/pki_err.h @@ -0,0 +1,224 @@ +/* OpenCA libpki package +* (c) 2000-2007 by Massimiliano Pala and OpenCA Group +* All Rights Reserved +* +* =================================================================== +* Released under OpenCA LICENSE +*/ + +#ifndef _LIBPKI_ERR_H +#define _LIBPKI_ERR_H + +/// @brief PKI Errors Enum +typedef enum { + // General Errors + PKI_ERR_UNKNOWN = 0, + PKI_ERR_GENERAL, + PKI_ERR_NOT_IMPLEMENTED, + PKI_ERR_MEMORY_ALLOC, + PKI_ERR_OBJECT_CREATE, + PKI_ERR_OBJECT_TYPE_UNKNOWN, + PKI_ERR_POINTER_NULL, + PKI_ERR_PARAM_NULL, + PKI_ERR_PARAM_TYPE, + PKI_ERR_PARAM_RANGE, + PKI_ERR_CALLBACK_NULL, + PKI_ERR_PKI_FORMAT_UNKNOW, + PKI_ERR_DATA_FORMAT_UNKNOWN, + PKI_ERR_DATA_ASN1_ENCODING, + // PKI MEM Errors + PKI_ERR_MEM_, + // PKI DIGEST Errors + PKI_ERR_DIGEST_TYPE_UNKNOWN, + PKI_ERR_DIGEST_VALUE_NULL, + // PKI ALGOR Errors + PKI_ERR_ALGOR_UNKNOWN, + PKI_ERR_ALGOR_SET, + PKI_ERR_ALGOR_GET, + PKI_ERR_ALGOR_ADD, + PKI_ERR_ALGOR_PKEY_METHOD_NEW, + PKI_ERR_ALGOR_PKEY_METHOD_ADD, + PKI_ERR_ALGOR_PKEY_METHOD_UNKNOWN, + PKI_ERR_ALGOR_PKEY_ASN1_METHOD_NEW, + PKI_ERR_ALGOR_PKEY_ASN1_METHOD_ADD, + PKI_ERR_ALGOR_PKEY_ASN1_METHOD_UNKNOWN, + PKI_ERR_ALGOR_COMPOSITE_EXPLICIT_WRONG_COMPONENT, + // URI related Errors + PKI_ERR_URI_UNSUPPORTED, + PKI_ERR_URI_GENERAL, + PKI_ERR_URI_PARSE, + PKI_ERR_URI_OPEN, + PKI_ERR_URI_CLOSE, + PKI_ERR_URI_READ, + PKI_ERR_URI_WRITE, + PKI_ERR_URI_DNS, + PKI_ERR_URI_SSL, + PKI_ERR_URI_SSL_TRUST, + // HSM Related + PKI_ERR_HSM_INIT, + PKI_ERR_HSM_LOGIN, + PKI_ERR_HSM_SET_ALGOR, + PKI_ERR_HSM_SET_SLOT, + PKI_ERR_HSM_KEYPAIR_LOAD, + PKI_ERR_HSM_KEYPAIR_STORE, + PKI_ERR_HSM_KEYPAIR_IMPORT, + PKI_ERR_HSM_KEYPAIR_EXPORT, + PKI_ERR_HSM_KEYPAIR_GENERATE, + PKI_ERR_HSM_SCHEME_UNSUPPORTED, + PKI_ERR_HSM_POINTER_NULL, + PKI_ERR_HSM_PKCS11_LIB_POINTER_NULL, + PKI_ERR_HSM_, + // Configuration Related + PKI_ERR_CONFIG_MISSING, + PKI_ERR_CONFIG_LOAD, + PKI_ERR_CONFIG_SAVE, + PKI_ERR_CONFIG_, + // Profile Related + PKI_ERR_X509_PROFILE_, + // Token Related + PKI_ERR_TOKEN_INIT, + PKI_ERR_TOKEN_LOGIN, + PKI_ERR_TOKEN_NOT_LOGGED_IN, + PKI_ERR_TOKEN_KEYPAIR_LOAD, + PKI_ERR_TOKEN_KEYPAIR_SET, + PKI_ERR_TOKEN_CERT_LOAD, + PKI_ERR_TOKEN_CACERT_LOAD, + PKI_ERR_TOKEN_OTHERCERTS_LOAD, + PKI_ERR_TOKEN_TRUSTEDCERTS_LOAD, + PKI_ERR_TOKEN_SET_CRED, + PKI_ERR_TOKEN_USE_SLOT, + PKI_ERR_TOKEN_PROFILE_LOAD, + PKI_ERR_TOKEN_SET_ALGOR, + PKI_ERR_TOKEN_GET_ALGOR, + PKI_ERR_TOKEN_SET_STATUS, + PKI_ERR_TOKEN_GET_STATUS, + PKI_ERR_TOKEN_, + // Key Operations + PKI_ERR_X509_KEYPAIR_SIZE, + PKI_ERR_X509_KEYPAIR_SIZE_SHORT, + PKI_ERR_X509_KEYPAIR_SIZE_LONG, + PKI_ERR_X509_KEYPAIR_GENERATION, + PKI_ERR_X509_KEYPAIR_DECODE, + PKI_ERR_X509_KEYPAIR_ENCODE, + PKI_ERR_X509_KEYPAIR_ENCRYPT_INIT, + PKI_ERR_X509_KEYPAIR_ENCRYPT, + PKI_ERR_X509_KEYPAIR_DECRYPT_INIT, + PKI_ERR_X509_KEYPAIR_DECRYPT, + PKI_ERR_X509_KEYPAIR_, + // Certificate Operations + PKI_ERR_X509_CERT_CREATE, + PKI_ERR_X509_CERT_CREATE_SUBJECT, + PKI_ERR_X509_CERT_CREATE_VERSION, + PKI_ERR_X509_CERT_CREATE_NOTBEFORE, + PKI_ERR_X509_CERT_CREATE_NOTAFTER, + PKI_ERR_X509_CERT_CREATE_ISSUER, + PKI_ERR_X509_CERT_CREATE_SERIAL, + PKI_ERR_X509_CERT_CREATE_EXT, + PKI_ERR_X509_CERT_VERIFY_, + PKI_ERR_X509_CERT_, + // Request Operations + PKI_ERR_X509_REQ_CREATE, + PKI_ERR_X509_REQ_CREATE_SUBJECT, + PKI_ERR_X509_REQ_CREATE_VERSION, + PKI_ERR_X509_REQ_CREATE_NOTBEFORE, + PKI_ERR_X509_REQ_CREATE_NOTAFTER, + PKI_ERR_X509_REQ_CREATE_PUBKEY, + PKI_ERR_X509_REQ_CREATE_ALGORITHM, + PKI_ERR_X509_REQ_, + // CRL Errors + PKI_ERR_X509_CRL_NUMBER, + PKI_ERR_X509_CRL_VERSION, + PKI_ERR_X509_CRL_REVOCATION_ENTRY, + PKI_ERR_X509_CRL_REVOCATION_ENTRY_DATE, + PKI_ERR_X509_CRL_REVOCATION_ENTRY_REASON_CODE, + PKI_ERR_X509_CRL_REVOCATION_ENTRY_EXTENSION, + PKI_ERR_X509_CRL_EXTENSION, + PKI_ERR_X509_CRL_, + // PKI X509 PKCS7 ERRORS + PKI_ERR_X509_PKCS7_TYPE_UNKNOWN, + PKI_ERR_X509_PKCS7_SIGNER_INFO_NULL, + PKI_ERR_X509_PKCS7_CIPHER, + PKI_ERR_X509_PKCS7_, + // PKI X509 CMS ERRORS + PKI_ERR_X509_CMS_TYPE_UNKNOWN, + PKI_ERR_X509_CMS_SIGNER_INFO_NULL, + PKI_ERR_X509_CMS_CIPHER, + PKI_ERR_X509_CMS_RECIPIENT_INFO_NULL, + PKI_ERR_X509_CMS_DATA_INIT, + PKI_ERR_X509_CMS_DATA_READ, + PKI_ERR_X509_CMS_DATA_WRITE, + PKI_ERR_X509_CMS_DATA_FINALIZE, + PKI_ERR_X509_CMS_WRONG_TYPE, + PKI_ERR_X509_CMS_SIGNER_ADD, + PKI_ERR_X509_CMS_SIGNER_GET, + PKI_ERR_X509_CMS_RECIPIENT_ADD, + PKI_ERR_X509_CMS_RECIPIENT_GET, + PKI_ERR_X509_CMS_SET_DETACHED, + PKI_ERR_X509_CMS_, + // Generic PKI_X509_AUX_DATA Errors + PKI_ERR_X509_AUX_DATA_MEMORY_FREE_CB_NULL, + PKI_ERR_X509_AUX_DATA_MEMORY_DUP_CB_NULL, + PKI_ERR_X509_AUX_DATA_, + // OCSP Ops + PKI_ERR_OCSP_RESP_ENCODE, + PKI_ERR_OCSP_RESP_DECODE, + PKI_ERR_OCSP_RESP_SIGN, + PKI_ERR_OCSP_REQ_ENCODE, + PKI_ERR_OCSP_REQ_DECODE, + PKI_ERR_OCSP_REQ_SIGN, + PKI_ERR_OCSP_NONCE_COPY, + PKI_ERR_OCSP_, + // PRQP Ops */ + PKI_ERR_PRQP_, + // PKI Message Operations + PKI_ERR_MSG_, + // Enrollment Protocol Related + PKI_ERR_ENROLL_, + // Signatures Related Errors + PKI_ERR_SIGNATURE_CREATE, + PKI_ERR_SIGNATURE_CREATE_CALLBACK, + PKI_ERR_SIGNATURE_VERIFY, + PKI_ERR_SIGNATURE_, + // Network Related Errors + PKI_ERR_NET_OPEN, + PKI_ERR_NET_, + // SSL/TLS Related Errors + PKI_ERR_NET_SSL_NOT_SUPPORTED, + PKI_ERR_NET_SSL_NO_CIPHER, + PKI_ERR_NET_SSL_VERIFY, + PKI_ERR_NET_SSL_SET_SOCKET, + PKI_ERR_NET_SSL_SET_CIPHER, + PKI_ERR_NET_SSL_SET_FLAGS, + PKI_ERR_NET_SSL_INIT, + PKI_ERR_NET_SSL_START, + PKI_ERR_NET_SSL_CONNECT, + PKI_ERR_NET_SSL_PEER_CERTIFICATE, + PKI_ERR_NET_SSL_, + // EST Related Errors + PKI_ERR_EST_ATTRIBUTE_UNKNOWN, + PKI_ERR_EST_, + // SCEP Related Errors + PKI_ERR_SCEP_ATTRIBUTE_UNKNOWN, + PKI_ERR_SCEP_, + // CMP Related Errors + PKI_ERR_CMP_ATTRIBUTE_UNKNOWN, + PKI_ERR_CMP_, +} PKI_ERR_CODE; + +// ------------------------- Useful Macros --------------------------- // + +// Second Argument is a const char * +#define PKI_ERROR(a,b,args...) \ + __pki_error(__FILE__, __LINE__, a, b, ## args) + +#define PKI_ERROR_crypto_get_errno() \ + HSM_get_errno(NULL) + +#define PKI_ERROR_crypto_get_errdesc() \ + HSM_get_errdesc(HSM_get_errno(NULL),NULL) + +// --------------------- Function Prototypes ------------------------- // + +int __pki_error ( const char *file, int line, int err, const char *info, ... ); + +#endif diff --git a/include/libpki/utils/pki_id.h b/include/libpki/utils/pki_id.h new file mode 100644 index 00000000..b89a0d5a --- /dev/null +++ b/include/libpki/utils/pki_id.h @@ -0,0 +1,53 @@ +/* ID management for libpki */ + +#ifndef _LIBPKI_PKI_ID_H +#define _LIBPKI_PKI_ID_H + +#ifndef _LIBPKI_HEADER_DATA_ST_H +#include +#endif + +// ====================== +// Exported Data Pointers +// ====================== + +extern int pqc_sig_nids_list[]; +extern int pqc_kem_nids_list[]; + +// ================== +// Exported Functions +// ================== + +/*! + * \brief Create a new ID object + * + * Create a new ID by using its name. It returns an int + * if successful, otherwise it returns NULL + */ +PKI_ID PKI_ID_get_by_name(const char * name); + +/*! + * \brief Checks if a PKI IDentifier exists + * + * This function retrieves an ID generated from the passed ID, if the ID + * does not exist in the library database, it returns PKI_ID_UNKNOWN. + * + * Basically it checks if it exists or not. + */ +PKI_ID PKI_ID_get( PKI_ID id ); + +const char * PKI_ID_get_txt( PKI_ID id ); + +int PKI_ID_is_composite(PKI_ID id, PKI_SCHEME_ID * scheme_id); + +int PKI_ID_is_explicit_composite(PKI_ID id, PKI_SCHEME_ID * scheme_id); + +int PKI_ID_is_traditional(PKI_ID key_id, PKI_SCHEME_ID * scheme_id); + +int PKI_ID_is_pqc(PKI_ID id, PKI_SCHEME_ID * scheme_id); + +int PKI_ID_requires_digest(PKI_ID id); + +#endif // End of _LIBPKI_PKI_ID_H + + diff --git a/include/libpki/utils/pki_id_info.h b/include/libpki/utils/pki_id_info.h new file mode 100644 index 00000000..2dfe1f81 --- /dev/null +++ b/include/libpki/utils/pki_id_info.h @@ -0,0 +1,25 @@ +/* PKI_ID_INFO data structure definition */ + +#ifndef _LIBPKI_PKI_ID_INFO_ST_H +#define _LIBPKI_PKI_ID_INFO_ST_H + +/* Structure for PKI_ID_INFO definition */ +typedef struct pki_id_info_st { + + /*! Number of the ID within the TOKEN */ + int num; + + /*! Number of the SLOT where the TOKEN is connected + * (0 if not applicable */ + int slot_id; + + /*! Label for the identity (ID) */ + char *label; + + /*! Pointer to the Token who holds the ID (if available) */ + PKI_TOKEN *tk; + +} PKI_ID_INFO; + +/* End of _LIBPKI_PKI_ID_INFO_ST_H */ +#endif diff --git a/include/libpki/utils/pki_init.h b/include/libpki/utils/pki_init.h new file mode 100644 index 00000000..4cdc7350 --- /dev/null +++ b/include/libpki/utils/pki_init.h @@ -0,0 +1,45 @@ +/* Library Initialization */ + +#ifndef _LIBPKI_INIT_H +#define _LIBPKI_INIT_H + +#ifndef _LIBPKI_STACK_H +#include +#endif + +// ================== +// Defines and Macros +// ================== + +#define PKI_STATUS_NOT_INIT 0 +#define PKI_STATUS_INIT 1 + +// =================== +// Function Prototypes +// =================== + +int PKI_init_all( void ) __attribute__((constructor)); +void PKI_final_all ( void ); + +int PKI_get_init_status ( void ); + +int PKI_is_fips_mode(); +int PKI_set_fips_mode(int k); + +PKI_STACK * PKI_list_all_tokens ( char *dir ); +PKI_STACK * PKI_list_all_tokens_dir ( char * dir, PKI_STACK *list ); + +PKI_TOKEN_STACK *PKI_get_all_tokens ( char *dir ); +PKI_TOKEN_STACK *PKI_get_all_tokens_dir ( char *dir, PKI_TOKEN_STACK *list ); +PKI_ID_INFO_STACK * PKI_list_all_id ( void ); + +int PKI_init_providers(void); +int PKI_cleanup_providers(void); + +#if OPENSSL_VERSION_NUMBER > 0x3000000fL +OSSL_LIB_CTX * PKI_init_get_ossl_library_ctx(); +# else +void * PKI_init_get_ossl_library_ctx(); +#endif // End of OPENSSL_VERSION_NUMBER > 0x3000000fL + +#endif // End of _LIBPKI_INIT_H diff --git a/include/libpki/utils/pki_log.h b/include/libpki/utils/pki_log.h new file mode 100644 index 00000000..e7d416e6 --- /dev/null +++ b/include/libpki/utils/pki_log.h @@ -0,0 +1,113 @@ + +#ifndef _LIBPKI_LOG_H +#define _LIBPKI_LOG_H + +#ifndef _LIBPKI_COMPAT_H +#include +#endif + +BEGIN_C_DECLS + +#ifndef _LIBPKI_TOKEN_HEADERS_H +# include +#endif + +typedef enum { + PKI_LOG_TYPE_STDOUT = 0, + PKI_LOG_TYPE_STDERR, + PKI_LOG_TYPE_SYSLOG, + PKI_LOG_TYPE_FILE, + PKI_LOG_TYPE_FILE_XML, + PKI_LOG_TYPE_DB +} PKI_LOG_TYPE; + +typedef enum { + PKI_LOG_NONE = -1, + PKI_LOG_MSG = 0, + PKI_LOG_ERR = 1, + PKI_LOG_WARNING = 2, + PKI_LOG_NOTICE = 3, + PKI_LOG_INFO = 4, + PKI_LOG_DEBUG = 5, + PKI_LOG_ALWAYS = 99 +} PKI_LOG_LEVEL; + +typedef enum { + PKI_LOG_FLAGS_NONE = 0, + PKI_LOG_FLAGS_ENABLE_DEBUG = 0x01, + PKI_LOG_FLAGS_ENABLE_SIGNATURE = 0x02, +} PKI_LOG_FLAGS; + + +typedef struct PKIlog_st { + /* Keep track if the LOG subsystem has undergone initialization */ + int initialized; + + /* Type of PKI_LOG - PKI_LOG_TYPE */ + PKI_LOG_TYPE type; + + /* Identifier of the resource */ + char *resource; + + /* Log Level - one of PKI_LOG_LEVEL */ + PKI_LOG_LEVEL level; + + /* Flags for log activities - DEBUG, SIGNATURE, etc... */ + PKI_LOG_FLAGS flags; + + /* Enable Signed Log */ + PKI_TOKEN *tk; + + /* Callbacks function - init */ + int (*init)(struct PKIlog_st *); + + /* Callbacks function - add */ + void (*add)(int, const char *, va_list); + + /* Callbacks function - finalize */ + int (*finalize)(struct PKIlog_st *); + + /* Callback function - sign */ + int (*entry_sign)(struct PKIlog_st *, char * ); + +} PKI_LOG; + +// --------------------- Function Prototypes ------------------------- // + +int PKI_log_init ( PKI_LOG_TYPE type, PKI_LOG_LEVEL level, char *resource, + PKI_LOG_FLAGS flags, PKI_TOKEN *tk ); + +void PKI_log( int level, const char *fmt, ... ); + +void PKI_log_debug_simple( const char *fmt, ... ); + +void PKI_log_err_simple( const char *fmt, ... ); + +int PKI_log_end( void ); + +// ------------------------- Useful Macros ---------==---------------- // + +/* Macro To Automatically add [__FILE__:__LINE__] to the message */ +#define PKI_log_line(a, b, args...) \ + PKI_log(a, "[%s:%d] " b, __FILE__, __LINE__, ## args) + +/* Macro To Automatically add [__FILE__:__LINE__]::DEBUG:: to the message */ +#define PKI_log_debug(a, args...) \ + PKI_log_debug_simple((const char *)"[%s:%d] [%s()] [DEBUG] " a, \ + __FILE__, __LINE__, __func__, ## args) + +#define PKI_log_err(a, args...) \ + PKI_log_err_simple((const char *) "[%s:%d] [%s()] [ERROR] " a, \ + __FILE__, __LINE__, __func__, ## args) + +#define PKI_log_crypto_err(a) \ + PKI_log_err_simple("[%s:%d] [%s()] [ERROR] %d:%s", __FILE__, __LINE__, \ + __func__, HSM_get_errno(a), HSM_get_errdesc(HSM_get_errno(a), a)) + +#define PKI_DEBUG(a, args...) \ + PKI_log_debug_simple((const char *)"[%s:%d] [%s()] [DEBUG]: " a, \ + __FILE__, __LINE__, __func__, ## args) + +END_C_DECLS + +#endif diff --git a/include/libpki/utils/pki_mem.h b/include/libpki/utils/pki_mem.h new file mode 100644 index 00000000..27476a73 --- /dev/null +++ b/include/libpki/utils/pki_mem.h @@ -0,0 +1,112 @@ +/* + * LIBPKI - OpenSource PKI library + * by Massimiliano Pala (madwolf@openca.org) and OpenCA project + * + * Copyright (c) 2001-2007 The OpenCA Project. All rights reserved. + * + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* Functions prototypes*/ + +#ifndef _LIBPKI_PKI_IO_H +#include +#endif + +#ifndef _LIBPKI_PKI_MEM_H +#define _LIBPKI_PKI_MEM_H + +typedef struct pki_mem_st { + unsigned char * data; + // size_t current; + size_t size; +} PKI_MEM; + +/* Function prototypes */ + +void *PKI_Malloc( size_t size ); +void PKI_Free( void *ret ); +void PKI_ZFree ( void *pnt, size_t size ); +void PKI_ZFree_str ( char *str ); + +PKI_MEM *PKI_MEM_new ( size_t size ); + +/*! \brief Creates a new PKI_MEM object with a copy of the passed data */ +PKI_MEM *PKI_MEM_new_data ( size_t size, const unsigned char *data ); +PKI_MEM *PKI_MEM_new_null ( void ); +PKI_MEM *PKI_MEM_dup ( PKI_MEM *mem ); + +PKI_MEM *PKI_MEM_new_func ( void *obj, int (*func)() ); +PKI_MEM *PKI_MEM_new_func_bio (void *obj, int (*func)()); + +int PKI_MEM_free ( PKI_MEM *buf ); + +int PKI_MEM_grow( PKI_MEM *buf, size_t new_size ); +int PKI_MEM_add( PKI_MEM *buf, const unsigned char *data, size_t data_size ); +const unsigned char * PKI_MEM_get_data(const PKI_MEM * const buf); +char * PKI_MEM_get_parsed(PKI_MEM *buf); +size_t PKI_MEM_get_size(const PKI_MEM * const buf ); + +ssize_t PKI_MEM_printf( PKI_MEM * buf ); +ssize_t PKI_MEM_fprintf( FILE *file, PKI_MEM *buf ); + +PKI_MEM *PKI_MEM_new_membio ( PKI_IO *io ); +PKI_MEM *PKI_MEM_new_bio ( PKI_IO *io, PKI_MEM **mem ); + +// Specific Format Encoding / Decoding +PKI_MEM *PKI_MEM_get_url_encoded( PKI_MEM *mem, int skip_newlines); +PKI_MEM *PKI_MEM_get_url_decoded( PKI_MEM *mem); +PKI_MEM *PKI_MEM_get_b64_encoded( PKI_MEM *mem, int addNewLines); +PKI_MEM *PKI_MEM_get_b64_decoded( PKI_MEM *mem, int withNewLines); + +// Generic Format Encoding / Decoding +PKI_MEM * PKI_MEM_get_encoded(PKI_MEM *mem, PKI_DATA_FORMAT format, int opt); +PKI_MEM * PKI_MEM_get_decoded(PKI_MEM *mem, PKI_DATA_FORMAT format, int opt); + +/*! + * @brief Encodes the contents of a PKI_MEM according to the provided data format. + * + * @param mem The first parameter should be a pointer to a valid PKI_MEM container. + * @param format The second parameter controls the format to be encoded. Supported + * formats are PKI_DATA_FORMAT_B64 and PKI_DATA_FORMAT_URL. + * @param opts The third parameter is format-specific. For B64 encoding, if this + * parameter is set to anything but 0, the encoded data will be bound with new lines + * every 76 chars. For URL encoding, if this parameter is set to anything but 0, new + * line characters (\n and \r) will be skipped (and, thus, NOT encoded). + * @return PKI_OK if the decoding was successful. In case of errors, the appropriate + * error code is returned. + */ +int PKI_MEM_encode(PKI_MEM *mem, PKI_DATA_FORMAT format, int opt); + +/*! + * @brief Decodes the contents of a PKI_MEM according to the selected format. + * + * @param mem The first parameter should be a pointer to a valid PKI_MEM container. + * @param format The second parameter controls the format to be decoded. Supported + * formats are PKI_DATA_FORMAT_B64 and PKI_DATA_FORMAT_URL. + * @param opts The third parameter is format-specific. For B64 decoding, if this + * parameter is set to anything but 0, the decoded data will be bound with new lines + * every 76 chars (Max). For URL encoding, this parameter has no effect. + * @return PKI_OK if the decoding was successful. In case of errors, the appropriate + * error code is returned. + */ +int PKI_MEM_decode(PKI_MEM *mem, PKI_DATA_FORMAT format, int opt); + +/*! @brief Attaches the passed data to the PKI_MEM */ +int PKI_MEM_attach(PKI_MEM * mem, unsigned char * data, size_t len); + +/*! @brief Detaches the data from the PKI_MEM */ +int PKI_MEM_detach(PKI_MEM * mem, unsigned char ** data, size_t * len); + +/*! @brief Transfers the data from src to dst */ +int PKI_MEM_transfer(PKI_MEM * dst, PKI_MEM * src); + +/*! @brief Clears (free) the data from a PKI_MEM */ +int PKI_MEM_clear(PKI_MEM * mem); + +#endif diff --git a/include/libpki/utils/pki_threads.h b/include/libpki/utils/pki_threads.h new file mode 100644 index 00000000..eac57e76 --- /dev/null +++ b/include/libpki/utils/pki_threads.h @@ -0,0 +1,19 @@ + +#ifndef _LIBPKI_THREADS_ +#define _LIBPKI_THREADS_ + +/* ------------------------ Generic Functions ---------------------- */ + +int PKI_THREAD_create ( PKI_THREAD *th, PKI_THREAD_ATTR *attr, + void *(*func)(void *), void *arg ); + +PKI_THREAD *PKI_THREAD_new ( void * (*func)(void *arg), void *arg ); + +PKI_THREAD_ID PKI_THREAD_self ( void ); + +int PKI_THREAD_join(PKI_THREAD *th, void **retval); +int PKI_THREAD_terminate(PKI_THREAD *th); + +void PKI_THREAD_exit(void *retval); + +#endif diff --git a/include/libpki/utils/pki_threads_vars.h b/include/libpki/utils/pki_threads_vars.h new file mode 100644 index 00000000..b15d6c8d --- /dev/null +++ b/include/libpki/utils/pki_threads_vars.h @@ -0,0 +1,50 @@ + +#ifndef _LIBPKI_THREADS_VARS_ +#define _LIBPKI_THREADS_VARS_ + +/* ------------------------ Generic Functions ---------------------- */ + +struct timespec * PKI_clock_gettime ( void ); + +/* ----------------------- R/W Locs Variables ---------------------------- */ + +PKI_RWLOCK * PKI_RWLOCK_new (); +void PKI_RWLOCK_free ( PKI_RWLOCK *l ); + +int PKI_RWLOCK_init ( PKI_RWLOCK *l ); +int PKI_RWLOCK_destroy ( PKI_RWLOCK *l ); + +int PKI_RWLOCK_read_lock ( PKI_RWLOCK *l ); +int PKI_RWLOCK_write_lock ( PKI_RWLOCK *l ); +#ifdef HAVE_PTHREAD_RWLOCK +int PKI_RWLOCK_try_read_lock ( PKI_RWLOCK *l ); +int PKI_RWLOCK_try_write_lock ( PKI_RWLOCK *l ); +#endif + +int PKI_RWLOCK_release_read ( PKI_RWLOCK *l ); +int PKI_RWLOCK_release_write ( PKI_RWLOCK *l ); + +/* --------------------- CONDITION VARIABLES ----------------------- */ + +PKI_COND *PKI_COND_new (); +void PKI_COND_free ( PKI_COND *var ); + +int PKI_COND_init ( PKI_COND *var ); +int PKI_COND_destroy ( PKI_COND *var ); + +int PKI_COND_signal ( PKI_COND *var ); +int PKI_COND_broadcast ( PKI_COND *var ); +int PKI_COND_wait ( PKI_COND *var, PKI_MUTEX *mutex ); + +/* --------------------------- MUTEXES ------------------------------ */ + +PKI_MUTEX * PKI_MUTEX_new (); +void PKI_MUTEX_free ( PKI_MUTEX *var ); + +int PKI_MUTEX_init ( PKI_MUTEX *var ); +int PKI_MUTEX_destroy ( PKI_MUTEX *var ); + +int PKI_MUTEX_acquire ( PKI_MUTEX *var ); +int PKI_MUTEX_release ( PKI_MUTEX *var ); + +#endif diff --git a/include/libpki/utils/profile.h b/include/libpki/utils/profile.h new file mode 100644 index 00000000..1ae1398a --- /dev/null +++ b/include/libpki/utils/profile.h @@ -0,0 +1,56 @@ +/* PKI PROFILE Management Functions */ + +#ifndef _LIBPKI_UTILS_TYPES_H +#include +#endif + +#ifndef _LIBPKI_PROFILE_HEADERS_H +#define _LIBPKI_PROFILE_HEADERS_H + +#include +#include +#include +#include + +#define PKI_PROFILE_DEFAULT_PROXY_NAME "__DEFAULT_PROXY_PROFILE__" +#define PKI_PROFILE_DEFAULT_USER_NAME "__DEFAULT_USER_PROFILE__" + +PKI_X509_PROFILE * PKI_X509_PROFILE_get_default ( + PKI_X509_PROFILE_TYPE profile_id ); + +char * PKI_X509_PROFILE_get_value(const PKI_X509_PROFILE *doc, + const char *path ); +char * PKI_X509_PROFILE_get_name(const PKI_X509_PROFILE *doc ); + +PKI_X509_PROFILE * PKI_X509_PROFILE_load(const char *urlPath); +int PKI_X509_PROFILE_free ( PKI_X509_PROFILE * doc ); + +PKI_X509_PROFILE *PKI_X509_PROFILE_new (const char *name ); + +PKI_CONFIG_ELEMENT * PKI_X509_PROFILE_add_child(PKI_X509_PROFILE *doc, + const char *name, + const char *value ); + +PKI_CONFIG_ELEMENT * PKI_X509_PROFILE_add_child_el(PKI_X509_PROFILE *doc, + PKI_CONFIG_ELEMENT *el ); + +int PKI_X509_PROFILE_put_file ( PKI_X509_PROFILE *doc, const char *url ); + +int PKI_X509_PROFILE_get_exts_num ( const PKI_X509_PROFILE *doc ); + +PKI_X509_EXTENSION *PKI_X509_PROFILE_get_ext_by_num ( + const PKI_X509_PROFILE *doc, + int num, + PKI_TOKEN *tk); + +PKI_CONFIG_ELEMENT *PKI_X509_PROFILE_get_extensions(const PKI_X509_PROFILE *doc); + +PKI_CONFIG_ELEMENT *PKI_X509_PROFILE_add_extension (PKI_X509_PROFILE *doc, + const char *name, + const char *value, + const char *type, + int crit ); + +#endif + + diff --git a/include/libpki/utils/pthread_init.h b/include/libpki/utils/pthread_init.h new file mode 100644 index 00000000..2c6ccdb7 --- /dev/null +++ b/include/libpki/utils/pthread_init.h @@ -0,0 +1,8 @@ +/* OpenCA LIBPKI - openssl/pthread_init.h + * ==================================================================== + * Threads help function from OpenSSL - slightly modified by Madwolf + */ + +void OpenSSL_pthread_init(void); +void OpenSSL_pthread_cleanup(void); + diff --git a/include/libpki/utils/stack.h b/include/libpki/utils/stack.h new file mode 100644 index 00000000..a59a1196 --- /dev/null +++ b/include/libpki/utils/stack.h @@ -0,0 +1,241 @@ +/* src/stack.h */ +/* + * OCSP responder + * by Massimiliano Pala (madwolf@openca.org) + * OpenCA Licensed Software + * + * Copyright (c) 2001-2006 The OpenCA Project. All rights reserved. + * + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef _LIBPKI_CRYPTO_TYPES_H +#include +#endif + +#ifndef _LIBPKI_UTILS_TYPES_H +#include +#endif + +#ifndef _LIBPKI_STACK_H +#define _LIBPKI_STACK_H + +PKI_STACK * PKI_STACK_new( void (*)(void *) ); +PKI_STACK * PKI_STACK_new_type ( PKI_TYPE type ); +PKI_STACK * PKI_STACK_new_null( void ); + +int PKI_STACK_free ( PKI_STACK * st ); +int PKI_STACK_free_all ( PKI_STACK * st ); + +int PKI_STACK_elements ( PKI_STACK *st ); + +int PKI_STACK_push ( PKI_STACK *st, void *obj ); + +void * PKI_STACK_pop ( PKI_STACK *st ); +int PKI_STACK_pop_free ( PKI_STACK *st ); + +void * PKI_STACK_get_num ( PKI_STACK *st, int num ); +void * PKI_STACK_del_num ( PKI_STACK *st, int num ); +int PKI_STACK_ins_num ( PKI_STACK *st, int num, void *obj ); + +/* define for PKI_MEM stacks - implement object type casting */ +#define PKI_STACK_MEM_new() (PKI_MEM_STACK *) PKI_STACK_new((void (*)(void *))PKI_MEM_free) +#define PKI_STACK_MEM_free( p ) PKI_STACK_free ( (PKI_STACK *) p) +#define PKI_STACK_MEM_free_all( p ) PKI_STACK_free_all ( (PKI_STACK *) p) +#define PKI_STACK_MEM_push(p, obj) PKI_STACK_push((PKI_STACK *)p, (void *)obj) +#define PKI_STACK_MEM_pop(p) (PKI_MEM *) PKI_STACK_pop( (PKI_STACK *) p ) +#define PKI_STACK_MEM_get_num(p,n) (PKI_MEM *) PKI_STACK_get_num( (PKI_STACK *)p, n) +#define PKI_STACK_MEM_ins_num(p,n,obj) PKI_STACK_ins_num((PKI_STACK *)p,n,(void *)obj) +#define PKI_STACK_MEM_del_num(p,n) PKI_STACK_del_num((PKI_STACK *)p, n) +#define PKI_STACK_MEM_elements(p) PKI_STACK_elements((PKI_STACK *)p) + +/* define for X509 stacks - implement object type casting */ +#define PKI_STACK_X509_new() (PKI_X509_STACK *) PKI_STACK_new((void (*)(void *))PKI_X509_free) +#define PKI_STACK_X509_free( p ) PKI_STACK_free ( (PKI_STACK *) p) +#define PKI_STACK_X509_free_all( p ) PKI_STACK_free_all ( (PKI_STACK *) p) +#define PKI_STACK_X509_push(p, obj) PKI_STACK_push((PKI_STACK *)p, (void *)obj) +#define PKI_STACK_X509_pop(p) (PKI_X509 *) PKI_STACK_pop( (PKI_STACK *) p ) +#define PKI_STACK_X509_get_num(p,n) \ + (PKI_X509 *) PKI_STACK_get_num( (PKI_STACK *)p, n) +#define PKI_STACK_X509_ins_num(p,n,obj) \ + PKI_STACK_ins_num((PKI_STACK *)p,n,(void *)obj) +#define PKI_STACK_X509_del_num(p,n) \ + PKI_STACK_del_num((PKI_STACK *)p, n) +#define PKI_STACK_X509_elements(p) PKI_STACK_elements((PKI_STACK *)p) + +/* define for X509_CERT (certs) stacks - implement object type casting */ +#define PKI_STACK_X509_CERT_new() (PKI_X509_CERT_STACK *) PKI_STACK_new((void (*)(void *))PKI_X509_CERT_free) +#define PKI_STACK_X509_CERT_free( p ) PKI_STACK_free ( (PKI_STACK *) p) +#define PKI_STACK_X509_CERT_free_all( p ) PKI_STACK_free_all ( (PKI_STACK *) p) +#define PKI_STACK_X509_CERT_push(p, obj) PKI_STACK_push((PKI_STACK *)p, (void *)obj) +#define PKI_STACK_X509_CERT_pop(p) (PKI_X509_CERT *) PKI_STACK_pop( (PKI_STACK *) p ) +#define PKI_STACK_X509_CERT_get_num(p,n) (PKI_X509_CERT *) PKI_STACK_get_num( (PKI_STACK *)p, n) +#define PKI_STACK_X509_CERT_ins_num(p,n,obj) PKI_STACK_ins_num((PKI_STACK *)p,n,(void *)obj) +#define PKI_STACK_X509_CERT_del_num(p,n) PKI_STACK_del_num((PKI_STACK *)p, n) +#define PKI_STACK_X509_CERT_elements(p) PKI_STACK_elements((PKI_STACK *)p) + +/* define for X509_REQ (requests) stacks - implement object type casting */ +#define PKI_STACK_X509_REQ_new() (PKI_STACK *) PKI_STACK_new((void (*)(void *))PKI_X509_REQ_free) +#define PKI_STACK_X509_REQ_free( p ) PKI_STACK_free ( (PKI_STACK *) p) +#define PKI_STACK_X509_REQ_free_all( p ) PKI_STACK_free_all ( (PKI_STACK *) p) +#define PKI_STACK_X509_REQ_push(p, obj) PKI_STACK_push((PKI_STACK *)p, (void *)obj) +#define PKI_STACK_X509_REQ_pop(p) (PKI_X509_REQ *) PKI_STACK_pop( (PKI_STACK *) p ) +#define PKI_STACK_X509_REQ_get_num(p,n) (PKI_X509_REQ *) PKI_STACK_get_num( (PKI_STACK *)p, n) +#define PKI_STACK_X509_REQ_ins_num(p,n,obj) PKI_STACK_ins_num((PKI_STACK *)p,n,(void *)obj) +#define PKI_STACK_X509_REQ_del_num(p,n) PKI_STACK_del_num((PKI_STACK *)p, n) +#define PKI_STACK_X509_REQ_elements(p) PKI_STACK_elements((PKI_STACK *)p) + +/* define for X509_PROFILE stacks - implement object type casting */ +#define PKI_STACK_X509_PROFILE_new() (PKI_X509_PROFILE_STACK *) PKI_STACK_new((void (*)(void *))PKI_X509_PROFILE_free) +#define PKI_STACK_X509_PROFILE_free( p ) PKI_STACK_free ( (PKI_STACK *) p) +#define PKI_STACK_X509_PROFILE_free_all( p ) PKI_STACK_free_all ( (PKI_STACK *) p) +#define PKI_STACK_X509_PROFILE_push(p, obj) PKI_STACK_push((PKI_STACK *)p, (void *)obj) +#define PKI_STACK_X509_PROFILE_pop(p) (PKI_X509_PROFILE *) PKI_STACK_pop( (PKI_STACK *) p ) +#define PKI_STACK_X509_PROFILE_get_num(p,n) (PKI_X509_PROFILE *) PKI_STACK_get_num( (PKI_STACK *)p, n) +#define PKI_STACK_X509_PROFILE_ins_num(p,n,obj) PKI_STACK_ins_num((PKI_STACK *)p,n,(void *)obj) +#define PKI_STACK_X509_PROFILE_del_num(p,n) PKI_STACK_del_num((PKI_STACK *)p, n) +#define PKI_STACK_X509_PROFILE_elements(p) PKI_STACK_elements((PKI_STACK *)p) + +/* define for X509_EXTENSION stacks - implement object type casting */ +#define PKI_STACK_X509_EXTENSION_new() (PKI_X509_EXTENSION_STACK *) PKI_STACK_new((void (*)(void *))PKI_X509_EXTENSION_free) +#define PKI_STACK_X509_EXTENSION_free( p ) PKI_STACK_free ( (PKI_STACK *) p) +#define PKI_STACK_X509_EXTENSION_free_all( p ) PKI_STACK_free_all ( (PKI_STACK *) p) +#define PKI_STACK_X509_EXTENSION_push(p, obj) PKI_STACK_push((PKI_STACK *)p, (void *)obj) +#define PKI_STACK_X509_EXTENSION_pop(p) (PKI_X509_EXTENSION *) PKI_STACK_pop( (PKI_STACK *) p ) +#define PKI_STACK_X509_EXTENSION_get_num(p,n) (PKI_X509_EXTENSION *) PKI_STACK_get_num( (PKI_STACK *)p, n) +#define PKI_STACK_X509_EXTENSION_ins_num(p,n,obj) PKI_STACK_ins_num((PKI_STACK *)p,n,(void *)obj) +#define PKI_STACK_X509_EXTENSION_del_num(p,n) PKI_STACK_del_num((PKI_STACK *)p, n) +#define PKI_STACK_X509_EXTENSION_elements(p) PKI_STACK_elements((PKI_STACK *)p) + +/* define for PKI_STACK_X509_CRL_ENTRY stacks - implement object type casting */ +#define PKI_STACK_X509_CRL_ENTRY_new() (PKI_X509_CRL_ENTRY_STACK *) PKI_STACK_new((void (*)(void *))PKI_X509_CRL_ENTRY_free) +#define PKI_STACK_X509_CRL_ENTRY_free( p ) PKI_STACK_free ( (PKI_STACK *) p) +#define PKI_STACK_X509_CRL_ENTRY_free_all( p ) PKI_STACK_free_all ( (PKI_STACK *) p) +#define PKI_STACK_X509_CRL_ENTRY_push(p, obj) PKI_STACK_push((PKI_STACK *)p, (void *)obj) +#define PKI_STACK_X509_CRL_ENTRY_pop(p) (PKI_X509_CRL_ENTRY *) PKI_STACK_pop( (PKI_STACK *) p ) +#define PKI_STACK_X509_CRL_ENTRY_get_num(p,n) (PKI_X509_CRL_ENTRY *) PKI_STACK_get_num( (PKI_STACK *)p, n) +#define PKI_STACK_X509_CRL_ENTRY_ins_num(p,n,obj) PKI_STACK_ins_num((PKI_STACK *)p,n,(void *)obj) +#define PKI_STACK_X509_CRL_ENTRY_del_num(p,n) PKI_STACK_del_num((PKI_STACK *)p, n) +#define PKI_STACK_X509_CRL_ENTRY_elements(p) PKI_STACK_elements((PKI_STACK *)p) + +/* define for PKI_X509_CRL stacks - implement object type casting */ +#define PKI_STACK_X509_CRL_new(a) (PKI_X509_CRL_STACK *) PKI_STACK_new((void (*)(void *))PKI_X509_CRL_free_void) +#define PKI_STACK_X509_CRL_free( p ) PKI_STACK_free ( (PKI_STACK *) p) +#define PKI_STACK_X509_CRL_free_all( p ) PKI_STACK_free_all ( (PKI_STACK *) p) +#define PKI_STACK_X509_CRL_push(p, obj) PKI_STACK_push((PKI_STACK *)p, (void *)obj) +#define PKI_STACK_X509_CRL_pop(p) (PKI_X509_CRL *) PKI_STACK_pop( (PKI_STACK *) p ) +#define PKI_STACK_X509_CRL_get_num(p,n) (PKI_X509_CRL *) PKI_STACK_get_num( (PKI_STACK *)p, n) +#define PKI_STACK_X509_CRL_ins_num(p,n,obj) PKI_STACK_ins_num((PKI_STACK *)p,n,(void *)obj) +#define PKI_STACK_X509_CRL_del_num(p,n) PKI_STACK_del_num((PKI_STACK *)p, n) +#define PKI_STACK_X509_CRL_elements(p) PKI_STACK_elements((PKI_STACK *)p) + +/* define for CONFIG (configs) stacks - implement object type casting */ +#define PKI_STACK_CONFIG_new() (PKI_CONFIG_STACK *) PKI_STACK_new((void (*)(void *))PKI_CONFIG_free) +#define PKI_STACK_CONFIG_free( p ) PKI_STACK_free ( (PKI_STACK *) p) +#define PKI_STACK_CONFIG_free_all( p ) PKI_STACK_free_all ( (PKI_STACK *) p) +#define PKI_STACK_CONFIG_push(p, obj) PKI_STACK_push((PKI_STACK *)p, (void *)obj) +#define PKI_STACK_CONFIG_pop(p) (PKI_CONFIG *) PKI_STACK_pop( (PKI_STACK *) p ) +#define PKI_STACK_CONFIG_get_num(p,n) (PKI_CONFIG *) PKI_STACK_get_num( (PKI_STACK *)p, n) +#define PKI_STACK_CONFIG_ins_num(p,n,obj) PKI_STACK_ins_num((PKI_STACK *)p,n,(void *)obj) +#define PKI_STACK_CONFIG_del_num(p,n) PKI_STACK_del_num((PKI_STACK *)p, n) +#define PKI_STACK_CONFIG_elements(p) PKI_STACK_elements((PKI_STACK *)p) + +/* define for CONFIG_ELEMENT stacks - implement object type casting */ +// #define PKI_STACK_CONFIG_ELEMENT_new() (PKI_CONFIG_ELEMENT_STACK *) PKI_STACK_new((void (*)(void *))xmlFreeNode) +#define PKI_STACK_CONFIG_ELEMENT_new() (PKI_CONFIG_ELEMENT_STACK *) PKI_STACK_new(NULL) +#define PKI_STACK_CONFIG_ELEMENT_free( p ) PKI_STACK_free ( (PKI_STACK *) p) +#define PKI_STACK_CONFIG_ELEMENT_free_all( p ) PKI_STACK_free ( (PKI_STACK *) p) +#define PKI_STACK_CONFIG_free_all( p ) PKI_STACK_free_all ( (PKI_STACK *) p) +#define PKI_STACK_CONFIG_ELEMENT_push(p, obj) PKI_STACK_push((PKI_STACK *)p, (void *)obj) +#define PKI_STACK_CONFIG_ELEMENT_pop(p) (PKI_CONFIG_ELEMENT *) PKI_STACK_pop( (PKI_STACK *) p ) +#define PKI_STACK_CONFIG_ELEMENT_get_num(p,n) (PKI_CONFIG_ELEMENT *) PKI_STACK_get_num( (PKI_STACK *)p, n) +#define PKI_STACK_CONFIG_ELEMENT_ins_num(p,n,obj) PKI_STACK_ins_num((PKI_STACK *)p,n,(void *)obj) +#define PKI_STACK_CONFIG_ELEMENT_del_num(p,n) PKI_STACK_del_num((PKI_STACK *)p, n) +#define PKI_STACK_CONFIG_ELEMENT_elements(p) PKI_STACK_elements((PKI_STACK *)p) + +/* define for PKI_OID stacks - implement object type casting */ +#define PKI_STACK_OID_new() (PKI_OID_STACK *) PKI_STACK_new((void (*)(void *))PKI_OID_free) +#define PKI_STACK_OID_free( p ) PKI_STACK_free ( (PKI_STACK *) p) +#define PKI_STACK_OID_free_all( p ) PKI_STACK_free_all ( (PKI_STACK *) p) +#define PKI_STACK_OID_push(p, obj) PKI_STACK_push((PKI_STACK *)p, (void *)obj) +#define PKI_STACK_OID_pop(p) (PKI_OID *) PKI_STACK_pop( (PKI_STACK *) p ) +#define PKI_STACK_OID_get_num(p,n) (PKI_OID *) PKI_STACK_get_num( (PKI_STACK *)p, n) +#define PKI_STACK_OID_ins_num(p,n,obj) PKI_STACK_ins_num((PKI_STACK *)p,n,(void *)obj) +#define PKI_STACK_OID_del_num(p,n) PKI_STACK_del_num((PKI_STACK *)p, n) +#define PKI_STACK_OID_elements(p) PKI_STACK_elements((PKI_STACK *)p) + +/* define for PKI_ID_INFO stacks - implement object type casting */ +#define PKI_STACK_INFO_ID_new() (PKI_ID_INFO_STACK *) PKI_STACK_new((void (*)(void *))PKI_STACK_INFO_ID_free) +#define PKI_STACK_INFO_ID_free( p ) PKI_STACK_free ( (PKI_STACK *) p) +#define PKI_STACK_INFO_ID_free_all( p ) PKI_STACK_free_all ( (PKI_STACK *) p) +#define PKI_STACK_INFO_ID_push(p, obj) PKI_STACK_push((PKI_STACK *)p, (void *)obj) +#define PKI_STACK_INFO_ID_pop(p) (PKI_ID_INFO*) PKI_STACK_pop( (PKI_STACK *) p ) +#define PKI_STACK_INFO_ID_get_num(p,n) (PKI_ID_INFO*) PKI_STACK_get_num( (PKI_STACK *)p, n) +#define PKI_STACK_INFO_ID_ins_num(p,n,obj) PKI_STACK_ins_num((PKI_STACK *)p,n,(void *)obj) +#define PKI_STACK_INFO_ID_del_num(p,n) PKI_STACK_del_num((PKI_STACK *)p, n) +#define PKI_STACK_INFO_ID_elements(p) PKI_STACK_elements((PKI_STACK *)p) + +/* define for PKI_TOKEN stacks - implement object type casting */ +#define PKI_STACK_TOKEN_new() (PKI_TOKEN_STACK *) PKI_STACK_new((void (*)(void *))PKI_TOKEN_free) +#define PKI_STACK_TOKEN_free( p ) PKI_STACK_free ( (PKI_STACK *) p) +#define PKI_STACK_TOKEN_free_all( p ) PKI_STACK_free_all ( (PKI_STACK *) p) +#define PKI_STACK_TOKEN_push(p, obj) PKI_STACK_push((PKI_STACK *)p, (void *)obj) +#define PKI_STACK_TOKEN_pop(p) (PKI_TOKEN *) PKI_STACK_pop( (PKI_STACK *) p ) +#define PKI_STACK_TOKEN_get_num(p,n) (PKI_TOKEN *) PKI_STACK_get_num( (PKI_STACK *)p, n) +#define PKI_STACK_TOKEN_ins_num(p,n,obj) PKI_STACK_ins_num((PKI_STACK *)p,n,(void *)obj) +#define PKI_STACK_TOKEN_del_num(p,n) PKI_STACK_del_num((PKI_STACK *)p, n) +#define PKI_STACK_TOKEN_elements(p) PKI_STACK_elements((PKI_STACK *)p) + +/* define for PKI_X509_KEYPAIR stacks - implement object type casting */ +#define PKI_STACK_X509_KEYPAIR_new() (PKI_X509_KEYPAIR_STACK *) PKI_STACK_new((void (*)(void *))PKI_X509_KEYPAIR_free) +#define PKI_STACK_X509_KEYPAIR_free( p ) PKI_STACK_free ( (PKI_STACK *) p) +#define PKI_STACK_X509_KEYPAIR_free_all( p ) PKI_STACK_free_all ( (PKI_STACK *) p) +#define PKI_STACK_X509_KEYPAIR_push(p, obj) PKI_STACK_push((PKI_STACK *)p, (void *)obj) +#define PKI_STACK_X509_KEYPAIR_pop(p) (PKI_X509_KEYPAIR *) PKI_STACK_pop( (PKI_STACK *) p ) +#define PKI_STACK_X509_KEYPAIR_get_num(p,n) (PKI_X509_KEYPAIR *) PKI_STACK_get_num( (PKI_STACK *)p, n) +#define PKI_STACK_X509_KEYPAIR_ins_num(p,n,obj) PKI_STACK_ins_num((PKI_STACK *)p,n,(void *)obj) +#define PKI_STACK_X509_KEYPAIR_del_num(p,n) PKI_STACK_del_num((PKI_STACK *)p, n) +#define PKI_STACK_X509_KEYPAIR_elements(p) PKI_STACK_elements((PKI_STACK *)p) + +/* define for X509_XPAIR (crossCertPair) stacks - object type casting */ +#define PKI_STACK_X509_XPAIR_new() (PKI_X509_XPAIR_STACK *) PKI_STACK_new((void (*)(void *))PKI_X509_XPAIR_free) +#define PKI_STACK_X509_XPAIR_free( p ) PKI_STACK_free ( (PKI_STACK *) p) +#define PKI_STACK_X509_XPAIR_free_all( p ) PKI_STACK_free_all ( (PKI_STACK *) p) +#define PKI_STACK_X509_XPAIR_push(p, obj) PKI_STACK_push((PKI_STACK *)p, (void *)obj) +#define PKI_STACK_X509_XPAIR_pop(p) (PKI_X509_XPAIR *) PKI_STACK_pop( (PKI_STACK *) p ) +#define PKI_STACK_X509_XPAIR_get_num(p,n) (PKI_X509_XPAIR *) PKI_STACK_get_num( (PKI_STACK *)p, n) +#define PKI_STACK_X509_XPAIR_ins_num(p,n,obj) PKI_STACK_ins_num((PKI_STACK *)p,n,(void *)obj) +#define PKI_STACK_X509_XPAIR_del_num(p,n) PKI_STACK_del_num((PKI_STACK *)p, n) +#define PKI_STACK_X509_XPAIR_elements(p) PKI_STACK_elements((PKI_STACK *)p) + +/* define for OCSP_REQ (ocsp requests) stacks - object type casting */ +#define PKI_STACK_OCSP_REQ_new() (PKI_X509_OCSP_REQ_STACK *) PKI_STACK_new((void (*)(void *))PKI_X509_OCSP_REQ_free) +#define PKI_STACK_OCSP_REQ_free( p ) PKI_STACK_free ( (PKI_STACK *) p) +#define PKI_STACK_OCSP_REQ_free_all( p ) PKI_STACK_free_all ( (PKI_STACK *) p) +#define PKI_STACK_OCSP_REQ_push(p, obj) PKI_STACK_push((PKI_STACK *)p, (void *)obj) +#define PKI_STACK_OCSP_REQ_pop(p) (PKI_X509_OCSP_REQ *) PKI_STACK_pop( (PKI_STACK *) p ) +#define PKI_STACK_OCSP_REQ_get_num(p,n) (PKI_X509_OCSP_REQ *) PKI_STACK_get_num( (PKI_STACK *)p, n) +#define PKI_STACK_OCSP_REQ_ins_num(p,n,obj) PKI_STACK_ins_num((PKI_STACK *)p,n,(void *)obj) +#define PKI_STACK_OCSP_REQ_del_num(p,n) PKI_STACK_del_num((PKI_STACK *)p, n) +#define PKI_STACK_OCSP_REQ_elements(p) PKI_STACK_elements((PKI_STACK *)p) + +/* define for OCSP_RESP (ocsp responses) stacks - object type casting */ +#define PKI_STACK_OCSP_RESP_new() (PKI_X509_OCSP_RESP_STACK *) PKI_STACK_new((void (*)(void *))PKI_X509_OCSP_RESP_free) +#define PKI_STACK_OCSP_RESP_free( p ) PKI_STACK_free ( (PKI_STACK *) p) +#define PKI_STACK_OCSP_RESP_free_all( p ) PKI_STACK_free_all ( (PKI_STACK *) p) +#define PKI_STACK_OCSP_RESP_push(p, obj) PKI_STACK_push((PKI_STACK *)p, (void *)obj) +#define PKI_STACK_OCSP_RESP_pop(p) (PKI_X509_OCSP_RESP *) PKI_STACK_pop( (PKI_STACK *) p ) +#define PKI_STACK_OCSP_RESP_get_num(p,n) (PKI_X509_OCSP_RESP *) PKI_STACK_get_num( (PKI_STACK *)p, n) +#define PKI_STACK_OCSP_RESP_ins_num(p,n,obj) PKI_STACK_ins_num((PKI_STACK *)p,n,(void *)obj) +#define PKI_STACK_OCSP_RESP_del_num(p,n) PKI_STACK_del_num((PKI_STACK *)p, n) +#define PKI_STACK_OCSP_RESP_elements(p) PKI_STACK_elements((PKI_STACK *)p) + +/* END of _PKI_STACK_H */ +#endif + + diff --git a/include/libpki/utils/support.h b/include/libpki/utils/support.h new file mode 100644 index 00000000..68650d41 --- /dev/null +++ b/include/libpki/utils/support.h @@ -0,0 +1,67 @@ +/* libpki/support.h */ +/* + * LibPKI - Easy-to-use PKI library + * by Massimiliano Pala (madwolf@openca.org) + * OpenCA project 2006-2007 + * + * Copyright (c) 2001-2007 The OpenCA Project. All rights reserved. + * + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef _LIBPKI_SUPPORT_H +#define _LIBPKI_SUPPORT_H + +#include +#include + +#define BUFF_MAX_SIZE 2048 + +/* Functions */ + +char * get_env_string(const char *str); + +char * PKI_get_env(const char * name); + +int PKI_set_env(const char * name, + const char * value); + +/*! + * @brief Compares two strings + * + * This function compares two strings and returns 0 if they are equal. + * The comparison can be limited to the first n characters of the strings + * by setting n to a value greater than 0. When set to 0, the comparison + * is performed on the whole strings (and the size of the strings will + * also be checked to be equal). + * + * If the nocase flag is set, the comparison is case insensitive. + * + * @param st1 The first string + * @param st2 The second string + * @param n Compare only the first n characters + * @param nocase Set to non-zero for case insensitive comparisons + * @return [int] 0 if the strings are equal, non-zero otherwise + */ +int str_cmp_ex(const char * st1, + const char * st2, + int n, + int nocase); + +int strcmp_nocase(const char * st1, + const char * st2); + +int strncmp_nocase(const char * st1, + const char * st2, + int n); + +const char * strstr_nocase(const char * buf, + const char * string); + +#endif /* _LIBPKI_SUPPORT_H */ + diff --git a/include/libpki/utils/types.h b/include/libpki/utils/types.h new file mode 100644 index 00000000..8d0a1f40 --- /dev/null +++ b/include/libpki/utils/types.h @@ -0,0 +1,85 @@ +/* net/types.h */ + + +#ifndef _LIBPKI_SYSTEM_H +#include +#endif + +#ifndef _LIBPKI_NET_TYPES_H +#include +#endif + +#ifndef _LIBPKI_UTILS_TYPES_H +#define _LIBPKI_UTILS_TYPES_H + +BEGIN_C_DECLS + +#ifndef HEADER_SAFESTACK_H +#include +#endif + +typedef enum { + PKI_X509_PROFILE_USER = 0, + PKI_X509_PROFILE_PROXY, + PKI_X509_PROFILE_WEB_SERVER, + PKI_X509_PROFILE_MAIL_SERVER +} PKI_X509_PROFILE_TYPE; + +#define PKI_PROFILE_DEFAULT_PROXY_NAME "__DEFAULT_PROXY_PROFILE__" +#define PKI_PROFILE_DEFAULT_USER_NAME "__DEFAULT_USER_PROFILE__" + +/*! + * \brief Data structure for PKI_STACK nodes (INTERNAL ONLY) + */ +typedef struct pki_stack_node_st { + struct pki_stack_node_st *next; + struct pki_stack_node_st *prev; + + void *data; +} PKI_STACK_NODE; + +/*! + * \brief Data structure for PKI_STACK + * + * The PKI_STACK is the basic structure for storing a stack of generic + * elements. Fields SHOULD NOT be accessed directly, instead specific + * PKI_STACK_new(), PKI_STACK_free(), etc... functions exist that take + * care about details and initialization of the structure. + */ +struct pki_stack_st { + /*! \brief Number of elements in the PKI_STACK */ + int elements; + + /*! \brief Pointer to the first node of the PKI_STACK */ + PKI_STACK_NODE *head; + + /*! \brief Pointer to the last node of the PKI_STACK */ + PKI_STACK_NODE *tail; + + /*! \brief Pointer to the function called to free the data object */ + void (*free)( void *); +}; + +/*! \brief Auxillary Types */ +typedef struct pki_stack_st PKI_X509_STACK; +typedef struct pki_stack_st PKI_X509_CERT_STACK; +typedef struct pki_stack_st PKI_X509_REQ_STACK; +typedef struct pki_stack_st PKI_X509_CRL_STACK; +typedef struct pki_stack_st PKI_X509_XPAIR_STACK; +typedef struct pki_stack_st PKI_X509_PROFILE_STACK; +typedef struct pki_stack_st PKI_X509_EXTENSION_STACK; +typedef struct pki_stack_st PKI_X509_CRL_ENTRY_STACK; +typedef struct pki_stack_st PKI_X509_CRL_STACK; +typedef struct pki_stack_st PKI_CONFIG_STACK; +typedef struct pki_stack_st PKI_CONFIG_ELEMENT_STACK; +typedef struct pki_stack_st PKI_OID_STACK; +typedef struct pki_stack_st PKI_ID_INFO_STACK; +typedef struct pki_stack_st PKI_TOKEN_STACK; +typedef struct pki_stack_st PKI_X509_OCSP_REQ_STACK; +typedef struct pki_stack_st PKI_X509_OCSP_RESP_STACK; +typedef struct pki_stack_st PKI_RESOURCE_IDENTIFIER_STACK; +typedef struct pki_stack_st PKI_RESOURCE_RESPONSE_TOKEN_STACK; + +END_C_DECLS + +#endif diff --git a/include/libpki/x509/extensions.h b/include/libpki/x509/extensions.h new file mode 100644 index 00000000..f847aa03 --- /dev/null +++ b/include/libpki/x509/extensions.h @@ -0,0 +1,30 @@ +/* X509 Profile Exts management for libpki */ + +#ifndef _LIBPKI_X509_EXTENSIONS_H +#define _LIBPKI_X509_EXTENSIONS_H + +int PKI_X509_EXTENSIONS_cert_add_profile(const PKI_X509_PROFILE *conf, + const PKI_CONFIG *oids, + PKI_X509_CERT *x, + PKI_TOKEN *tk ); + +int PKI_X509_EXTENSIONS_req_add_profile(const PKI_X509_PROFILE *conf, + const PKI_CONFIG *oids, + PKI_X509_REQ *req, + PKI_TOKEN *tk ); + +int PKI_X509_EXTENSIONS_crl_add_profile(const PKI_X509_PROFILE *conf, + const PKI_CONFIG *oids, + PKI_X509_CRL *crl, + PKI_TOKEN *tk ); + +/* +PKI_X509_EXTENSION *PKI_X509_EXTENSION_new_profile ( PKI_X509_PROFILE *profile, + PKI_CONFIG *oids, PKI_CONFIG_ELEMENT *extNode ); + +PKI_X509_EXTENSION *PKI_X509_EXTENSION_value_new_profile ( + PKI_X509_PROFILE *profile, PKI_CONFIG *oids, + PKI_CONFIG_ELEMENT *extNode ); +*/ + +#endif diff --git a/include/libpki/x509/io/pki_keypair_io.h b/include/libpki/x509/io/pki_keypair_io.h new file mode 100644 index 00000000..976b82db --- /dev/null +++ b/include/libpki/x509/io/pki_keypair_io.h @@ -0,0 +1,59 @@ +/* libpki KEYPAIR I/O */ + +#ifndef _LIBPKI_X509_KEYPAIR_IO_HEADER_H +#define _LIBPKI_X509_KEYPAIR_IO_HEADER_H + +/* ------------------ Key retrieve (load) functions ----------------------- */ + +/* Load a PKI_X509_KEYPAIR from a provided URL string */ +PKI_X509_KEYPAIR *PKI_X509_KEYPAIR_get ( char *url_s, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ); +PKI_X509_KEYPAIR *PKI_X509_KEYPAIR_get_url ( URL *url, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ); +PKI_X509_KEYPAIR_STACK *PKI_X509_KEYPAIR_STACK_get (char *url_s,PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm); +PKI_X509_KEYPAIR_STACK *PKI_X509_KEYPAIR_STACK_get_url ( URL *url, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ); + +/* ------------------ Keypair put (save) functions ----------------------- */ + +int PKI_X509_KEYPAIR_put (PKI_X509_KEYPAIR *x, PKI_DATA_FORMAT format, char *url_string, + PKI_CRED *cred, HSM *hsm); +int PKI_X509_KEYPAIR_put_url( PKI_X509_KEYPAIR *x, PKI_DATA_FORMAT format, URL *url, + PKI_CRED *cred, HSM *hsm); + +/* ------------------------- File I/O ------------------------------------ */ +/* These functions should be generalized with a write to mem and then sent */ +/* to the URL_put_data_url () function that will take care of send/save */ +/* the data according to the URL */ +int PKI_X509_KEYPAIR_put_file( PKI_X509_KEYPAIR *key, PKI_DATA_FORMAT format, URL *url, + PKI_CRED *cred ); + +/* -------------------------- Mem I/O ------------------------------------ */ +/* These are needed for the URL_put_data_url() functionality - not for HSM */ + +/*! \brief Returns a PKI_X509_KEYPAIR from a PKI_MEM buffer */ +PKI_X509_KEYPAIR * PKI_X509_KEYPAIR_get_mem(const PKI_MEM * const mem, + const PKI_DATA_FORMAT format, + const PKI_CRED * const cred ); + +/*! \brief Reads a PKI_X509_KEYPAIR_VALUE from a PKI_MEM buffer */ +PKI_X509_KEYPAIR_VALUE * PKI_X509_KEYPAIR_VALUE_get_mem(const PKI_MEM * const mem, + const PKI_DATA_FORMAT format, + const PKI_CRED * const cred ); + +/*! \brief Writes a PKI_X509_KEYPAIR to a PKI_MEM buffer */ +PKI_MEM * PKI_X509_KEYPAIR_put_mem(const PKI_X509_KEYPAIR * const key, + const PKI_DATA_FORMAT format, + PKI_MEM ** const pki_mem, + const PKI_CRED * cred, + const HSM * hsm); + +/*! \brief Writes a PKI_X509_KEYPAIR_VALUE to a PKI_MEM buffer */ +PKI_MEM * PKI_X509_KEYPAIR_VALUE_put_mem(const PKI_X509_KEYPAIR_VALUE * const key, + const PKI_DATA_FORMAT format, + PKI_MEM ** const pki_mem, + const PKI_CRED * cred, + const HSM * hsm); + +#endif diff --git a/include/libpki/x509/io/pki_msg_req_io.h b/include/libpki/x509/io/pki_msg_req_io.h new file mode 100644 index 00000000..cd2c98d5 --- /dev/null +++ b/include/libpki/x509/io/pki_msg_req_io.h @@ -0,0 +1,32 @@ +/* src/libpki/pki_msg_req.h - General PKI message */ + +#ifndef _LIBPKI_PKI_DATATYPES_H +# include +#endif + +#ifndef _LIBPKI_PKI_MSG_H +# include +#endif + +#ifndef _LIBPKI_PKI_CRED_H +# include +#endif + +#ifndef _LIBPKI_PKI_MEM_H +# include +#endif + +#ifndef _LIBPKI_PKI_MSG_REQ_IO_H +#define _LIBPKI_PKI_MSG_REQ_IO_H + +/* --------------------------- Functions -------------------------- */ + +/* Sends a message and retrieves the response */ +int PKI_MSG_REQ_put ( PKI_MSG_REQ *msg, PKI_DATA_FORMAT format, + char *url, char *mime, PKI_CRED *cred, HSM *hsm, + PKI_MEM_STACK **ret_sk ); + +PKI_MEM *PKI_MSG_REQ_put_mem ( PKI_MSG_REQ *msg, PKI_DATA_FORMAT format, + PKI_MEM **pki_mem, PKI_CRED *cred, HSM *hsm ); + +#endif diff --git a/include/libpki/x509/io/pki_msg_resp_io.h b/include/libpki/x509/io/pki_msg_resp_io.h new file mode 100644 index 00000000..b8f36a4c --- /dev/null +++ b/include/libpki/x509/io/pki_msg_resp_io.h @@ -0,0 +1,16 @@ +/* src/libpki/io/pki_msg_resp.h - General PKI message (responses) I/O */ + +#ifndef _LIBPKI_PKI_MSG_RESP_IO_H +#define _LIBPKI_PKI_MSG_RESP_IO_H + +/* --------------------------- Functions -------------------------- */ + +/*! \brief Writes the message to a URL */ +int PKI_MSG_RESP_put ( PKI_MSG_RESP *msg, PKI_DATA_FORMAT format, + char *url, char *mime, PKI_CRED *cred, HSM *hsm ); + +/*! \brief Writes the message in a memory buffer */ +PKI_MEM *PKI_MSG_RESP_put_mem ( PKI_MSG_RESP *msg, PKI_DATA_FORMAT format, + PKI_MEM **pki_mem, PKI_CRED *cred, HSM *hsm ); + +#endif diff --git a/include/libpki/x509/io/pki_ocsp_req_io.h b/include/libpki/x509/io/pki_ocsp_req_io.h new file mode 100644 index 00000000..610e9d0d --- /dev/null +++ b/include/libpki/x509/io/pki_ocsp_req_io.h @@ -0,0 +1,44 @@ +/* PKI_X509_OCSP_REQ I/O management */ + +#ifndef _LIBPKI_X509_OCSP_REQ_IO_H +#define _LIBPKI_X509_OCSP_REQ_IO_H + +#define PKI_X509_OCSP_REQ_BEGIN_ARMOUR "-----BEGIN OCSP REQUEST-----" +#define PKI_X509_OCSP_REQ_END_ARMOUR "-----END OCSP REQUEST-----" + +/* ------------------- OCSP_REQ get Operations --------------------------- */ +PKI_X509_OCSP_REQ *PKI_X509_OCSP_REQ_get (char *url_s, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm); +PKI_X509_OCSP_REQ *PKI_X509_OCSP_REQ_get_url (URL *url, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ); +PKI_X509_OCSP_REQ *PKI_X509_OCSP_REQ_get_mem (PKI_MEM *mem, + PKI_DATA_FORMAT format, PKI_CRED *cred); + +PKI_X509_OCSP_REQ_STACK *PKI_X509_OCSP_REQ_STACK_get ( char *url_s, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ); +PKI_X509_OCSP_REQ_STACK *PKI_X509_OCSP_REQ_STACK_get_url ( URL *url, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ); +PKI_X509_OCSP_REQ_STACK *PKI_X509_OCSP_REQ_STACK_get_mem ( PKI_MEM *mem, + PKI_DATA_FORMAT format, PKI_CRED *cred ); + +/* ------------------- OCSP_REQ put Operations --------------------------- */ +int PKI_X509_OCSP_REQ_put (PKI_X509_OCSP_REQ *req, PKI_DATA_FORMAT format, + char *url_s, char *mime, PKI_CRED *cred, HSM *hsm); +int PKI_X509_OCSP_REQ_put_url(PKI_X509_OCSP_REQ *req, PKI_DATA_FORMAT format, + URL *url, char *mime, PKI_CRED *cred, HSM *hsm); +PKI_MEM *PKI_X509_OCSP_REQ_put_mem( PKI_X509_OCSP_REQ *req, + PKI_DATA_FORMAT format, PKI_MEM **pki_mem, + PKI_CRED *cred, HSM *hsm); + +int PKI_X509_OCSP_REQ_STACK_put ( PKI_X509_OCSP_REQ_STACK *sk, + PKI_DATA_FORMAT format, char *url_s, char *mime, + PKI_CRED *cred, HSM *hsm); +int PKI_X509_OCSP_REQ_STACK_put_url (PKI_X509_OCSP_REQ_STACK *sk, + PKI_DATA_FORMAT format, URL *url, char *mime, + PKI_CRED *cred, HSM *hsm ); +PKI_MEM *PKI_X509_OCSP_REQ_STACK_put_mem (PKI_X509_OCSP_REQ_STACK *sk, + PKI_DATA_FORMAT format, PKI_MEM **pki_mem, + PKI_CRED *cred, HSM *hsm ); + +#endif + diff --git a/include/libpki/x509/io/pki_ocsp_resp_io.h b/include/libpki/x509/io/pki_ocsp_resp_io.h new file mode 100644 index 00000000..45f1d4c8 --- /dev/null +++ b/include/libpki/x509/io/pki_ocsp_resp_io.h @@ -0,0 +1,44 @@ +/* PKI_X509_OCSP_RESP I/O management */ + +#ifndef _LIBPKI_X509_OCSP_RESP_IO_H +#define _LIBPKI_X509_OCSP_RESP_IO_H + +#define PKI_X509_OCSP_RESP_BEGIN_ARMOUR "-----BEGIN OCSP RESPONSE-----" +#define PKI_X509_OCSP_RESP_END_ARMOUR "-----END OCSP RESPONSE-----" + +/* ------------------- OCSP_REQ get Operations --------------------------- */ +PKI_X509_OCSP_RESP *PKI_X509_OCSP_RESP_get ( char *url_s, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ); +PKI_X509_OCSP_RESP *PKI_X509_OCSP_RESP_get_url ( URL *url, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ); +PKI_X509_OCSP_RESP *PKI_X509_OCSP_RESP_get_mem ( PKI_MEM *url, + PKI_DATA_FORMAT format, PKI_CRED *cred ); + +PKI_X509_OCSP_RESP_STACK *PKI_X509_OCSP_RESP_STACK_get ( char *url_s, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ); +PKI_X509_OCSP_RESP_STACK *PKI_X509_OCSP_RESP_STACK_get_url ( URL *url, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ); +PKI_X509_OCSP_RESP_STACK *PKI_X509_OCSP_RESP_STACK_get_mem ( PKI_MEM *url, + PKI_DATA_FORMAT format, PKI_CRED *cred ); + +/* ------------------- OCSP_REQ put Operations --------------------------- */ +int PKI_X509_OCSP_RESP_put (PKI_X509_OCSP_RESP *r, PKI_DATA_FORMAT format, + char *url_s, char *mime, PKI_CRED *cred, HSM *hsm); +int PKI_X509_OCSP_RESP_put_url(PKI_X509_OCSP_RESP *r, PKI_DATA_FORMAT format, + URL *url, char *mime, PKI_CRED *cred, HSM *hsm); +PKI_MEM *PKI_X509_OCSP_RESP_put_mem ( PKI_X509_OCSP_RESP *r, + PKI_DATA_FORMAT format, PKI_MEM **pki_mem, + PKI_CRED *cred, HSM *hsm ); + +int PKI_X509_OCSP_RESP_STACK_put ( PKI_X509_OCSP_RESP_STACK *sk, + PKI_DATA_FORMAT format, char *url_s, char *mime, + PKI_CRED *cred, HSM *hsm); +int PKI_X509_OCSP_RESP_STACK_put_url (PKI_X509_OCSP_RESP_STACK *sk, + PKI_DATA_FORMAT format, URL *url, char *mime, + PKI_CRED *cred, HSM *hsm ); +PKI_MEM *PKI_X509_OCSP_RESP_STACK_put_mem ( PKI_X509_OCSP_RESP_STACK *sk, + PKI_DATA_FORMAT format, PKI_MEM **pki_mem, + PKI_CRED *cred, HSM *hsm ); + +#endif + diff --git a/include/libpki/x509/io/pki_x509_cert_io.h b/include/libpki/x509/io/pki_x509_cert_io.h new file mode 100644 index 00000000..2e2843e5 --- /dev/null +++ b/include/libpki/x509/io/pki_x509_cert_io.h @@ -0,0 +1,38 @@ +/* PKI_X509 I/O management */ + +#ifndef _LIBPKI_X509_CERT_IO_H +#define _LIBPKI_X509_CERT_IO_H + +/* --------------------- X509 CERT get (load) functions ------------------- */ +PKI_X509_CERT *PKI_X509_CERT_get ( char *url_s, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ); +PKI_X509_CERT *PKI_X509_CERT_get_url ( URL *url, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ); +PKI_X509_CERT *PKI_X509_CERT_get_mem ( PKI_MEM *mem, + PKI_DATA_FORMAT format, PKI_CRED *cred ); + +PKI_X509_CERT_STACK *PKI_X509_CERT_STACK_get ( char *url_s, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ); +PKI_X509_CERT_STACK *PKI_X509_CERT_STACK_get_url ( URL *url, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm); +PKI_X509_CERT_STACK *PKI_X509_CERT_STACK_get_mem (PKI_MEM *mem, + PKI_DATA_FORMAT format, PKI_CRED *cred); + +/* -------------------- X509 CERT put (write) functions ------------------- */ +int PKI_X509_CERT_put ( PKI_X509_CERT *x, PKI_DATA_FORMAT format, + char *url_string, char *mime, PKI_CRED *cred, HSM *hsm); +int PKI_X509_CERT_put_url ( PKI_X509_CERT *x, PKI_DATA_FORMAT format, + URL *url, char *mime, PKI_CRED *cred, HSM *hsm ); +PKI_MEM *PKI_X509_CERT_put_mem ( PKI_X509_CERT *x, PKI_DATA_FORMAT format, + PKI_MEM **pki_mem, PKI_CRED *cred, HSM *hsm ); + +int PKI_X509_CERT_STACK_put (PKI_X509_CERT_STACK *sk, PKI_DATA_FORMAT format, + char *url_s, char *mime, PKI_CRED *cred, HSM *hsm ); +int PKI_X509_CERT_STACK_put_url (PKI_X509_CERT_STACK *sk, + PKI_DATA_FORMAT format, URL *url, char *mime, + PKI_CRED *cred, HSM *hsm ); +PKI_MEM *PKI_X509_CERT_STACK_put_mem ( PKI_X509_CERT_STACK *sk, + PKI_DATA_FORMAT format, PKI_MEM **mem, + PKI_CRED *cred, HSM *hsm ); + +#endif diff --git a/include/libpki/x509/io/pki_x509_cms_io.h b/include/libpki/x509/io/pki_x509_cms_io.h new file mode 100644 index 00000000..d5126d86 --- /dev/null +++ b/include/libpki/x509/io/pki_x509_cms_io.h @@ -0,0 +1,60 @@ +/* PKI_X509_CMS I/O management */ + +#ifndef _LIBPKI_X509_CMS_IO_H +#define _LIBPKI_X509_CMS_IO_H + +#define PKI_X509_CMS_STACK PKI_STACK + +#define PKI_X509_CMS_BEGIN_ARMOUR "-----BEGIN CMS-----" +#define PKI_X509_CMS_END_ARMOUR "-----END CMS-----" + +#define PKI_STACK_CMS_new() (PKI_STACK *) PKI_STACK_new(PKI_X509_CMS_free_void) +#define PKI_STACK_CMS_free( p ) PKI_STACK_free ( (PKI_STACK *) p) +#define PKI_STACK_CMS_free_all( p ) PKI_STACK_free_all ( (PKI_STACK *) p) +#define PKI_STACK_CMS_push(p, obj) PKI_STACK_push((PKI_STACK *)p, (void *)obj) +#define PKI_STACK_CMS_pop(p) (PKI_X509_CMS *) PKI_STACK_pop( (PKI_STACK *) p ) +#define PKI_STACK_CMS_get_num(p,n) (PKI_X509_CMS *) PKI_STACK_get_num( (PKI_STACK *)p, n) +#define PKI_STACK_CMS_ins_num(p,n,obj) PKI_STACK_ins_num((PKI_STACK *)p,n,(void *)obj) +#define PKI_STACK_CMS_del_num(p,n) PKI_STACK_del_num((PKI_STACK *)p, n) +#define PKI_STACK_CMS_elements(p) PKI_STACK_elements((PKI_STACK *)p) + +/* ---------------------------- CMS get operations ------------------ */ + +PKI_X509_CMS *PKI_X509_CMS_get ( char *url_s, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ); +PKI_X509_CMS *PKI_X509_CMS_get_url ( URL *url, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ); +PKI_X509_CMS *PKI_X509_CMS_get_mem ( PKI_MEM *mem, PKI_DATA_FORMAT format, + PKI_CRED *cred); +PKI_X509_CMS_STACK *PKI_X509_CMS_STACK_get (char *url_s, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm); +PKI_X509_CMS_STACK *PKI_X509_CMS_STACK_get_url ( URL *url, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ); +PKI_X509_CMS_STACK *PKI_X509_CMS_STACK_get_mem ( PKI_MEM *mem, + PKI_DATA_FORMAT format, PKI_CRED *cred); + +/* ---------------------------- CMS put operations ------------------ */ + +int PKI_X509_CMS_put (PKI_X509_CMS *cms, PKI_DATA_FORMAT format, + char *url_s, char *mime, PKI_CRED *cred, HSM *hsm); + +int PKI_X509_CMS_put_url(PKI_X509_CMS *cms, PKI_DATA_FORMAT format, + URL *url, char *mime, PKI_CRED *cred, HSM *hsm); + +PKI_MEM *PKI_X509_CMS_put_mem ( PKI_X509_CMS *cms, + PKI_DATA_FORMAT format, PKI_MEM **pki_mem, + PKI_CRED *cred, HSM *hsm ); + +int PKI_X509_CMS_STACK_put (PKI_X509_CMS_STACK *sk, PKI_DATA_FORMAT format, + char *url_s, char *mime, PKI_CRED *cred, HSM *hsm); + +int PKI_X509_CMS_STACK_put_url (PKI_X509_CMS_STACK *sk, + PKI_DATA_FORMAT format, URL *url, char *mime, + PKI_CRED *cred, HSM *hsm ); + +PKI_MEM * PKI_X509_CMS_STACK_put_mem ( PKI_X509_CMS_STACK *sk, + PKI_DATA_FORMAT format, PKI_MEM **pki_mem, + PKI_CRED *cred, HSM *hsm ); + +#endif + diff --git a/include/libpki/x509/io/pki_x509_crl_io.h b/include/libpki/x509/io/pki_x509_crl_io.h new file mode 100644 index 00000000..7d56d6a6 --- /dev/null +++ b/include/libpki/x509/io/pki_x509_crl_io.h @@ -0,0 +1,37 @@ +/* PKI_X509_CRL I/O management */ + +#ifndef _LIBPKI_X509_CRL_IO_H +#define _LIBPKI_X509_CRL_IO_H + +PKI_X509_CRL *PKI_X509_CRL_get ( char *url_s, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ); +PKI_X509_CRL *PKI_X509_CRL_get_url ( URL *url, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ); +PKI_X509_CRL *PKI_X509_CRL_get_mem ( PKI_MEM *mem, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ); + +PKI_X509_CRL_STACK *PKI_X509_CRL_STACK_get ( char *url_s, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ); +PKI_X509_CRL_STACK *PKI_X509_CRL_STACK_get_url ( URL *url, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ); +PKI_X509_CRL_STACK *PKI_X509_CRL_STACK_get_mem( PKI_MEM *mem, + PKI_DATA_FORMAT format, PKI_CRED *cred ); + +int PKI_X509_CRL_put ( PKI_X509_CRL *crl, PKI_DATA_FORMAT format, char *url_s, + PKI_CRED *cred, HSM *hsm ); +int PKI_X509_CRL_put_url ( PKI_X509_CRL *crl, PKI_DATA_FORMAT, URL *url_s, + PKI_CRED *cred, HSM *hsm ); + +PKI_MEM *PKI_X509_CRL_put_mem ( PKI_X509_CRL *crl, PKI_DATA_FORMAT format, + PKI_MEM **mem, PKI_CRED *cred, HSM *hsm ); + +int PKI_X509_CRL_STACK_put (PKI_X509_CRL_STACK *sk, PKI_DATA_FORMAT format, + char *url_s, PKI_CRED *cred, HSM *hsm ); +int PKI_X509_CRL_STACK_put_url (PKI_X509_CRL_STACK *sk, PKI_DATA_FORMAT format, + URL *pki_mem, PKI_CRED *cred, HSM *hsm ); + +PKI_MEM *PKI_X509_CRL_STACK_put_mem (PKI_X509_CRL_STACK *sk, + PKI_DATA_FORMAT format, PKI_MEM **pki_mem, + PKI_CRED *cred, HSM *hsm ); + +#endif diff --git a/include/libpki/x509/io/pki_x509_io.h b/include/libpki/x509/io/pki_x509_io.h new file mode 100644 index 00000000..2ff1d9aa --- /dev/null +++ b/include/libpki/x509/io/pki_x509_io.h @@ -0,0 +1,53 @@ +/* PKI_X509 I/O management */ + +#ifndef _LIBPKI_PKI_DATATYPES_H +# include +#endif + +#ifndef _LIBPKI_PKI_URL_H +# include +#endif + +#ifndef _LIBPKI_PKI_CRED_H +# include +#endif + +#ifndef _LIBPKI_PKI_X509_IO_H +#define _LIBPKI_PKI_X509_IO_H + +/* ---------------------------- X509 get (read) ----------------------- */ + +PKI_X509 *PKI_X509_get ( char *url_s, PKI_DATATYPE type, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ); + +void *PKI_get_value ( char *url_s, PKI_DATATYPE type, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ); + +PKI_X509 *PKI_X509_get_url ( URL *url, PKI_DATATYPE type, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ); + +PKI_X509_STACK *PKI_X509_STACK_get ( char *url_s, PKI_DATATYPE type, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ); + +PKI_X509_STACK *PKI_X509_STACK_get_url ( URL *url, PKI_DATATYPE type, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ); + +/* --------------------------- X509 put (write) ----------------------- */ + +int PKI_X509_put ( PKI_X509 *x, PKI_DATA_FORMAT format, char *url_string, + const char *mime, PKI_CRED *cred, HSM *hsm ); + +int PKI_X509_put_value ( void *x, PKI_DATATYPE type, PKI_DATA_FORMAT format, + char *url_string, const char *mime, PKI_CRED *cred, HSM *hsm ); + +int PKI_X509_put_url ( PKI_X509 *x, PKI_DATA_FORMAT format, URL *url, + const char *mime, PKI_CRED *cred, HSM *hsm ); + +int PKI_X509_STACK_put (PKI_X509_STACK *sk, PKI_DATA_FORMAT format, + char *url_string, const char *mime, PKI_CRED *cred, HSM *hsm); + +int PKI_X509_STACK_put_url (PKI_X509_STACK *sk, PKI_DATA_FORMAT format, + URL *url, const char *mime, PKI_CRED *cred, HSM *hsm); + +#endif + diff --git a/include/libpki/x509/io/pki_x509_p12_io.h b/include/libpki/x509/io/pki_x509_p12_io.h new file mode 100644 index 00000000..3671c43e --- /dev/null +++ b/include/libpki/x509/io/pki_x509_p12_io.h @@ -0,0 +1,64 @@ +/* PKI_X509_PKCS12 I/O management */ + +#ifndef _LIBPKI_X509_PKCS12_IO_H +#define _LIBPKI_X509_PKCS12_IO_H + +#define PKI_X509_PKCS12_STACK PKI_STACK + +#define PKI_X509_PKCS12_BEGIN_ARMOUR "-----BEGIN PKCS12-----" +#define PKI_X509_PKCS12_END_ARMOUR "-----END PKCS12-----" +#define PKI_X509_PKCS12_PEM_ARMOUR "PKCS12" + +#define PKI_STACK_X509_PKCS12_new() (PKI_X509_PKCS12_STACK *) \ + PKI_STACK_new(PKI_X509_PKCS12_free_void) +#define PKI_STACK_X509_PKCS12_free( p ) PKI_STACK_free ( (PKI_STACK *) p) +#define PKI_STACK_X509_PKCS12_free_all( p ) PKI_STACK_free_all ( (PKI_STACK *) p) +#define PKI_STACK_X509_PKCS12_push(p, obj) PKI_STACK_push((PKI_STACK *)p, (void *)obj) +#define PKI_STACK_X509_PKCS12_pop(p) (PKI_X509_PKCS12 *) PKI_STACK_pop( (PKI_STACK *) p ) +#define PKI_STACK_X509_PKCS12_get_num(p,n) (PKI_X509_PKCS12 *) PKI_STACK_get_num( (PKI_STACK *)p, n) +#define PKI_STACK_X509_PKCS12_ins_num(p,n,obj) PKI_STACK_ins_num((PKI_STACK *)p,n,(void *)obj) +#define PKI_STACK_X509_PKCS12_del_num(p,n) PKI_STACK_del_num((PKI_STACK *)p, n) +#define PKI_STACK_X509_PKCS12_elements(p) PKI_STACK_elements((PKI_STACK *)p) + +/* ---------------------------- PKCS12 get operations ------------------ */ + +PKI_X509_PKCS12 *PKI_X509_PKCS12_get ( char *url_s, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ); +PKI_X509_PKCS12 *PKI_X509_PKCS12_get_url ( URL *url, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ); +PKI_X509_PKCS12 *PKI_X509_PKCS12_get_mem ( PKI_MEM *mem, PKI_DATA_FORMAT format, + PKI_CRED *cred ); + +PKI_X509_PKCS12_STACK *PKI_X509_PKCS12_STACK_get (char *url_s, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm); +PKI_X509_PKCS12_STACK *PKI_X509_PKCS12_STACK_get_url ( URL *url, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ); +PKI_X509_PKCS12_STACK *PKI_X509_PKCS12_STACK_get_mem ( PKI_MEM *mem, + PKI_DATA_FORMAT format, PKI_CRED *cred); + +/* ---------------------------- PKCS12 put operations ------------------ */ + +int PKI_X509_PKCS12_put (PKI_X509_PKCS12 *p12, PKI_DATA_FORMAT format, + char *url_s, char *mime, PKI_CRED *cred, HSM *hsm); + +int PKI_X509_PKCS12_put_url(PKI_X509_PKCS12 *p12, PKI_DATA_FORMAT format, + URL *url, char *mime, PKI_CRED *cred, HSM *hsm); + +PKI_MEM *PKI_X509_PKCS12_put_mem ( PKI_X509_PKCS12 *p12, + PKI_DATA_FORMAT format, PKI_MEM **pki_mem, + PKI_CRED *cred, HSM *hsm ); + +int PKI_X509_PKCS12_STACK_put ( PKI_X509_PKCS12_STACK *sk, + PKI_DATA_FORMAT format, char *url_s, char *mime, + PKI_CRED *cred, HSM *hsm); + +int PKI_X509_PKCS12_STACK_put_url (PKI_X509_PKCS12_STACK *sk, + PKI_DATA_FORMAT format, URL *url, char *mime, + PKI_CRED *cred, HSM *hsm ); + +PKI_MEM *PKI_X509_PKCS12_STACK_put_mem ( PKI_X509_PKCS12_STACK *sk, + PKI_DATA_FORMAT format, PKI_MEM **pki_mem, + PKI_CRED *cred, HSM *hsm ); + +#endif + diff --git a/include/libpki/x509/io/pki_x509_pkcs7_io.h b/include/libpki/x509/io/pki_x509_pkcs7_io.h new file mode 100644 index 00000000..db62f548 --- /dev/null +++ b/include/libpki/x509/io/pki_x509_pkcs7_io.h @@ -0,0 +1,61 @@ +/* PKI_X509_PKCS7 I/O management */ + +#ifndef _LIBPKI_X509_PKCS7_IO_H +#define _LIBPKI_X509_PKCS7_IO_H + +#define PKI_X509_PKCS7_STACK PKI_STACK + +#define PKI_X509_PKCS7_BEGIN_ARMOUR "-----BEGIN PKCS7-----" +#define PKI_X509_PKCS7_END_ARMOUR "-----END PKCS7-----" + +#define PKI_STACK_PKCS7_new() (PKI_STACK *) PKI_STACK_new(PKI_X509_PKCS7_free_void) +#define PKI_STACK_PKCS7_free( p ) PKI_STACK_free ( (PKI_STACK *) p) +#define PKI_STACK_PKCS7_free_all( p ) PKI_STACK_free_all ( (PKI_STACK *) p) +#define PKI_STACK_PKCS7_push(p, obj) PKI_STACK_push((PKI_STACK *)p, (void *)obj) +#define PKI_STACK_PKCS7_pop(p) (PKI_X509_PKCS7 *) PKI_STACK_pop( (PKI_STACK *) p ) +#define PKI_STACK_PKCS7_get_num(p,n) (PKI_X509_PKCS7 *) PKI_STACK_get_num( (PKI_STACK *)p, n) +#define PKI_STACK_PKCS7_ins_num(p,n,obj) PKI_STACK_ins_num((PKI_STACK *)p,n,(void *)obj) +#define PKI_STACK_PKCS7_del_num(p,n) PKI_STACK_del_num((PKI_STACK *)p, n) +#define PKI_STACK_PKCS7_elements(p) PKI_STACK_elements((PKI_STACK *)p) + +/* ---------------------------- PKCS7 get operations ------------------ */ + +PKI_X509_PKCS7 *PKI_X509_PKCS7_get ( char *url_s, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ); +PKI_X509_PKCS7 *PKI_X509_PKCS7_get_url ( URL *url, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ); +PKI_X509_PKCS7 *PKI_X509_PKCS7_get_mem ( PKI_MEM *mem, PKI_DATA_FORMAT format, + PKI_CRED *cred); +PKI_X509_PKCS7_STACK *PKI_X509_PKCS7_STACK_get (char *url_s, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm); +PKI_X509_PKCS7_STACK *PKI_X509_PKCS7_STACK_get_url ( URL *url, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ); +PKI_X509_PKCS7_STACK *PKI_X509_PKCS7_STACK_get_mem ( PKI_MEM *mem, + PKI_DATA_FORMAT format, PKI_CRED *cred); + +/* ---------------------------- PKCS7 put operations ------------------ */ + +int PKI_X509_PKCS7_put (PKI_X509_PKCS7 *p7, PKI_DATA_FORMAT format, + char *url_s, char *mime, PKI_CRED *cred, HSM *hsm); + +int PKI_X509_PKCS7_put_url(PKI_X509_PKCS7 *p7, PKI_DATA_FORMAT format, + URL *url, char *mime, PKI_CRED *cred, HSM *hsm); + +PKI_MEM *PKI_X509_PKCS7_put_mem ( PKI_X509_PKCS7 *p7, + PKI_DATA_FORMAT format, PKI_MEM **pki_mem, + PKI_CRED *cred, HSM *hsm ); + +int PKI_X509_PKCS7_STACK_put (PKI_X509_PKCS7_STACK *sk, PKI_DATA_FORMAT format, + char *url_s, char *mime, PKI_CRED *cred, HSM *hsm); + +int PKI_X509_PKCS7_STACK_put_url (PKI_X509_PKCS7_STACK *sk, + PKI_DATA_FORMAT format, URL *url, char *mime, + PKI_CRED *cred, HSM *hsm ); + +PKI_MEM * PKI_X509_PKCS7_STACK_put_mem ( PKI_X509_PKCS7_STACK *sk, + PKI_DATA_FORMAT format, PKI_MEM **pki_mem, + PKI_CRED *cred, HSM *hsm ); + + +#endif + diff --git a/include/libpki/x509/io/pki_x509_req_io.h b/include/libpki/x509/io/pki_x509_req_io.h new file mode 100644 index 00000000..e3da893e --- /dev/null +++ b/include/libpki/x509/io/pki_x509_req_io.h @@ -0,0 +1,38 @@ +/* PKI_X509_REQ I/O management */ + +#ifndef _LIBPKI_X509_REQ_IO_H +#define _LIBPKI_X509_REQ_IO_H + +/* ------------------- X509_REQ get Operations --------------------------- */ +PKI_X509_REQ *PKI_X509_REQ_get ( char *url_s, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ); +PKI_X509_REQ *PKI_X509_REQ_get_url ( URL *url, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ); +PKI_X509_REQ *PKI_X509_REQ_get_mem ( PKI_MEM *mem, PKI_DATA_FORMAT format, + PKI_CRED *cred ); + +PKI_X509_REQ_STACK *PKI_X509_REQ_STACK_get ( char *url_s, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ); +PKI_X509_REQ_STACK *PKI_X509_REQ_STACK_get_url ( URL *url, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ); +PKI_X509_REQ_STACK *PKI_X509_REQ_STACK_get_mem(PKI_MEM *mem, + PKI_DATA_FORMAT format, PKI_CRED *cred); + +/* ------------------- X509_REQ put Operations --------------------------- */ +int PKI_X509_REQ_put (PKI_X509_REQ *req, PKI_DATA_FORMAT format, char *url_s, + char *mime, PKI_CRED *cred, HSM *hsm); +int PKI_X509_REQ_put_url(PKI_X509_REQ *req, PKI_DATA_FORMAT format, URL *url, + char *mime, PKI_CRED *cred, HSM *hsm); +PKI_MEM *PKI_X509_REQ_put_mem ( PKI_X509_REQ *r, PKI_DATA_FORMAT format, + PKI_MEM **pki_mem, PKI_CRED *cred, HSM *hsm ); + +int PKI_X509_REQ_STACK_put ( PKI_X509_REQ_STACK *sk, PKI_DATA_FORMAT format, + char *url_s, char *mime, PKI_CRED *cred, HSM *hsm); +int PKI_X509_REQ_STACK_put_url (PKI_X509_REQ_STACK *sk, PKI_DATA_FORMAT format, + URL *url, char *mime, PKI_CRED *cred, HSM *hsm ); +PKI_MEM *PKI_X509_REQ_STACK_put_mem ( PKI_X509_REQ_STACK *sk, + PKI_DATA_FORMAT format, + PKI_MEM **pki_mem, PKI_CRED *cred, HSM *hsm ); + +#endif + diff --git a/include/libpki/x509/io/pki_x509_xpair_io.h b/include/libpki/x509/io/pki_x509_xpair_io.h new file mode 100644 index 00000000..e42904f0 --- /dev/null +++ b/include/libpki/x509/io/pki_x509_xpair_io.h @@ -0,0 +1,51 @@ +/* PKI_X509_XPAIR I/O management */ + +#ifndef _LIBPKI_X509_XPAIR_H +# include +#endif + +#ifndef _LIBPKI_X509_XPAIR_IO_H +#define _LIBPKI_X509_XPAIR_IO_H + +// #define PKI_X509_XPAIR_BEGIN_ARMOUR "-----BEGIN CROSS CERTIFICATE PAIR-----" +// #define PKI_X509_XPAIR_END_ARMOUR "-----END CROSS CERTIFICATE PAIR-----" +#define PEM_STRING_X509_XPAIR "CROSS CERTIFICATE PAIR" + +/* --------------------- X509 CERT get (load) functions ------------------- */ +PKI_X509_XPAIR *PKI_X509_XPAIR_get ( char *url_s, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ); +PKI_X509_XPAIR *PKI_X509_XPAIR_get_url ( URL *url, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ); +PKI_X509_XPAIR *PKI_X509_XPAIR_get_mem( PKI_MEM *mem, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm); + +PKI_X509_XPAIR_STACK *PKI_X509_XPAIR_STACK_get ( char *url_s, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ); +PKI_X509_XPAIR_STACK *PKI_X509_XPAIR_STACK_get_url ( URL *url, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm); + +/* -------------------- X509 CERT put (write) functions ------------------- */ +int PKI_X509_XPAIR_put ( PKI_X509_XPAIR *x, PKI_DATA_FORMAT format, + char *url_s, char *mime, PKI_CRED *cred, HSM *hsm ); +int PKI_X509_XPAIR_put_url ( PKI_X509_XPAIR *x, PKI_DATA_FORMAT, URL *url, + char *mime, PKI_CRED *cred, HSM *hsm ); +PKI_MEM *PKI_X509_XPAIR_put_mem ( PKI_X509_XPAIR *x, PKI_DATA_FORMAT format, + PKI_MEM **pki_mem, PKI_CRED *cred, HSM *hsm ); +int PKI_X509_XPAIR_STACK_put (PKI_X509_XPAIR_STACK *sk, PKI_DATA_FORMAT format, + char *url_string, char *mime, PKI_CRED *cred, HSM *hsm); +int PKI_X509_XPAIR_STACK_put_url (PKI_X509_XPAIR_STACK *sk, + PKI_DATA_FORMAT format, URL *url, char *mime, + PKI_CRED *cred, HSM *hsm ); + +/* ---------------------- X509_XPAIR mem Operations ------------------------ */ + +PKI_X509_XPAIR_STACK *PKI_X509_XPAIR_STACK_get_mem(PKI_MEM *mem, + PKI_DATA_FORMAT format, PKI_CRED *cred); + +PKI_MEM * PKI_X509_XPAIR_STACK_put_mem ( PKI_X509_XPAIR_STACK *sk, + PKI_DATA_FORMAT format, PKI_MEM **pki_mem, PKI_CRED *cred, HSM *hsm ); + +int PKI_XPAIR_print( BIO *bio, PKI_XPAIR *xp ); + + +#endif diff --git a/include/libpki/x509/pki_algor.h b/include/libpki/x509/pki_algor.h new file mode 100644 index 00000000..69ae5887 --- /dev/null +++ b/include/libpki/x509/pki_algor.h @@ -0,0 +1,189 @@ +/* libpki/pki_algor.h */ + +#ifndef _LIBPKI_PKI_ALGOR_VALUE_H +#define _LIBPKI_PKI_ALGOR_VALUE_H + +// --------------------------- PKI_X509_ALGOR_VALUE --------------------------- // + +/*! \brief Returns an empty PKI_X509_ALGOR_VALUE value */ +PKI_X509_ALGOR_VALUE * PKI_X509_ALGOR_VALUE_new (); + +/*! \brief Frees the memory associated with a PKI_X509_ALGORITHM_VALUE */ +void PKI_X509_ALGORITHM_VALUE_free ( PKI_X509_ALGOR_VALUE *a ); + +/*! \brief Returns a new PKI_X509_ALGORITHM_VALUE of the identified type */ +PKI_X509_ALGOR_VALUE * PKI_X509_ALGOR_VALUE_new_type ( int type ); + +/*! \brief Returns a new PKI_X509_ALGORITHM_VALUE from PKEY and DIGEST id */ +PKI_X509_ALGOR_VALUE * PKI_X509_ALGOR_VALUE_new_pkey(const PKI_X509_KEYPAIR_VALUE * pkey, + const PKI_ID digest_id); + +// /*! \brief Returns a new PKI_X509_ALGORITHM_VALIE from the passed PKI_DIGEST_ALG structure */ +// PKI_X509_ALGOR_VALUE * PKI_X509_ALGOR_VALUE_new_digest ( PKI_DIGEST_ALG *alg ); + +/*! \brief Get PKI_X509_ALGOR (AlgorithmIdentifier) from a specified algorithm ID */ +PKI_X509_ALGOR_VALUE *PKI_X509_ALGOR_VALUE_get ( PKI_ALGOR_ID algor ); + +// /*! \brief Get the PKI_X509_ALGOR (AlgorithmIdentifier) for a pubkey and digest combination */ +// PKI_X509_ALGOR_VALUE *PKI_X509_ALGOR_VALUE_get_ex(PKI_ALGOR_ID pubkey_id, PKI_ALGOR_ID digest_id); + +/*! \brief Build a PKI_ALGOR structure from its name (char *) + * + * The function returns the pointer to a PKI_ALGOR structure based on the + * name. Names are in the form of "RSA-SHA1", "RSA-SHA512", or "DSA-SHA1". + * + * @param alg_s The string describing the algorithm name + * @retval The pointer to the newly allocated PKI_X509_ALGOR_VALUE + */ +PKI_X509_ALGOR_VALUE *PKI_X509_ALGOR_VALUE_get_by_name ( const char *alg_s ); + +void PKI_X509_ALGOR_VALUE_free( PKI_X509_ALGOR_VALUE *algor); + +// -------------------------- PKI_X509_ALGOR_VALUE_ID --------------------------- // + +PKI_ALGOR_ID PKI_X509_ALGOR_VALUE_get_id (const PKI_X509_ALGOR_VALUE * algor ); + +PKI_ALGOR_ID PKI_X509_ALGOR_VALUE_get_digest_id (const PKI_X509_ALGOR_VALUE *algor ); + +const PKI_DIGEST_ALG * PKI_X509_ALGOR_VALUE_get_digest (const PKI_X509_ALGOR_VALUE *algor ); + +/*! + * \brief Returns a text representation of the algorithm identifier + */ +const char * PKI_X509_ALGOR_VALUE_get_parsed (const PKI_X509_ALGOR_VALUE * algor ); + +PKI_SCHEME_ID PKI_X509_ALGOR_VALUE_get_scheme (const PKI_X509_ALGOR_VALUE * algor ); + +// ------------------------------- PKI_SCHEME_ID ------------------------------- // + +/*! + * \brief Returns the PKI_SCHEME_ID from the passed string + */ +PKI_SCHEME_ID PKI_SCHEME_ID_get_by_name(const char * data, int * classic_sec_bits, int * quantum_sec_bits); + +/*! + * @brief Returns the string representation of the passed PKI_SCHEME_ID + * + * This function returns the string representation of the passed PKI_SCHEME_ID. + * + * @param id The PKI_SCHEME_ID that is being parsed + * @return The string representation of the passed PKI_SCHEME_ID + */ +const char * PKI_SCHEME_ID_get_parsed(PKI_SCHEME_ID id); + +/*! + * \brief Determines if the passed scheme supports multiple key components. + * + * This function checks if the passed PKI_SCHEME_ID supports the use of multiple + * components algorithm for the key. Examples of schemes that support multiple + * keys are: + * - Generic Composite (PKI_ALGOR_ID_COMPOSITE) + * - Explicit Composite (PKI_ALGOR_ID_COMPOSITE_EXPLICIT_ ... ) + * - Generic Multikey (PKI_ALGOR_ID_COMBINED) + * + * @param id The scheme that is being checked + * @retval Returns PKI_OK if the scheme is composite, PKI_ERR otherwise + */ +int PKI_SCHEME_ID_supports_multiple_components(PKI_SCHEME_ID id); + +/*! + * \brief Determines if the passed scheme is composite. + * + * This function checks if the passed PKI_SCHEME_ID is indeed a + * Generic Composite. + * + * @param id The scheme that is being checked + * @retval Returns PKI_OK if the scheme is composite, PKI_ERR otherwise + */ +int PKI_SCHEME_ID_is_composite(PKI_SCHEME_ID id); + +/*! + * \brief Determines if the passed scheme is explicit composite. + * + * This function checks if the passed PKI_SCHEME_ID is indeed an explicit + * composite scheme. This function only checks for explicit composite OIDs + * and does not check for the generic composite or the generic multikey ones. + * + * @param id The scheme that is being checked + * @retval Returns PKI_OK if the scheme is explicit composite, PKI_ERR otherwise + */ +int PKI_SCHEME_ID_is_explicit_composite(PKI_SCHEME_ID id); + +/*! + * \brief Determines if the passed scheme is post-quantum. + * + * This function checks if the passed PKI_SCHEME_ID is indeed a post-quantum + * algorithm or a classic one. + * + * @param id The scheme that is being checked + * @retval Returns PKI_OK if the scheme is post-quantum, PKI_ERR otherwise + */ +int PKI_SCHEME_ID_is_post_quantum(PKI_SCHEME_ID id); + +/*! + * \brief Determines if the passed scheme requires the use of hash-n-sign. + * + * This function checks if the passed PKI_SCHEME_ID requires the use of a + * digest (hash function) as intermediate step for signing or if arbitrary + * data can be signed without the use of hash-n-sign paradigm. + * + * @param id The scheme that is being checked + * @retval Returns PKI_OK if the scheme requires a digest, PKI_ERR otherwise. + */ +int PKI_SCHEME_ID_requires_digest(PKI_SCHEME_ID id); + +int PKI_SCHEME_ID_security_bits(const PKI_SCHEME_ID scheme_id, + int * classic_sec_bits, + int * quantum_sec_bits); + +/*! + * @brief Translates the security bits into key-gen bit sizes + * + * This function translates the security bits into the key-gen bit sizes + * for the passed scheme. + * + * @param scheme_id The scheme that is being checked + * @param sec_bits The requested security bits + * @return The key-gen bit size + */ +int PKI_SCHEME_ID_get_bitsize(const PKI_SCHEME_ID scheme_id, const int sec_bits); + + +// ------------------------------ PKI_DIGEST_ALG ------------------------------- // + +const PKI_DIGEST_ALG * PKI_X509_ALGOR_VALUE_get_digest (const PKI_X509_ALGOR_VALUE * algor ); + +const PKI_DIGEST_ALG * PKI_DIGEST_ALG_get_by_key (const PKI_X509_KEYPAIR *pkey ); + +const PKI_DIGEST_ALG * PKI_DIGEST_ALG_get_by_name( const char *name ); + +const PKI_DIGEST_ALG * PKI_DIGEST_ALG_get( PKI_ALGOR_ID alg ); + +const PKI_DIGEST_ALG * PKI_DIGEST_ALG_get_default(const PKI_X509_KEYPAIR * const x); + +const char * PKI_DIGEST_ALG_get_parsed (const PKI_DIGEST_ALG * alg ); + +// --------------------------- PKI_ALGOR_ID Lists ------------------------------- // + +/*! + * \brief Returns the List of supported Algorithms + */ +const PKI_ALGOR_ID *PKI_ALGOR_ID_list ( PKI_SCHEME_ID scheme ); + +/*! + * \brief Returns the List of supported Digest Algorithms + */ +const PKI_ALGOR_ID *PKI_DIGEST_ALG_ID_list( void ); + +/*! + * \brief Returns the size of a list of a PKI_ALGOR_ID + */ +size_t PKI_ALGOR_ID_list_size( const PKI_ALGOR_ID * const list ); + +/*! + * \brief Returns a text string with the algorithm identifier + */ +char *PKI_ALGOR_ID_txt ( PKI_ALGOR_ID algor ); + +#endif + diff --git a/include/libpki/x509/pki_integer.h b/include/libpki/x509/pki_integer.h new file mode 100644 index 00000000..97b99cd5 --- /dev/null +++ b/include/libpki/x509/pki_integer.h @@ -0,0 +1,28 @@ +/* PKI_INTEGER */ + +#ifndef _LIBPKI_PKI_INTEGER_H +#define _LIBPKI_PKI_INTEGER_H + +PKI_INTEGER *PKI_INTEGER_new_bin ( const unsigned char *data, size_t size ); +PKI_INTEGER *PKI_INTEGER_new_char( const char *val ); +/*! + * @brief Returns a random PKI_INTEGER of the specified size + * @param num The number of random bits to generate + * @return An allocated PKI_INTEGER pointer or NULL if an error occurs + */ +PKI_INTEGER *PKI_INTEGER_new_rand(int bits); + +PKI_INTEGER *PKI_INTEGER_new( long long val ); +PKI_INTEGER *PKI_INTEGER_dup( const PKI_INTEGER *a ); + +void PKI_INTEGER_free_void( void *i ); +int PKI_INTEGER_free( PKI_INTEGER *i ); +char *PKI_INTEGER_get_parsed ( const PKI_INTEGER *i ); + +int PKI_INTEGER_cmp ( const PKI_INTEGER *a, const PKI_INTEGER *b ); + +int PKI_INTEGER_print( const PKI_INTEGER *s ); +int PKI_INTEGER_print_fp( FILE *fp, const PKI_INTEGER *s ); + +#endif + diff --git a/include/libpki/x509/pki_oid.h b/include/libpki/x509/pki_oid.h new file mode 100644 index 00000000..8c6275ab --- /dev/null +++ b/include/libpki/x509/pki_oid.h @@ -0,0 +1,21 @@ +/* OID management for libpki */ + +#ifndef _LIBPKI_OID_H +#define _LIBPKI_OID_H + +PKI_OID *PKI_OID_new( const char *oid, const char *name, const char *descr ); +PKI_OID *PKI_OID_new_id ( PKI_ID id ); +PKI_OID *PKI_OID_new_text ( const char *name ); +PKI_OID *PKI_OID_get( const char *name ); + +void PKI_OID_free ( PKI_OID *oid ); + +PKI_OID *PKI_OID_dup( const PKI_OID *a ); +int PKI_OID_cmp( const PKI_OID *a, const PKI_OID *b ); + +PKI_ID PKI_OID_get_id ( const PKI_OID *a ); +const char * PKI_OID_get_descr ( const PKI_OID *a ); +char * PKI_OID_get_str ( const PKI_OID *a ); + +#endif + diff --git a/include/libpki/x509/pki_string.h b/include/libpki/x509/pki_string.h new file mode 100644 index 00000000..fe68f374 --- /dev/null +++ b/include/libpki/x509/pki_string.h @@ -0,0 +1,65 @@ +/* PKI_STRING management for libpki */ + +#ifndef _LIBPKI_STRING_H +#define _LIBPKI_STRING_H + +#include +#include + +/* Basic Definitions */ +#define PKI_STRING ASN1_STRING +#define PKI_BIT_STRING ASN1_BIT_STRING + +typedef enum { + /* Unknown */ + PKI_STRING_UNKNOWN = -1, + /* ASCII Strings */ + PKI_STRING_IA5 = V_ASN1_IA5STRING, + /* UTF8 Strings */ + PKI_STRING_UTF8 = V_ASN1_UTF8STRING, + /* BIT Strings */ + PKI_STRING_BIT = V_ASN1_BIT_STRING, + /* Two Bytes Chars */ + PKI_STRING_BMP = V_ASN1_BMPSTRING, + /* OCTECT STRING */ + PKI_STRING_OCTET = V_ASN1_OCTET_STRING, + /* T61 Strings - Don't use in PKIX standards */ + PKI_STRING_T61 = V_ASN1_T61STRING, + PKI_STRING_PRINTABLE = V_ASN1_PRINTABLESTRING, + PKI_STRING_NUMERIC = V_ASN1_NUMERICSTRING, + PKI_STRING_VISIBLE = V_ASN1_VISIBLESTRING, + PKI_STRING_GENERAL = V_ASN1_GENERALSTRING, + PKI_STRING_UNIVERSAL = V_ASN1_UNIVERSALSTRING, +} PKI_STRING_DATATYPE; + +/// @brief Allocates and returns a new empty PKI_STRING +/// @param type The type of the string (e.g., PKI_STRING_OCTET, etc.) +/// @return The pointer to the allocated PKI_STRING if successful, NULL otherwise. +PKI_STRING * PKI_STRING_new_null ( int type ); + +/// @brief Allocates and returns a new PKI_STRING and copies the passed data +/// @param type The type of the string (e.g., PKI_STRING_OCTET, etc.) +/// @param val The pointer to the buffer with the data to be copied +/// @param size The size of the data to be copied into the string +/// @return The pointer to the new PKI_STRING if successful, NULL in case of errors +PKI_STRING * PKI_STRING_new( int type, char * val, ssize_t size ); + +PKI_STRING * PKI_STRING_dup ( const PKI_STRING *a ); +void PKI_STRING_free( PKI_STRING *s ); + +int PKI_STRING_cmp(const PKI_STRING *a, const PKI_STRING *b); +int PKI_STRING_set( PKI_STRING *s, char *content, ssize_t size ); +int PKI_STRING_get_type( const PKI_STRING *s ); +int PKI_STRING_set_type( PKI_STRING *s, int type); +char * PKI_STRING_get_parsed( const PKI_STRING *s ); +char * PKI_STRING_get_utf8( const PKI_STRING *s ); +CRYPTO_DIGEST * PKI_STRING_get_digest( const PKI_STRING *s, + const PKI_DIGEST_ALG *digest); + +/* Printing to fd or stdout */ +int PKI_STRING_print( const PKI_STRING *s ); +int PKI_STRING_print_fp( FILE *fp, const PKI_STRING *s ); + +#endif + + diff --git a/include/libpki/x509/pki_time.h b/include/libpki/x509/pki_time.h new file mode 100644 index 00000000..a0e3a401 --- /dev/null +++ b/include/libpki/x509/pki_time.h @@ -0,0 +1,22 @@ +/* PKI_TIME */ + +#ifndef _LIBPKI_TIME_H +#define _LIBPKI_TIME_H + +PKI_TIME *PKI_TIME_new( long long offset ); + +void PKI_TIME_free_void( void *time ); +int PKI_TIME_free( PKI_TIME *time ); + +PKI_TIME * PKI_TIME_set(PKI_TIME *time, time_t new_time); +int PKI_TIME_adj( PKI_TIME *time, long long offset ); + +PKI_TIME * PKI_TIME_dup(const PKI_TIME *time ); + +char *PKI_TIME_get_parsed(const PKI_TIME *t ); + +int PKI_TIME_print (const PKI_TIME *time ); +int PKI_TIME_print_fp (const FILE *fp, const PKI_TIME *time ); + + +#endif diff --git a/include/libpki/x509/pki_x509.h b/include/libpki/x509/pki_x509.h new file mode 100644 index 00000000..03a054b8 --- /dev/null +++ b/include/libpki/x509/pki_x509.h @@ -0,0 +1,322 @@ +/* PKI_X509 object management */ + +#ifndef _LIBPKI_HSM_MAIN_H +#include +#endif + +#ifndef _LIBPKI_CRYPTO_TYPES_H +#include +#endif + +#ifndef _LIBPKI_PKI_X509_H +#define _LIBPKI_PKI_X509_H + + +// =================== +// Function Prototypes +// =================== + +/*! \brief Allocates A New X509 structure + * + * This function allocates a new PKI_X509 structure and returns a pointer to it. + * The type parameter is used to specify the type of the PKI_X509 object to be + * created. The hsm parameter is used to specify the HSM to be used with the + * PKI_X509 object. If the hsm parameter is NULL, the default HSM will be used. + * + * @param type The type of the PKI_X509 object to be created + * @param hsm The HSM to be used with the PKI_X509 object + * @return A pointer to the newly created PKI_X509 object + */ +PKI_X509 *PKI_X509_new(PKI_TYPE type, PKI_X509 *hsm); + +/*! \brief Allocates A New PKI_X509 structure by using the passed value + * + * This function allocates a new PKI_X509 structure and returns a pointer to it. + * The type parameter is used to specify the type of the PKI_X509 object to be + * created. The data parameter is used to specify the value to be used with the + * PKI_X509 object. The hsm parameter is used to specify the HSM to be used with + * the PKI_X509 object. If the hsm parameter is NULL, the default HSM will be used. + * + * @param type The type of the PKI_X509 object to be created + * @param data The value to be used with the PKI_X509 object + * @param hsm The HSM to be used with the PKI_X509 object + * @return A pointer to the newly created PKI_X509 object + */ +PKI_X509 *PKI_X509_new_value(PKI_TYPE type, void *data, HSM *hsm); + +/*! \brief Allocates A New PKI_X509 structure by duplicating the passed value + * + * This function allocates a new PKI_X509 structure and returns a pointer to it. + * The type parameter is used to specify the type of the PKI_X509 object to be + * created. The data parameter is used to specify the value to be used with the + * PKI_X509 object. The hsm parameter is used to specify the HSM to be used with + * the PKI_X509 object. If the hsm parameter is NULL, the default HSM will be used. + * + * @param type The type of the PKI_X509 object to be created + * @param data The value to be used with the PKI_X509 object + * @param hsm The HSM to be used with the PKI_X509 object + * @return A pointer to the newly created PKI_X509 object + * @see PKI_X509_new_value + */ +PKI_X509 *PKI_X509_new_dup_value(PKI_TYPE type, const void *data, HSM *hsm); + +/*! \brief Frees the PKI_X509 object + * + * This function frees the PKI_X509 object and all of its associated memory. + * + * @param x A pointer to the PKI_X509 object to be freed + */ +void PKI_X509_free_void(void *x); + +/*! \brief Frees the PKI_X509 object + * + * This function frees the PKI_X509 object and all of its associated memory. + * + * @param x A pointer to the PKI_X509 object to be freed + */ +void PKI_X509_free(PKI_X509 *x); + +/*! \brief Sets the HSM for the PKI_X509 object + * + * This function sets the HSM for the PKI_X509 object. + * + * @param x A pointer to the PKI_X509 object + * @param hsm A pointer to the HSM object + * @return PKI_OK if successful, PKI_ERR otherwise + */ +int PKI_X509_set_hsm ( PKI_X509 *x, struct hsm_st *hsm ); + +/*! \brief Returns the HSM for the PKI_X509 object + * + * This function returns the HSM for the PKI_X509 object. + * + * @param x A pointer to the PKI_X509 object + * @return A pointer to the HSM object + */ +struct hsm_st *PKI_X509_get_hsm (const PKI_X509 *x ); + +/*! \brief Sets the reference URL for the PKI_X509 object + * + * This function sets the reference URL for the PKI_X509 object. + * + * @param x A pointer to the PKI_X509 object + * @param url A pointer to the URL object + * @return PKI_OK if successful, PKI_ERR otherwise + */ +int PKI_X509_set_reference ( PKI_X509 *x, URL *url ); + +/*! \brief Returns the reference URL for the PKI_X509 object + * + * This function returns the reference URL for the PKI_X509 object. + * + * @param x A pointer to the PKI_X509 object + * @return A pointer to the URL object + */ +URL *PKI_X509_get_reference (const PKI_X509 *x ); + +/*! \brief Duplicates the PKI_X509 object + * + * This function duplicates the PKI_X509 object and returns a pointer to the new object. + * + * @param x A pointer to the PKI_X509 object to be duplicated + * @return A pointer to the duplicated PKI_X509 object + */ +PKI_X509 * PKI_X509_dup (const PKI_X509 *x ); + +/*! \brief Duplicates the value of the PKI_X509 object + * + * This function duplicates the value of the PKI_X509 object and returns a pointer to the new object. + * + * @param x A pointer to the PKI_X509 object + * @return A pointer to the duplicated value + */ +void * PKI_X509_dup_value (const PKI_X509 *x ); + +/*! \brief Sets the value of the PKI_X509 object + * + * This function sets the value of the PKI_X509 object. + * + * @param x A pointer to the PKI_X509 object + * @param data A pointer to the value to be set + * @return PKI_OK if successful, PKI_ERR otherwise + */ +void * PKI_X509_get_value (const PKI_X509 *x ); + +/*! \brief Sets the value of the PKI_X509 object + * + * This function sets the value of the PKI_X509 object. + * + * @param x A pointer to the PKI_X509 object + * @param data A pointer to the value to be set + * @return PKI_OK if successful, PKI_ERR otherwise + */ +int PKI_X509_set_value ( PKI_X509 *x, void *data ); + +/*! \brief Returns the type of the PKI_X509 object + * + * This function returns the type of the PKI_X509 object. + * + * @param x A pointer to the PKI_X509 object + * @return The type of the PKI_X509 object + */ +PKI_TYPE PKI_X509_get_type (const PKI_X509 *x ); + +/*! \brief Returns the type of the PKI_X509 object as a string + * + * This function returns the type of the PKI_X509 object as a string. + * + * @param x A pointer to the PKI_X509 object + * @return The type of the PKI_X509 object as a string + */ +const char * PKI_X509_get_type_parsed (const PKI_X509 *x ); + +/*! \brief Returns the pointer to the requested data in the PKI_X509 object + * + * This function returns the pointer to the requested data in the PKI_X509 object. + * + * @param x A pointer to the PKI_X509 object + * @return The type of the PKI_X509 data to be returned + * @return The pointer to the requested data in the PKI_X509 object + * @see PKI_X509_DATA + */ +void * PKI_X509_get0 (const PKI_X509 *x, PKI_X509_DATA type ); + +/*! \brief Returns a copy of the specified data in the PKI_X509 object + * + * This function returns a copy of the specified data in the PKI_X509 object. + * The caller will be responsible for freeing the returned data. + * + * @param x A pointer to the PKI_X509 object + * @return A copy of the specified data in the PKI_X509 object + * @see PKI_X509_DATA + */ +void * PKI_X509_get (const PKI_X509 *x, PKI_X509_DATA type ); + +/*! \brief Returns the parsed data from a PKI_X509 object + * + * This function returns the parsed data from a PKI_X509 object. + * The caller will be responsible for freeing the returned data. + * + * @param x A pointer to the PKI_X509 object + * @param type The type of the PKI_X509 data to be returned + * @return The parsed data from the PKI_X509 object + * @see PKI_X509_DATA + */ +void * PKI_X509_get_parsed (const PKI_X509 *x, PKI_X509_DATA type ); + +/*! \brief Prints the parsed data from a PKI_X509 object + * + * This function prints the parsed data from a PKI_X509 object. + * + * @param x A pointer to the PKI_X509 object + * @param type The type of the PKI_X509 data to be printed + * @param fd The file descriptor to which the data will be printed + * @return PKI_OK if successful, PKI_ERR otherwise + * @see PKI_X509_DATA + */ +int PKI_X509_print_parsed (const PKI_X509 *x, PKI_X509_DATA type, int fd ); + +/*! \brief Deletes the PKI_X509 object pointed by the reference field + * + * This function deletes the PKI_X509 object by calling the corresponding + * calback function in the associated HSM. If the HSM is not set, the default + * callback function will be used. + * + * @param x A pointer to the PKI_X509 object to be deleted + * @return PKI_OK if successful, PKI_ERR otherwise + */ +int PKI_X509_delete(PKI_X509 *x); + +/*! \brief Take ownership of the passed data and set it into the PKI_X509 object + * + * This function takes ownership of the passed data and sets it into the PKI_X509 object. + * + * @param x A pointer to the PKI_X509 object + * @param type The type of the PKI_X509 data to be set + * @param data A pointer to the data to be set + * @param hsm A pointer to the HSM object + * @return PKI_OK if successful, PKI_ERR otherwise + * @see PKI_X509_DATA + */ +int PKI_X509_attach(PKI_X509 * x, PKI_TYPE type, void * data, HSM * hsm); + +/*! \brief Detach the data from the PKI_X509 object and return it + * + * This function detaches the data from the PKI_X509 object and returns it. + * The caller will be responsible for freeing the returned data. + * + * @param x A pointer to the PKI_X509 object + * @param data A pointer to the data to be returned + * @param type The type of the PKI_X509 data to be returned + * @param hsm A pointer to the HSM object + * @return PKI_OK if successful, PKI_ERR otherwise + * @see PKI_X509_DATA + */ +int PKI_X509_detach(PKI_X509 * x, void ** data, PKI_TYPE * type, HSM **hsm); + +/*! \brief Set the AUX data into the PKI_X509 object + * + * This function sets auxillary data into the PKI_X509 object + * that is preserved across the PKI_X509 object's lifecycle. + * + * @param x A pointer to the PKI_X509 object + * @param data A pointer to the data to be set + * @param data_free_func A pointer to the function that will free the data + * @param data_dup_func A pointer to the function that will duplicate the data + * @return PKI_OK if successful, PKI_ERR otherwise + */ +int PKI_X509_aux_data_set (PKI_X509 * x, + void * data, + void (*data_free_func)(void *), + void * (*data_dup_func )(void *)); + +/*! \brief Get the AUX data from the PKI_X509 object + * + * This function gets auxillary data from the PKI_X509 object + * that is preserved across the PKI_X509 object's lifecycle. + * + * @param x A pointer to the PKI_X509 object + * @return A pointer to the auxillary data + */ +void * PKI_X509_aux_data_get(PKI_X509 * x); + +/*! \brief Duplicate the AUX data from the PKI_X509 object + * + * This function duplicates the auxillary data from the PKI_X509 object + * that is preserved across the PKI_X509 object's lifecycle. + * + * @param x A pointer to the PKI_X509 object + * @return A pointer to the duplicated auxillary data + */ +void * PKI_X509_aux_data_dup(PKI_X509 * x); + +/*! \brief Delete the AUX data from the PKI_X509 object + * + * This function deletes the auxillary data from the PKI_X509 object + * that is preserved across the PKI_X509 object's lifecycle. + * + * @param x A pointer to the PKI_X509 object + * @return PKI_OK if successful, PKI_ERR otherwise + */ +int PKI_X509_aux_data_del(PKI_X509 * x); + +// /*! \brief Set the status of the PKI_X509 object +// * +// * This function sets the status of the PKI_X509 object. +// * +// * @param x A pointer to the PKI_X509 object +// * @param status The status to be set +// * @return PKI_OK if successful, PKI_ERR otherwise +// */ +// int PKI_X509_set_status(PKI_X509 *x, int status); + +// /*! \brief Get the status of the PKI_X509 object +// * +// * This function gets the status of the PKI_X509 object. +// * +// * @param x A pointer to the PKI_X509 object +// * @return The status of the PKI_X509 object +// */ +// int PKI_X509_get_status(PKI_X509 *x); + +#endif diff --git a/include/libpki/x509/pki_x509_attribute.h b/include/libpki/x509/pki_x509_attribute.h new file mode 100644 index 00000000..c7354b4d --- /dev/null +++ b/include/libpki/x509/pki_x509_attribute.h @@ -0,0 +1,72 @@ +/* src/libpki/pki_x509_attribute.h */ + +#ifndef _LIBPKI_X509_ATTRIBUTE_H_ +#define _LIBPKI_X509_ATTRIBUTE_H_ + +#define PKI_X509_ATTRIBUTE X509_ATTRIBUTE + +/* ------------------- PKI_X509_ATTRIBUTE_STACK ops -------------------- */ + +#define PKI_X509_ATTRIBUTE_STACK STACK_OF(X509_ATTRIBUTE) + +#define PKI_STACK_X509_ATTRIBUTE_elements(a) sk_X509_ATTRIBUTE_num ( a ) +#define PKI_STACK_X509_ATTRIBUTE_get_num(a,b) sk_X509_ATTRIBUTE_value (a, b) +#define PKI_STACK_X509_ATTRIBUTE_pop(a) sk_X509_ATTRIBUTE_pop(a) +#define PKI_STACK_X509_ATTRIBUTE_pop_free(a) sk_X509_ATTRIBUTE_pop_free(a) +#define PKI_STACK_X509_ATTRIBUTE_new_null() sk_X509_ATTRIBUTE_new_null() +#define PKI_STACK_X509_ATTRIBUTE_push(a,b) sk_X509_ATTRIBUTE_push(a,b) + + +/* --------------------- PKI_X509_ATTRIBUTE_STACK ---------------------- */ +void PKI_X509_ATTRIBUTE_free ( PKI_X509_ATTRIBUTE *a ); +void PKI_X509_ATTRIBUTE_free_null ( void *a ); + +PKI_X509_ATTRIBUTE *PKI_X509_ATTRIBUTE_new_null ( void ); + +PKI_X509_ATTRIBUTE *PKI_X509_ATTRIBUTE_new( PKI_ID attribute_id, + int data_type, + const unsigned char *value, + size_t size ); + +PKI_X509_ATTRIBUTE *PKI_X509_ATTRIBUTE_new_name(const char *name, + int data_type, + const char *value, + size_t size ); + +void PKI_STACK_X509_ATTRIBUTE_free ( PKI_X509_ATTRIBUTE_STACK *sk ); +void PKI_STACK_X509_ATTRIBUTE_free_all ( PKI_X509_ATTRIBUTE_STACK *sk ); + +int PKI_STACK_X509_ATTRIBUTE_add(const PKI_X509_ATTRIBUTE_STACK * a_sk, + PKI_X509_ATTRIBUTE * a ); + +const PKI_X509_ATTRIBUTE *PKI_STACK_X509_ATTRIBUTE_get( + const PKI_X509_ATTRIBUTE_STACK * const a_sk, + PKI_ID attribute_id ); + +const PKI_X509_ATTRIBUTE *PKI_STACK_X509_ATTRIBUTE_get_by_num ( + const PKI_X509_ATTRIBUTE_STACK * const a_sk, + int num ); + +const PKI_X509_ATTRIBUTE *PKI_STACK_X509_ATTRIBUTE_get_by_name ( + const PKI_X509_ATTRIBUTE_STACK * const a_sk, + const char * const name ); + +int PKI_STACK_X509_ATTRIBUTE_delete(const PKI_X509_ATTRIBUTE_STACK * a_sk, + PKI_ID attr ); + +int PKI_STACK_X509_ATTRIBUTE_delete_by_num( + const PKI_X509_ATTRIBUTE_STACK * a_sk, + int num); + +int PKI_STACK_X509_ATTRIBUTE_delete_by_name ( + const PKI_X509_ATTRIBUTE_STACK * a_sk, + const char * const name ); + +int PKI_STACK_X509_ATTRIBUTE_replace(const PKI_X509_ATTRIBUTE_STACK * a_sk, + PKI_X509_ATTRIBUTE * a); + +const char *PKI_X509_ATTRIBUTE_get_descr ( const PKI_X509_ATTRIBUTE * const a ); +const PKI_STRING *PKI_X509_ATTRIBUTE_get_value ( const PKI_X509_ATTRIBUTE * const a ); +char *PKI_X509_ATTRIBUTE_get_parsed (const PKI_X509_ATTRIBUTE * const a ); + +#endif diff --git a/include/libpki/x509/pki_x509_cert.h b/include/libpki/x509/pki_x509_cert.h new file mode 100644 index 00000000..cba39cf6 --- /dev/null +++ b/include/libpki/x509/pki_x509_cert.h @@ -0,0 +1,97 @@ +/* pki_x509.h */ + +#ifndef _LIBPKI_X509_CERT_HEADER_H +#define _LIBPKI_X509_CERT_HEADER_H + +/* Memory functions */ +PKI_X509_CERT *PKI_X509_CERT_new_null( void ); + +void PKI_X509_CERT_free ( PKI_X509_CERT *x ); + +PKI_X509_CERT * PKI_X509_CERT_new (const PKI_X509_CERT *ca_cert, + const PKI_X509_KEYPAIR *pkey, + const PKI_X509_REQ *req, + const char *subj_s, + const char *serial, + uint64_t validity, + const PKI_X509_PROFILE *conf, + const PKI_X509_ALGOR_VALUE * algor, + const PKI_CONFIG *oids, + HSM *hsm ); + +PKI_X509_CERT *PKI_X509_CERT_dup (const PKI_X509_CERT *x ); + +/* Signature Specific Functions */ +int PKI_X509_CERT_sign ( PKI_X509_CERT *x, PKI_X509_KEYPAIR *k, + PKI_DIGEST_ALG *alg ); +int PKI_X509_CERT_sign_tk ( PKI_X509_CERT *cert, PKI_TOKEN *tk, + PKI_DIGEST_ALG *alg); + +/* Get/Set data in a certificate */ + +/*! \brief Returns a pointer to a specified data field in a certificate */ +const void * PKI_X509_CERT_get_data(const PKI_X509_CERT *x, PKI_X509_DATA type); + +int PKI_X509_CERT_set_data(PKI_X509_CERT *x, int type, void *data); + +/* Special case for TBS encoded data */ +PKI_MEM * PKI_X509_CERT_get_der_tbs(const PKI_X509_CERT *x ); + +/* Print and Get Parsed Data */ +int PKI_X509_CERT_get_keysize (const PKI_X509_CERT *x ); + +char * PKI_X509_CERT_get_parsed(const PKI_X509_CERT *x, + PKI_X509_DATA type ); + +int PKI_X509_CERT_print_parsed(const PKI_X509_CERT *x, + PKI_X509_DATA type, + int fd ); + +/* Key Check function */ +int PKI_X509_CERT_check_pubkey(const PKI_X509_CERT *x, + const PKI_X509_KEYPAIR *k); + +/* Exts functions */ +int PKI_X509_CERT_add_extension( PKI_X509_CERT *x, + const PKI_X509_EXTENSION *ext ); +int PKI_X509_CERT_add_extension_stack (PKI_X509_CERT *x, + const PKI_X509_EXTENSION_STACK *ext); + +/* Fingerprint functions */ +CRYPTO_DIGEST *PKI_X509_CERT_fingerprint(const PKI_X509_CERT *x, + const PKI_DIGEST_ALG *alg ); +CRYPTO_DIGEST *PKI_X509_CERT_fingerprint_by_name(const PKI_X509_CERT *x, + const char *alg ); + +/* Key Hash functions */ +CRYPTO_DIGEST *PKI_X509_CERT_key_hash(const PKI_X509_CERT *x, + const PKI_DIGEST_ALG *alg ); +CRYPTO_DIGEST *PKI_X509_CERT_key_hash_by_name(const PKI_X509_CERT *x, + const char *alg ); + +/* Get Certificate type - look for PKI_X509_CERT_TYPE */ +PKI_X509_CERT_TYPE PKI_X509_CERT_get_type(const PKI_X509_CERT *x ); + +/* Retrieve Extensions from the Certificate */ +PKI_STACK *PKI_X509_CERT_get_cdp(const PKI_X509_CERT *cert ); + +int PKI_X509_CERT_is_selfsigned(const PKI_X509_CERT *x ); +int PKI_X509_CERT_is_ca(const PKI_X509_CERT *x ); +int PKI_X509_CERT_is_proxy(const PKI_X509_CERT *x ); +int PKI_X509_CERT_check_domain(const PKI_X509_CERT *x, + const char *domain ); + +/* Retrieves the e-mail address from the Subject or SubjectAltName */ +PKI_STACK * PKI_X509_CERT_get_email(const PKI_X509_CERT *x ); + +// PKI_X509_EXTENSION * PKI_X509_CERT_get_extension_by_num ( PKI_X509_CERT *x, +// int num ); + +PKI_X509_EXTENSION * PKI_X509_CERT_get_extension_by_id(const PKI_X509_CERT *x, + PKI_ID id ); +PKI_X509_EXTENSION * PKI_X509_CERT_get_extension_by_name(const PKI_X509_CERT *x, + const char * name ); +PKI_X509_EXTENSION *PKI_X509_CERT_get_extension_by_oid (const PKI_X509_CERT *x, + const PKI_OID *id ); + +#endif diff --git a/include/libpki/x509/pki_x509_cert_mem.h b/include/libpki/x509/pki_x509_cert_mem.h new file mode 100644 index 00000000..1ffe92b0 --- /dev/null +++ b/include/libpki/x509/pki_x509_cert_mem.h @@ -0,0 +1,16 @@ +/* PKI_X509 to/from PKI_MEM management */ + +#ifndef _LIBPKI_PKI_X509_CERT_MEM_H +#define _LIBPKI_PKI_X509_CERT_MEM_H + +/* ----------------------------------- Get -------------------------------- */ + +PKI_X509_CERT *PKI_X509_CERT_get_mem ( PKI_MEM *mem, PKI_CRED *cred ); +PKI_X509_CERT_STACK *PKI_X509_CERT_STACK_get_mem(PKI_MEM *mem, PKI_CRED *cred); + +/* ----------------------------------- Put -------------------------------- */ +// PKI_MEM *PKI_X509_CERT_put_mem ( PKI_X509_CERT *x, int format, PKI_CRED *cred); +int PKI_X509_CERT_STACK_put_mem ( PKI_X509_CERT_STACK *sk, int format, + PKI_MEM *pki_mem, PKI_CRED *cred, int num ); + +#endif diff --git a/include/libpki/x509/pki_x509_cms.h b/include/libpki/x509/pki_x509_cms.h new file mode 100644 index 00000000..5c1108d2 --- /dev/null +++ b/include/libpki/x509/pki_x509_cms.h @@ -0,0 +1,272 @@ +/* libpki/pki_x509_cms.h */ + +#ifndef HEADER_CMS_H +#include +#endif + +#ifndef _LIBPKI_HEADER_DATA_ST_H +#include +#endif + +#ifndef _LIBPKI_X509_CMS_H +#define _LIBPKI_X509_CMS_H + +#ifndef CMS_ASCIICRLF +#define CMS_ASCIICRLF 0x80000 +#endif + +/* ---------------------- Stack and Data Types -------------------------- */ + +typedef enum { + PKI_X509_CMS_TYPE_UNKNOWN = NID_undef, + PKI_X509_CMS_TYPE_SIGNED = NID_pkcs7_signed, + PKI_X509_CMS_TYPE_ENVELOPED = NID_pkcs7_enveloped, + PKI_X509_CMS_TYPE_DATA = NID_pkcs7_data, + PKI_X509_CMS_TYPE_DIGEST = NID_pkcs7_digest, + PKI_X509_CMS_TYPE_SMIME_COMPRESSED = NID_id_smime_ct_compressedData, + PKI_X509_CMS_TYPE_SYM_ENCRYPTED = NID_pkcs7_encrypted +} PKI_X509_CMS_TYPE; + +typedef enum { + // Format Flags + PKI_X509_CMS_FLAGS_BINARY = CMS_BINARY, + PKI_X509_CMS_FLAGS_PARTIAL = CMS_PARTIAL, + PKI_X509_CMS_FLAGS_DETACHED = CMS_DETACHED, + // Features Flags + PKI_X509_CMS_FLAGS_NOSMIMECAP = CMS_NOSMIMECAP, + PKI_X509_CMS_FLAGS_NOCERTS = CMS_NOCERTS, + PKI_X509_CMS_FLAGS_NOATTR = CMS_NOATTR, + PKI_X509_CMS_FLAGS_NOCRL = CMS_NOCRL, + PKI_X509_CMS_FLAGS_NOOLDMIMETYPE = CMS_NOOLDMIMETYPE, + PKI_X509_CMS_FLAGS_USE_KEYID = CMS_USE_KEYID, + PKI_X509_CMS_FLAGS_STREAM = CMS_STREAM, + // Operational Flags + PKI_X509_CMS_FLAGS_REUSE_DIGEST = CMS_REUSE_DIGEST, + PKI_X509_CMS_FLAGS_OP_DEBUG_DECRYPT = CMS_DEBUG_DECRYPT, + PKI_X509_CMS_FLAGS_OP_ASCIICRLF = CMS_ASCIICRLF, + PKI_X509_CMS_FLAGS_OP_NOINTERN = CMS_NOINTERN, + PKI_X509_CMS_FLAGS_OP_NOSIGS = CMS_NOSIGS, + PKI_X509_CMS_FLAGS_OP_NO_SIGNER_VERIFY = CMS_NO_SIGNER_CERT_VERIFY, + PKI_X509_CMS_FLAGS_NO_CONTENT_VERIFY = CMS_NO_CONTENT_VERIFY, + PKI_X509_CMS_FLAGS_NO_ATTRIBUTES_VERIFY = CMS_NO_ATTR_VERIFY +} PKI_X509_CMS_FLAGS; + +// To help developers, we provide the 'positive' flags as well +#define PKI_X509_CMS_FLAGS_ADD_SMIMECAP(a) \ + a &= ~CMS_NOSMIMECAP + +#define PKI_X509_CMS_FLAGS_ADD_CERTS(a) \ + a &= ~CMS_NOCERTS + +#define PKI_X509_CMS_FLAGS_ADD_ATTR(a) \ + a &= ~CMS_NOATTR + +#define PKI_X509_CMS_FLAGS_ADD_CRL(a) \ + a &= ~CMS_NOCRL + +#define PKI_X509_CMS_FLAGS_USE_OLDMIMETYPE(a) \ + a &= ~CMS_NOOLDMIMETYPE + +#define PKI_X509_CMS_FLAGS_USE_ISSUERANDSERIAL(a) \ + a &= ~CMS_USE_KEYID + +#define PKI_X509_CMS_FLAGS_INIT_DEFAULT \ + PKI_X509_CMS_FLAGS_BINARY | PKI_X509_CMS_FLAGS_PARTIAL | \ + PKI_X509_CMS_FLAGS_NOSMIMECAP | PKI_X509_CMS_FLAGS_STREAM | \ + PKI_X509_CMS_FLAGS_NOOLDMIMETYPE + +#define PKI_X509_CMS_FLAGS_INIT_SMIME \ + PKI_X509_CMS_FLAGS_PARTIAL | PKI_X509_CMS_FLAGS_STREAM + +/* --------------------- Internal Mem Functions ------------------------- */ + +PKI_X509_CMS_VALUE * PKI_X509_CMS_VALUE_new(void); + +PKI_X509_CMS_VALUE * PKI_X509_CMS_VALUE_dup(const PKI_X509_CMS_VALUE * const cms); + +void PKI_X509_CMS_VALUE_free(PKI_X509_CMS_VALUE *cms); + +/* ------------------------ PEM I/O Functions --------------------------- */ + +PKI_X509_CMS_VALUE *PKI_PEM_read_bio_CMS( BIO *bp ); + +// int PEM_write_bio_CMS( BIO *bp, PKI_X509_CMS_VALUE *o ); + +/* ---------------------------- Functions ------------------------------- */ + +void PKI_X509_CMS_free(PKI_X509_CMS *cms); + +void PKI_X509_CMS_free_void(void *cms); + +PKI_X509_CMS *PKI_X509_CMS_new(PKI_X509_CMS_TYPE type, + int flags); + +PKI_X509_CMS *PKI_X509_CMS_new_value(PKI_X509_CMS_VALUE * value); + +PKI_X509_CMS_TYPE PKI_X509_CMS_get_type(const PKI_X509_CMS * const cms); + +int PKI_X509_CMS_data_set_mem(PKI_X509_CMS * cms, + PKI_MEM * mem, + PKI_MEM ** out_mem, + int flags); + +int PKI_X509_CMS_data_set(PKI_X509_CMS * cms, + unsigned char * data, + size_t size, + PKI_MEM ** out_mem, + int flags); + +PKI_IO * PKI_X509_CMS_stream_init(PKI_X509_CMS * cms); + +int PKI_X509_CMS_stream_write_mem(PKI_IO * cms_io, + const PKI_MEM * mem); + +int PKI_X509_CMS_stream_write(PKI_IO * cms_io, + const unsigned char * data, + size_t size); + +int PKI_X509_CMS_stream_final(PKI_X509_CMS * cms, + PKI_IO * cms_io); + +PKI_X509_CMS * PKI_X509_CMS_wrap(PKI_X509_CMS ** cms, + PKI_X509_CMS_TYPE type); + +PKI_X509_CMS * PKI_X509_CMS_unwrap(PKI_X509_CMS ** cms); + +// CRL +int PKI_X509_CMS_add_crl(PKI_X509_CMS * cms, + const PKI_X509_CRL * const crl); + +int PKI_X509_CMS_add_crl_stack(PKI_X509_CMS * cms, + const PKI_X509_CRL_STACK * const crl_sk ); + +int PKI_X509_CMS_get_crls_num(const PKI_X509_CMS * const cms); + +PKI_X509_CRL * PKI_X509_CMS_get_crl(const PKI_X509_CMS * const cms, + int idx ); + +// Certs +int PKI_X509_CMS_add_cert(const PKI_X509_CMS * cms, + const PKI_X509_CERT * const x); + +int PKI_X509_CMS_add_cert_stack(const PKI_X509_CMS * cms, + const PKI_X509_CERT_STACK * const x_sk); + +int PKI_X509_CMS_get_certs_num(const PKI_X509_CMS * const cms ); + +PKI_X509_CERT *PKI_X509_CMS_get_cert(const PKI_X509_CMS * const cms, + int idx ); + +int PKI_X509_CMS_get_signer_num(const PKI_X509_CMS * cms); + +PKI_X509_CERT *PKI_X509_CMS_get_signer_cert(const PKI_X509_CMS * cms, + int idx); + +int PKI_X509_CMS_clear_certs(const PKI_X509_CMS * cms); + +// Signer +int PKI_X509_CMS_has_signers(const PKI_X509_CMS * const cms ); + +int PKI_X509_CMS_add_signer(const PKI_X509_CMS * const cms, + const PKI_X509_CERT * const signer, + const PKI_X509_KEYPAIR * const k, + const PKI_DIGEST_ALG * md, + const int flags ); + +int PKI_X509_CMS_add_signer_tk(PKI_X509_CMS * cms, + const PKI_TOKEN * const tk, + const PKI_DIGEST_ALG * const md, + const int flags); + +const PKI_X509_CMS_SIGNER_INFO * PKI_X509_CMS_get_signer_info( + const PKI_X509_CMS * const cms, + int idx); + +// Cipher +int PKI_X509_CMS_set_cipher(PKI_X509_CMS * const cms, + const PKI_CIPHER * const cipher); + +const PKI_X509_ALGOR_VALUE * PKI_X509_CMS_get_encode_alg( + const PKI_X509_CMS * const cms); + +int PKI_X509_CMS_encode(const PKI_X509_CMS * const cms, + unsigned char * data, + size_t size); + +PKI_MEM *PKI_X509_CMS_decode(const PKI_X509_CMS * const cms, + const PKI_X509_KEYPAIR * const pkey, + const PKI_X509_CERT * const x); + +// Recipients +int PKI_X509_CMS_has_recipients(const PKI_X509_CMS * const cms ); + +int PKI_X509_CMS_set_recipients(const PKI_X509_CMS * cms, + const PKI_X509_CERT_STACK * const x_sk); + +int PKI_X509_CMS_add_recipient(const PKI_X509_CMS * cms, + const PKI_X509_CERT * const x, + const PKI_CIPHER * const cipher, + const int flags); + +int PKI_X509_CMS_add_recipient_tk(const PKI_X509_CMS * cms, + const PKI_TOKEN * const tk, + const PKI_CIPHER * const cipher, + const int flags); + +int PKI_X509_CMS_get_recipients_num(const PKI_X509_CMS * const cms); + +PKI_X509_CMS_RECIPIENT_INFO * PKI_X509_CMS_get_recipient_info( + const PKI_X509_CMS * const cms, + int idx ); + +int PKI_X509_CMS_recipient_num(const PKI_X509_CMS * const cms, + const PKI_X509_CERT * const x ); + +// Data +PKI_MEM *PKI_X509_CMS_get_data(const PKI_X509_CMS * const cms, + const PKI_X509_KEYPAIR * const pkey, + const PKI_X509_CERT * const x ); + +PKI_MEM *PKI_X509_CMS_get_data_tk(const PKI_X509_CMS * const cms, + const PKI_TOKEN * const tk); + +PKI_MEM *PKI_X509_CMS_get_raw_data(const PKI_X509_CMS * const cms ); + + +/* ------------------------- X509_ATTRIBUTE funcs ----------------------- */ + +int PKI_X509_CMS_add_attribute(const PKI_X509_CMS * cms, + PKI_X509_ATTRIBUTE * a); + +int PKI_X509_CMS_add_signed_attribute(const PKI_X509_CMS * cms, + PKI_X509_ATTRIBUTE * a); + +const PKI_X509_ATTRIBUTE *PKI_X509_CMS_get_signed_attribute( + const PKI_X509_CMS * const cms, + PKI_ID id ); + +const PKI_X509_ATTRIBUTE *PKI_X509_CMS_get_attribute( + const PKI_X509_CMS * const cms, + PKI_ID id); + +const PKI_X509_ATTRIBUTE *PKI_X509_CMS_get_signed_attribute_by_name( + const PKI_X509_CMS * const cms, + const char * const name ); + +const PKI_X509_ATTRIBUTE *PKI_X509_CMS_get_attribute_by_name( + const PKI_X509_CMS * const cms, + const char * const name); + +int PKI_X509_CMS_delete_attribute(const PKI_X509_CMS * cms, + PKI_ID id); + +int PKI_X509_CMS_delete_signed_attribute(const PKI_X509_CMS * cms, + PKI_ID id); + +/* ------------------------------ TXT Format CB -------------------------- */ + +int PKI_X509_CMS_VALUE_print_bio(PKI_IO * bio, + const PKI_X509_CMS_VALUE * const cmsval ); + +#endif + diff --git a/include/libpki/x509/pki_x509_crl.h b/include/libpki/x509/pki_x509_crl.h new file mode 100644 index 00000000..3adb2abb --- /dev/null +++ b/include/libpki/x509/pki_x509_crl.h @@ -0,0 +1,68 @@ +/* PKI_X509_CRL object management */ + +#ifndef _LIBPKI_PKI_X509_CRL_H +#define _LIBPKI_PKI_X509_CRL_H + +/* PKI_X509_CRL_ENTRY */ +PKI_X509_CRL_ENTRY * PKI_X509_CRL_ENTRY_new(const PKI_X509_CERT * cert, + PKI_X509_CRL_REASON reason, + const PKI_TIME * revDate, + const PKI_X509_EXTENSION_STACK * sk_exts, + const PKI_X509_PROFILE * profile); + +PKI_X509_CRL_ENTRY * PKI_X509_CRL_ENTRY_new_serial(const char * serial, + PKI_X509_CRL_REASON reason, + const PKI_TIME * revDate, + const PKI_X509_EXTENSION_STACK * sk_exts, + const PKI_X509_PROFILE * profile); + +void PKI_X509_CRL_ENTRY_free ( PKI_X509_CRL_ENTRY *entry ); + +/* PKI CRL lookup functions */ +const PKI_X509_CRL_ENTRY * PKI_X509_CRL_lookup(const PKI_X509_CRL *x, + const PKI_INTEGER *s ); + +const PKI_X509_CRL_ENTRY * PKI_X509_CRL_lookup_serial(const PKI_X509_CRL *x, + const char *serial); + +const PKI_X509_CRL_ENTRY * PKI_X509_CRL_lookup_cert(const PKI_X509_CRL *x, + const PKI_X509_CERT *cert ); + +const PKI_X509_CRL_ENTRY * PKI_X509_CRL_lookup_long(const PKI_X509_CRL *x, + long long s ); + +/* PKI CRL Reason Codes */ +int PKI_X509_CRL_REASON_CODE_num ( void ); +int PKI_X509_CRL_REASON_CODE_get ( const char * st ); +const char *PKI_X509_CRL_REASON_CODE_get_parsed ( PKI_X509_CRL_REASON reason ); +const char *PKI_X509_CRL_REASON_CODE_get_descr ( PKI_X509_CRL_REASON reason ); + +/* PKI CRL */ +PKI_X509_CRL *PKI_X509_CRL_new_null ( void ); +void PKI_X509_CRL_free_void( void *x ); + +PKI_X509_CRL *PKI_X509_CRL_new (const PKI_X509_KEYPAIR * pkey, + const PKI_X509_CERT * cert, + const char * crlNum_s, + const long long thisUpdate, + const long long nextUpdate, + const PKI_X509_CRL_ENTRY_STACK * sk, + const PKI_X509_EXTENSION_STACK * sk_exts, + const PKI_X509_PROFILE * profile, + const PKI_CONFIG * oids, + HSM * hsm); + +int PKI_X509_CRL_free ( PKI_X509_CRL * x ); +int PKI_X509_CRL_add_extension(const PKI_X509_CRL *x, const PKI_X509_EXTENSION *ext); +int PKI_X509_CRL_add_extension_stack(const PKI_X509_CRL * x, + const PKI_X509_EXTENSION_STACK * ext); + +PKI_MEM * PKI_X509_CRL_tbs_asn1(PKI_X509_CRL *x); + +const void * PKI_X509_CRL_get_data ( const PKI_X509_CRL *x, + PKI_X509_DATA type ); + +char * PKI_X509_CRL_get_parsed(const PKI_X509_CRL *x, + PKI_X509_DATA type ); + +#endif diff --git a/include/libpki/x509/pki_x509_data_st.h b/include/libpki/x509/pki_x509_data_st.h new file mode 100644 index 00000000..7d8a0bfd --- /dev/null +++ b/include/libpki/x509/pki_x509_data_st.h @@ -0,0 +1,81 @@ +/* OpenCA libpki package +* (c) 2000-2006 by Massimiliano Pala and OpenCA Group +* All Rights Reserved +* +* =================================================================== +* Released under OpenCA LICENSE +*/ + +#ifndef _LIBPKI_PKI_DATATYPES_H +#include +#endif + +#ifndef _LIBPKI_PKI_CRED_H +#include +#endif + +#ifndef _LIBPKI_PKI_X509_DATATYPES_ST_H +#define _LIBPKI_PKI_X509_DATATYPES_ST_H + +typedef struct pki_x509_callbacks_st { + + // /* ---------------- Memory Management -------------------- */ + + // void * (*new) (void ); + // void (*del) (void *x ); + + /* ------------ DER Encoding and Decoding ---------------------- */ + + void * (*encode)(PKI_X509 *x, unsigned char **out, size_t *size + unsigned char *secret, size_t secret_len); + void * (*decode)(PKI_X509 *x, unsigned char *in, size_t size); + + /* Set and Retrieve Data */ + +} PKI_ASN1_CALLBACKS; + +/* This structure helps us in maintaining all the drivers aligned */ + +typedef struct pki_x509_callback + +typedef struct pki_x509_all_callbacks_st { + const struct pki_x509_callbacks_st * test_only; +} PKI_X509_CALLBACKS_ALL; + +/* PKI_X509 general object */ +typedef struct pki_x509_st { + + /* Type of Object - taken from PKI_DATATYPE */ + PKI_DATATYPE type; + + /* Internal Value - usually the supported crypto lib internal format */ + void *value; + + /* HSM to use for operations */ + struct hsm_st *hsm; + + /* Reference URL */ + URL *ref; + + /* Callbacks */ + const PKI_X509_ENCODING_CB *cb; + + /* Template Reference */ + const ASN1_ITEM * asn1_it; + + /* Internal Status */ + int status; + + /* Auxillary Data */ + void * aux_data; + + /* Callback to free auxillary data */ + void (*free_aux_data)(void *); + + /* Callback to duplicate auxillary data */ + void * (*dup_aux_data)(void *); + +} PKI_X509; + +/* End of _LIBPKI_PKI_X509_DATA_ST_H */ +#endif diff --git a/include/libpki/x509/pki_x509_extension.h b/include/libpki/x509/pki_x509_extension.h new file mode 100644 index 00000000..69b1edfc --- /dev/null +++ b/include/libpki/x509/pki_x509_extension.h @@ -0,0 +1,25 @@ +/* Extensions - driver specific part */ + +#ifndef _LIBPKI_X509_EXTENSION_H +#define _LIBPKI_X509_EXTENSION_H + +PKI_X509_EXTENSION *PKI_X509_EXTENSION_new( void ); + +void PKI_X509_EXTENSION_free ( PKI_X509_EXTENSION *ext ); + +void PKI_X509_EXTENSION_free_void ( void *ext ); + +PKI_X509_EXTENSION *PKI_X509_EXTENSION_value_new_profile( + const PKI_X509_PROFILE * profile, + const PKI_CONFIG * oids, + const PKI_CONFIG_ELEMENT * extNode, + const PKI_TOKEN * tk); + +PKI_X509_EXTENSION_STACK *PKI_X509_CERT_ext_list(PKI_X509_CERT * x); + +PKI_X509_EXTENSION_STACK *PKI_X509_CERT_VALUE_ext_list(PKI_X509_CERT_VALUE * x); + + +#endif + + diff --git a/include/libpki/x509/pki_x509_item.h b/include/libpki/x509/pki_x509_item.h new file mode 100644 index 00000000..2cfcd368 --- /dev/null +++ b/include/libpki/x509/pki_x509_item.h @@ -0,0 +1,16 @@ +/* pki_x509_item.h */ + +#ifndef _LIBPKI_X509_ITEM_H +#define _LIBPKI_X509_ITEM_H + +#ifndef _LIBPKI_OS_H +#include +#endif + +int PKI_X509_ITEM_verify(const ASN1_ITEM * it, + X509_ALGOR * a, + ASN1_BIT_STRING * signature, + void * asn, + EVP_PKEY * pkey); + +#endif diff --git a/include/libpki/x509/pki_x509_mem.h b/include/libpki/x509/pki_x509_mem.h new file mode 100644 index 00000000..ef8c4acf --- /dev/null +++ b/include/libpki/x509/pki_x509_mem.h @@ -0,0 +1,26 @@ +/* PKI_X509 to/from PKI_MEM */ + +#ifndef _LIBPKI_PKI_X509_MEM_H +#define _LIBPKI_PKI_X509_MEM_H + +/* --------------------------- PKI_MEM get ------------------------------- */ +PKI_X509 *PKI_X509_get_mem ( PKI_MEM *mem, PKI_DATATYPE type, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ); + +void *PKI_X509_get_mem_value ( PKI_MEM *mem, PKI_DATATYPE type, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ); + +PKI_X509_STACK *PKI_X509_STACK_get_mem ( PKI_MEM *mem, PKI_DATATYPE type, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ); + +/* --------------------------- PKI_MEM put ------------------------------- */ +PKI_MEM *PKI_X509_put_mem ( PKI_X509 *x, PKI_DATA_FORMAT format, + PKI_MEM **pki_mem, PKI_CRED *cred ); + +PKI_MEM *PKI_X509_put_mem_value ( void *x, PKI_DATATYPE type, PKI_MEM **mem, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ); + +PKI_MEM * PKI_X509_STACK_put_mem ( PKI_X509_STACK *sk, PKI_DATA_FORMAT format, + PKI_MEM **pki_mem, PKI_CRED *cred, HSM *hsm ); + +#endif /* _LIBPKI_PKI_X509_MEM_H */ diff --git a/include/libpki/x509/pki_x509_mime.h b/include/libpki/x509/pki_x509_mime.h new file mode 100644 index 00000000..3d512547 --- /dev/null +++ b/include/libpki/x509/pki_x509_mime.h @@ -0,0 +1,30 @@ +/* OpenCA libpki package +* (c) 2000-2006 by Massimiliano Pala and OpenCA Group +* All Rights Reserved +* +* =================================================================== +* Released under OpenCA LICENSE +*/ + +#ifndef _LIBPKI_HEADER_PKI_509_MIME_H +#define _LIBPKI_HEADER_PKI_509_MIME_H + +#define PKI_MIMETYPE_UNKNOWN "x-application/unknown" +#define PKI_MIMETYPE_KEYPAIR "x-application/x-x509-keypair" +#define PKI_MIMETYPE_PUBKEY "x-application/x-x509-pubkey" +#define PKI_MIMETYPE_PRIVKEY "x-application/x-x509-privkey" +#define PKI_MIMETYPE_CRED "x-application/x-x509-cred" +#define PKI_MIMETYPE_X509_CERT "x-application/x-x509-cert" +#define PKI_MIMETYPE_X509_CRL "x-application/x-x509-crl" +#define PKI_MIMETYPE_X509_REQ "x-application/x-x509-request" +#define PKI_MIMETYPE_X509_PKCS7 "x-application/x-x509-pkcs7" +#define PKI_MIMETYPE_X509_PKCS12 "x-application/x-x509-pkcs12" +#define PKI_MIMETYPE_X509_OCSP_REQ "x-application/x-x509-ocsp-request" +#define PKI_MIMETYPE_X509_OCSP_RESP "x-application/x-x509-ocsp-response" +#define PKI_MIMETYPE_X509_PRQP_REQ "x-application/x-x509-prqp-request" +#define PKI_MIMETYPE_X509_PRQP_RESP "x-application/x-x509-prqp-response" +#define PKI_MIMETYPE_X509_X509_XPAIR "x-application/x-x509-crossCertPair" + +const char * PKI_X509_get_mimetype ( PKI_DATATYPE type ); + +#endif /* _LIBPKI_HEADER_PKI_X509_MIME_H */ diff --git a/include/libpki/x509/pki_x509_name.h b/include/libpki/x509/pki_x509_name.h new file mode 100644 index 00000000..c81aa8f3 --- /dev/null +++ b/include/libpki/x509/pki_x509_name.h @@ -0,0 +1,30 @@ +/* pki_x509_name.h */ + +#ifndef _LIBPKI_X509_NAME_H +#define _LIBPKI_X509_NAME_H + +PKI_X509_NAME *PKI_X509_NAME_new_null ( void ); +PKI_X509_NAME *PKI_X509_NAME_new ( const char *name ); +PKI_X509_NAME *PKI_X509_NAME_add ( PKI_X509_NAME *name, const char *entry ); +PKI_X509_NAME *PKI_X509_NAME_dup ( const PKI_X509_NAME *name ); + +int PKI_X509_NAME_cmp ( const PKI_X509_NAME *a, const PKI_X509_NAME *b ); + +int PKI_X509_NAME_free( PKI_X509_NAME *name ); + +char *PKI_X509_NAME_get_parsed ( const PKI_X509_NAME *name ); + +PKI_X509_NAME_RDN **PKI_X509_NAME_get_list ( const PKI_X509_NAME *name, + PKI_X509_NAME_TYPE filter ); + +void PKI_X509_NAME_list_free ( PKI_X509_NAME_RDN **list ); + +PKI_DIGEST * PKI_X509_NAME_get_digest ( const PKI_X509_NAME *name, + const PKI_DIGEST_ALG *alg ); + +char *PKI_X509_NAME_RDN_value(PKI_X509_NAME_RDN *rdn ); +PKI_X509_NAME_TYPE PKI_X509_NAME_RDN_type_id ( const PKI_X509_NAME_RDN *rdn ); +const char *PKI_X509_NAME_RDN_type_text ( const PKI_X509_NAME_RDN *rdn ); +const char *PKI_X509_NAME_RDN_type_descr ( const PKI_X509_NAME_RDN *rdn ); + +#endif diff --git a/include/libpki/x509/pki_x509_p12.h b/include/libpki/x509/pki_x509_p12.h new file mode 100644 index 00000000..d4c7f5df --- /dev/null +++ b/include/libpki/x509/pki_x509_p12.h @@ -0,0 +1,69 @@ +/* PKI_TOKEN write/load object management */ + + +#ifndef _LIBPKI_X509_PKCS12_TOKEN_H +#define _LIBPKI_X509_PKCS12_TOKEN_H + +PKI_X509_PKCS12 *PKI_X509_PKCS12_new_null( void ); + +void PKI_X509_PKCS12_free ( PKI_X509_PKCS12*p12 ); +void PKI_X509_PKCS12_free_void ( void *p12 ); + +/* Retrieve data from a P12 */ +int PKI_X509_PKCS12_verify_cred(const PKI_X509_PKCS12 * const p12, + const PKI_CRED * const cred ); + +PKI_X509_KEYPAIR *PKI_X509_PKCS12_get_keypair( + const PKI_X509_PKCS12 * const p12, + const PKI_CRED * const cred ); + +PKI_X509_CERT *PKI_X509_PKCS12_get_cert( + const PKI_X509_PKCS12 * const p12, + const PKI_CRED *cred ); + +PKI_X509_CERT *PKI_X509_PKCS12_get_cacert( + const PKI_X509_PKCS12 * const p12, + const PKI_CRED *cred); + +PKI_X509_CERT_STACK *PKI_X509_PKCS12_get_otherCerts( + const PKI_X509_PKCS12 * const p12, + const PKI_CRED * const cred); + +/* Write a token to a URL */ +int PKI_X509_PKCS12_TOKEN_export(const PKI_TOKEN * const tk, + const URL * const url, + int format, + HSM *hsm ); + +/* PKCS12 generation tools */ +PKI_X509_PKCS12* PKI_X509_PKCS12_new( + const PKI_X509_PKCS12_DATA * const p12_data, + const PKI_CRED * const cred ); + +PKI_X509_PKCS12_DATA *PKI_X509_PKCS12_DATA_new ( void ); + +void PKI_X509_PKCS12_DATA_free ( PKI_X509_PKCS12_DATA *p12_data ); + +int PKI_X509_PKCS12_DATA_add_keypair( + PKI_X509_PKCS12_DATA *data, + const PKI_X509_KEYPAIR * const keypair, + const PKI_CRED * const cred ); + +int PKI_X509_PKCS12_DATA_add_certs( + PKI_X509_PKCS12_DATA *data, + const PKI_X509_CERT * const cert, + const PKI_X509_CERT * const cacert, + const PKI_X509_CERT_STACK * const trusted, + const PKI_CRED * const cred ); + +int PKI_X509_PKCS12_DATA_add_other_certs( + PKI_X509_PKCS12_DATA *data, + const PKI_X509_CERT_STACK * const sk, + const PKI_CRED * const cred ); + +/* -------------------------- PKCS12 PEM I/O operations ---------------- */ + +PKI_X509_PKCS12_VALUE *PEM_read_bio_PKCS12(PKI_IO *bp); +int PEM_write_bio_PKCS12(PKI_IO *bp, const PKI_X509_PKCS12_VALUE *o ); + +#endif diff --git a/include/libpki/x509/pki_x509_pkcs7.h b/include/libpki/x509/pki_x509_pkcs7.h new file mode 100644 index 00000000..452117a7 --- /dev/null +++ b/include/libpki/x509/pki_x509_pkcs7.h @@ -0,0 +1,150 @@ +/* libpki/pki_x509_pkcs7.h */ + +#ifndef _LIBPKI_X509_PKCS7_H +#define _LIBPKI_X509_PKCS7_H + +/* ---------------------- Stack and Data Types -------------------------- */ + +typedef enum { + PKI_X509_PKCS7_TYPE_UNKNOWN = NID_undef, + PKI_X509_PKCS7_TYPE_EMPTY = 1, + PKI_X509_PKCS7_TYPE_SIGNED = NID_pkcs7_signed, + PKI_X509_PKCS7_TYPE_ENCRYPTED = NID_pkcs7_enveloped, + PKI_X509_PKCS7_TYPE_SIGNEDANDENCRYPTED = NID_pkcs7_signedAndEnveloped, + PKI_X509_PKCS7_TYPE_DATA = NID_pkcs7_data, +} PKI_X509_PKCS7_TYPE; + +/* ---------------------------- Functions ------------------------------- */ + +void PKI_X509_PKCS7_free(PKI_X509_PKCS7 *p7); + +void PKI_X509_PKCS7_free_void(void *p7); + +PKI_X509_PKCS7 *PKI_X509_PKCS7_new(PKI_X509_PKCS7_TYPE type); + +PKI_X509_PKCS7_TYPE PKI_X509_PKCS7_get_type(const PKI_X509_PKCS7 * const p7); + +// CRL +int PKI_X509_PKCS7_add_crl(PKI_X509_PKCS7 * p7, + const PKI_X509_CRL * const crl); + +int PKI_X509_PKCS7_add_crl_stack(PKI_X509_PKCS7 * p7, + const PKI_X509_CRL_STACK * const crl_sk ); + +int PKI_X509_PKCS7_get_crls_num(const PKI_X509_PKCS7 * const p7); + +PKI_X509_CRL * PKI_X509_PKCS7_get_crl(const PKI_X509_PKCS7 * const p7, + int idx ); + +// Certs +int PKI_X509_PKCS7_add_cert(const PKI_X509_PKCS7 * p7, + const PKI_X509_CERT * const x); + +int PKI_X509_PKCS7_add_cert_stack(const PKI_X509_PKCS7 * p7, + const PKI_X509_CERT_STACK * const x_sk); + +int PKI_X509_PKCS7_get_certs_num(const PKI_X509_PKCS7 * const p7 ); + +PKI_X509_CERT *PKI_X509_PKCS7_get_cert(const PKI_X509_PKCS7 * const p7, + int idx ); + +int PKI_X509_PKCS7_clear_certs(const PKI_X509_PKCS7 * p7); + +// Signer +int PKI_X509_PKCS7_has_signers(const PKI_X509_PKCS7 * const p7 ); + +int PKI_X509_PKCS7_add_signer(const PKI_X509_PKCS7 * p7, + const PKI_X509_CERT * const signer, + const PKI_X509_KEYPAIR * const k, + const PKI_DIGEST_ALG * md ); + +int PKI_X509_PKCS7_add_signer_tk(PKI_X509_PKCS7 * p7, + const PKI_TOKEN * const tk, + const PKI_DIGEST_ALG * const md); + +const PKCS7_SIGNER_INFO * PKI_X509_PKCS7_get_signer_info( + const PKI_X509_PKCS7 * const p7, + int idx); + +// Cipher +int PKI_X509_PKCS7_set_cipher(const PKI_X509_PKCS7 * p7, + const PKI_CIPHER * const cipher); + +const PKI_X509_ALGOR_VALUE * PKI_X509_PKCS7_get_encode_alg( + const PKI_X509_PKCS7 * const p7); + +int PKI_X509_PKCS7_encode(const PKI_X509_PKCS7 * const p7, + unsigned char * data, + size_t size); + +PKI_MEM *PKI_X509_PKCS7_decode(const PKI_X509_PKCS7 * const p7, + const PKI_X509_KEYPAIR * const pkey, + const PKI_X509_CERT * const x); + +// Recipients +int PKI_X509_PKCS7_has_recipients(const PKI_X509_PKCS7 * const p7 ); + +int PKI_X509_PKCS7_set_recipients(const PKI_X509_PKCS7 * p7, + const PKI_X509_CERT_STACK * const x_sk); + +int PKI_X509_PKCS7_add_recipient(const PKI_X509_PKCS7 * p7, + const PKI_X509_CERT * x); + +int PKI_X509_PKCS7_get_recipients_num(const PKI_X509_PKCS7 * const p7); + +const PKCS7_RECIP_INFO * PKI_X509_PKCS7_get_recipient_info( + const PKI_X509_PKCS7 * const p7, + int idx ); + +const PKI_X509_CERT * PKI_X509_PKCS7_get_recipient_cert( + const PKI_X509_PKCS7 * const p7, + int idx ); + +// Data +PKI_MEM *PKI_X509_PKCS7_get_data(const PKI_X509_PKCS7 * const p7, + const PKI_X509_KEYPAIR * const pkey, + const PKI_X509_CERT * const x ); + +PKI_MEM *PKI_X509_PKCS7_get_data_tk(const PKI_X509_PKCS7 * const p7, + const PKI_TOKEN * const tk); + +PKI_MEM *PKI_X509_PKCS7_get_raw_data(const PKI_X509_PKCS7 * const p7 ); + + +/* ------------------------- X509_ATTRIBUTE funcs ----------------------- */ + +int PKI_X509_PKCS7_add_attribute(const PKI_X509_PKCS7 * p7, + PKI_X509_ATTRIBUTE * a); + +int PKI_X509_PKCS7_add_signed_attribute(const PKI_X509_PKCS7 * p7, + PKI_X509_ATTRIBUTE * a); + +const PKI_X509_ATTRIBUTE *PKI_X509_PKCS7_get_signed_attribute( + const PKI_X509_PKCS7 * const p7, + PKI_ID id ); + +const PKI_X509_ATTRIBUTE *PKI_X509_PKCS7_get_attribute( + const PKI_X509_PKCS7 * const p7, + PKI_ID id); + +const PKI_X509_ATTRIBUTE *PKI_X509_PKCS7_get_signed_attribute_by_name( + const PKI_X509_PKCS7 * const p7, + const char * const name ); + +const PKI_X509_ATTRIBUTE *PKI_X509_PKCS7_get_attribute_by_name( + const PKI_X509_PKCS7 * const p7, + const char * const name); + +int PKI_X509_PKCS7_delete_attribute(const PKI_X509_PKCS7 * p7, + PKI_ID id); + +int PKI_X509_PKCS7_delete_signed_attribute(const PKI_X509_PKCS7 * p7, + PKI_ID id); + +/* ------------------------------ TXT Format CB -------------------------- */ + +int PKI_X509_PKCS7_VALUE_print_bio(PKI_IO * bio, + const PKI_X509_PKCS7_VALUE * const p7val ); + +#endif + diff --git a/include/libpki/x509/pki_x509_profile.h b/include/libpki/x509/pki_x509_profile.h new file mode 100644 index 00000000..c0d832cb --- /dev/null +++ b/include/libpki/x509/pki_x509_profile.h @@ -0,0 +1,30 @@ +/* + * LibPKI - X509 Profile Management functionality + * (c) 2006-2007 by Massimiliano Pala and OpenCA Project + * OpenCA LICENSED software + * +*/ + +#ifndef __XML_TREE_H__ +#include +#endif + +#ifndef _LIBPKI_X509_PROFILE_H +#define _LIBPKI_X509_PROFILE_H + +// =========================== +// PKI_X509_PROFILE definition +// =========================== + +#define PKI_X509_PROFILE xmlDoc + +// ========== +// Prototypes +// ========== + +PKI_X509_PROFILE * PKI_X509_PROFILE_get ( char *url ); +PKI_X509_PROFILE * PKI_X509_PROFILE_write( PKI_X509_PROFILE *prof, char *url ); + +#endif + + diff --git a/include/libpki/x509/pki_x509_req.h b/include/libpki/x509/pki_x509_req.h new file mode 100644 index 00000000..0a5831b7 --- /dev/null +++ b/include/libpki/x509/pki_x509_req.h @@ -0,0 +1,64 @@ +/* PKI_X509_REQ driver specific object management */ + +#ifndef _LIBPKI_PKI_X509_REQ_H +#define _LIBPKI_PKI_X509_REQ_H + +/* Create/Destroy REQ objects */ +PKI_X509_REQ * PKI_X509_REQ_new_null ( void ); + +PKI_X509_REQ *PKI_X509_REQ_new(const PKI_X509_KEYPAIR *pkey, + const char *subj_s, + const PKI_X509_PROFILE *req_cnf, + const PKI_CONFIG *oids, + const PKI_DIGEST_ALG *digest, + HSM *hsm ); + +void PKI_X509_REQ_free( PKI_X509_REQ *x ); +void PKI_X509_REQ_free_void( void *x ); + +/* Manage extensions */ +int PKI_X509_REQ_add_extension(PKI_X509_REQ *x, PKI_X509_EXTENSION *ext); +int PKI_X509_REQ_add_extension_stack(PKI_X509_REQ *x, + PKI_X509_EXTENSION_STACK *ext); + +/* Attributes */ +int PKI_X509_REQ_add_attribute ( PKI_X509_REQ *req, PKI_X509_ATTRIBUTE *attr ); +int PKI_X509_REQ_delete_attribute ( PKI_X509_REQ *req, PKI_ID id ); +int PKI_X509_REQ_delete_attribute_by_num ( PKI_X509_REQ *req, int num ); +int PKI_X509_REQ_delete_attribute_by_name ( PKI_X509_REQ *req, char *name ); +int PKI_X509_REQ_clear_attributes ( PKI_X509_REQ *req ); +int PKI_X509_REQ_get_attributes_num (const PKI_X509_REQ *req ); + +const PKI_X509_ATTRIBUTE *PKI_X509_REQ_get_attribute(const PKI_X509_REQ *req, + PKI_ID type ); + +const PKI_X509_ATTRIBUTE *PKI_X509_REQ_get_attribute_by_num( + const PKI_X509_REQ *req, int num); + +const PKI_X509_ATTRIBUTE *PKI_X509_REQ_get_attribute_by_name( + const PKI_X509_REQ *req, + const char * name ); + +/* Retrieve Data from a REQ object */ +int PKI_X509_REQ_get_keysize ( const PKI_X509_REQ *x ); + +const void * PKI_X509_REQ_get_data ( const PKI_X509_REQ *req, + PKI_X509_DATA type ); + +const char * PKI_X509_REQ_get_parsed(const PKI_X509_REQ *req, + PKI_X509_DATA type); + +int PKI_X509_REQ_print_parsed(const PKI_X509_REQ *req, + PKI_X509_DATA type, + int fd ); + +/* Retrieve Extensions from the Request */ +int PKI_X509_REQ_get_extension_by_num(const PKI_X509_REQ *req, int num ); + +int PKI_X509_REQ_get_extension_by_oid(const PKI_X509_REQ *req, + const PKI_OID *id ); + +int PKI_X509_REQ_get_extension_by_name(const PKI_X509_REQ *req, + const char * name ); + +#endif /* _LIBPKI_PKI_X509_REQ_H */ diff --git a/include/libpki/x509/pki_x509_signature.h b/include/libpki/x509/pki_x509_signature.h new file mode 100644 index 00000000..6361e3a3 --- /dev/null +++ b/include/libpki/x509/pki_x509_signature.h @@ -0,0 +1,8 @@ +/* libpki X509_SIGNATURE header file */ + +#ifndef _LIBPKI_X509_SIGNATURE_HEADER_H +#define _LIBPKI_X509_SIGNATURE_HEADER_H + +char * PKI_X509_SIGNATURE_get_parsed ( PKI_X509_SIGNATURE *sig ); + +#endif diff --git a/include/libpki/x509/pki_x509_xpair.h b/include/libpki/x509/pki_x509_xpair.h new file mode 100644 index 00000000..01a04c6f --- /dev/null +++ b/include/libpki/x509/pki_x509_xpair.h @@ -0,0 +1,32 @@ +/* src/libpki/pki_x509_xpair.h */ + +#ifndef _LIBPKI_X509_XPAIR_ASN1_H +# include +#endif + +#ifndef _LIBPKI_X509_XPAIR_H +#define _LIBPKI_X509_XPAIR_H + +DECLARE_ASN1_FUNCTIONS(PKI_XPAIR) + +/* New functions */ +PKI_XPAIR *PKI_XPAIR_new_null ( void ); + +void PKI_XPAIR_free ( PKI_XPAIR *x ); + +void PKI_X509_XPAIR_free_void ( void *x ); +void PKI_X509_XPAIR_free ( PKI_X509_XPAIR *x ); + +PKI_X509_XPAIR *PKI_X509_XPAIR_new_null ( void ); +PKI_X509_XPAIR *PKI_X509_XPAIR_new_certs ( PKI_X509_CERT *forward, + PKI_X509_CERT *reverse ); + +/* Set functions */ +int PKI_X509_XPAIR_set_forward ( PKI_X509_XPAIR *xp, PKI_X509_CERT *cert ); +int PKI_X509_XPAIR_set_reverse ( PKI_X509_XPAIR *xp, PKI_X509_CERT *cert ); + +/* Get functions */ +PKI_X509_CERT *PKI_X509_XPAIR_get_forward ( PKI_X509_XPAIR *xp ); +PKI_X509_CERT *PKI_X509_XPAIR_get_reverse ( PKI_X509_XPAIR *xp ); + +#endif diff --git a/include/libpki/x509/pki_x509_xpair_asn1.h b/include/libpki/x509/pki_x509_xpair_asn1.h new file mode 100644 index 00000000..c52adb27 --- /dev/null +++ b/include/libpki/x509/pki_x509_xpair_asn1.h @@ -0,0 +1,19 @@ + +#ifndef _LIBPKI_X509_XPAIR_ASN1_H +#define _LIBPKI_X509_XPAIR_ASN1_H + +#define PEM_STRING_XPAIR "CROSS CERTIFICATE PAIR" + +typedef struct pki_x509_xpair_st { + PKI_X509_CERT_VALUE *forward; + PKI_X509_CERT_VALUE *reverse; +} PKI_XPAIR; + +DECLARE_ASN1_FUNCTIONS(PKI_XPAIR) + +PKI_X509_XPAIR_VALUE *d2i_PKI_XPAIR_bio ( BIO *bp, PKI_XPAIR *p ); +int i2d_PKI_XPAIR_bio(BIO *bp, PKI_XPAIR *o ); +int PEM_write_bio_PKI_XPAIR( PKI_IO *bp, PKI_XPAIR *o ); +PKI_X509_XPAIR_VALUE *PEM_read_bio_PKI_XPAIR( PKI_IO *bp ); + +#endif diff --git a/include/libpki/x509/types.h b/include/libpki/x509/types.h new file mode 100644 index 00000000..ae4afb82 --- /dev/null +++ b/include/libpki/x509/types.h @@ -0,0 +1,95 @@ +/* OpenCA libpki package +* (c) 2000-2007 by Massimiliano Pala and OpenCA Group +* All Rights Reserved +* +* =================================================================== +* Released under OpenCA LICENSE +*/ + +// Library configuration +#ifndef _LIBPKI_SYSTEM_H +#include +#endif + +#ifndef _LIBPKI_PKI_DATATYPES_H +#define _LIBPKI_PKI_DATATYPES_H + +BEGIN_C_DECLS + +/* Supported Datatype for retrieving data from an X509 data object */ +typedef enum { + PKI_X509_DATA_SERIAL = 0, + PKI_X509_DATA_VERSION, + PKI_X509_DATA_SUBJECT, + PKI_X509_DATA_ISSUER, + PKI_X509_DATA_NOTBEFORE, + PKI_X509_DATA_NOTAFTER, + PKI_X509_DATA_THISUPDATE, + PKI_X509_DATA_LASTUPDATE, + PKI_X509_DATA_NEXTUPDATE, + PKI_X509_DATA_PRODUCEDAT, + PKI_X509_DATA_ALGORITHM, + PKI_X509_DATA_KEYSIZE, + PKI_X509_DATA_KEYPAIR_VALUE, + PKI_X509_DATA_X509_PUBKEY, + PKI_X509_DATA_PUBKEY_BITSTRING, + PKI_X509_DATA_PRIVKEY, + PKI_X509_DATA_SIGNATURE, + PKI_X509_DATA_SIGNATURE_ALG1, + PKI_X509_DATA_SIGNATURE_ALG2, + PKI_X509_DATA_TBS_MEM_ASN1, + PKI_X509_DATA_SIGNER_CERT, + PKI_X509_DATA_SIGNATURE_CERTS, + PKI_X509_DATA_PRQP_SERVICES, + PKI_X509_DATA_PRQP_STATUS_STRING, + PKI_X509_DATA_PRQP_STATUS_VALUE, + PKI_X509_DATA_PRQP_REFERRALS, + PKI_X509_DATA_PRQP_CAID, + PKI_X509_DATA_NONCE, + PKI_X509_DATA_CERT_TYPE, + PKI_X509_DATA_EXTENSIONS +} PKI_X509_DATA; + +#define PKI_X509_DATA_SIZE 30 + +typedef enum { + PKI_X509_CERT_TYPE_UNKNOWN = 0, + PKI_X509_CERT_TYPE_CA = (1<<0), + PKI_X509_CERT_TYPE_USER = (1<<1), + PKI_X509_CERT_TYPE_SERVER = (1<<2), + PKI_X509_CERT_TYPE_PROXY = (1<<3), + PKI_X509_CERT_TYPE_ROOT = (1<<4) +} PKI_X509_CERT_TYPE; + +#define PKI_X509_CERT_TYPE_SIZE 6 + +/* PKI_X509 general object */ +typedef struct pki_x509_st { + + /* Type of Object - taken from PKI_DATATYPE */ + int type; + + /* Internal Value - usually the supported crypto lib internal format */ + void *value; + + /* HSM to use for operations */ + struct hsm_st *hsm; + + /* Reference URL */ + char * ref; + + /* Auxillary Data */ + void * aux_data; + + /* Callback to free auxillary data */ + void (*free_aux_data)(void *); + + /* Callback to duplicate auxillary data */ + void * (*dup_aux_data)(void *); + +} PKI_X509; + + +END_C_DECLS + +#endif diff --git a/src/crypto/artifacts/3gpp/README.md b/src/crypto/artifacts/3gpp/README.md new file mode 100644 index 00000000..d12757dd --- /dev/null +++ b/src/crypto/artifacts/3gpp/README.md @@ -0,0 +1,4 @@ +# Crypto Test Material for 3GPP + +Please add the official testing material from the 3GPP environmet. + diff --git a/src/crypto/artifacts/Makefile.am b/src/crypto/artifacts/Makefile.am new file mode 100644 index 00000000..c465f332 --- /dev/null +++ b/src/crypto/artifacts/Makefile.am @@ -0,0 +1,27 @@ +## OpenCA Makefile - by Massimiliano Pala +## (c) 1999-2024 by Massimiliano Pala and OpenCA Project +## All Rights Reserved + +TOP = .. +include $(TOP)/global-vars + +BASE_DEFS = + +DEFS = $(OPENCA_DEFS) + +AM_CPPFLAGS = -I$(TOP) \ + $(openssl_cflags) \ + $(libxml2_cflags) \ + $(COND_INCLUDES) + +SRCS = \ + pki_testing.c \ + docsis/test_keys.c \ + docsis/test_certs.c + x9f/test_keys.c \ + x9f/test_certs.c + +noinst_LTLIBRARIES = libpki-testing.la +libpki_testing_la_SOURCES = $(SRCS) +libpki_testing_la_CFLAGS = $(BUILD_LIBPKI_CFLAGS) + diff --git a/src/crypto/artifacts/docsis/README.md b/src/crypto/artifacts/docsis/README.md new file mode 100644 index 00000000..549920ff --- /dev/null +++ b/src/crypto/artifacts/docsis/README.md @@ -0,0 +1,4 @@ +# Crypto Test Material for DOCSIS + +Please add the official testing material from the DOCSIS environmet. + diff --git a/src/crypto/artifacts/docsis/docsis_test_certs.c b/src/crypto/artifacts/docsis/docsis_test_certs.c new file mode 100644 index 00000000..82cc281d --- /dev/null +++ b/src/crypto/artifacts/docsis/docsis_test_certs.c @@ -0,0 +1,2 @@ +/* DOCSIS Test Certificates */ + diff --git a/src/crypto/artifacts/docsis/docsis_test_keys.c b/src/crypto/artifacts/docsis/docsis_test_keys.c new file mode 100644 index 00000000..411bfb1b --- /dev/null +++ b/src/crypto/artifacts/docsis/docsis_test_keys.c @@ -0,0 +1,2 @@ +/* DOCSIS Test Keys */ + diff --git a/src/crypto/artifacts/matter/README.md b/src/crypto/artifacts/matter/README.md new file mode 100644 index 00000000..919ceca4 --- /dev/null +++ b/src/crypto/artifacts/matter/README.md @@ -0,0 +1,4 @@ +# Crypto Test Material for MATTER + +Please add the official testing material from the MATTER environmet. + diff --git a/src/crypto/artifacts/ocf/README.md b/src/crypto/artifacts/ocf/README.md new file mode 100644 index 00000000..982e2318 --- /dev/null +++ b/src/crypto/artifacts/ocf/README.md @@ -0,0 +1,4 @@ +# Crypto Test Material for OCF + +Please add the official testing material from the OCF environmet. + diff --git a/src/crypto/artifacts/pki_testing.c b/src/crypto/artifacts/pki_testing.c new file mode 100644 index 00000000..f648320c --- /dev/null +++ b/src/crypto/artifacts/pki_testing.c @@ -0,0 +1,278 @@ + +/* OpenCA libpki package + * (c) 2000-2012 by Massimiliano Pala and OpenCA Labs + * All Rights Reserved + * + * =================================================================== + * Released under OpenCA LICENSE + */ + +#include + +#ifdef HAVE_LIBRESOLV +#include +#include +#include +#include +#ifndef T_AAAA +#include +#endif +#include +#endif + +// get_dnsRecords() - Returns an array of char * of requested records +// @name - requested domain name +// @type - Type of records. Supported types are: +// T_A = 1 - Internet Address; +// T_NS = 2 - Name Server; +// T_MX = 15 - Mail Routing; +// T_TXT = 16 - Used for different purposes (SPF, etc.); +// T_AAAA = 28 - IPv6 Addresses; +// T_SRV = 33 - Service Records; +// T_CERT = 36 - Certificates) +// @result - Returned Array. NULL if none are found. +// +// Return value is -1 on Error and 0 on success + +/*! \brief Returns a MEM STACK with the requested DNS records */ +PKI_MEM_STACK *URL_get_data_dns_url(const URL * url, + ssize_t size) { + + PKI_MEM_STACK *ret = NULL; + +#ifdef HAVE_LIBRESOLV + + int type = T_A; + PKI_MEM *obj = NULL; + + if( (!url) || (!url->addr)) { + return NULL; + } + + unsigned char response[NS_PACKETSZ]; + + ns_msg dnsMessage; + ns_rr dnsRecord; + + int dnsRecordSection = ns_s_an; + int dns_msgCount = 0; + int len = 0; + + // Check the Type of record + if ((type = URL_get_dns_type(url->attrs)) == -1) return NULL; + + PKI_log_debug("DNS URI: Searching for %s (%s/%d)", + url->addr, url->attrs, type); + + if ((len = res_search(url->addr, C_IN, type, response, sizeof(response))) < 0) + { + // An Error Occurred + PKI_log_err("DNS URI: search failed\n"); + return NULL; + } + + if (ns_initparse(response, len, &dnsMessage) < 0) + { + // This should not happen if the record is correct + PKI_log_err("DNS URI: can not init DNS parsing of the dnsMessage\n"); + return NULL; + } + + len = ns_msg_count(dnsMessage, dnsRecordSection); + PKI_log_debug("DNS_URI: msg count ==> %d\n", len); + + if (len <= 0) return NULL; + + if((ret = PKI_STACK_MEM_new()) == NULL ) { + PKI_log_debug ("DNS URI: Memory Failure"); + return NULL; + } + + for (dns_msgCount = 0; dns_msgCount < len; dns_msgCount++) + { + PKI_log_debug("DNS URI: Retrieving DNS record #%d",dns_msgCount); + + if (ns_parserr(&dnsMessage, dnsRecordSection, dns_msgCount, &dnsRecord)) + { + // ERROR: ns_parserr failed, let's continue to the next record + PKI_log_err("DNS URI: Can not parse record %d of %d", dns_msgCount, len); + continue; + } + + PKI_log_debug("DNS URI: type = %d (req: %d)\n", ns_rr_type(dnsRecord), type); + + if (type == pki_ns_t_address) + { + switch (ns_rr_type(dnsRecord)) + { + case T_A: + case T_AAAA: + case T_CNAME: + break; + default: + continue; + } + } + else if (type != ns_rr_type(dnsRecord)) + { + PKI_log_debug("DNS URI: recived type %d is different from requested (%d)", + type, ns_rr_type(dnsRecord)); + // continue; + } + + // int i = 0; + int rv = 0; + // int len = 0; + int offset = 0; + + char dnsRecordName[MAXDNAME]; + + memset(dnsRecordName, '\x0', MAXDNAME); + // Parse the different types of DNS records + if ((ns_rr_type(dnsRecord) == T_A) || (ns_rr_type(dnsRecord) == T_AAAA)) + { + // These require Translation using IPv4/IPv6 functions + int family = AF_INET; + + if (ns_rr_type(dnsRecord) == T_A) family = AF_INET; + else family = AF_INET6; + + if(inet_ntop(family, ns_rr_rdata(dnsRecord), dnsRecordName, + sizeof(dnsRecordName)) == NULL) + { + // Can not convert + continue; + } + } + else if ((ns_rr_type(dnsRecord) == T_CNAME) || (ns_rr_type(dnsRecord) == T_MX) || + (ns_rr_type(dnsRecord) == T_NS)) + { + if (ns_rr_type(dnsRecord) == T_MX) offset = NS_INT16SZ; + + rv = ns_name_uncompress(ns_msg_base(dnsMessage), ns_msg_end(dnsMessage), + ns_rr_rdata(dnsRecord) + offset, dnsRecordName, MAXDNAME); + + // ERROR, can not uncompress the names + if (rv < 0) continue; + } + else if (ns_rr_type(dnsRecord) == T_SRV) + { + // This requires special handling, the format is [SHORT][SHORT][SHORT][DATA] + // unsigned short *pri = (unsigned short *) ns_rr_rdata(dnsRecord); + // unsigned short *weight = (unsigned short *) &(ns_rr_rdata(dnsRecord)[2]); + // unsigned short *port = (unsigned short *) &(ns_rr_rdata(dnsRecord)[4]); + + // Shall we return the additional data too ? + // printf("PRI : %d\n", *pri); + // printf("WEIGHT : %d\n", ntohs(*weight)); + // printf("PORT : %d\n", ntohs(*port)); + + offset = 6; + rv = ns_name_uncompress(ns_msg_base(dnsMessage), ns_msg_end(dnsMessage), + ns_rr_rdata(dnsRecord) + offset, dnsRecordName, MAXDNAME); + + if (rv < 0) continue; + } + else if (ns_rr_type(dnsRecord) == T_TXT) + { + // Special handling required. Format is [BYTE][DATA] + unsigned char *p = (unsigned char *)ns_rr_rdata(dnsRecord); + + snprintf(dnsRecordName, (size_t) *p+1, "%s", &ns_rr_rdata(dnsRecord)[1]); + } + else + { + PKI_log_debug("DNS URI: record type not supported [%d]", ns_rr_type(dnsRecord)); + continue; + } + + if((obj = PKI_MEM_new_null()) == NULL ) { + // Memory Allocation Error, we abort + break; + } + + if (strlen(dnsRecordName) > 0) { + // If it is a printable value, we add the parsed version of the + // record + if(PKI_MEM_add(obj, (char *) dnsRecordName, strlen(dnsRecordName)) == PKI_ERR) { + /* ERROR in memory growth */; + PKI_log_err("DNS URI: Memory Allocation Error"); + break; + } + } else { + // The value is not parsed/parsable, we return the raw data + // the application should know what to do with the data! + if(PKI_MEM_add(obj, (char *) ns_rr_rdata(dnsRecord), + ns_rr_rdlen(dnsRecord)) == PKI_ERR) { + /* ERROR in memory growth */; + PKI_log_err("DNS URI: Memory Allocation Error"); + break; + } + } + +/* + printf("MSG Data [%d]:\n", ns_rr_rdlen(dnsRecord)); + for (i=0; i < ns_rr_rdlen(dnsRecord); i++) + { + unsigned char *kk; + + kk = (unsigned char *) &ns_rr_rdata(dnsRecord)[i]; + printf("%x:", *kk); + }; + printf("\n"); + + fprintf(stderr, "DEBUG: RV => %d (err: %d, %s)\n", rv, h_errno, hstrerror(h_errno)); + fprintf(stderr, "DEBUG: name => %s (%s)\n", ns_rr_name(dnsRecord), url->addr); + fprintf(stderr, "DEBUG: value => %s\n", dnsRecordName); + fprintf(stderr, "DEBUG: type => %d\n", ns_rr_type(dnsRecord)); + fprintf(stderr, "DEBUG: class => %d\n", ns_rr_class(dnsRecord)); +*/ + + PKI_STACK_MEM_push(ret, obj); + + // PKI_log_debug("DNS URI: Added object #%d to stack", PKI_STACK_MEM_elements(ret)); + } + +#endif + + return ret; +}; + +/*! \brief Returns the type of DNS records identified by the passed char * arg */ +int URL_get_dns_type(const char *str) { + + int ret = -1; + if (!str) return ret; + +#ifdef HAVE_LIBRESOLV + + if (strncmp_nocase(str, "AAAA", 4) == 0) { + ret = T_AAAA; + } else if (strncmp_nocase(str, "A", 1) == 0) { + ret = T_A; + } else if (strncmp_nocase(str, "NS", 2) == 0) { + ret = T_NS; + } else if (strncmp_nocase(str, "MX", 2) == 0) { + ret = T_MX; + } else if (strncmp_nocase(str, "CNAME", 5) == 0) { + ret = T_CNAME; + } else if (strncmp_nocase(str, "SRV", 3) == 0) { + ret = T_SRV; + } else if (strncmp_nocase(str, "TXT", 3) == 0) { + ret = T_TXT; + } else if (strncmp_nocase(str, "CERT", 4) == 0) { + ret = T_CERT; + } else if (strncmp_nocase(str, "ANY", 3) == 0) { + ret = T_ANY; + } else if (atoi(str) > 0) { + ret = atoi(str); + } else { + PKI_log_err("DNS URI: record type (%s) not supported.", str); + } + + PKI_log_debug("DNS URI: record type (%s=%d) parsed", str, ret); +#else + PKI_log_debug("DNS URI: dns support disabled at compile time"); +#endif + return ret; +} diff --git a/src/crypto/artifacts/wba/README.md b/src/crypto/artifacts/wba/README.md new file mode 100644 index 00000000..4227ea58 --- /dev/null +++ b/src/crypto/artifacts/wba/README.md @@ -0,0 +1,4 @@ +# Crypto Test Material for WBA + +Please add the official testing material from the WBA environmet. + diff --git a/src/crypto/artifacts/webpki/README.md b/src/crypto/artifacts/webpki/README.md new file mode 100644 index 00000000..c0294955 --- /dev/null +++ b/src/crypto/artifacts/webpki/README.md @@ -0,0 +1,4 @@ +# Crypto Test Material for the Internet PKI + +Please add the official testing material from the Internet PKI environmet. + diff --git a/src/crypto/artifacts/wfa/README.md b/src/crypto/artifacts/wfa/README.md new file mode 100644 index 00000000..fa846f0c --- /dev/null +++ b/src/crypto/artifacts/wfa/README.md @@ -0,0 +1,4 @@ +# Crypto Test Material for WFA + +Please add the official testing material from the WFA environmet. + diff --git a/src/crypto/artifacts/winnforum/README.md b/src/crypto/artifacts/winnforum/README.md new file mode 100644 index 00000000..f0f92f9b --- /dev/null +++ b/src/crypto/artifacts/winnforum/README.md @@ -0,0 +1,4 @@ +# Crypto Test Material for WInnForum + +Please add the official testing material from the WInnForum environmet. + diff --git a/src/crypto/artifacts/x9f/README.md b/src/crypto/artifacts/x9f/README.md new file mode 100644 index 00000000..ffb73bae --- /dev/null +++ b/src/crypto/artifacts/x9f/README.md @@ -0,0 +1,4 @@ +# Crypto Test Material for X9F DEV PKI + +Please add the official testing material from the X9F DEV PKI environmet. + diff --git a/src/crypto/artifacts/x9f/x9f_dev_certs.c b/src/crypto/artifacts/x9f/x9f_dev_certs.c new file mode 100644 index 00000000..66debbbd --- /dev/null +++ b/src/crypto/artifacts/x9f/x9f_dev_certs.c @@ -0,0 +1,2 @@ +/* X9F DEV Certificates */ + diff --git a/src/crypto/artifacts/x9f/x9f_dev_keys.c b/src/crypto/artifacts/x9f/x9f_dev_keys.c new file mode 100644 index 00000000..be5b41a7 --- /dev/null +++ b/src/crypto/artifacts/x9f/x9f_dev_keys.c @@ -0,0 +1,2 @@ +/* X9F DEV Test Keys */ + diff --git a/src/crypto/composite/Makefile.am b/src/crypto/composite/Makefile.am new file mode 100644 index 00000000..668363f7 --- /dev/null +++ b/src/crypto/composite/Makefile.am @@ -0,0 +1,37 @@ +## OpenCA Makefile - by Massimiliano Pala +## (c) 1999-2022 by Massimiliano Pala and OpenCA Project +## All Rights Reserved + +TOP = ../.. +include $(TOP)/global-vars + +BASE_DEFS = + +DEFS = $(OPENCA_DEFS) + +AM_CPPFLAGS = -I$(TOP) \ + $(openssl_cflags) \ + $(libxml2_cflags) \ + $(COND_INCLUDES) + +OPENSSL_INTERNAL_SRCS = \ + composite_ossl_lcl.h \ + composite_ameth_lcl.h + +nobase_include_HEADERS = + +COMPOSITE_SRCS = \ + composite_key.c \ + composite_ctx.c \ + composite_ameth.c \ + composite_pmeth.c \ + composite_err.c \ + composite_utils.c \ + composite_init.c \ + $(OPENSSL_INTERNAL_SRCS) + +noinst_LTLIBRARIES = libpki-composite.la + +libpki_composite_la_SOURCES = $(COMPOSITE_SRCS) +libpki_composite_la_CFLAGS = $(BUILD_LIBPKI_CFLAGS) + diff --git a/src/crypto/composite/Makefile.in b/src/crypto/composite/Makefile.in new file mode 100644 index 00000000..bb020d70 --- /dev/null +++ b/src/crypto/composite/Makefile.in @@ -0,0 +1,901 @@ +# Makefile.in generated by automake 1.16.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = src/openssl/composite +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(nobase_include_HEADERS) \ + $(am__DIST_COMMON) +mkinstalldirs = $(SHELL) $(top_srcdir)/build/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/src/libpki/config.h \ + $(top_builddir)/src/libpki/libpki_enables.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +libpki_composite_la_LIBADD = +am__objects_1 = +am__objects_2 = libpki_composite_la-composite_key.lo \ + libpki_composite_la-composite_ctx.lo \ + libpki_composite_la-composite_ameth.lo \ + libpki_composite_la-composite_pmeth.lo \ + libpki_composite_la-composite_err.lo \ + libpki_composite_la-composite_utils.lo \ + libpki_composite_la-composite_init.lo $(am__objects_1) +am_libpki_composite_la_OBJECTS = $(am__objects_2) +libpki_composite_la_OBJECTS = $(am_libpki_composite_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libpki_composite_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(libpki_composite_la_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src/libpki +depcomp = $(SHELL) $(top_srcdir)/build/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = \ + ./$(DEPDIR)/libpki_composite_la-composite_ameth.Plo \ + ./$(DEPDIR)/libpki_composite_la-composite_ctx.Plo \ + ./$(DEPDIR)/libpki_composite_la-composite_err.Plo \ + ./$(DEPDIR)/libpki_composite_la-composite_init.Plo \ + ./$(DEPDIR)/libpki_composite_la-composite_key.Plo \ + ./$(DEPDIR)/libpki_composite_la-composite_pmeth.Plo \ + ./$(DEPDIR)/libpki_composite_la-composite_utils.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libpki_composite_la_SOURCES) +DIST_SOURCES = $(libpki_composite_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(includedir)" +HEADERS = $(nobase_include_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/build/depcomp \ + $(top_srcdir)/build/mkinstalldirs +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_DATE = @BUILD_DATE@ +BUILD_DATE_FULL = @BUILD_DATE_FULL@ +BUILD_DATE_PRETTY = @BUILD_DATE_PRETTY@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CHMOD = @CHMOD@ +CHOWN = @CHOWN@ +CP = @CP@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CPU = @CPU@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CXX = @CXX@ +CYGPATH_W = @CYGPATH_W@ +DATE = @DATE@ +DEFS = $(OPENCA_DEFS) +DEPDIR = @DEPDIR@ +DESTDIR = @DESTDIR@ +DIST_NAME = @DIST_NAME@ +DIST_VERSION = @DIST_VERSION@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +GZIP = @GZIP@ +HAS_PKGCONF = @HAS_PKGCONF@ +INSTALL = @INSTALL@ +INSTALL_BUILDER = @INSTALL_BUILDER@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKE = @MAKE@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR = @MKDIR@ +MKDIR_P = @MKDIR_P@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PDFLATEX = @PDFLATEX@ +PERL = @PERL@ +PG_CONFIG = @PG_CONFIG@ +PG_CPPFLAGS = @PG_CPPFLAGS@ +PKGMK = @PKGMK@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POD2MAN = @POD2MAN@ +PWD = @PWD@ +RANLIB = @RANLIB@ +RC = @RC@ +RPM = @RPM@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TAR = @TAR@ +TODAY = @TODAY@ +VERSION = @VERSION@ +ZIP = @ZIP@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_aux_dir = @ac_aux_dir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +arch_target = @arch_target@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +composite_cflags = @composite_cflags@ +composite_ldadd = @composite_ldadd@ +composite_ldflags = @composite_ldflags@ +conf_dir = @conf_dir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +day = @day@ +dist_group = @dist_group@ +dist_user = @dist_user@ +docdir = @docdir@ +dvidir = @dvidir@ +enable_debug = @enable_debug@ +etc_dir = @etc_dir@ +exec_prefix = @exec_prefix@ +extra_checks = @extra_checks@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +hr = @hr@ +htmldir = @htmldir@ +iface_age = @iface_age@ +iface_current = @iface_current@ +iface_revision = @iface_revision@ +iface_version = @iface_version@ +include_dir = @include_dir@ +include_prefix = @include_prefix@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +kmf_cflags = @kmf_cflags@ +kmf_ldadd = @kmf_ldadd@ +kmf_libflags = @kmf_libflags@ +kmf_prefix = @kmf_prefix@ +ldap_cflags = @ldap_cflags@ +ldap_ldadd = @ldap_ldadd@ +ldap_ldflags = @ldap_ldflags@ +ldap_prefix = @ldap_prefix@ +ldap_vendor = @ldap_vendor@ +lib_major = @lib_major@ +lib_micro = @lib_micro@ +lib_minor = @lib_minor@ +lib_prefix = @lib_prefix@ +lib_revision = @lib_revision@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libpki_cflags = @libpki_cflags@ +libpki_ldadd = @libpki_ldadd@ +libpki_ldflags = @libpki_ldflags@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +min = @min@ +mkdir_p = @mkdir_p@ +mon = @mon@ +my_cflags = @my_cflags@ +my_ldadd = @my_ldadd@ +my_ldflags = @my_ldflags@ +myarch = @myarch@ +mybits = @mybits@ +mybits_install = @mybits_install@ +mysql_cflags = @mysql_cflags@ +mysql_config = @mysql_config@ +mysql_ldadd = @mysql_ldadd@ +mysql_ldflags = @mysql_ldflags@ +mysql_prefix = @mysql_prefix@ +oldincludedir = @oldincludedir@ +openssl_cflags = @openssl_cflags@ +openssl_include = @openssl_include@ +openssl_ldadd = @openssl_ldadd@ +openssl_ldflags = @openssl_ldflags@ +openssl_prefix = @openssl_prefix@ +openssl_static_libs = @openssl_static_libs@ +oqs_cflags = @oqs_cflags@ +oqs_ldadd = @oqs_ldadd@ +oqs_ldflags = @oqs_ldflags@ +oqsprov_cflags = @oqsprov_cflags@ +oqsprov_ldadd = @oqsprov_ldadd@ +oqsprov_ldflags = @oqsprov_ldflags@ +package_build = @package_build@ +package_prefix = @package_prefix@ +pdfdir = @pdfdir@ +pg_cflags = @pg_cflags@ +pg_config = @pg_config@ +pg_ldadd = @pg_ldadd@ +pg_ldflags = @pg_ldflags@ +pg_prefix = @pg_prefix@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pthread_opts = @pthread_opts@ +resolv_ldadd = @resolv_ldadd@ +rpath = @rpath@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sdkver = @sdkver@ +sec = @sec@ +sharedstatedir = @sharedstatedir@ +shlext = @shlext@ +shlib_history = @shlib_history@ +shlib_version = @shlib_version@ +srcdir = @srcdir@ +sys_cflags = @sys_cflags@ +sys_ldadd = @sys_ldadd@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +test_libs = @test_libs@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +txt_revision = @txt_revision@ +xml2_cflags = @xml2_cflags@ +xml2_config = @xml2_config@ +xml2_include = @xml2_include@ +xml2_ldadd = @xml2_ldadd@ +xml2_ldflags = @xml2_ldflags@ +xml2_prefix = @xml2_prefix@ +yr = @yr@ +TOP = ../.. +BASE_DEFS = +AM_CPPFLAGS = -I$(TOP) \ + $(openssl_cflags) \ + $(libxml2_cflags) \ + $(COND_INCLUDES) + +OPENSSL_INTERNAL_SRCS = \ + composite_ossl_lcl.h \ + composite_ameth_lcl.h + +nobase_include_HEADERS = +COMPOSITE_SRCS = \ + composite_key.c \ + composite_ctx.c \ + composite_ameth.c \ + composite_pmeth.c \ + composite_err.c \ + composite_utils.c \ + composite_init.c \ + $(OPENSSL_INTERNAL_SRCS) + +noinst_LTLIBRARIES = libpki-composite.la +libpki_composite_la_SOURCES = $(COMPOSITE_SRCS) +libpki_composite_la_CFLAGS = $(BUILD_LIBPKI_CFLAGS) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/openssl/composite/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/openssl/composite/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libpki-composite.la: $(libpki_composite_la_OBJECTS) $(libpki_composite_la_DEPENDENCIES) $(EXTRA_libpki_composite_la_DEPENDENCIES) + $(AM_V_CCLD)$(libpki_composite_la_LINK) $(libpki_composite_la_OBJECTS) $(libpki_composite_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_composite_la-composite_ameth.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_composite_la-composite_ctx.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_composite_la-composite_err.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_composite_la-composite_init.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_composite_la-composite_key.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_composite_la-composite_pmeth.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_composite_la-composite_utils.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +libpki_composite_la-composite_key.lo: composite_key.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_composite_la_CFLAGS) $(CFLAGS) -MT libpki_composite_la-composite_key.lo -MD -MP -MF $(DEPDIR)/libpki_composite_la-composite_key.Tpo -c -o libpki_composite_la-composite_key.lo `test -f 'composite_key.c' || echo '$(srcdir)/'`composite_key.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_composite_la-composite_key.Tpo $(DEPDIR)/libpki_composite_la-composite_key.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='composite_key.c' object='libpki_composite_la-composite_key.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_composite_la_CFLAGS) $(CFLAGS) -c -o libpki_composite_la-composite_key.lo `test -f 'composite_key.c' || echo '$(srcdir)/'`composite_key.c + +libpki_composite_la-composite_ctx.lo: composite_ctx.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_composite_la_CFLAGS) $(CFLAGS) -MT libpki_composite_la-composite_ctx.lo -MD -MP -MF $(DEPDIR)/libpki_composite_la-composite_ctx.Tpo -c -o libpki_composite_la-composite_ctx.lo `test -f 'composite_ctx.c' || echo '$(srcdir)/'`composite_ctx.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_composite_la-composite_ctx.Tpo $(DEPDIR)/libpki_composite_la-composite_ctx.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='composite_ctx.c' object='libpki_composite_la-composite_ctx.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_composite_la_CFLAGS) $(CFLAGS) -c -o libpki_composite_la-composite_ctx.lo `test -f 'composite_ctx.c' || echo '$(srcdir)/'`composite_ctx.c + +libpki_composite_la-composite_ameth.lo: composite_ameth.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_composite_la_CFLAGS) $(CFLAGS) -MT libpki_composite_la-composite_ameth.lo -MD -MP -MF $(DEPDIR)/libpki_composite_la-composite_ameth.Tpo -c -o libpki_composite_la-composite_ameth.lo `test -f 'composite_ameth.c' || echo '$(srcdir)/'`composite_ameth.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_composite_la-composite_ameth.Tpo $(DEPDIR)/libpki_composite_la-composite_ameth.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='composite_ameth.c' object='libpki_composite_la-composite_ameth.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_composite_la_CFLAGS) $(CFLAGS) -c -o libpki_composite_la-composite_ameth.lo `test -f 'composite_ameth.c' || echo '$(srcdir)/'`composite_ameth.c + +libpki_composite_la-composite_pmeth.lo: composite_pmeth.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_composite_la_CFLAGS) $(CFLAGS) -MT libpki_composite_la-composite_pmeth.lo -MD -MP -MF $(DEPDIR)/libpki_composite_la-composite_pmeth.Tpo -c -o libpki_composite_la-composite_pmeth.lo `test -f 'composite_pmeth.c' || echo '$(srcdir)/'`composite_pmeth.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_composite_la-composite_pmeth.Tpo $(DEPDIR)/libpki_composite_la-composite_pmeth.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='composite_pmeth.c' object='libpki_composite_la-composite_pmeth.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_composite_la_CFLAGS) $(CFLAGS) -c -o libpki_composite_la-composite_pmeth.lo `test -f 'composite_pmeth.c' || echo '$(srcdir)/'`composite_pmeth.c + +libpki_composite_la-composite_err.lo: composite_err.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_composite_la_CFLAGS) $(CFLAGS) -MT libpki_composite_la-composite_err.lo -MD -MP -MF $(DEPDIR)/libpki_composite_la-composite_err.Tpo -c -o libpki_composite_la-composite_err.lo `test -f 'composite_err.c' || echo '$(srcdir)/'`composite_err.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_composite_la-composite_err.Tpo $(DEPDIR)/libpki_composite_la-composite_err.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='composite_err.c' object='libpki_composite_la-composite_err.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_composite_la_CFLAGS) $(CFLAGS) -c -o libpki_composite_la-composite_err.lo `test -f 'composite_err.c' || echo '$(srcdir)/'`composite_err.c + +libpki_composite_la-composite_utils.lo: composite_utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_composite_la_CFLAGS) $(CFLAGS) -MT libpki_composite_la-composite_utils.lo -MD -MP -MF $(DEPDIR)/libpki_composite_la-composite_utils.Tpo -c -o libpki_composite_la-composite_utils.lo `test -f 'composite_utils.c' || echo '$(srcdir)/'`composite_utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_composite_la-composite_utils.Tpo $(DEPDIR)/libpki_composite_la-composite_utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='composite_utils.c' object='libpki_composite_la-composite_utils.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_composite_la_CFLAGS) $(CFLAGS) -c -o libpki_composite_la-composite_utils.lo `test -f 'composite_utils.c' || echo '$(srcdir)/'`composite_utils.c + +libpki_composite_la-composite_init.lo: composite_init.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_composite_la_CFLAGS) $(CFLAGS) -MT libpki_composite_la-composite_init.lo -MD -MP -MF $(DEPDIR)/libpki_composite_la-composite_init.Tpo -c -o libpki_composite_la-composite_init.lo `test -f 'composite_init.c' || echo '$(srcdir)/'`composite_init.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_composite_la-composite_init.Tpo $(DEPDIR)/libpki_composite_la-composite_init.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='composite_init.c' object='libpki_composite_la-composite_init.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_composite_la_CFLAGS) $(CFLAGS) -c -o libpki_composite_la-composite_init.lo `test -f 'composite_init.c' || echo '$(srcdir)/'`composite_init.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-nobase_includeHEADERS: $(nobase_include_HEADERS) + @$(NORMAL_INSTALL) + @list='$(nobase_include_HEADERS)'; test -n "$(includedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \ + fi; \ + $(am__nobase_list) | while read dir files; do \ + xfiles=; for file in $$files; do \ + if test -f "$$file"; then xfiles="$$xfiles $$file"; \ + else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ + test -z "$$xfiles" || { \ + test "x$$dir" = x. || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(includedir)/$$dir'"; \ + $(MKDIR_P) "$(DESTDIR)$(includedir)/$$dir"; }; \ + echo " $(INSTALL_HEADER) $$xfiles '$(DESTDIR)$(includedir)/$$dir'"; \ + $(INSTALL_HEADER) $$xfiles "$(DESTDIR)$(includedir)/$$dir" || exit $$?; }; \ + done + +uninstall-nobase_includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(nobase_include_HEADERS)'; test -n "$(includedir)" || list=; \ + $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ + dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(includedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/libpki_composite_la-composite_ameth.Plo + -rm -f ./$(DEPDIR)/libpki_composite_la-composite_ctx.Plo + -rm -f ./$(DEPDIR)/libpki_composite_la-composite_err.Plo + -rm -f ./$(DEPDIR)/libpki_composite_la-composite_init.Plo + -rm -f ./$(DEPDIR)/libpki_composite_la-composite_key.Plo + -rm -f ./$(DEPDIR)/libpki_composite_la-composite_pmeth.Plo + -rm -f ./$(DEPDIR)/libpki_composite_la-composite_utils.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-nobase_includeHEADERS + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/libpki_composite_la-composite_ameth.Plo + -rm -f ./$(DEPDIR)/libpki_composite_la-composite_ctx.Plo + -rm -f ./$(DEPDIR)/libpki_composite_la-composite_err.Plo + -rm -f ./$(DEPDIR)/libpki_composite_la-composite_init.Plo + -rm -f ./$(DEPDIR)/libpki_composite_la-composite_key.Plo + -rm -f ./$(DEPDIR)/libpki_composite_la-composite_pmeth.Plo + -rm -f ./$(DEPDIR)/libpki_composite_la-composite_utils.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-nobase_includeHEADERS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-noinstLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man \ + install-nobase_includeHEADERS install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am \ + uninstall-nobase_includeHEADERS + +.PRECIOUS: Makefile + +include $(TOP)/global-vars + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/crypto/composite/composite_ameth.c b/src/crypto/composite/composite_ameth.c new file mode 100644 index 00000000..e1f865b6 --- /dev/null +++ b/src/crypto/composite/composite_ameth.c @@ -0,0 +1,1686 @@ +/* BEGIN: composite_amenth.c */ + +// Composite Crypto authentication methods. +// (c) 2021 by Massimiliano Pala + +#pragma GCC diagnostic ignored "-Wunused-function" + +// Local Include +#include "composite_ameth_lcl.h" + +#include + +// =============== +// Data Structures +// =============== + +#ifndef _LIBPKI_COMPOSITE_OPENSSL_LOCAL_H +#include "composite_ossl_lcl.h" +#endif + +// ====================== +// MACRO & Other Oddities +// ====================== + +#define DEBUG(args...) \ + { fprintf(stderr, "[%s:%d] %s() - ", __FILE__, __LINE__, __func__) ; \ + fprintf(stderr, ## args) ; fprintf(stderr,"\n") ; fflush(stderr); } + +#ifdef ENABLE_COMPOSITE + +// ============================== +// EVP_PKEY_ASN1_METHOD Functions +// ============================== + +// Implemented +int pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) { + + // Strategy: + // + // Get the COMPOSITE_KEY and decode each EVP_PKEY from + // each of the X509_PUBKEY that is encoded in ASN1_OCTET_STRING + // from the generic sequence + + EVP_PKEY * tmp_pkey = NULL; + // Containers for the different + // encodings of the components + + X509_PUBKEY * tmp_pub = NULL; + // Pointer to individual components + // X509_PUBKEY structure + + STACK_OF(ASN1_TYPE) *sk = NULL; + // Stack of ASN1_OCTET_STRINGs + + COMPOSITE_KEY * comp_key = NULL; + // Pointer to the Composite Key + // (just a STACK_OF(EVP_PKEY)) + + ASN1_TYPE * aType = NULL; + // ASN1 generic wrapper + + ASN1_BIT_STRING aBitStr; + // Temp Octet Pointer + + const void *params_value = NULL; + // Value for the parameters + + const unsigned char *param_der = NULL; + int param_len = 0; + // Buffer + + X509_ALGOR * pkey_alg = NULL; + int pkey_type = 0; + // Public Key Type and Algorithms + + // Input Checking + if (!pkey || !pubkey) return 0; + + // Let's use the aOctetStr to avoid the internal + // p8 pointers to be modified + aBitStr.data = pubkey->public_key->data; + aBitStr.length = pubkey->public_key->length; + + // Gets the Sequence from the data itself, error if + // it is not a sequence of ASN1_OCTET_STRING + if ((sk = d2i_ASN1_SEQUENCE_ANY(NULL, + (const unsigned char **)&aBitStr.data, + aBitStr.length)) <= 0) { + PKI_ERROR(PKI_ERR_GENERAL, "Cannot decode the composite key"); + return 0; + } + + // Allocates Memory for the inner key structure + if ((comp_key = COMPOSITE_KEY_new()) == NULL) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Cannot allocate a new composite key internal structure"); + goto err; + } + + // Process each component + for (int i = 0; i < sk_ASN1_TYPE_num(sk); i++) { + + // Retrieve the value + if ((aType = sk_ASN1_TYPE_value(sk, i)) == NULL) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Cannot get the ASN1_TYPE for key #%d", i); + goto err; + } + + // Checks we got the right type + if ((aType->type != V_ASN1_SEQUENCE) || (aType->value.sequence == NULL)) { + PKI_ERROR(PKI_ERR_PARAM_TYPE, "Composite key encoding error (expecting OCTET STRINGs for component #%d)", i); + goto err; + } + + // Sets the Pointers so that our original ones + // are not moved (can cause memory issues) + aBitStr.data = aType->value.sequence->data; + aBitStr.length = aType->value.sequence->length; + + // Retrieve the EVP_PKEY from the ASN1_TYPE + if ((tmp_pub = d2i_X509_PUBKEY(NULL, + (const unsigned char **)&(aBitStr.data), + (long)aBitStr.length)) == NULL) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_DECODE, "Cannot decode X509_PUBKEY of Key #%d", i); + goto err; + } + + if ((tmp_pkey = X509_PUBKEY_get(tmp_pub)) == NULL) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Cannot retrieve the public key for component #%d", i); + goto err; + } + + // Here we can free the X509_PUBKEY structure + X509_PUBKEY_free(tmp_pub); + tmp_pub = NULL; // Safety + + // Add the component to the key + if (!COMPOSITE_KEY_push(comp_key, tmp_pkey)) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Cannot add component #%d to the composite key", i); + goto err; + } + } + + // Assigns the key in the EVP_PKEY structure + if (!EVP_PKEY_assign_COMPOSITE(pkey, comp_key)) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "pkey = %p, pkey->pkey = %p, comp_key = %p", pkey, pkey->pkey, comp_key); + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Cannot assign internal composite key structure to the key"); + PKI_DEBUG("OpenSSL Error: %s", HSM_get_errdesc(HSM_get_errno(NULL), NULL)); + goto err; + } + + // Free the stack memory + // while ((aType = sk_ASN1_TYPE_pop(sk)) != NULL) { + // ASN1_TYPE_free(aType); + // } sk_ASN1_TYPE_free(sk); + + if (sk) sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); + sk = NULL; // Safety + + // ====================== + // Process Key Parameters + // ====================== + + // Retrieves the Public Key parameter + if (!X509_PUBKEY_get0_param(NULL, + ¶m_der, + ¶m_len, + &pkey_alg, + pubkey)) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_DECODE, "Cannot get the public key parameters"); + return 0; + }; + + // Gets the type and the parameters + X509_ALGOR_get0(NULL, &pkey_type, ¶ms_value, pkey_alg); + if (params_value) { + // If we have parameters, we need to save them to the key + if ((comp_key->params = ASN1_INTEGER_dup((ASN1_INTEGER *)params_value)) == NULL) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Cannot duplicate the parameters"); + goto err; + } + } + + // All Done. + return 1; + +err: + + if (sk) sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); + sk = NULL; + + // Free the Composite Key + if (comp_key) COMPOSITE_KEY_free(comp_key); + + // Error Condition + return 0; + +} + +// Implemented +int pub_encode(X509_PUBKEY *pub, const EVP_PKEY *pk) { + + + // Strategy: + // + // Get the COMPOSITE_KEY and encode each EVP_PKEY in a + // separate X509_PUBKEY that is placed in an ASN1_OCTET_STRING + // and then added to the generic SEQUENCE + // + // struct X509_pubkey_st { + // X509_ALGOR *algor; + // ASN1_BIT_STRING *public_key; + // EVP_PKEY *pkey; + // }; + // + // Small Comments for ASN1_TYPE - The Structure is defined + // in openssl/asn1.h and it is basically a type (int) and + // a value (union). The value.sequence() is where you can + // put the sequence to get encoded + + + EVP_PKEY * tmp_pkey = NULL; + // Containers for the different + // encodings of the components + + X509_PUBKEY * tmp_pubkey = NULL; + // Temp Structure for Privkey component + + STACK_OF(ASN1_TYPE) *sk = NULL; + // Stack of ASN1_OCTET_STRINGs + + COMPOSITE_KEY * comp_key = NULL; + // Pointer to the Composite Key + // (just a STACK_OF(EVP_PKEY)) + + ASN1_BIT_STRING * bit_string = NULL; + // Output Buffer + + ASN1_TYPE * aType = NULL; + // ASN1 generic wrapper + + unsigned char * buff = NULL; + int buff_len = 0; + // Temporary Storage for ASN1 data + + ASN1_INTEGER * key_param = NULL; + int key_param_type = V_ASN1_UNDEF; + // K of N parameter + + // Input Checking + if (!pub || !pk) return 0; + + + // First we should encode the parameters, however + // in Composite, we do not have parameters, so we + // can omit them entirely + + // Gets the Key Bytes + if ((comp_key = EVP_PKEY_get0(pk)) == NULL) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Cannot get the Key Inner Structure"); + return 0; + } + + if ((sk = sk_ASN1_TYPE_new_null()) == NULL) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Cannot allocate a new stack of ASN1 Types"); + if (key_param) ASN1_INTEGER_free(key_param); + return 0; + } + + // Gets the P8 info for each key and + // adds it to the output stack + for (int i = 0; i < COMPOSITE_KEY_num(comp_key); i++) { + + // Get the component of the key + if ((tmp_pkey = COMPOSITE_KEY_get0(comp_key, i)) == NULL) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Cannot access [%d] component of the key", i); + goto err; + } + + if (tmp_pkey->ameth->pub_encode == NULL) { + PKI_ERROR(PKI_ERR_GENERAL, "Key %d of alg %d does not have a pub_encode ameth.", + i, tmp_pkey->ameth->pkey_id); + goto err; + } + + // Sets the Public Key + if(!X509_PUBKEY_set(&tmp_pubkey, tmp_pkey)) { + PKI_ERROR(PKI_ERR_ALGOR_SET, "ERROR: Cannot set the PUBKEY for component #%d", i); + goto err; + } + + // Encodes the PUBLIC key + if ((buff_len = i2d_X509_PUBKEY(tmp_pubkey, &buff)) <= 0) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_ENCODE, "Cannot ASN1 encode the [%d] component of the key", i); + goto err; + } + + // Generates the wrapping string + if ((bit_string = ASN1_OCTET_STRING_new()) == NULL) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Cannot allocate a new OCTET string for component %d", i); + goto err; + } + + // This sets and transfer ownership + ASN1_STRING_set0(bit_string, buff, buff_len); + + // Resets the pointer and length after ownership transfer + buff = NULL; buff_len = 0; + + // Let's free the X509_PUBKEY structure + X509_PUBKEY_free(tmp_pubkey); + tmp_pubkey = NULL; + + // Let's now generate the ASN1_TYPE and add it to the stack + if ((aType = ASN1_TYPE_new()) == NULL) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Cannot allocate a new ASN1 Type"); + goto err; + } + + // Transfer Ownership to the aType structure + ASN1_TYPE_set(aType, V_ASN1_SEQUENCE, bit_string); + bit_string = NULL; + + // Adds the component to the stack + if (!sk_ASN1_TYPE_push(sk, aType)) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Cannot add the new Type to the stack of public keys"); + goto err; + } + + } + + // Encodes the Sequence + if ((buff_len = i2d_ASN1_SEQUENCE_ANY(sk, &buff)) <= 0) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_ENCODE, "Cannot ASN1 encode the stack of public keys"); + goto err; + } + + // Free the stack's memory + if (sk) sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); + sk = NULL; + + // Encode the parameters (if any) + if (comp_key->params) { + PKI_DEBUG("Detected k-of-n parameter, processing it...\n"); + key_param_type = V_ASN1_INTEGER; + key_param = ASN1_INTEGER_dup(comp_key->params); + if (!key_param) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Cannot duplicate the key parameters"); + return 0; + } + } + + // We do not have parameters + if (!X509_PUBKEY_set0_param(pub, OBJ_nid2obj(pk->ameth->pkey_id), + key_param_type, key_param, + buff, buff_len)) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_ENCODE, "Cannot encode the parameter"); + goto err; + } + + // All Done + return 1; + +err: + + // Free allocated memory + if (key_param) ASN1_INTEGER_free(key_param); + if (buff && buff_len >= 0) OPENSSL_secure_clear_free(buff, (size_t) buff_len); + if (bit_string) ASN1_BIT_STRING_free(bit_string); + if (aType) ASN1_TYPE_free(aType); + + if (sk) { + while ((aType = sk_ASN1_TYPE_pop(sk)) == NULL) { + ASN1_TYPE_free(aType); + } + sk_ASN1_TYPE_free(sk); + sk = NULL; + } + + // Error Condition + return 0; +} + +// Implemented +int pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { + + // Strategy: We compare all keys from the two different + // COMPOSITE_KEY within the EVP_PKEY ptr. If any difference, + // we return !0 + + COMPOSITE_KEY * comp_a = NULL; + COMPOSITE_KEY * comp_b = NULL; + // Pointers to inner data structures + + int ret = 0; + // Return value + + // Input checks + if (!a || !a->ameth || !b || !b->ameth) return -1; + + if (((comp_a = EVP_PKEY_get0(a)) == NULL) || + ((comp_b = EVP_PKEY_get0(b)) == NULL)) { + // If any of the two is NULL, we return -1 + return -1; + } + + // Checks both have (or not) parameters + if ((comp_a->params && !comp_b->params) || + (!comp_a->params && comp_b->params) ) { + // If one has parameters and the other not, we + // return an error + return -1; + } + + // Checks the parameters + if (ASN1_INTEGER_cmp(comp_a->params, comp_b->params) != 0) { + // If the parameters are different, we return -1 + return -1; + } + + // If the number of keys is different, we return -1 + if (COMPOSITE_KEY_num(comp_a) != COMPOSITE_KEY_num(comp_b)) { + return -1; + } + + // Compares all components + for (int i = 0; i < COMPOSITE_KEY_num(comp_b); i++) { + + // 'get0' returns the i-th EVP_PKEY, then we apply + // the call to the two returned ones from a and b + + ret = EVP_PKEY_cmp( + COMPOSITE_KEY_get0(comp_a, i), + COMPOSITE_KEY_get0(comp_b, i)); + + if (ret != 0) return ret; + } + + return 0; +} + +// Implemented +int pub_print(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) { + + COMPOSITE_KEY * comp_key = NULL; + + if ((comp_key = EVP_PKEY_get0(pkey)) == NULL) + return 0; + + if (!BIO_indent(out, indent, 128)) + return 0; + + PKI_ID pkey_id = PKI_X509_KEYPAIR_VALUE_get_id(pkey); + + BIO_printf(out, "Composite Public Alternative Keys (%d Equivalent Keys):\n", + COMPOSITE_KEY_num(comp_key)); + + for (int i = 0; i < COMPOSITE_KEY_num(comp_key); i++) { + + EVP_PKEY * tmp_pkey = NULL; + + if ((tmp_pkey = COMPOSITE_KEY_get0(comp_key, i)) == NULL) { + BIO_printf(out, "%*s", indent, ""); + BIO_printf(out, "Public Key Component #%d (UNKNOWN): \n", i); + continue; + } + + BIO_printf(out, "%*s", indent, ""); + BIO_printf(out, "[%d] Public Key Component (%s):\n", + i, OBJ_nid2ln(tmp_pkey->ameth->pkey_id)); + + if (tmp_pkey->ameth->pub_print) { + tmp_pkey->ameth->pub_print(out, tmp_pkey, indent + 8, pctx); + } else { + BIO_printf(out, " \n"); + } + } + + if (PKI_ID_is_composite(pkey_id, NULL) +#ifdef ENABLE_COMBINED + || PKI_ID_is_comined(pkey_id, NULL) +#endif + ) { + BIO_printf(out, "%*s", indent, ""); + BIO_printf(out, "Required Valid Components Signatures (K-of-N): %ld (%ld-%d)\n", + comp_key->params ? ASN1_INTEGER_get(comp_key->params) : -1, + comp_key->params ? ASN1_INTEGER_get(comp_key->params) : COMPOSITE_KEY_num(comp_key), + COMPOSITE_KEY_num(comp_key)); + } + + return 1; +} + +// Implemented +int priv_decode(EVP_PKEY *pk, const PKCS8_PRIV_KEY_INFO *p8) { + + // Strategy: + // + // GET the DER representation from the p8 info + // then we can use the d21_ASN1_SEQUENCE_ANY() to get + // the stack of P8. + // + // For each of the P8, we use the EVP_PKCS82PKEY() to + // retrieve the corresponding PKEY. Once we have that, + // we add it to the internal structure of the 'pk' param + // + // UPDATE: Let's look at using the auto type function, + // which is crypto/asn1/d2i_pr.c: + // + // EVP_PKEY *d2i_AutoPrivateKey( + // EVP_PKEY **a, + // const unsigned char **pp, + // long length) + // + // The P8 structure is quite simple and it is available + // in includes/openssl/x509.h: + // + // struct pkcs8_priv_key_info_st { + // ASN1_INTEGER *version; + // X509_ALGOR *pkeyalg; + // ASN1_OCTET_STRING *pkey; + // STACK_OF(X509_ATTRIBUTE) *attributes; + // }; + + EVP_PKEY * tmp_pkey = NULL; + // Containers for the different + // encodings of the components + + STACK_OF(ASN1_TYPE) *sk = NULL; + // Stack of ASN1_OCTET_STRINGs + + COMPOSITE_KEY * comp_key = NULL; + // Pointer to the Composite Key + // (just a STACK_OF(EVP_PKEY)) + + ASN1_TYPE * aType = NULL; + // ASN1 generic wrapper + + ASN1_OCTET_STRING inBitStr; + // Temp Octet Pointer + + ASN1_OCTET_STRING outBitStr; + // Temp BitString Pointer + + const void *params_value = NULL; + // Value for the parameters + + const unsigned char *param_der = NULL; + int param_len = 0; + // Buffer + + const ASN1_OBJECT * alg_oid; + const X509_ALGOR * pkey_alg; + int param_type = 0; + // Public Key Type and Algorithms + + // Input Checking + if (!p8 || !pk) return 0; + + // Let's use the aOctetStr to avoid the internal + // p8 pointers to be modified + outBitStr.data = p8->pkey->data; + outBitStr.length = p8->pkey->length; + + // Gets the Sequence from the data itself, error if + // it is not a sequence of ASN1_OCTET_STRING + if ((sk = d2i_ASN1_SEQUENCE_ANY(NULL, + (const unsigned char **)&outBitStr.data, + outBitStr.length)) <= 0) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_DECODE, "Cannot decode the composite key"); + return 0; + } + + // Allocates Memory for the inner key structure + if ((comp_key = COMPOSITE_KEY_new()) == NULL) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Cannot allocate a new internal composite key structure"); + goto err; + } + + // Process the internal components + for (int i = 0; i < sk_ASN1_TYPE_num(sk); i++) { + + // Gets the single values + if ((aType = sk_ASN1_TYPE_value(sk, i)) == NULL) { + PKI_ERROR(PKI_ERR_DATA_ASN1_ENCODING, "Cannot get the ASN1_TYPE for key #%d", i); + goto err; + } + + // Checks we got the right type + if ((aType->type != V_ASN1_SEQUENCE) || (aType->value.sequence == NULL)) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_DECODE, "Decoding error on key component #%d", i); + goto err; + } + + // Sets the Pointers so that our original ones + // are not moved (can cause memory issues) + inBitStr.data = aType->value.sequence->data; + inBitStr.length = aType->value.sequence->length; + + // Retrieve the EVP_PKEY from the ASN1_TYPE + if ((tmp_pkey = d2i_AutoPrivateKey(NULL, + (const unsigned char **)&(inBitStr.data), + (long)inBitStr.length)) == NULL) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_DECODE, "Cannot decode key component #%d", i); + goto err; + } + + // Add the component to the key + if (!COMPOSITE_KEY_push(comp_key, tmp_pkey)) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Cannot add component key #%d", i); + goto err; + } + } + + // ====================== + // Process Key Parameters + // ====================== + + // Retrieves the Public Key parameter + if (!PKCS8_pkey_get0(NULL, + ¶m_der, + ¶m_len, + &pkey_alg, + p8)) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_DECODE, "Cannot get the public key parameters"); + return 0; + }; + + // Gets the type and the parameters + X509_ALGOR_get0(&alg_oid, ¶m_type, ¶ms_value, pkey_alg); + if (params_value) { + + // Free current allocated params, if any + if (comp_key->params) ASN1_INTEGER_free(comp_key->params); + comp_key->params = NULL; + + // If we have parameters, we need to save them to the key + if ((comp_key->params = ASN1_INTEGER_dup((ASN1_INTEGER *)params_value)) == NULL) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Cannot duplicate the parameters"); + goto err; + } + } + + // Let's Get the PKEY and MD algorithms + comp_key->algorithm = OBJ_obj2nid(alg_oid); + if (comp_key->algorithm == NID_undef) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_DECODE, "Cannot decode the private key algorithm"); + goto err; + } + + PKI_DEBUG("GOT THE KEY Algorithm OID (%d)", comp_key->algorithm); + // if (alg_oid) comp_key->algorithm = OBJ_obj2nid(alg_oid); + + // // Free the stack memory + // while ((aType = sk_ASN1_TYPE_pop(sk)) != NULL) { + // ASN1_TYPE_free(aType); + // } sk_ASN1_TYPE_free(sk); + // sk = NULL; // Safety + if (sk) sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); + sk = NULL; + + // Assigns the internal structure to the EVP key + if (!EVP_PKEY_assign_COMPOSITE(pk, comp_key)) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Cannot assign Composite Key to EVP_PKEY!"); + goto err; + } + + // All Done + return 1; + +err: + + // Free the Stack of ASN1_TYPE + while ((sk != NULL) && + (aType = sk_ASN1_TYPE_pop(sk)) != NULL) { + ASN1_TYPE_free(aType); + } sk_ASN1_TYPE_free(sk); + + // Free the Composite Key + if (comp_key) COMPOSITE_KEY_free(comp_key); + + // Error Condition + return 0; +} + +// Implemented +int priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk) { + + // Strategy: + // + // GET the DER representation of the different keys + // by using the same function EVP_PKEY2PKCS8(pkey), + // then you can use the PKCS8_pkey_get0() to get the + // binary representation (ASN1_OCTET_STRING) + // put them into the p8/ + // + // Small Comments for ASN1_TYPE - The Structure is defined + // in openssl/asn1.h and it is basically a type (int) and + // a value (union). The value.sequence() is where you can + // put the sequence to get encoded + + EVP_PKEY * tmp_pkey = NULL; + // Containers for the different + // encodings of the components + + PKCS8_PRIV_KEY_INFO * tmp_pkey_info = NULL; + // Temp Structure for Privkey component + + STACK_OF(ASN1_TYPE) *sk = NULL; + // Stack of ASN1_OCTET_STRINGs + + COMPOSITE_KEY * comp_key = NULL; + // Pointer to the Composite Key + // (just a STACK_OF(EVP_PKEY)) + + ASN1_BIT_STRING * bit_string = NULL; + // Output Buffer + + ASN1_TYPE * aType = NULL; + // ASN1 generic wrapper + + unsigned char * buff = NULL; + int buff_len = 0; + // Temporary Storage for ASN1 data + + ASN1_INTEGER * key_param = NULL; + int key_param_type = V_ASN1_UNDEF; + // K of N parameter + + // Input Checking + if (!p8 || !pk) return 0; + + // Gets the Key Bytes + if ((comp_key = EVP_PKEY_get0(pk)) == NULL) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Cannot get the inner composite key structure"); + return 0; + } + + // Allocates the stack of private keys + if ((sk = sk_ASN1_TYPE_new_null()) == NULL) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Cannot allocate the stack of private key components"); + return 0; + } + + // Gets the P8 info for each key and + // adds it to the output stack + for (int i = 0; i < COMPOSITE_KEY_num(comp_key); i++) { + + // Get the component of the key + if ((tmp_pkey = COMPOSITE_KEY_get0(comp_key, i)) == NULL) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Cannot access [%d] component of the key", i); + goto err; + } + + // Generates the P8 info + if ((tmp_pkey_info = EVP_PKEY2PKCS8(tmp_pkey)) == NULL) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_ENCODE, "Cannot generate PKCS8 for [%d] component of the key", i); + goto err; + } + + // NOTE: buff must be set to NULL, otherwise OpenSSL + // thinks there is an already allocated buffer and + // writes to it and moves the pointer at the end + buff = NULL; + + // Generates the DER encoding of the component + if ((buff_len = i2d_PKCS8_PRIV_KEY_INFO(tmp_pkey_info, &buff)) <= 0) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_ENCODE, "Cannot ASN1 encode the [%d] component of the key", i); + goto err; + } + + // Generates the wrapping OCTET string + if ((bit_string = ASN1_BIT_STRING_new()) == NULL) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + goto err; + } + + // This sets and transfer ownership + ASN1_STRING_set0(bit_string, buff, buff_len); + + // Resets the pointer and length after ownership transfer + buff = NULL; buff_len = 0; + + // Let's free the X509_PUBKEY structure + PKCS8_PRIV_KEY_INFO_free(tmp_pkey_info); + tmp_pkey_info = NULL; + + // Let's now generate the ASN1_TYPE and add it to the stack + if ((aType = ASN1_TYPE_new()) == NULL) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + goto err; + } + + // Transfer Ownership to the aType structure + ASN1_TYPE_set(aType, V_ASN1_SEQUENCE, bit_string); + bit_string = NULL; + + // Adds the component to the stack + if (!sk_ASN1_TYPE_push(sk, aType)) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + goto err; + } + } + + buff = NULL; + if ((buff_len = i2d_ASN1_SEQUENCE_ANY(sk, &buff)) <= 0) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_ENCODE, "Cannot ASN1 encode the Overall Composite Key"); + goto err; + } + + // Free the stack's memory + while ((aType = sk_ASN1_TYPE_pop(sk)) != NULL) { + ASN1_TYPE_free(aType); + } + sk_ASN1_TYPE_free(sk); + sk = NULL; + + // Encode the parameters (if any) + if (comp_key->params) { + key_param_type = V_ASN1_INTEGER; + key_param = ASN1_INTEGER_dup(comp_key->params); + if (!key_param) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Cannot duplicate the key parameters"); + goto err; + } + } + + // PKI_DEBUG("PRIV. KEY. ENCODING: COMPOSITE KEY - algorithm = %d", comp_key->algorithm); + // PKI_DEBUG("PRIV. KEY. ENCODING: EVP_PKEY TYPE - pk->type = %d, pk->save_type = %d", pk->type, pk->save_type); + // PKI_DEBUG("PRIV. KEY. ENCODING: PKEY_AMETH - pkey_id = %d", pk->ameth->pkey_id); + + int my_nid = pk->save_type; + ASN1_OBJECT * obj = OBJ_nid2obj(my_nid); + + // PKI_DEBUG("PRIV. KEY. ENCODING: my_nid = %d", my_nid); + // PKI_DEBUG("PRIV. KEY. ENCODING: OBJ_nid2obj(%d) = %s", pk->save_type || pk->ameth->pkey_id, PKI_OID_get_descr(obj)); + + // Sets the params for the P8 + if (!PKCS8_pkey_set0(p8, obj, 0, key_param_type, key_param, buff, buff_len)) { + PKI_ERROR(PKI_ERR_GENERAL, "Cannot set the P8 null parameters contents"); + goto err; + } + + // All Done. + return 1; + +err: + + // Free allocated memory + if (key_param) ASN1_INTEGER_free(key_param); + if (buff && buff_len >= 0) OPENSSL_secure_clear_free(buff, (size_t) buff_len); + if (bit_string) ASN1_BIT_STRING_free(bit_string); + + // Free the Stack of ASN1_TYPE + if (sk) { + while ((aType = sk_ASN1_TYPE_pop(sk)) == NULL) { + ASN1_TYPE_free(aType); + } + sk_ASN1_TYPE_free(sk); + sk = NULL; + } + + // Error Condition + return 0; + +} + +// Implemented +int priv_print(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) { + + COMPOSITE_KEY * comp_key = NULL; + + if ((comp_key = EVP_PKEY_get0(pkey)) == NULL) + return 0; + + if (!BIO_indent(out, indent, 128)) + return 0; + + BIO_printf(out, "Composite Alternative Keys (%d Equivalent Keys):\n", + COMPOSITE_KEY_num(comp_key)); + + for (int i = 0; i < COMPOSITE_KEY_num(comp_key); i++) { + + EVP_PKEY * tmp_pkey = NULL; + + if ((tmp_pkey = COMPOSITE_KEY_get0(comp_key, i)) == NULL) { + BIO_printf(out, " Key Component #%d (UNKNOWN): \n", i); + continue; + } + + BIO_printf(out, " [%d] Key Component (%s):\n", + i, OBJ_nid2ln(tmp_pkey->ameth->pkey_id)); + + if (tmp_pkey->ameth->pub_print) { + tmp_pkey->ameth->pub_print(out, tmp_pkey, indent + 8, pctx); + } else { + BIO_printf(out, " \n"); + } + } + + BIO_printf(out, "Required Positive Components Validation (K-of-N): %d\n", + COMPOSITE_KEY_get_kofn(comp_key)); + + return 1; +} + +// Implemented +int pkey_size(const EVP_PKEY *pk) { + + int ret = 0; + // Return Value + + int key_num = 0; + // Index for cycling across keys + + COMPOSITE_KEY * comp_key = NULL; + // Pointer to the inner structure + + EVP_PKEY * pkey = NULL; + // Individual components keys + + // Input Check + if (!pk || !pk->ameth) return 0; + + // Gets the Composite Key + if ((comp_key = EVP_PKEY_get0(pk)) == NULL) + return 0; + + // Gets the number of keys + key_num = COMPOSITE_KEY_num(comp_key); + + // Process each key + for (int i = 0; i < key_num; i++) { + + // Retrieves the individual component + if ((pkey = COMPOSITE_KEY_get0(comp_key, i)) == NULL) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Cannot get the key material for component %d", i); + return 0; + } + + // Updates the total size + ret += EVP_PKEY_size(pkey); + + // Adds 5 extra bytes for ASN1 encoding (long) + ret += 5; + } + + // Adds 4 extra bytes for encoding the sequence (long) + ret += 5; + + // All Done + return ret; +} + +// Implemented +int pkey_bits(const EVP_PKEY *pk) { + + COMPOSITE_KEY * comp_Key = NULL; + // Composite Key pointer + + // Input Checks + if (pk == NULL) return 0; + + if ((comp_Key = EVP_PKEY_get0(pk)) == NULL) { + DEBUG("ERROR: Cannot retrieve the Composite Key."); + return 0; + } + + // Gets the Bits from the COMPOSITE_KEY + return COMPOSITE_KEY_bits(comp_Key); +} + +// Implemented +int pkey_security_bits(const EVP_PKEY *pk) { + + // Strategy: + // + // For Alternative Keys (OR logic Operation), + // we should report the minimum sec_bits level + // as any of the keys can be used. + // + // For Combined Keys (AND logic Operation), + // we should report the maximum sec_bits level + // as all of the keys must be used. + + int sec_bits = 0; + // Security Bits, we start with + // the max value and return the lowest + + COMPOSITE_KEY * comp_key = NULL; + // Pointer to the inner data structure + + // Input Checks + if (pk == NULL) return 0; + + if ((comp_key = EVP_PKEY_get0(pk)) == NULL) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Cannot retrieve the Composite Key"); + return 0; + } + + // Process the individual components + for (int i = 0; i < COMPOSITE_KEY_num(comp_key); i++) { + + EVP_PKEY * tmp_pkey = COMPOSITE_KEY_get0(comp_key, i); + // Compnent's key + + int tmp_pkey_sec_bits = INT_MAX; + // Security Bits, starts from INT_MAX + + // if (tmp_pkey && tmp_pkey->ameth->pkey_security_bits) { + // // Checks if it is composite (OR) and use the lowest + // // of the current or pkey values + // tmp_pkey_sec_bits = + // tmp_pkey->ameth->pkey_security_bits(tmp_pkey); + // } + + tmp_pkey_sec_bits = EVP_PKEY_security_bits(tmp_pkey); + + // If the current sec_bits is smaller, let's get the + // new (larger) value (Composite Keys are for auth + // and not for encryption) + if (sec_bits < tmp_pkey_sec_bits) { + sec_bits = tmp_pkey_sec_bits; + } + } + + // If there are no components, we return '0' + if (sec_bits == INT_MAX) return 0; + + // All Done. + return sec_bits; +} + +// // ======================== +// // Key Parameters Functions +// // ======================== + +// // Not Implemented +// int param_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen) { +// // There are no parameters to decode, always succeed +// return 1; +// } + +// // Not Implemented +// int param_encode(const EVP_PKEY *pkey, unsigned char **pder) { +// // There are no parameters to encode, always succeed +// return 1; +// } + +// // Not Implemented +// int param_missing(const EVP_PKEY *pk) { +// // There are no parameters, we return 1 for +// // indicating there are no missing parameters +// // (error condition is 0) +// // return 1; +// } + +// // Not Implemented +// int param_copy(EVP_PKEY *to, const EVP_PKEY *from) { +// // There are no parameters, we return 1 for +// // indicating there are no missing parameters +// // (error condition is 0) +// return 1; +// } + +// Implemented +int param_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { + + COMPOSITE_KEY * comp_a = NULL; + COMPOSITE_KEY * comp_b = NULL; + // Pointers to the inner data structure + + int param_a = -1; + int param_b = -1; + // Holds the parameters' values + + // Input Checks + if (a == NULL || b == NULL) return -1; + + if ((comp_a = EVP_PKEY_get0(a)) == NULL || + (comp_b = EVP_PKEY_get0(b)) == NULL) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Cannot retrieve the Composite Key"); + return -1; + } + + // Gets the parameters' values + if (comp_a->params) param_a = (int) ASN1_INTEGER_get(comp_a->params); + if (comp_b->params) param_b = (int) ASN1_INTEGER_get(comp_b->params); + + // Compares the values + if (param_a == param_b) return 0; + + // All Done + return (param_a > param_b ? 1 : -1); +} + +// // Not Implemented +// int param_print(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) { +// // There are no parameters to print, nothing to do +// return 1; +// } + +// Not Implemented +int sig_print(BIO *out, const X509_ALGOR *sigalg, const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx) { + BIO_printf(out, "\n"); + return 0; +} + +// Implemented +void pkey_free(EVP_PKEY *pk) { + + // Purpose: free the algorithm-specific + // data structure + COMPOSITE_KEY * comp_key = NULL; + // Composite Key Pointer + + // Input Validation + if (!pk || !pk->ameth) return; + + // Gets the Key Bytes + if ((comp_key = pk->pkey.ptr /* EVP_PKEY_get0(pk) */ ) == NULL) { + return; + } + + // Clears the Key and Frees the memory + COMPOSITE_KEY_free(comp_key); + pk->pkey.ptr = NULL; + + // All Done. + return; +} + +// Implemented +int ameth_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) { + + COMPOSITE_KEY * comp_key = NULL; + // Composite Key Pointer + + // Gets the Key Bytes + if ((comp_key = (COMPOSITE_KEY *)EVP_PKEY_get0(pkey)) == NULL) { + return 0; + } + + /* + # define ASN1_PKEY_CTRL_PKCS7_SIGN 0x1 + # define ASN1_PKEY_CTRL_PKCS7_ENCRYPT 0x2 + # define ASN1_PKEY_CTRL_DEFAULT_MD_NID 0x3 + # define ASN1_PKEY_CTRL_CMS_SIGN 0x5 + # define ASN1_PKEY_CTRL_CMS_ENVELOPE 0x7 + # define ASN1_PKEY_CTRL_CMS_RI_TYPE 0x8 + */ + + switch (op) { + + case ASN1_PKEY_CTRL_DEFAULT_MD_NID: { + // Deafault MD for the algorithm + *(int *)arg2 = NID_undef; // NID_sha512; + } break; + + case COMPOSITE_PKEY_CTRL_SET_K_OF_N: { + // Sets the Valid Signature Requirement + if (arg2) { + if (PKI_OK != COMPOSITE_KEY_set_kofn(comp_key, *((int *)arg2))) { + PKI_ERROR(PKI_ERR_GENERAL, "Can not set the K of N value"); + return 0; + } + } + } break; + + case COMPOSITE_PKEY_CTRL_GET_K_OF_N: { + // Gets the Valid Signature Requirement + int kofn = COMPOSITE_KEY_get_kofn(comp_key); + // Sets the output parameter + if (arg2) *(int *)arg2 = kofn; + // Returns an error if no validation policy is set + if (kofn <= 0) return 0; + } break; + + case ASN1_PKEY_CTRL_PKCS7_SIGN: + case ASN1_PKEY_CTRL_CMS_SIGN: { + // Signing Operation + } break; + + case ASN1_PKEY_CTRL_PKCS7_ENCRYPT: + case ASN1_PKEY_CTRL_CMS_ENVELOPE: { + // Encryption Operation + } break; + + case ASN1_PKEY_CTRL_CMS_RI_TYPE: { + // CMS RI Type Operation + } break; + + default: { + PKI_DEBUG("Unknown Operation [%d] (arg1 = %ld)", op, arg1); + return 0; + } + + } + + // All Done + return 1; +} + +// // ============================ +// // Legacy Functions for old PEM +// // ============================ + +// // Not Implemented +// int old_priv_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen) { +// PKI_DEBUG("Not implemented, yet."); +// return 0; +// } + +// // Not Implemented +// int old_priv_encode(const EVP_PKEY *pkey, unsigned char **pder) { +// PKI_DEBUG("Not implemented, yet."); +// return 0; +// } + +// ================================== +// Custom ASN1 signature verification +// ================================== + +// Implemented +int item_verify(EVP_MD_CTX * ctx, + const ASN1_ITEM * it, + void * asn, + X509_ALGOR * sigalg, + ASN1_BIT_STRING * sig, + EVP_PKEY * pkey) { + + EVP_PKEY_CTX * pctx = NULL; + EVP_PKEY * pkey_val = NULL; + // OpenSSL's context + + COMPOSITE_CTX * comp_ctx = NULL; + COMPOSITE_KEY * comp_key = NULL; + // Composite Key and CTX pointers + + // Get the EVP_PKEY_CTX from the EVP_MD_CTX + pctx = EVP_MD_CTX_pkey_ctx(ctx); + if (!pctx) { + + // Resets the EVP_MD_CTX + EVP_MD_CTX_init(ctx); + + // Allocates a new EVP_PKEY_CTX (this is the case + // where we do not have an MD and ASN1_item_verify + // calls this directly)) + pctx = EVP_PKEY_CTX_new(pkey, NULL); + if (!pctx) { + PKI_ERROR(PKI_ERR_GENERAL, "Can not instantiate a new EVP_PKEY_CTX"); + return -1; + } + + // Sets the EVP_PKEY_CTX in the EVP_MD_CTX + EVP_MD_CTX_set_pkey_ctx(ctx, pctx); + + // Checks that the operation was successful + if (!EVP_MD_CTX_pkey_ctx(ctx)) { + PKI_ERROR(PKI_ERR_GENERAL, "Can not get the EVP_PKEY_CTX from the EVP_MD_CTX"); + return -1; + } + + } + + // Gets the Composite Context + comp_ctx = pctx->data; + if (!comp_ctx) { + PKI_ERROR(PKI_ERR_GENERAL, "Can not get the Composite Context from the EVP_PKEY_CTX"); + return -1; + } + + // Get the Composite Key from the EVP_PKEY_CTX + if ((pkey_val = EVP_PKEY_CTX_get0_pkey(pctx)) != NULL) { + comp_key = EVP_PKEY_get0(pkey_val); + } + if (!comp_key) { + PKI_ERROR(PKI_ERR_GENERAL, "Can not get the Composite Key from the EVP_PKEY_CTX"); + } + + // Gets the PKI_SCHEME_ID from the Composite Key + PKI_SCHEME_ID scheme_id = PKI_X509_KEYPAIR_VALUE_get_scheme(pkey_val); + if (scheme_id <= PKI_SCHEME_UNKNOWN) { + PKI_ERROR(PKI_ERR_GENERAL, "Can not get the PKI_SCHEME_ID from the Composite Key"); + return -1; + } + + // ====================== + // Process Key Parameters + // ====================== + + int pkey_type = 0; + int md_type = 0; + // Public Key Type and Algorithms + + X509_ALGORS * params = NULL; + + const void * packed_sequence; + // Value for the parameters + + const PKI_OID *signature_oid = NULL; + // OID for the public key + + // Gets the type and the parameters + X509_ALGOR_get0(&signature_oid, &pkey_type, (const void **)&packed_sequence, sigalg); + if (!packed_sequence) { + PKI_ERROR(PKI_ERR_GENERAL, "Can not get the parameters from the X509_ALGOR"); + return -1; + }; + + PKI_DEBUG("Signature OID is %s", PKI_OID_get_descr(signature_oid)); + + // Now we need to unpack the sequence of algorithms + params = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(X509_ALGORS), sigalg->parameter); + if (params == NULL) { + PKI_ERROR(PKI_ERR_GENERAL, "Can not unpack the sequence of algorithms"); + return -1; + } + + PKI_DEBUG("params_value = %p (num = %d)", params, sk_X509_ALGOR_num(params)); + + // Let's copy the parameters into the EVP_PKEY_CTX + int success = COMPOSITE_CTX_algors_set0(comp_ctx, sk_X509_ALGOR_dup(params)); + if (!success) { + PKI_ERROR(PKI_ERR_GENERAL, "Can not set the parameters into the EVP_PKEY_CTX"); + return -1; + } + + + // Let's see if we are using the hash-n-sign scheme + // so that we can calculate the digest only once + if (!OBJ_find_sigid_algs(OBJ_obj2nid(signature_oid), &md_type, NULL)) { + PKI_ERROR(PKI_ERR_GENERAL, "Can not find the signature algorithm"); + return -1; + } + + // Sets the algorithm in the COMPOSITE_CTX that we use in the PKEY_METH (digestverify). + if (md_type != NID_undef) { + if (PKI_ERR == COMPOSITE_CTX_set_md(comp_ctx, EVP_get_digestbynid(md_type))) { + PKI_ERROR(PKI_ERR_GENERAL, "Can not set the digest algorithm in the COMPOSITE context"); + return -1; + } + } else { + if (PKI_ERR == COMPOSITE_CTX_set_md(comp_ctx, EVP_md_null())) { + PKI_ERROR(PKI_ERR_GENERAL, "Can not set the digest algorithm in the COMPOSITE context"); + return -1; + } + } + + /* + * Return value of 2 means carry on, anything else means we exit + * straight away: either a fatal error of the underlying verification + * routine handles all verification. + */ + + // // This is needed to pass the list of algorithms + // EVP_PKEY_CTX_set_app_data(pctx, (void *)a); + + return 2; +} + +// Implemented +int item_sign(EVP_MD_CTX * ctx, + const ASN1_ITEM * it, + void * asn, + X509_ALGOR * alg1, + X509_ALGOR * alg2, + ASN1_BIT_STRING * sig) { + + EVP_PKEY_CTX * pctx = NULL; + EVP_PKEY * pkey_val = NULL; + int pkey_type = 0; + // OpenSSL's context + + COMPOSITE_CTX * comp_ctx = NULL; + COMPOSITE_KEY * comp_key = NULL; + // Composite Key and CTX pointers + + X509_ALGORS * sig_algs = NULL; + // List of signature algorithms + + PKI_SCHEME_ID scheme_id = PKI_SCHEME_UNKNOWN; + // Signature Scheme ID + + int signature_id = NID_undef; + // Signature ID + + /* + * Return value meanings: + * <=0: error. + * 1: method does everything. + * 2: carry on as normal. + * 3: ASN1 method sets algorithm identifiers: just sign. + * + * See ASN1_item_sign_ctx() at OPENSSL/crypto/asn1/a_sign.c:140 + */ + + // Get the EVP_PKEY_CTX from the EVP_MD_CTX + pctx = EVP_MD_CTX_pkey_ctx(ctx); + if (!pctx) { + PKI_ERROR(PKI_ERR_GENERAL, "Can not get the EVP_PKEY_CTX from the EVP_MD_CTX"); + return -1; + } + + // Gets the Composite Context + comp_ctx = pctx->data; + if (!comp_ctx) { + PKI_ERROR(PKI_ERR_GENERAL, "Can not get the Composite Context from the EVP_PKEY_CTX"); + return -1; + } + + // Copies the ASN1_ITEM into the Composite Context + comp_ctx->asn1_item = it; + + // Get the Composite Key from the EVP_PKEY_CTX + if ((pkey_val = EVP_PKEY_CTX_get0_pkey(pctx)) != NULL) { + comp_key = EVP_PKEY_get0(pkey_val); + } + if (!comp_key) { + PKI_ERROR(PKI_ERR_GENERAL, "Can not get the Composite Key from the EVP_PKEY_CTX"); + } + + // Retrieves the Composite Public Key Type + pkey_type = EVP_PKEY_type(PKI_X509_KEYPAIR_VALUE_get_id(pkey_val)); + + // Here we shall generate and validate the list of components + // when the pkey_id is one of the explicit composite + if (PKI_ID_is_explicit_composite(pkey_type, &scheme_id) == PKI_OK) { + + PKI_DEBUG("********* DETECTED EXPLICIT COMPOSITE ***************"); + PKI_DEBUG("MISSING CODE FOR AUTO-GENERATING THE X509_ALGORS LIST"); + PKI_DEBUG("********* DETECTED EXPLICIT COMPOSITE ***************"); + + if (!OBJ_find_sigid_by_algs(&signature_id, NID_undef, pkey_type)) { + PKI_DEBUG("Can not find the signature algorithm, using the pkey_type directly"); + signature_id = pkey_type; + } + + PKI_DEBUG("Building the Explicit Composite list of algorithms for signing"); + + // Build the list with defaults + int success = COMPOSITE_CTX_explicit_algors_new0(comp_ctx, + pkey_type, + it, + comp_key->components, + &sig_algs); + if (!success || !sig_algs) { + PKI_ERROR(PKI_ERR_GENERAL, "Can not get the list of algorithms from the Composite Key"); + return -1; + } + + } else { + + // Gets the ID for the algorithm components + int digest_id = NID_undef; + + if (comp_ctx->md == PKI_DIGEST_ALG_NULL) { + PKI_DEBUG("NULL Digest Algorithm - Setting to NID_undef"); + digest_id = NID_undef; + } else if (comp_ctx->md == NULL) { + PKI_DEBUG("Default Digest Algorithm - Setting to EVP_MD_type(comp_ctx->default_md)"); + digest_id = comp_ctx->default_md ? EVP_MD_type(comp_ctx->default_md) : PKI_DIGEST_ALG_ID_DEFAULT; + } else { + digest_id = EVP_MD_type(comp_ctx->md); + } + + PKI_DEBUG("***** Selected Digest ID: %d", digest_id); + + // Search for the Algorithm ID + if (!OBJ_find_sigid_by_algs(&signature_id, digest_id, pkey_type)) { + PKI_DEBUG("Cannot find the Algorithm ID (digest: %d, pkey: %d)", digest_id, pkey_type); + return -1; + } + + PKI_DEBUG("***** Found the Signature ID: %d", signature_id); + + PKI_DEBUG("Building the generic composite list of algorithms for signing"); + + // Build the list with defaults + int success = COMPOSITE_CTX_algors_new0(comp_ctx, pkey_type, it, comp_key->components, &sig_algs); + if (!success || !sig_algs) { + PKI_ERROR(PKI_ERR_GENERAL, "Can not get the list of algorithms from the Composite Key"); + return -1; + } + } + + // Pack the list of algorithms + ASN1_STRING * param_str = NULL; + param_str = ASN1_item_pack(sig_algs, ASN1_ITEM_rptr(X509_ALGORS), NULL); + if (!param_str) { + PKI_ERROR(PKI_ERR_GENERAL, "Can not pack the list of algorithms"); + return -1; + } + + // Sets the Algorithm IDs + if (alg1 != NULL) + X509_ALGOR_set0(alg1, OBJ_nid2obj(signature_id), V_ASN1_SEQUENCE, param_str); + + if (alg2 != NULL) { + // We need to duplicate the parameter string + ASN1_STRING * param_str_dup = ASN1_STRING_dup(param_str); + X509_ALGOR_set0(alg2, OBJ_nid2obj(signature_id), V_ASN1_SEQUENCE, param_str_dup); + } + + // for (int i = 0; i < sk_X509_ALGOR_num(comp_ctx->sig_algs); i++) { + // PKI_DEBUG("Signature Algorithm [%d]: %s", i, OBJ_nid2ln(OBJ_obj2nid(sk_X509_ALGOR_value(comp_ctx->sig_algs, i)->algorithm))); + // } + + // Should return 3 to indicate that the algorithm identifiers + // are already set, proceed with signing + return 3; +} + +// Not Implemented +int siginf_set(X509_SIG_INFO *siginf, const X509_ALGOR *alg, const ASN1_STRING *sig) { + fprintf(stderr, "%s:%d: DEBUG: siginf_set() called\n", __FILE__, __LINE__); + return 1; +} + +// =================== +// EVP Check Functions +// =================== + +int pkey_check(const EVP_PKEY *pkey) { + + COMPOSITE_KEY * comp_key = NULL; + + // Input Checks + if (!pkey) return 0; + + // Retrieves the Composite Key internal structure + if ((comp_key = EVP_PKEY_get0(pkey)) == NULL) return 0; + + // Checks we have at least one component + if (COMPOSITE_KEY_num(comp_key) < 1) return 0; + + // Process each component + for (int i = 0; i < COMPOSITE_KEY_num(comp_key); i++) { + + EVP_PKEY * tmp_pkey = NULL; + // Pointer to the individual component + + // If we cannot get any component, we have a problem + if ((tmp_pkey = COMPOSITE_KEY_get0(comp_key, i)) == NULL) return 0; + + // We need an ASN1 method + if (!tmp_pkey->ameth) return 0; + + // If the component has the check, let's perform + // it on the single component and return 0 if any + // of these fail at the component level + if (tmp_pkey->ameth->pkey_check && tmp_pkey->ameth->pkey_check(tmp_pkey) == 0) { + PKI_DEBUG("ERROR: Key Check failed for Composite Key Component #%d", i); + return 0; + } + } + + // All Done + return 1; +} + +// Not Implemented +int pkey_public_check(const EVP_PKEY *pkey) { + + COMPOSITE_KEY * comp_key = NULL; + + if (!pkey) return 0; + + if ((comp_key = EVP_PKEY_get0(pkey)) == NULL) + return 0; + + if (COMPOSITE_KEY_num(comp_key) < 1) + return 0; + + for (int i = 0; i < COMPOSITE_KEY_num(comp_key); i++) { + EVP_PKEY * tmp_pkey = NULL; + + // If we cannot get any component, we have a problem + if ((tmp_pkey = COMPOSITE_KEY_get0(comp_key, i)) == NULL) + return 0; + + // We need an ASN1 method + if (!tmp_pkey->ameth) return 0; + + // If the component has the check, let's perform + // it on the single component and return 0 if any + // of these fail at the component level + if (tmp_pkey->ameth->pkey_public_check) { + if (tmp_pkey->ameth->pkey_public_check(tmp_pkey) == 0) { + return 0; + } + } + } + + return 1; +} + +// Not Implemented +int pkey_param_check(const EVP_PKEY *pkey) { + return 1; +} + +// // ================================= +// // Get/Set For Raw priv/pub key data +// // ================================= + +// // Not Implemented +// int set_priv_key(EVP_PKEY *pk, const unsigned char *priv, size_t len) { +// PKI_DEBUG("Not implemented, yet."); +// return 0; +// } + +// // Not Implemented +// int set_pub_key(EVP_PKEY *pk, const unsigned char *pub, size_t len) { +// PKI_DEBUG("Not implemented, yet."); +// return 0; +// } + +// // Not Implemented +// int get_priv_key(const EVP_PKEY *pk, unsigned char *priv, size_t *len) { +// PKI_DEBUG("Not implemented, yet."); +// return 0; +// } + +// // Not Implemented +// int get_pub_key(const EVP_PKEY *pk, unsigned char *pub, size_t *len) { +// PKI_DEBUG("Not implemented, yet."); +// return 0; +// } + +// =========================== +// ASN1 PKEY Method Definition +// =========================== + +// The Definition of the EVP_PKEY_ASN1_METHOD is provided above and +// it is taken from OPENSSL_SRC/include/crypto/asn1.h, see the +// OPENSSL_SRC/include/ossl_typ.h +EVP_PKEY_ASN1_METHOD composite_asn1_meth = { + 0, // int pkey_id; // EVP_PKEY_COMPOSITE + 0, // int pkey_base_id; // EVP_PKEY_COMPOSITE + 0, // unsigned long pkey_flags; ASN1_PKEY_SIGPARAM_NULL + "COMPOSITE", // char *pem_str; + "Composite Crypto With Combined Keys", // char *info; + pub_decode, // int (*pub_decode) (EVP_PKEY *pk, X509_PUBKEY *pub); + pub_encode, // int (*pub_encode) (X509_PUBKEY *pub, const EVP_PKEY *pk); + pub_cmp, // int (*pub_cmp) (const EVP_PKEY *a, const EVP_PKEY *b); + pub_print, // int (*pub_print) (BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx); + + priv_decode, // int (*priv_decode) (EVP_PKEY *pk, const PKCS8_PRIV_KEY_INFO *p8inf); + priv_encode, // int (*priv_encode) (PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk); + priv_print, // int (*priv_print) (BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx); + + pkey_size, // int (*pkey_size) (const EVP_PKEY *pk); + pkey_bits, // int (*pkey_bits) (const EVP_PKEY *pk); + pkey_security_bits, // int (*pkey_security_bits) (const EVP_PKEY *pk); + + 0, // param_decode, // int (*param_decode) (EVP_PKEY *pkey, const unsigned char **pder, int derlen); + 0, // param_encode, // int (*param_encode) (const EVP_PKEY *pkey, unsigned char **pder); + 0, // param_missing, // int (*param_missing) (const EVP_PKEY *pk); + 0, // param_copy, // int (*param_copy) (EVP_PKEY *to, const EVP_PKEY *from); + 0, // param_cmp, // int (*param_cmp) (const EVP_PKEY *a, const EVP_PKEY *b); + 0, // param_print, // int (*param_print) (BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx); + + sig_print, // int (*sig_print) (BIO *out, const X509_ALGOR *sigalg, const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx); + pkey_free, // void (*pkey_free) (EVP_PKEY *pkey); + ameth_ctrl, // int (*pkey_ctrl) (EVP_PKEY *pkey, int op, long arg1, void *arg2); + // Legacy Functions for old PEM + 0, // old_priv_decode, // int (*old_priv_decode) (EVP_PKEY *pkey, const unsigned char **pder, int derlen); + 0, // old_priv_encode, // int (*old_priv_encode) (const EVP_PKEY *pkey, unsigned char **pder); + // Custom ASN1 signature verification + item_verify, // int (*item_verify) (EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, X509_ALGOR *a, ASN1_BIT_STRING *sig, EVP_PKEY *pkey); + item_sign, // int (*item_sign) (EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, X509_ALGOR *alg1, X509_ALGOR *alg2, ASN1_BIT_STRING *sig); + siginf_set, // int (*siginf_set) (X509_SIG_INFO *siginf, const X509_ALGOR *alg, const ASN1_STRING *sig); + // PKEY checking interface + pkey_check, // int (*pkey_check) (EVP_PKEY *pkey); + pkey_public_check, // int (*pkey_public_check) (EVP_PKEY *pkey); + pkey_param_check, // int (*pkey_param_check) (EVP_PKEY *pkey); + 0, // set_priv_key, // int (*set_priv_key) (EVP_PKEY *pk, const unsigned char *priv, size_t len); + 0, // set_pub_key, // int (*set_pub_key) (EVP_PKEY *pk, const unsigned char *pub, size_t len); + 0, // get_priv_key, // int (*get_priv_key) (const EVP_PKEY *pk, unsigned char *priv, size_t *len); + 0, // get_pub_key, // int (*get_pub_key) (const EVP_PKEY *pk, unsigned char *pub, size_t *len); +}; + +#endif + +/* END: composite_amenth.c */ diff --git a/src/crypto/composite/composite_ameth_lcl.h b/src/crypto/composite/composite_ameth_lcl.h new file mode 100644 index 00000000..4e496df8 --- /dev/null +++ b/src/crypto/composite/composite_ameth_lcl.h @@ -0,0 +1,70 @@ +/* BEGIN: composite_ameth.h */ + +#ifndef _LIBPKI_COMPOSITE_ASN1_METH_H +#define _LIBPKI_COMPOSITE_ASN1_METH_H + +// Temporary Measure until the functions are all used +#pragma GCC diagnostic ignored "-Wunused-function" + +// Composite Crypto authentication methods. +// (c) 2021 by Massimiliano Pala + +#ifndef HEADER_X509_H +#include +#endif + +#ifndef HEADER_EC_H +#include +#endif + +#ifndef HEADER_ENVELOPE_H +#include +#endif + +#ifndef HEADER_ASN1_H +#include +#endif + +#ifndef HEADER_OPENSSLV_H +#include +#endif + +#ifndef _LIBPKI_OS_H +#include +#endif + +#ifndef _LIBPKI_COMPOSITE_KEY_H +#include +#endif + +#ifndef _LIBPKI_COMPOSITE_CTX_H +#include +#endif + +#ifndef _LIBPKI_COMPOSITE_UTILS_H +#include +#endif + +#ifndef _LIBPKI_PKI_ALGOR_VALUE_H +#include +#endif + +#ifndef _LIBPKI_PKI_ID_H +#include +#endif + +BEGIN_C_DECLS + +// =============== +// Data Structures +// =============== + +// ====================== +// MACRO & Other Oddities +// ====================== + +END_C_DECLS + +#endif // _LIBPKI_COMPOSITE_AMETH_H + +/* END: composite_ameth.h */ \ No newline at end of file diff --git a/src/crypto/composite/composite_ctx.c b/src/crypto/composite/composite_ctx.c new file mode 100644 index 00000000..dc23addf --- /dev/null +++ b/src/crypto/composite/composite_ctx.c @@ -0,0 +1,1015 @@ +/* BEGIN: composite_pmeth.c */ + +// Temporary Measure until the functions are all used +#pragma GCC diagnostic ignored "-Wunused-function" + +// Composite Crypto authentication methods. +// (c) 2021 by Massimiliano Pala + +#ifndef _LIBPKI_COMPOSITE_PKEY_CTX_H +#include +#endif + +#ifndef _LIBPKI_COMPOSITE_KEY_H +#include +#endif + +#ifndef _LIBPKI_PKI_ID_H +#include +#endif + +#ifndef _LIBPKI_PKI_OID_H +#include +#endif + +#ifndef _LIBPKI_PKI_ALGOR_VALUE_H +#include +#endif + +// ============== +// Local Includes +// ============== + +#ifndef _LIBPKI_COMPOSITE_OPENSSL_LOCAL_H +#include "composite_ossl_lcl.h" +#endif + +// ====================== +// MACRO & Other Oddities +// ====================== + +#define DEBUG(args...) \ + { fprintf(stderr, "[%s:%d] %s() - ", __FILE__, __LINE__, __func__); \ + fprintf(stderr, ## args) ; fprintf(stderr,"\n"); fflush(stderr) ; } + +// ======================== +// Exported Global Variable +// ======================== + +// Temporary Measure until the functions are all used +#pragma GCC diagnostic ignored "-Wunused-function" + +#ifdef ENABLE_COMPOSITE + +// ======================= +// COMPOSITE_CTX Functions +// ======================= + + +COMPOSITE_CTX * COMPOSITE_CTX_new(const PKI_DIGEST_ALG * alg) { + + COMPOSITE_CTX * ret = NULL; + // Return Pointer + + // Allocates the memory + ret = COMPOSITE_CTX_new_null(); + if (ret) { + // If provided, set the default MD + ret->default_md = alg; + } + + // All Done + return ret; +} + +COMPOSITE_CTX * COMPOSITE_CTX_new_null() { + + COMPOSITE_CTX * ret = NULL; + // Return pointer + + // Allocates the needed memory + ret = PKI_Malloc(sizeof(COMPOSITE_CTX)); + if (!ret) return NULL; + + // Zeroize the memory + memset(ret, 0, sizeof(COMPOSITE_CTX)); + + // Initializes the stack of components + ret->components = COMPOSITE_KEY_STACK_new(); + if (!ret->components) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + if (ret) PKI_Free(ret); + return NULL; + } + + // Sets the default for algorithms that cannot + // do direct signing + ret->default_md = PKI_DIGEST_ALG_DEFAULT; + + // No need to initialize the MD or the X509_ALGORs + // only used during the signing and verifying processes + + // All Done + return ret; +} + +void COMPOSITE_CTX_free(COMPOSITE_CTX * comp_ctx) { + + // Input checks + if (!comp_ctx) return; + + // Free Components Stack Memory + if (comp_ctx->components) sk_EVP_PKEY_pop_free(comp_ctx->components, EVP_PKEY_free); + comp_ctx->components = NULL; + + // Free the signatures' algorithms, if any + if (comp_ctx->sig_algs) sk_X509_ALGOR_pop_free(comp_ctx->sig_algs, X509_ALGOR_free); + + // Free the memory + PKI_ZFree(comp_ctx, sizeof(COMPOSITE_CTX)); +} + +int COMPOSITE_CTX_set_md(COMPOSITE_CTX * ctx, const EVP_MD * md) { + + // Input Checks + if (!ctx || !md) return PKI_ERR; + + // Sets the MD + ctx->md = md; + + // All Done + return PKI_OK; +} + +int COMPOSITE_CTX_set_default_md(COMPOSITE_CTX * ctx, const EVP_MD * md) { + + // Input Checks + if (!ctx || !md) return PKI_ERR; + + // Sets the MD + ctx->default_md = md; + + // All Done + return PKI_OK; +} + +const EVP_MD * COMPOSITE_CTX_get_md(COMPOSITE_CTX * ctx) { + + // Input checks + if (!ctx) return NULL; + + // Returns the internal pointer + return ctx->md; +} + +const EVP_MD * COMPOSITE_CTX_get_default_md(COMPOSITE_CTX * ctx) { + + // Input checks + if (!ctx) return NULL; + + // Returns the internal pointer + return ctx->default_md; +} + + +int COMPOSITE_CTX_pkey_push(COMPOSITE_CTX * comp_ctx, + PKI_X509_KEYPAIR_VALUE * pkey) { + + // Input Checks + if (!comp_ctx || !pkey) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return PKI_ERR; + } + + // Gets the reference to the stack + if (!comp_ctx->components) { + PKI_DEBUG("Missing internal stack of keys in CTX"); + return PKI_ERR; + } + + // Pushes the new component + COMPOSITE_KEY_STACK_push(comp_ctx->components, pkey); + + // All Done + return PKI_OK; +} + +int COMPOSITE_CTX_pkey_pop(COMPOSITE_CTX * comp_ctx, + PKI_X509_KEYPAIR_VALUE ** pkey, + const PKI_DIGEST_ALG ** md) { + + PKI_X509_KEYPAIR_VALUE * x = NULL; + // Return pointer + + // const PKI_DIGEST_ALG * x_md; + // // Pointer to the MD associated with the PKEY + + // Input Checks + if (!comp_ctx || !comp_ctx->components) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return PKI_ERR; + } + + // Checks for the number of components + if (sk_EVP_PKEY_num(comp_ctx->components) < 1) { + // Something is wrong with the stacks + PKI_ERROR(PKI_ERR_GENERAL, "Inconsistency in number of elements in components stack"); + return PKI_ERR; + } + + // Pops and returns the last component + x = COMPOSITE_KEY_STACK_pop(comp_ctx->components); + if (!x) { + // Cannot get the EVP_PKEY from the stack + PKI_ERROR(PKI_ERR_GENERAL, "Cannot get the EVP_PKEY from the components stack"); + return PKI_ERR; + } + + // Sets the output parameters + if (pkey) *pkey = x; + if (md) *md = comp_ctx->md; + + // All Done + return PKI_OK; +} + +int COMPOSITE_CTX_pkey_clear(COMPOSITE_CTX * comp_ctx) { + + // Input Checks + if (!comp_ctx) return PKI_ERR; + + // Clears the components + if (comp_ctx->components) COMPOSITE_KEY_STACK_clear(comp_ctx->components); + + // Clears the k-of-n parameter + if (comp_ctx->params) ASN1_INTEGER_free(comp_ctx->params); + comp_ctx->params = NULL; + + // Clears the signature algorithms + if (comp_ctx->sig_algs) sk_X509_ALGOR_pop_free(comp_ctx->sig_algs, X509_ALGOR_free); + comp_ctx->sig_algs = NULL; + + // Clears the MD for hash-n-sign + comp_ctx->md = NULL; + + // All Done + return PKI_OK; +} + +int COMPOSITE_CTX_components_get0(const COMPOSITE_CTX * const ctx, + const COMPOSITE_KEY_STACK ** const components) { + // Input Checks + if (!ctx) return PKI_ERR; + + // Sets the return values + if (components) *components = ctx->components; + + // All Done + return PKI_OK; +} + +/*! \brief Sets the MD for the Composite CTX */ +int COMPOSITE_CTX_components_set0(COMPOSITE_CTX * ctx, + COMPOSITE_KEY_STACK * const components) { + // Input Checks + if (!ctx) return PKI_ERR; + + // Checks the values and set them in the CTX + if (components) { + if (ctx->components) COMPOSITE_KEY_STACK_pop_free(ctx->components); + ctx->components = components; + } + + // All Done + return PKI_OK; +} + +int COMPOSITE_CTX_components_detach(COMPOSITE_CTX * ctx, + COMPOSITE_KEY_STACK ** const components) { + + // Input Checks + if (!ctx) return PKI_ERR; + + // Returns the components if requested + if (components) *components = ctx->components; + + // Resets the internal pointer + ctx->components = NULL; + + // All Done + return PKI_OK; +} + +int COMPOSITE_CTX_algors_clear(COMPOSITE_CTX * const ctx) { + + // Input Checks + if (!ctx) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return PKI_ERR; + } + + // Clears the signature algorithms + if (ctx->sig_algs) sk_X509_ALGOR_pop_free(ctx->sig_algs, X509_ALGOR_free); + ctx->sig_algs = NULL; + + // All Done + return PKI_OK; +} + +int COMPOSITE_CTX_explicit_algors_new0(COMPOSITE_CTX * ctx, + const int pkey_type, + const ASN1_ITEM * asn1_item, + const COMPOSITE_KEY_STACK * const components, + X509_ALGORS ** algors) { + + int stack_elements_num = 0; + // Number of elements in the stack + + X509_ALGORS * sk = NULL; + X509_ALGOR algor = { 0x0 }; + // Pointer to the new stack of X509_ALGOR + + PKI_SCHEME_ID scheme = PKI_SCHEME_UNKNOWN; + // NID of the algorithm + + // Input Checks + if (!ctx || !components) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return PKI_ERR; + } + + if (!PKI_ID_is_explicit_composite(pkey_type, &scheme)) { + PKI_DEBUG("Scheme %d is not an explicit composite", scheme); + return PKI_ERR; + } + + PKI_DEBUG("Scheme %d is an explicit composite (number of components = %d)", + scheme, COMPOSITE_KEY_STACK_num(components)); + + sk = sk_X509_ALGOR_new_null(); + if (!sk) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return PKI_ERR; + } + + // Gets the number of components + if ((stack_elements_num = COMPOSITE_KEY_STACK_num(components)) < 2) { + PKI_DEBUG("Insufficient number of components in the key stack (%d)", stack_elements_num); + return PKI_ERR; + } + + switch (scheme) { + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_RSA: { + // Dilithium3 Component + // Sets the algorithm identifier in the X509_ALGOR + // (and then fails, we generate the signatures in PMETH) + X509_ALGOR_set0(&algor, OBJ_nid2obj(PKI_ALGOR_DILITHIUM3), V_ASN1_UNDEF, NULL); + sk_X509_ALGOR_push(sk, X509_ALGOR_dup(&algor)); + // RSA component + ASN1_item_sign(asn1_item, + &algor, + NULL, + NULL, + NULL, + COMPOSITE_KEY_STACK_get0(components, 1), + EVP_sha256()); + // X509_ALGOR_set0(&algor, OBJ_nid2obj(PKI_ALGOR_RSA), V_ASN1_UNDEF, NULL); + sk_X509_ALGOR_push(sk, X509_ALGOR_dup(&algor)); + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_P256: { + // Dilithium3 Component + X509_ALGOR_set0(&algor, OBJ_nid2obj(PKI_ALGOR_DILITHIUM3), V_ASN1_UNDEF, NULL); + sk_X509_ALGOR_push(sk, X509_ALGOR_dup(&algor)); + // ECDSA-with-SHA256 component + ASN1_item_sign(asn1_item, + &algor, + NULL, + NULL, + NULL, + COMPOSITE_KEY_STACK_get0(components, 1), + EVP_sha256()); + // X509_ALGOR_set0(&algor, OBJ_nid2obj(NID_ecdsa_with_SHA256), V_ASN1_UNDEF, NULL); + sk_X509_ALGOR_push(sk, X509_ALGOR_dup(&algor)); + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_BRAINPOOL256: { + // Dilithium3 Component + X509_ALGOR_set0(&algor, OBJ_nid2obj(PKI_ALGOR_DILITHIUM3), V_ASN1_UNDEF, NULL); + sk_X509_ALGOR_push(sk, X509_ALGOR_dup(&algor)); + // Brainpool256 component + ASN1_item_sign(asn1_item, + &algor, + NULL, + NULL, + NULL, + COMPOSITE_KEY_STACK_get0(components, 1), + EVP_sha256()); + // X509_ALGOR_set0(&algor, OBJ_nid2obj(NID_brainpoolP256r1), V_ASN1_UNDEF, NULL); + sk_X509_ALGOR_push(sk, X509_ALGOR_dup(&algor)); + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_ED25519:{ + // Dilithium3 Component + X509_ALGOR_set0(&algor, OBJ_nid2obj(PKI_ALGOR_DILITHIUM3), V_ASN1_UNDEF, NULL); + sk_X509_ALGOR_push(sk, X509_ALGOR_dup(&algor)); + // ED 25519 component + ASN1_item_sign(asn1_item, + &algor, + NULL, + NULL, + NULL, + COMPOSITE_KEY_STACK_get0(components, 1), + EVP_sha256()); + // X509_ALGOR_set0(&algor, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL); + sk_X509_ALGOR_push(sk, X509_ALGOR_dup(&algor)); + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_P384: { + // Dilithium5 Component + X509_ALGOR_set0(&algor, OBJ_nid2obj(PKI_ALGOR_DILITHIUM5), V_ASN1_UNDEF, NULL); + sk_X509_ALGOR_push(sk, X509_ALGOR_dup(&algor)); + // ECDSA-with-SHA384 component + ASN1_item_sign(asn1_item, + &algor, + NULL, + NULL, + NULL, + COMPOSITE_KEY_STACK_get0(components, 1), + EVP_sha384()); + // X509_ALGOR_set0(&algor, OBJ_nid2obj(NID_ecdsa_with_SHA384), V_ASN1_UNDEF, NULL); + sk_X509_ALGOR_push(sk, X509_ALGOR_dup(&algor)); + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_BRAINPOOL384: { + // Dilithium5 Component + X509_ALGOR_set0(&algor, OBJ_nid2obj(PKI_ALGOR_DILITHIUM5), V_ASN1_UNDEF, NULL); + sk_X509_ALGOR_push(sk, X509_ALGOR_dup(&algor)); + // Brainpool384 component + ASN1_item_sign(asn1_item, + &algor, + NULL, + NULL, + NULL, + COMPOSITE_KEY_STACK_get0(components, 1), + EVP_sha384()); + // X509_ALGOR_set0(&algor, OBJ_nid2obj(NID_brainpoolP384r1), V_ASN1_UNDEF, NULL); + sk_X509_ALGOR_push(sk, X509_ALGOR_dup(&algor)); + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_ED448: { + // Dilithium5 Component + X509_ALGOR_set0(&algor, OBJ_nid2obj(PKI_ALGOR_DILITHIUM5), V_ASN1_UNDEF, NULL); + sk_X509_ALGOR_push(sk, X509_ALGOR_dup(&algor)); + // ED 448 component + // ASN1_item_sign(asn1_item, + // &algor, + // NULL, + // NULL, + // NULL, + // COMPOSITE_KEY_STACK_get0(components, 1), + // NULL); + X509_ALGOR_set0(&algor, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL); + sk_X509_ALGOR_push(sk, X509_ALGOR_dup(&algor)); + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_P256: { + // Falcon512 Component + X509_ALGOR_set0(&algor, OBJ_nid2obj(PKI_ALGOR_FALCON512), V_ASN1_UNDEF, NULL); + sk_X509_ALGOR_push(sk, X509_ALGOR_dup(&algor)); + // ECDSA-with-SHA256 component + ASN1_item_sign(asn1_item, + &algor, + NULL, + NULL, + NULL, + COMPOSITE_KEY_STACK_get0(components, 1), + EVP_sha256()); + // X509_ALGOR_set0(&algor, OBJ_nid2obj(NID_ecdsa_with_SHA384), V_ASN1_UNDEF, NULL); + sk_X509_ALGOR_push(sk, X509_ALGOR_dup(&algor)); + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_BRAINPOOL256: { + // Falcon512 Component + X509_ALGOR_set0(&algor, OBJ_nid2obj(PKI_ALGOR_FALCON512), V_ASN1_UNDEF, NULL); + sk_X509_ALGOR_push(sk, X509_ALGOR_dup(&algor)); + // Brainpool256 component + ASN1_item_sign(asn1_item, + &algor, + NULL, + NULL, + NULL, + COMPOSITE_KEY_STACK_get0(components, 1), + EVP_sha256()); + // X509_ALGOR_set0(&algor, OBJ_nid2obj(NID_brainpoolP256r1), V_ASN1_UNDEF, NULL); + sk_X509_ALGOR_push(sk, X509_ALGOR_dup(&algor)); + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_ED25519: { + // Falcon512 Component + X509_ALGOR_set0(&algor, OBJ_nid2obj(PKI_ALGOR_FALCON512), V_ASN1_UNDEF, NULL); + sk_X509_ALGOR_push(sk, X509_ALGOR_dup(&algor)); + // Brainpool256 component + ASN1_item_sign(asn1_item, + &algor, + NULL, + NULL, + NULL, + COMPOSITE_KEY_STACK_get0(components, 1), + EVP_sha256()); + // X509_ALGOR_set0(&algor, OBJ_nid2obj(NID_brainpoolP256r1), V_ASN1_UNDEF, NULL); + sk_X509_ALGOR_push(sk, X509_ALGOR_dup(&algor)); + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_RSAPSS: { + // Dilithium3 + X509_ALGOR_set0(&algor, OBJ_nid2obj(PKI_ALGOR_DILITHIUM3), V_ASN1_UNDEF, NULL); + sk_X509_ALGOR_push(sk, X509_ALGOR_dup(&algor)); + // RSAPSS component + ASN1_item_sign(asn1_item, + &algor, + NULL, + NULL, + NULL, + COMPOSITE_KEY_STACK_get0(components, 1), + NULL); + // X509_ALGOR_set0(&algor, OBJ_nid2obj(PKI_ALGOR_RSAPSS), V_ASN1_UNDEF, NULL); + sk_X509_ALGOR_push(sk, X509_ALGOR_dup(&algor)); + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_RSA: { + // Falcon512 component + X509_ALGOR_set0(&algor, OBJ_nid2obj(PKI_ALGOR_FALCON512), V_ASN1_UNDEF, NULL); + sk_X509_ALGOR_push(sk, X509_ALGOR_dup(&algor)); + // RSA component + ASN1_item_sign(asn1_item, + &algor, + NULL, + NULL, + NULL, + COMPOSITE_KEY_STACK_get0(components, 1), + EVP_sha256()); + // X509_ALGOR_set0(&algor, OBJ_nid2obj(PKI_ALGOR_RSA), V_ASN1_UNDEF, NULL); + sk_X509_ALGOR_push(sk, X509_ALGOR_dup(&algor)); + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_FALCON1024_P521: { + if (stack_elements_num != 3) { + PKI_DEBUG("Insufficient number of components in the key stack (%d)", stack_elements_num); + return PKI_ERR; + } + // Dilithium5 component + X509_ALGOR_set0(&algor, OBJ_nid2obj(PKI_ALGOR_FALCON512), V_ASN1_UNDEF, NULL); + sk_X509_ALGOR_push(sk, X509_ALGOR_dup(&algor)); + // Falcon1024 component + X509_ALGOR_set0(&algor, OBJ_nid2obj(PKI_ALGOR_RSA), V_ASN1_UNDEF, NULL); + sk_X509_ALGOR_push(sk, X509_ALGOR_dup(&algor)); + // ECDSA-with-SHA512 component + ASN1_item_sign(asn1_item, + &algor, + NULL, + NULL, + NULL, + COMPOSITE_KEY_STACK_get0(components, 2), + EVP_sha512()); + // X509_ALGOR_set0(&algor, OBJ_nid2obj(PKI_ALGOR_ECDSA_SHA512), V_ASN1_UNDEF, NULL); + sk_X509_ALGOR_push(sk, X509_ALGOR_dup(&algor)); + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_FALCON1024_RSA: { + if (stack_elements_num != 3) { + PKI_DEBUG("Insufficient number of components in the key stack (%d)", stack_elements_num); + return PKI_ERR; + } + // Dilithium5 component + X509_ALGOR_set0(&algor, OBJ_nid2obj(PKI_ALGOR_FALCON512), V_ASN1_UNDEF, NULL); + sk_X509_ALGOR_push(sk, X509_ALGOR_dup(&algor)); + // Falcon1024 component + X509_ALGOR_set0(&algor, OBJ_nid2obj(PKI_ALGOR_RSA), V_ASN1_UNDEF, NULL); + sk_X509_ALGOR_push(sk, X509_ALGOR_dup(&algor)); + // RSA component + ASN1_item_sign(asn1_item, + &algor, + NULL, + NULL, + NULL, + COMPOSITE_KEY_STACK_get0(components, 2), + EVP_sha256()); + // X509_ALGOR_set0(&algor, OBJ_nid2obj(PKI_ALGOR_RSA), V_ASN1_UNDEF, NULL); + sk_X509_ALGOR_push(sk, X509_ALGOR_dup(&algor)); + } break; + + default: + PKI_DEBUG("Explicit configuration for scheme %d not supported", scheme); + sk_X509_ALGOR_pop_free(sk, X509_ALGOR_free); + return PKI_ERR; + } + + int algor_num = sk_X509_ALGOR_num(sk); + int components_num = COMPOSITE_KEY_STACK_num(components); + + // Checks the number of components and algorithms to be the same + if (algor_num != components_num) { + PKI_DEBUG("Number of components (%d) and algorithms (%d) do not match", + COMPOSITE_KEY_STACK_num(components), sk_X509_ALGOR_num(ctx->sig_algs)); + sk_X509_ALGOR_pop_free(sk, X509_ALGOR_free); + return PKI_ERR; + } + + PKI_DEBUG("Same number of components and algorithms (%d)", sk_X509_ALGOR_num(sk)); + + // Cycles through the components and checks the pkey algors + for (int idx = 0; idx < COMPOSITE_KEY_STACK_num(components); idx++) { + + X509_ALGOR * algor = NULL; + // Pointer to a X509_ALGOR in the stack + + PKI_X509_KEYPAIR_VALUE * pkey = NULL; + // Pointer to a key in the components' stack + + int x_id = 0; + int x_type = 0; + int pkey_id = 0; + int md_id = 0; + // IDs of the pkey and the message digest + + PKI_DEBUG("Validating component #%d", idx); + + // Gets the component and the algorithm + pkey = COMPOSITE_KEY_STACK_value(components, idx); + if (!pkey) { + PKI_DEBUG("Cannot retrieve Key Component #%d", idx); + return PKI_ERR; + } + + // Gets the PKEY type + x_id = PKI_X509_KEYPAIR_VALUE_get_id(pkey); + x_type = EVP_PKEY_type(x_id); + if (x_type <= 0) { +#if OPENSSL_VERSION_NUMBER > 0x3000000fL + x_type = pkey_id; +#else + PKI_DEBUG("Cannot retrieve PKEY type for component #%d", idx); + return PKI_ERR; +#endif // End of OPENSSL_VERSION_NUMBER > 0x3000000fL + } + + // Gets the algorithm + algor = sk_X509_ALGOR_value(sk, idx); + + // Gets the PKEY and the MD IDs + if (!OBJ_find_sigid_algs(OBJ_obj2nid(algor->algorithm), &md_id, &pkey_id)) { + PKI_DEBUG("Cannot parse PKEY and MD IDs for algorithm %s from component #%d", + OBJ_nid2ln(OBJ_obj2nid(algor->algorithm)), idx); + sk_X509_ALGOR_pop_free(sk, X509_ALGOR_free); + return PKI_ERR; + } + + // Checks that the PKEY ID is valid + if (pkey_id == NID_undef) { + PKI_DEBUG("Cannot retrieve the PKEY ID for algorithm %s from component #%d", + OBJ_nid2ln(OBJ_obj2nid(algor->algorithm)), idx); + sk_X509_ALGOR_pop_free(sk, X509_ALGOR_free); + return PKI_ERR; + } + + // Make sure that the pkey type is the same + if (pkey_id != x_type) { + PKI_DEBUG("PKEY type (%d) and algorithm (%d) do not match in component #%d", + pkey_id, x_type, idx); + sk_X509_ALGOR_pop_free(sk, X509_ALGOR_free); + return PKI_ERR; + } + + PKI_DEBUG("SUCCESS: Verified Explicit Component #%d: PKEY ID = %d, MD ID = %d", + idx, pkey_id, md_id); + } + + // Updates the internal status + if (ctx->sig_algs) sk_X509_ALGOR_pop_free(ctx->sig_algs, X509_ALGOR_free); + ctx->sig_algs = sk; + + // Returns the stack of X509_ALGOR + if (algors) *algors = sk; + + // All Done + return PKI_OK; +} + +int COMPOSITE_CTX_algors_new0(COMPOSITE_CTX * ctx, + const int pkey_type, + const ASN1_ITEM * const asn1_item, + const COMPOSITE_KEY_STACK * const components, + X509_ALGORS ** algors) { + + int use_global_hash = 0; + const EVP_MD * global_hash = NULL; + // Global hash to be used for all the components + + X509_ALGORS * sk = NULL; + // Pointer to the new stack of X509_ALGOR + + PKI_DEBUG("Building the list of Algorithms"); + + // Input Checks + if (!ctx) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return PKI_ERR; + } + + // Warns about missing pkey_type + if (pkey_type == PKI_ID_UNKNOWN) { + PKI_DEBUG("Missing pkey_type when building the list of X509_ALGORS, using defaults"); + } + + // Checks for global hash + if (ctx->md && ctx->md != EVP_md_null()) { + use_global_hash = 1; + global_hash = ctx->md; + } + + if (!PKI_ID_is_composite(pkey_type, NULL)) { + PKI_DEBUG("PKEY type %d is not a composite key", pkey_type); + return PKI_ERR; + } + + // Allocates a new stack of X509_ALGOR + if ((sk = sk_X509_ALGOR_new_null()) == NULL) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return PKI_ERR; + } + + PKI_DEBUG("Allocated a new stack of X509_ALGOR, adding entries."); + + // Cycles through the components and adds the algors + for (int idx = 0; idx < COMPOSITE_KEY_STACK_num(components); idx++) { + + PKI_X509_KEYPAIR_VALUE * x = NULL; + PKI_SCHEME_ID x_scheme_id = PKI_SCHEME_UNKNOWN; + + const PKI_DIGEST_ALG * x_md = NULL; + + int algid = PKI_ALGOR_ID_UNKNOWN; + PKI_X509_ALGOR_VALUE * algor = NULL; + + PKI_DEBUG("(SigAlgs) Adding component #%d", idx); + + // Gets the component + x = COMPOSITE_KEY_STACK_get0(components, idx); + if (!x) { + sk_X509_ALGOR_pop_free(sk, X509_ALGOR_free); + PKI_DEBUG("Cannot get the component from the stack"); + return PKI_ERR; + } + +// // Gets the type of component (PKEY) +// int x_id = PKI_X509_KEYPAIR_VALUE_get_id(x); +// int x_type = EVP_PKEY_type(x_id); +// if (x_type <= 0) { +// #if OPENSSL_VERSION_NUMBER > 0x3000000fL +// x_type = x_id; +// #else +// sk_X509_ALGOR_pop_free(sk, X509_ALGOR_free); +// PKI_DEBUG("Cannot get the type of component #%d", idx); +// return PKI_ERR; +// #endif // End of OPENSSL_VERSION_NUMBER > 0x3000000fL +// } + + int x_type = PKI_X509_KEYPAIR_VALUE_get_id(x); + PKI_DEBUG("***** OSSL3 UPGRADE: GOT KEY ID %d (type)", x_type); + + // Checks we are not recursing + if (PKI_ID_is_composite(x_type, &x_scheme_id) || + PKI_ID_is_explicit_composite(x_type, &x_scheme_id)) { + // Error, we cannot have recursion + PKI_DEBUG("Recursion detected in component #%d (scheme: %d)", idx, x_scheme_id); + sk_X509_ALGOR_pop_free(sk, X509_ALGOR_free); + return PKI_ERR; + } + + PKI_DEBUG("(SigAlgs) Component %d is of type %d (%s)", idx, x_type, PKI_ID_get_txt(x_type)); + + // Gets the right MD + if (use_global_hash) { + // Use hash-n-sign if set + x_md = global_hash; + } else { + // Checks if the component requires the digest + // and we are not using the hash-n-sign paradigm + // let's use the configured default (if any) + if (PKI_ID_requires_digest(x_type)) { + + PKI_DEBUG("(SigAlgs) Digest is required for component %d", idx); + + int md_nid = 0; + md_nid = PKI_X509_KEYPAIR_VALUE_get_default_digest(x); + +// #if OPENSSL_VERSION_NUMBER > 0x30000000L +// char name_buf[50] = { 0x0 }; +// int digestResult = EVP_PKEY_get_default_digest_name(x, name_buf, sizeof(name_buf)); +// md_nid = OBJ_txt2nid(name_buf); +// #else +// int digestResult = EVP_PKEY_get_default_digest_nid(x, &md_nid); +// #endif + + // Search for a default digest for the type of key + if (md_nid < 0) { + PKI_DEBUG("***** OSSL3 UPGRADE: EVP_PKEY_get_default_digest_nid seems to fail *****"); + PKI_DEBUG("No default exists for component #%d, using library default (%d)", + idx, EVP_MD_type(PKI_DIGEST_ALG_DEFAULT)); + // Use the library's default for the digest + x_md = PKI_DIGEST_ALG_DEFAULT; + } else { + // Use the default digest for the key type + x_md = EVP_get_digestbynid(md_nid); + } + + } else { + + PKI_DEBUG("(SigAlgs) Digest is NOT required for component %d", idx); + x_md = NULL; + + } + } + + // Allocates a new X509_ALGOR + if ((algor = X509_ALGOR_new()) == NULL) { + sk_X509_ALGOR_pop_free(sk, X509_ALGOR_free); + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return PKI_ERR; + } + + if (asn1_item) { + + // Generating Parameters via the ASN1_item_sign() function + PKI_DEBUG("(SigAlgs) Using ASN1 item sign for component %d (algor: %s)", + idx, PKI_X509_ALGOR_VALUE_get_parsed(algor)); + + // Sets the parameter(s) and the algorithm identifier for the component + ASN1_item_sign(asn1_item, algor, NULL, NULL, NULL, x, x_md); + + } + + int algor_nid = OBJ_obj2nid(algor->algorithm); + PKI_DEBUG("(SigAlgs) After ASN1_item_sign component %d, the algorithm is set to => %s (%p) (algor->algorithm: %d)", + idx, PKI_X509_ALGOR_VALUE_get_parsed(algor), algor->algorithm, algor_nid, OBJ_obj2nid(algor->algorithm)); + + // If the algorithm is still NULL, we add the OIDs ourselves + if (!algor->algorithm || !OBJ_obj2nid(algor->algorithm)) { + + PKI_DEBUG("(SigAlgs) Since the Algorithm is still NULL, we add the OIDs ourselves %d (algor: %s)", + idx, PKI_X509_ALGOR_VALUE_get_parsed(algor)); + + // If PQC, the OBJ_find_sigid_by_algs() does not seem to work, + // we use a different approach + if (PKI_ID_is_pqc(x_type, NULL) && !use_global_hash) { + // Use the same ID for key and algorithm + algid = x_type; + + } else { + + PKI_DEBUG("(SigAlgs) No ASN1 item provided %d (algor: %s)", + idx, PKI_X509_ALGOR_VALUE_get_parsed(algor)); + + // Retrieves the algorithm identifier + if (!OBJ_find_sigid_by_algs(&algid, + x_md && x_md != PKI_DIGEST_ALG_NULL ? EVP_MD_type(x_md) : PKI_DIGEST_ALG_ID_UNKNOWN, + x_type)) { + + // Checks for special use-cases + if (x_type == PKI_ALGOR_ID_ED25519 || + x_type == PKI_ALGOR_ID_ED448) { + + // EdDSA does not require a digest but they + // only support digestsign() and digestverify() + // + // When we enable signing with an empty digest, the algorithms + // do not seem to be performing correctly, so we disable it + // + // To re-enable them, just uncomment the following line + algid = x_type; + + // To disable them, just uncomment the following code + // if (algor) X509_ALGOR_free(algor); + // sk_X509_ALGOR_pop_free(sk, X509_ALGOR_free); + // return PKI_ERR; + + } else { + + // Cannot find the algorithm + PKI_DEBUG("Global Hash is selected (%s), but cannot find signature alg for component #%d (pkey: %d)", + EVP_MD_name(x_md), idx, x_type); + if (algor) X509_ALGOR_free(algor); + sk_X509_ALGOR_pop_free(sk, X509_ALGOR_free); + return PKI_ERR; + } + } + } + + PKI_DEBUG("(SigAlgs) X509 Algor Generated without ASN1_item_sign() for component %d. " + "Setting the OID (%d) and NO parameters (%s)", idx, algid, OBJ_nid2ln(algid)); + + // Sets the algorithm identifier in the X509_ALGOR + if (!X509_ALGOR_set0(algor, OBJ_nid2obj(algid), V_ASN1_UNDEF, NULL)) { + // Cannot set the algorithm identifier + PKI_ERROR(PKI_ERR_GENERAL, "Cannot set the algorithm identifier"); + if (algor) X509_ALGOR_free(algor); + if (sk) sk_X509_ALGOR_pop_free(sk, X509_ALGOR_free); + return PKI_ERR; + } + } + + PKI_DEBUG("(SigAlgs) Pushing the algorithm to the stack for component %d", idx); + + // Adds the algorithm to the stack + if (!sk_X509_ALGOR_push(sk, algor)) { + PKI_ERROR(PKI_ERR_GENERAL, "Cannot push the algorithm to the stack"); + X509_ALGOR_free(algor); + sk_X509_ALGOR_pop_free(*algors, X509_ALGOR_free); + return PKI_ERR; + } + } + + // Updates the internal cache + if (ctx->sig_algs) sk_X509_ALGOR_pop_free(ctx->sig_algs, X509_ALGOR_free); + ctx->sig_algs = sk; + + // Also sets the output variable + if (algors) *algors = sk; + + PKI_DEBUG("(SigAlgs) Done generating the signature algorithms"); + + // All Done + return PKI_OK; +} + +int COMPOSITE_CTX_algors_get0(const COMPOSITE_CTX * const ctx, + const X509_ALGORS ** const algors) { + + // Input Checks + if (!ctx || !algors) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return PKI_ERR; + } + + *algors = ctx->sig_algs; + + return PKI_OK; +} + +int COMPOSITE_CTX_algors_set0(COMPOSITE_CTX * const ctx, + X509_ALGORS * const algors) { + + // Input Checks + if (!ctx || !algors) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return PKI_ERR; + } + + // Clears the internal values and transfer ownership + if (ctx->sig_algs) sk_X509_ALGOR_pop_free(ctx->sig_algs, X509_ALGOR_free); + ctx->sig_algs = algors; + + // All Done + return PKI_OK; +} + +int COMPOSITE_CTX_algors_detach(COMPOSITE_CTX * const ctx, + X509_ALGORS ** const algors) { + + // Input Checks + if (!ctx) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return PKI_ERR; + } + + // Clears the internal values and transfer ownership + if (algors) *algors = ctx->sig_algs; + ctx->sig_algs = NULL; + + // All Done + return PKI_OK; +} + +int COMPOSITE_CTX_set_kofn(COMPOSITE_CTX * ctx, int kofn) { + + // Input Checks + if (!ctx) return PKI_ERR; + + // Sets the K-of-N value + if (!ctx->params) ASN1_INTEGER_new(); + ASN1_INTEGER_set(ctx->params, kofn); + + // All Done + return PKI_OK; +} + +int COMPOSITE_CTX_get_kofn(COMPOSITE_CTX * ctx) { + + int ret = 0; + // Return value + + // Input Checks + if (!ctx) return PKI_ERR; + + // Returns the K-of-N value + ret = (int) ASN1_INTEGER_get(ctx->params); + + // All Done + return ret; +} + +#endif // ENABLE_COMPOSITE + +/* END: composite_ctx.c */ diff --git a/src/crypto/composite/composite_err.c b/src/crypto/composite/composite_err.c new file mode 100644 index 00000000..1d8b554e --- /dev/null +++ b/src/crypto/composite/composite_err.c @@ -0,0 +1,42 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +// #include +// // #include + +// #ifndef OPENSSL_NO_ERR + +// static const ERR_STRING_DATA COMPOSITE_str_functs[] = { +// // {ERR_PACK(ERR_LIB_COMPOSITE, EC_F_BN_TO_FELEM, 0), "BN_to_felem"}, +// {0, NULL} +// }; + +// static const ERR_STRING_DATA COMPOSITE_str_reasons[] = { +// // {ERR_PACK(ERR_LIB_COMPOSITE, 0, COMPOSITE_R_ASN1_ERROR), "asn1 error"}, +// // {ERR_PACK(ERR_LIB_COMPOSITE, 0, COMPOSITE_R_BAD_SIGNATURE), "bad signature"}, +// // {ERR_PACK(ERR_LIB_COMPOSITE, 0, ECOMPOSITE_R_WRONG_DIGEST), "wrong digest"}, +// // {ERR_PACK(ERR_LIB_COMPOSITE, 0, COMPOSITE_R_WRONG_LENGTH), "wrong length"}, +// // {ERR_PACK(ERR_LIB_COMPOSITE, 0, COMPOSITE_R_WRONG_ORDER), "wrong order"}, +// // {ERR_PACK(ERR_LIB_COMPOSITE, 0, COMPOSITE_R_WRONG_PARAMETERS), "wrong parameters"}, +// {0, NULL} +// }; + +// #endif + +// int ERR_load_COMPOSITE_strings(void) +// { +// #ifndef OPENSSL_NO_ERR +// // if (ERR_func_error_string(COMPOSITE_str_functs[0].error) == NULL) { +// // ERR_load_strings_const(COMPOSITE_str_functs); +// // ERR_load_strings_const(COMPOSITE_str_reasons); +// // } +// #endif +// return 1; +// } diff --git a/src/crypto/composite/composite_init.c b/src/crypto/composite/composite_init.c new file mode 100644 index 00000000..8b50717b --- /dev/null +++ b/src/crypto/composite/composite_init.c @@ -0,0 +1,487 @@ + +// =============== +// Public Includes +// =============== + +#ifndef _LIBPKI_COMPOSITE_INIT_H +#include +#endif + +// ============== +// Local Includes +// ============== + +#ifndef _LIBPKI_OS_H +#include +#endif + +#ifndef _LIBPKI_COMPAT_H +#include +#endif + +#ifndef _LIBPKI_OID_DEFS_H +#include +#endif + +#ifndef _LIBPKI_PQC_DEFS_H +#include +#endif + +#ifndef _LIBPKI_COMPOSITE_UTILS_H +#include +#endif + +#ifndef _LIBPKI_COMPOSITE_PKEY_METH_H +#include +#endif + +#ifndef _LIBPKI_LOG_H +#include +#endif + +#ifndef LIBPKI_X509_DATA_ST_H +#include "../internal/x509_data_st.h" +#endif + +#ifndef _LIBPKI_COMPOSITE_ASN1_METH_H +#include "composite_ameth_lcl.h" +#endif + +// Composite Methods +extern EVP_PKEY_ASN1_METHOD composite_asn1_meth; +extern EVP_PKEY_METHOD composite_pkey_meth; + +#define PKI_REGISTER_PKEY_METH(ALG, OID) \ + PKI_PQC_asn1_meth_set_id(&ALG##_ASN1_METH, OBJ_txt2nid(OID)); \ + if (EVP_PKEY_meth_add0(&ALG##_PKEY_METH)) { \ + EVP_PKEY_asn1_add0(&ALG##_ASN1_METH); \ + } else { \ + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Cannot add PKEY method"); \ + } + +// ==== +// Data +// ==== + +// // TODO: +// // ===== +// // +// // Update the way we add the composite ASN1 method. Currently we use the +// // auxillary function (see composite_ameth.c) to set the method's pkey id. +// // +// // The Right way to add a new method would be to first generate a new +// // one and then set the different callbacks, such as: +// // +// // composite_asn1_method = EVP_PKEY_asn1_meth_new(NID_composite); +// // EVP_PKEY_asn1_meth_set_XXX(composite_asn1_method, .... ); + +// // Retrieves the COMPOSITE id +// int composite_id = OBJ_txt2nid(OPENCA_ALG_PKEY_EXP_COMP_OID); + +// // Assigns the generated IDs +// EVP_PKEY_asn1_meth_set_id(&composite_asn1_meth, composite_id); + +// // Assigns the PKEY ID +// EVP_PKEY_meth_set_id(&composite_pkey_meth, composite_id, -1); // EVP_PKEY_FLAG_SIGCTX_CUSTOM + +// // We also Need to initialize the PKEY method for the algorithm +// // https://www.openssl.org/docs/man1.1.1/man3/EVP_PKEY_METHOD.html +// if (!EVP_PKEY_meth_add0(&composite_pkey_meth)) return 0; + +// // We Need to initialize the ASN1 conversion method +// // https://www.openssl.org/docs/man1.1.1/man3/EVP_PKEY_ASN1_METHOD.html +// if (!EVP_PKEY_asn1_add0(&composite_asn1_meth)) return 0; + +// // All Done, Success. +// return 1; +// } + + +// ================ +// Local Prototypes +// ================ + +int PKI_COMPOSITE_asn1_meth_set_id(EVP_PKEY_ASN1_METHOD * pkey_ameth, int pkey_id); + +EVP_PKEY_METHOD * PKI_COMPOSITE_PKEY_METH_new(int nid, int flags); + +EVP_PKEY_ASN1_METHOD * PKI_COMPOSITE_PKEY_ASN1_METH_new(int nid, + int flags, + const char * const pem_str, + const char * const info); + +int PKI_COMPOSITE_ALG_new(const char * name, int flags); + +// ========= +// Functions +// ========= + +int PKI_COMPOSITE_asn1_meth_set_id(EVP_PKEY_ASN1_METHOD * pkey_ameth, int pkey_id) { + + // Input Check + if (!pkey_ameth || pkey_id <= 0) return 0; + + // Assigns the generated IDs + pkey_ameth->pkey_id = pkey_id; + pkey_ameth->pkey_base_id = pkey_id; + pkey_ameth->pkey_id = pkey_id; + + // All Done + return 1; +}; + +EVP_PKEY_METHOD * PKI_COMPOSITE_PKEY_METH_new(int nid, int flags) { + + // Input check + if (nid <= 0) { + PKI_ERROR(PKI_ERR_PARAM_RANGE, "Out-of-Range NID for PKEY method"); + return NULL; + } + + // Initializes the PKEY method first + EVP_PKEY_METHOD * pkey_meth = EVP_PKEY_meth_new(nid, flags); + if (!pkey_meth) { + PKI_ERROR(PKI_ERR_ALGOR_SET, "Cannot create a new PKEY method"); + return NULL; + } + + // ------------------------------ + // PKEY Let's add all the methods + // ------------------------------ + + // // Copy + // EVP_PKEY_meth_set_copy(pkey_meth, pkey_oqs_copy); + + // // Key Generation + // EVP_PKEY_meth_set_keygen(pkey_meth, NULL, pkey_oqs_keygen); + + // // Sign & Sign Init + // EVP_PKEY_meth_set_sign(pkey_meth, pkey_oqs_sign_init, pkey_oqs_sign); + + // // // Verify & Verify Init + // EVP_PKEY_meth_set_verify(pkey_meth, pkey_oqs_verify_init, pkey_oqs_verify); + + // // // SignCTX and SignCTX Init + // EVP_PKEY_meth_set_signctx(pkey_meth, pkey_oqs_signctx_init, pkey_oqs_signctx); + + // // // VerifyCTX and VerifyCTX Init + // EVP_PKEY_meth_set_verifyctx(pkey_meth, pkey_oqs_verifyctx_init, pkey_oqs_verifyctx); + + // // // CTRL & CTRL str + // EVP_PKEY_meth_set_ctrl(pkey_meth, pkey_oqs_ctrl, NULL); + + // // // Digest Sign + // EVP_PKEY_meth_set_digestsign(pkey_meth, pkey_oqs_digestsign); + + // // // Digest Verify + // EVP_PKEY_meth_set_digestverify(pkey_meth, pkey_oqs_digestverify); + + // // // Digest Custom + // EVP_PKEY_meth_set_digest_custom(pkey_meth, pkey_oqs_digestcustom); + + // All Done + return pkey_meth; +} + +EVP_PKEY_ASN1_METHOD * PKI_COMPOSITE_PKEY_ASN1_METH_new(int nid, + int flags, + const char * const pem_str, + const char * const info) { + + if (nid <= 0) { + PKI_ERROR(PKI_ERR_PARAM_RANGE, "Out-of-Range NID for ASN1 PKEY creation"); + return NULL; + } + + // Generates a new ASN1 PKEY method + EVP_PKEY_ASN1_METHOD * a_meth = EVP_PKEY_asn1_new(nid, + flags, + pem_str ? pem_str : OBJ_nid2sn(nid), + info); + + // // We need to add all the different methods + + // // // Sets the Public Key methods + // EVP_PKEY_asn1_set_public(a_meth, + // oqs_pub_decode, + // oqs_pub_encode, + // oqs_pub_cmp, + // oqs_pub_print, + // oqs_size_lcl, + // oqs_bits + // ); + + // // Sets the Private Key methods + // EVP_PKEY_asn1_set_private(a_meth, + // oqs_priv_decode, + // oqs_priv_encode, + // oqs_priv_print + // ); + + // // Sets the Param + // EVP_PKEY_asn1_set_param(a_meth, + // NULL, // oqs_param_decode, + // NULL, // oqs_param_encode, + // NULL, // oqs_param_missing, + // NULL, // oqs_param_copy, + // NULL, // oqs_param_cmp, + // NULL // oqs_param_print) + // ); + + // EVP_PKEY_asn1_set_free(a_meth, oqs_free); + + // EVP_PKEY_asn1_set_ctrl(a_meth, oqs_ameth_pkey_ctrl); + + // // Need to check this one + // EVP_PKEY_asn1_set_security_bits(a_meth, oqs_security_bits); + + // // item_sign and set_siginfo are algorithm-dependent + // // therefore we select the right functions based on + // // the nid value + // int (*fnc_item_sign)(EVP_MD_CTX *ctx, + // const ASN1_ITEM *it, + // void *asn, + // X509_ALGOR *alg1, + // X509_ALGOR *alg2, + // ASN1_BIT_STRING *sig) = NULL; + + // int (*fnc_set_siginfo)(X509_SIG_INFO *siginf, + // const X509_ALGOR *alg, + // const ASN1_STRING *sig) = NULL; + + // // Here we need to assign the functions dynamically + // // so that the right algorithm OID is used when + // // signing and setting the sig info + + // if (OBJ_sn2nid("dilithium2") == nid) { + // fnc_item_sign = oqs_item_sign_dilithium2; + // fnc_set_siginfo = oqs_sig_info_set_dilithium2; + // } else if (OBJ_sn2nid("dilithium3") == nid) { + // fnc_item_sign = oqs_item_sign_dilithium3; + // fnc_set_siginfo = oqs_sig_info_set_dilithium3; + // } else if (OBJ_sn2nid("dilithium5") == nid) { + // fnc_item_sign = oqs_item_sign_dilithium5; + // fnc_set_siginfo = oqs_sig_info_set_dilithium5; + // } else if (OBJ_sn2nid("falcon512") == nid) { + // fnc_item_sign = oqs_item_sign_falcon512; + // fnc_set_siginfo = oqs_sig_info_set_falcon512; + // } else if (OBJ_sn2nid("falcon1024") == nid) { + // fnc_item_sign = oqs_item_sign_falcon1024; + // fnc_set_siginfo = oqs_sig_info_set_falcon1024; + // } else if (OBJ_sn2nid("DilithiumX3") == nid || + // OBJ_sn2nid("dilithiumX3") == nid) { + // fnc_item_sign = oqs_item_sign_dilithiumX; + // fnc_set_siginfo = oqs_sig_info_set_dilithiumX; + // } else { + // fprintf(stderr, "Unsupported NID: %d\n", nid); + // fflush(stderr); + // // PKI_ERROR(PKI_ERR_ALGOR_UNKNOWN, "Unsupported NID %d (%s)", nid, OBJ_nid2sn(nid)); + // return NULL; + // } + + // // Sets the algorithm-dependent functions + // EVP_PKEY_asn1_set_item(a_meth, oqs_item_verify, fnc_item_sign); + // EVP_PKEY_asn1_set_siginf(a_meth, fnc_set_siginfo); + + // // Unused methods + // EVP_PKEY_asn1_set_check(a_meth, NULL); + // EVP_PKEY_asn1_set_public_check(a_meth, NULL); + // EVP_PKEY_asn1_set_param_check(a_meth, NULL); + + // EVP_PKEY_asn1_set_set_priv_key(a_meth, NULL); + // EVP_PKEY_asn1_set_set_pub_key(a_meth, NULL); + // EVP_PKEY_asn1_set_get_priv_key(a_meth, NULL); + // EVP_PKEY_asn1_set_get_pub_key(a_meth, NULL); + + // All Done + return a_meth; +}; + +int PKI_COMPOSITE_ALG_new(const char * name, int flags) { + + // Input Check + if (!name || strlen(name) <= 0) return PKI_ERR; + + // Retrieves the NID associated with the algorithm + int nid = OBJ_sn2nid(name); + if (nid == NID_undef) { + PKI_DEBUG("Cannot find the ID for %s algorithm", name); + return PKI_ERR; + } + + // Checks the input flags + if (flags < 0) flags = EVP_PKEY_FLAG_SIGCTX_CUSTOM; + + // ---------------------------------- + // Generates and Adds the PKEY method + // ---------------------------------- + + EVP_PKEY_METHOD * p_meth = PKI_COMPOSITE_PKEY_METH_new(nid, flags); + if (!p_meth) { + PKI_ERROR(PKI_ERR_ALGOR_PKEY_METHOD_NEW, "Cannot generate the PKEY method for %d (%s)\n", nid, name); + return PKI_ERR; + } + + // Adds the Method + if (!EVP_PKEY_meth_add0(p_meth)) { + PKI_ERROR(PKI_ERR_ALGOR_PKEY_METHOD_ADD, "Cannot Add the PKEY Method for %d (%s)", nid, name); + if (p_meth) EVP_PKEY_meth_free(p_meth); + return PKI_ERR; + } + + // Checks that the new method is added correctly + const EVP_PKEY_METHOD * tmp_p_meth = EVP_PKEY_meth_find(nid); + if (!tmp_p_meth) { + PKI_ERROR(PKI_ERR_ALGOR_PKEY_ASN1_METHOD_NEW, "Cannot find the PKEY method just added (%d)!\n", nid); + return PKI_ERR; + } + + // ---------------------------------- + // Now we need to add the ASN1 method + // ---------------------------------- + + EVP_PKEY_ASN1_METHOD * a_meth = PKI_COMPOSITE_PKEY_ASN1_METH_new(nid, 0, name, name); + if (!a_meth) { + PKI_ERROR(PKI_ERR_ALGOR_SET, "Cannot generate the PKEY ASN1 method for %d (%s)\n", nid, name); + fflush(stderr); + return PKI_ERR; + } + + // Adds the ASN1 method to the list of available ones + if (1 != EVP_PKEY_asn1_add0(a_meth)) { + PKI_ERROR(PKI_ERR_ALGOR_SET, "Cannot Set the ASN1 PKEY method for %d (%s)", nid, name); + if (a_meth) EVP_PKEY_asn1_free(a_meth); + return PKI_ERR; + } + + // All Done + return PKI_OK; +}; + +int PKI_COMPOSITE_init() { + + // Retrieves the COMPOSITE id + int composite_id = OBJ_txt2nid(OPENCA_ALG_PKEY_EXP_COMP_OID); + + EVP_PKEY_ASN1_METHOD * dyn_asn1_meth = PKI_Malloc(sizeof(EVP_PKEY_ASN1_METHOD)); + // The dynamically allocated ASN1 method + + EVP_PKEY_METHOD * dyn_pkey_meth = PKI_Malloc(sizeof(EVP_PKEY_METHOD)); + // The dynamically allocated PKEY method + + // Checks that the memory has been allocated + if (!dyn_asn1_meth || !dyn_pkey_meth) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + if (dyn_asn1_meth) PKI_Free(dyn_asn1_meth); + if (dyn_pkey_meth) PKI_Free(dyn_pkey_meth); + return PKI_ERR; + } + + // Copies our templates + memcpy(dyn_asn1_meth, &composite_asn1_meth, sizeof(EVP_PKEY_ASN1_METHOD)); + memcpy(dyn_pkey_meth, &composite_pkey_meth, sizeof(EVP_PKEY_METHOD)); + + // Assigns the generated IDs + EVP_PKEY_asn1_meth_set_id(dyn_asn1_meth, composite_id); + + // Assigns the PKEY ID + EVP_PKEY_meth_set_id(dyn_pkey_meth, composite_id, -1); // EVP_PKEY_FLAG_SIGCTX_CUSTOM + +// We also Need to initialize the PKEY method for the algorithm + // https://www.openssl.org/docs/man1.1.1/man3/EVP_PKEY_METHOD.html + if (!EVP_PKEY_meth_add0(dyn_pkey_meth)) { + PKI_DEBUG("ERROR::EVP_PKEY_meth_add0 (%s)", OPENCA_ALG_PKEY_EXP_COMP_OID); + PKI_Free(dyn_asn1_meth); + PKI_Free(dyn_pkey_meth); + return PKI_ERR; + } + + // We Need to initialize the ASN1 conversion method + // https://www.openssl.org/docs/man1.1.1/man3/EVP_PKEY_ASN1_METHOD.html + if (!EVP_PKEY_asn1_add0(dyn_asn1_meth)) { + PKI_DEBUG("ERROR::EVP_PKEY_asn1_add0 (%s)",OPENCA_ALG_PKEY_EXP_COMP_OID); + PKI_Free(dyn_asn1_meth); + PKI_Free(dyn_pkey_meth); + return PKI_ERR; + } + + // All Done + return PKI_OK; +}; + +int PKI_EXPLICIT_COMPOSITE_init() { + + + char * methods_oids[] = { + OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_RSA_SHA256_OID, + OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_P256_SHA256_OID, + OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_BRAINPOOL256_SHA256_OID, + OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_ED25519_OID, + OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_BRAINPOOL384_SHA384_OID, + OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_ED448_OID, + OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_FALCON512_P256_SHA256_OID, + OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_FALCON512_BRAINPOOL256_SHA256_OID, + OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_FALCON512_ED25519_OID, + // OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_SPHINCS256_P256_SHA256_OID, + // OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_SPHINCS256_BRAINPOOL256_SHA256_OID, + // OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_SPHINCS256_ED25519_OID, + OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_RSAPSS_SHA256_OID, + OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_FALCON512_RSA_SHA256_OID, + OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_FALCON1024_P521_SHA512_OID, + OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_FALCON1024_RSA_SHA256_OID, + // OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_SPHINCS256_RSA_SHA256_OID, + NULL, + }; + + for (int i = 0; methods_oids[i] != NULL; i++ ) { + + // Retrieves the ID for the Explicit PKEY + int explicit_comp_id = OBJ_txt2nid(methods_oids[i]); + + EVP_PKEY_ASN1_METHOD * dyn_asn1_meth = PKI_Malloc(sizeof(EVP_PKEY_ASN1_METHOD)); + // The dynamically allocated ASN1 method + + EVP_PKEY_METHOD * dyn_pkey_meth = PKI_Malloc(sizeof(EVP_PKEY_METHOD)); + // The dynamically allocated PKEY method + + // Checks that the memory has been allocated + if (!dyn_asn1_meth || !dyn_pkey_meth) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + if (dyn_asn1_meth) PKI_Free(dyn_asn1_meth); + if (dyn_pkey_meth) PKI_Free(dyn_pkey_meth); + return PKI_ERR; + } + + // Copies our templates + memcpy(dyn_asn1_meth, &composite_asn1_meth, sizeof(EVP_PKEY_ASN1_METHOD)); + memcpy(dyn_pkey_meth, &composite_pkey_meth, sizeof(EVP_PKEY_METHOD)); + + // Assigns the generated IDs + EVP_PKEY_asn1_meth_set_id(dyn_asn1_meth, explicit_comp_id); + + // Assigns the PKEY ID + EVP_PKEY_meth_set_id(dyn_pkey_meth, explicit_comp_id, -1); // EVP_PKEY_FLAG_SIGCTX_CUSTOM + + // We also Need to initialize the PKEY method for the algorithm + // https://www.openssl.org/docs/man1.1.1/man3/EVP_PKEY_METHOD.html + if (!EVP_PKEY_meth_add0(dyn_pkey_meth)) { + PKI_DEBUG("ERROR::EVP_PKEY_meth_add0 (%s)", methods_oids[i]); + PKI_Free(dyn_asn1_meth); + PKI_Free(dyn_pkey_meth); + continue; + } + + // We Need to initialize the ASN1 conversion method + // https://www.openssl.org/docs/man1.1.1/man3/EVP_PKEY_ASN1_METHOD.html + if (!EVP_PKEY_asn1_add0(dyn_asn1_meth)) { + PKI_DEBUG("ERROR::EVP_PKEY_asn1_add0 (%s)", methods_oids[i]); + PKI_Free(dyn_asn1_meth); + PKI_Free(dyn_pkey_meth); + continue; + } + + } + + // All Done + return PKI_OK; +}; \ No newline at end of file diff --git a/src/crypto/composite/composite_key.c b/src/crypto/composite/composite_key.c new file mode 100644 index 00000000..ea924add --- /dev/null +++ b/src/crypto/composite/composite_key.c @@ -0,0 +1,408 @@ +// BEGIN: composite_utils.c + +// Composite Crypto authentication methods. +// (c) 2021 by Massimiliano Pala + +#ifndef _LIBPKI_COMPOSITE_UTILS_H +#include +#endif + +#ifndef _LIBPKI_COMPOSITE_KEY_H +#include +#endif + +// =============== +// Data Structures +// =============== + +#ifndef _LIBPKI_COMPOSITE_OPENSSL_LOCAL_H +#include "composite_ossl_lcl.h" +#endif + +// ========================== +// Exported Functions: STACKs +// ========================== + +void COMPOSITE_KEY_STACK_clear(COMPOSITE_KEY_STACK * sk) { + + // Free all the entries, but not the stack structure itself + PKI_X509_KEYPAIR_VALUE * tmp_x; + + while (sk != NULL && (tmp_x = sk_EVP_PKEY_pop(sk)) != NULL) { + // Frees the component + if (tmp_x) EVP_PKEY_free(tmp_x); + } + +} + +void COMPOSITE_MD_STACK_clear(COMPOSITE_MD_STACK * sk) { + + // Free all the entries, but not the stack structure itself + const PKI_DIGEST_ALG * tmp_x; + + // Removes the entries from the stack but do not + // free them (they are all const pointers) + while (sk != NULL && sk_EVP_MD_num(sk) > 0) { + tmp_x = sk_EVP_MD_pop(sk); + if (!tmp_x) continue; + } + + // All Done + return; +} + +void COMPOSITE_MD_STACK_pop_free(COMPOSITE_MD_STACK * sk) { + + // Input Checks + if (!sk) return; + + // Removes all the entries but do not free the memory + // because they are all const pointers + while (sk != NULL && sk_EVP_MD_num(sk) > 0) { + sk_EVP_MD_pop(sk); + } + + // Free the STACK structure itself + sk_EVP_MD_free(sk); + + // All Done + return; +} + + +// ======================= +// Exported Functions: KEY +// ======================= + +COMPOSITE_KEY * COMPOSITE_KEY_new(void) { + + COMPOSITE_KEY * ret = NULL; + // Return Value + + // Allocates the memory structures + if ((ret = PKI_Malloc(sizeof(COMPOSITE_KEY))) == NULL || + ((ret->components = COMPOSITE_KEY_STACK_new()) == NULL)) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return NULL; + } + + // Sets the validation param to default value + ret->params = NULL; + + // All Done + return ret; +} + +COMPOSITE_KEY * COMPOSITE_KEY_dup(const COMPOSITE_KEY * const key) { + + COMPOSITE_KEY * ret = NULL; + // Return structure + + // Input checks + if (!key) return NULL; + + // Allocates the memory + if ((ret = COMPOSITE_KEY_new()) == NULL) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return NULL; + } + + // Copy the K param + if (key->params) { + ret->params = ASN1_INTEGER_dup(key->params); + if (!ret->params) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + COMPOSITE_KEY_free(ret); + return NULL; + } + } + + // Duplicates the stack + for (int i = 0; i < COMPOSITE_KEY_STACK_num(key->components); i++) { + + PKI_X509_KEYPAIR_VALUE * val = NULL; + // Pointer to the element to duplicate + + PKI_X509_KEYPAIR * dup = NULL; + // Duplicated component's value + + PKI_MEM * buff = NULL; + // Temporary Buffer structure + + PKI_X509 wrapper; + // Wrapper for the duplicated value + + // Retrieves the value to duplicate + if ((val = COMPOSITE_KEY_STACK_value(key->components, i)) == NULL) continue; + + // Duplicates the value by serializing and deserializing it + PKI_X509_KEYPAIR_put_mem(&wrapper, PKI_DATA_FORMAT_ASN1, &buff, NULL, NULL); + if (!buff) { + PKI_ERROR(PKI_ERR_HSM_KEYPAIR_EXPORT, NULL); + goto err; + } + + // De-Serializes the data from the buffer + dup = PKI_X509_KEYPAIR_get_mem(buff, PKI_DATA_FORMAT_ASN1, NULL); + if (!dup) { + PKI_ERROR(PKI_ERR_HSM_KEYPAIR_EXPORT, NULL); + PKI_MEM_free(buff); + goto err; + } + + // Free the buffer memory + PKI_MEM_free(buff); + buff = NULL; + + // Adds the value to the return object stack + if (!COMPOSITE_KEY_STACK_push(ret->components, PKI_X509_get_value(dup))) { + PKI_ERROR(PKI_ERR_HSM_KEYPAIR_IMPORT, NULL); + PKI_X509_free(dup); + goto err; + } + + // Frees the memory + // + // NOTE: we don't free the wrapper, since it's a stack variable + // and it will be freed automatically when the function + // returns + // + + } + + // All Done + return ret; + +err: + + // Free Memory + if (ret) COMPOSITE_KEY_free(ret); + + // Error Condition + return NULL; +} + +int COMPOSITE_KEY_push(COMPOSITE_KEY * key, PKI_X509_KEYPAIR_VALUE * val) { + + if (!key || !key->components || !val) return 0; + + return COMPOSITE_KEY_STACK_push(key->components, val); +} + +PKI_X509_KEYPAIR_VALUE * COMPOSITE_KEY_pop(COMPOSITE_KEY * key) { + + if (!key || !key->components) return NULL; + + return COMPOSITE_KEY_STACK_pop(key->components); +} + +void COMPOSITE_KEY_pop_free(COMPOSITE_KEY * key) { + + if (!key || !key->components) return; + + COMPOSITE_KEY_STACK_pop_free(key->components); + key->components = NULL; +} + + +int COMPOSITE_KEY_num(COMPOSITE_KEY * key) { + + if (!key || !key->components) return 0; + + return COMPOSITE_KEY_STACK_num(key->components); +} + +PKI_X509_KEYPAIR_VALUE * COMPOSITE_KEY_value(COMPOSITE_KEY * key, int num) { + if (!key || !key->components) return 0; + return COMPOSITE_KEY_STACK_value(key->components, num); +} + +int COMPOSITE_KEY_add(COMPOSITE_KEY * key, PKI_X509_KEYPAIR_VALUE * value, int num) { + + if (!key || !key->components || !value) return PKI_ERR; + + return COMPOSITE_KEY_STACK_add(key->components, value, num); +} + +int COMPOSITE_KEY_del(COMPOSITE_KEY * key, int num) { + + if (!key || !key->components) return PKI_ERR; + + COMPOSITE_KEY_STACK_del(key->components, num); + + return PKI_OK; +} + +// Free all components of the key +int COMPOSITE_KEY_clear(COMPOSITE_KEY *key) { + + if (!key) return PKI_ERR; + + // Clears (and free) the stack of key components + COMPOSITE_KEY_STACK_clear(key->components); + + // Clears the params + if (key->params) ASN1_INTEGER_free(key->params); + key->params = NULL; + + // All Done + return PKI_OK; +} + + +int COMPOSITE_KEY_size(COMPOSITE_KEY * key) { + + int i = 0; + int key_num = 0; + int total_size = 0; + + // Input Checks + if (!key) return -1; + + // Retrieves the number of components + if ((key_num = COMPOSITE_KEY_num(key)) <= 0) return PKI_ERR; + + // Process the individual keys + for (i = 0; i < key_num; i++) { + + const EVP_PKEY * single_key = NULL; + // Pointer to the component + + // Retrieves the component + if ((single_key = COMPOSITE_KEY_get0(key, i)) == NULL) { + PKI_DEBUG("ERROR: Cannot get key %d", i); + return 0; + } + + // Updates the total size + total_size += EVP_PKEY_size(single_key); + } + + // All Done + return total_size; +} + +int COMPOSITE_KEY_bits(COMPOSITE_KEY * key) { + + int i = 0; + int key_num = 0; + int total_bits = 0; + + // Input Checks + if (!key) return -1; + + // Returns '0' if no components were found + if ((key_num = COMPOSITE_KEY_num(key)) <= 0) return 0; + + // Process the individual components + for (i = 0; i < key_num; i++) { + + const EVP_PKEY * single_key = NULL; + // Pointer for the component + + if ((single_key = COMPOSITE_KEY_get0(key, i)) == NULL) { + PKI_DEBUG("ERROR: Cannot get key %d", i); + return -1; + } + + // Updates the total size + total_bits += EVP_PKEY_bits(single_key); + } + + // Total bits + return total_bits; +} + +int COMPOSITE_KEY_security_bits(COMPOSITE_KEY * key) { + + int i = 0; + int key_num = 0; + int sec_bits = INT_MAX; + int component_sec_bits = INT_MAX; + + // Input checks + if (!key) return -1; + + // Checks we have at least one component + if ((key_num = COMPOSITE_KEY_num(key)) <= 0) return -1; + + // Cycles through all the components + for (i = 0; i < key_num; i++) { + + const EVP_PKEY * single_key; + // Pouinter to the individual component + + // Retrieves the component key + if ((single_key = COMPOSITE_KEY_get0(key, i)) == NULL) { + PKI_DEBUG("ERROR: Cannot get key %d", i); + return -1; + } + + // Retrieves the security bits for the component + component_sec_bits = EVP_PKEY_security_bits(single_key); + + // Updates the composite security bits if the component's + // strength is higher than the previous components + if (sec_bits < component_sec_bits) sec_bits = component_sec_bits; + } + + // All Done + return sec_bits; +} + +void COMPOSITE_KEY_free(COMPOSITE_KEY * key) { + + // Input Checks + if (!key) return; + + // Clears the components + COMPOSITE_KEY_STACK_pop_free(key->components); + + // Clears the params + if (key->params) ASN1_INTEGER_free(key->params); + + // Free the memory + PKI_ZFree(key, sizeof(COMPOSITE_KEY)); +} + +int COMPOSITE_KEY_set_kofn(COMPOSITE_KEY * comp_key, int kofn) { + + // Input Checks + if (!comp_key) return PKI_ERR; + + // Sets the K-of-N value + if (!comp_key->params) ASN1_INTEGER_new(); + ASN1_INTEGER_set(comp_key->params, kofn); + + // All Done + return PKI_OK; +} + +int COMPOSITE_KEY_has_kofn(COMPOSITE_KEY * comp_key) { + + // Returns PKI_OK if a non-zero value is present + if (COMPOSITE_KEY_get_kofn(comp_key) > 0) return PKI_OK; + + // Returns PKI_ERR if the value is not present + // or less than zero + return PKI_ERR; +} + +int COMPOSITE_KEY_get_kofn(COMPOSITE_KEY * comp_key) { + + int ret = 0; + // Return value + + // Input Checks + if (!comp_key || !comp_key->params) return -1; + + // Returns the K-of-N value + ret = (int) ASN1_INTEGER_get(comp_key->params); + if (ret <= 0) return -1; + + // All Done + return ret; +} + + +// END: composite_internals.c diff --git a/src/crypto/composite/composite_ossl_lcl.h b/src/crypto/composite/composite_ossl_lcl.h new file mode 100644 index 00000000..2a1547dd --- /dev/null +++ b/src/crypto/composite/composite_ossl_lcl.h @@ -0,0 +1,243 @@ +/* BEGIN: composite_local.h */ + +// Composite Crypto authentication methods. +// (c) 2021 by Massimiliano Pala + +#include +#include +#include + +#ifndef _LIBPKI_COMPOSITE_OPENSSL_LOCAL_H +#define _LIBPKI_COMPOSITE_OPENSSL_LOCAL_H + +#if OPENSSL_VERSION_NUMBER >= 0x1010100fL +# include "../internal/ossl_1_1_1/refcount.h" +# include "../internal/ossl_1_1_1/x509_int.h" +#else +# if OPENSSL_VERSION_NUMBER >= 0x1010000fL +# include "../internal/ossl_1_1_1/refcount.h" +# include "../internal/ossl_1_1_0/x509_int.h" +# endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +// ============================== +// Declarations & Data Structures +// ============================== + +// Definition for EVP_PKEY and ECX_KEY +// taken from openssl/include/crypto/evp.h +# ifndef OPENSSL_NO_EC + +#define X25519_KEYLEN 32 +#define X448_KEYLEN 56 +#define ED448_KEYLEN 57 + +#define MAX_KEYLEN ED448_KEYLEN + +// Definition from +typedef struct { + unsigned char pubkey[MAX_KEYLEN]; + unsigned char *privkey; +} ECX_KEY; + +#endif + +// Definition from pem_pkey.c +struct X509_pubkey_st { + X509_ALGOR *algor; + ASN1_BIT_STRING *public_key; + EVP_PKEY *pkey; +}; + +// EVP_MD_CTX related stuff +// ======================== + +struct evp_md_ctx_st { + const EVP_MD *digest; + ENGINE *engine; /* functional reference if 'digest' is + * ENGINE-provided */ + unsigned long flags; + void *md_data; + /* Public key context for sign/verify */ + EVP_PKEY_CTX *pctx; + /* Update function: usually copied from EVP_MD */ + int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count); +} /* EVP_MD_CTX */ ; + + +// EVP_PKEY related stuff +// ====================== + +/* + * Type needs to be a bit field Sub-type needs to be for variations on the + * method, as in, can it do arbitrary encryption.... + */ +struct evp_pkey_st { + int type; + int save_type; + CRYPTO_REF_COUNT references; + const EVP_PKEY_ASN1_METHOD *ameth; + ENGINE *engine; + ENGINE *pmeth_engine; /* If not NULL public key ENGINE to use */ + union { + void *ptr; +# ifndef OPENSSL_NO_RSA + struct rsa_st *rsa; /* RSA */ +# endif +# ifndef OPENSSL_NO_DSA + struct dsa_st *dsa; /* DSA */ +# endif +# ifndef OPENSSL_NO_DH + struct dh_st *dh; /* DH */ +# endif +# ifndef OPENSSL_NO_EC + struct ec_key_st *ec; /* ECC */ + ECX_KEY *ecx; /* X25519, X448, Ed25519, Ed448 */ +# endif + } pkey; + int save_parameters; + STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */ + CRYPTO_RWLOCK *lock; +} /* EVP_PKEY */ ; + +struct evp_pkey_ctx_st { + /* Method associated with this operation */ + const EVP_PKEY_METHOD *pmeth; + /* Engine that implements this method or NULL if builtin */ + ENGINE *engine; + /* Key: may be NULL */ + EVP_PKEY *pkey; + /* Peer key for key agreement, may be NULL */ + EVP_PKEY *peerkey; + /* Actual operation */ + int operation; + /* Algorithm specific data */ + void *data; + /* Application specific data */ + void *app_data; + /* Keygen callback */ + EVP_PKEY_gen_cb *pkey_gencb; + /* implementation specific keygen data */ + int *keygen_info; + int keygen_info_count; +} /* EVP_PKEY_CTX */ ; + +// EVP_PKEY_ASN1_METHOD related stuff +// ================================== + +struct evp_pkey_asn1_method_st { + int pkey_id; + int pkey_base_id; + unsigned long pkey_flags; + char *pem_str; + char *info; + int (*pub_decode) (EVP_PKEY *pk, X509_PUBKEY *pub); + int (*pub_encode) (X509_PUBKEY *pub, const EVP_PKEY *pk); + int (*pub_cmp) (const EVP_PKEY *a, const EVP_PKEY *b); + int (*pub_print) (BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx); + int (*priv_decode) (EVP_PKEY *pk, const PKCS8_PRIV_KEY_INFO *p8inf); + int (*priv_encode) (PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk); + int (*priv_print) (BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx); + int (*pkey_size) (const EVP_PKEY *pk); + int (*pkey_bits) (const EVP_PKEY *pk); + int (*pkey_security_bits) (const EVP_PKEY *pk); + int (*param_decode) (EVP_PKEY *pkey, + const unsigned char **pder, int derlen); + int (*param_encode) (const EVP_PKEY *pkey, unsigned char **pder); + int (*param_missing) (const EVP_PKEY *pk); + int (*param_copy) (EVP_PKEY *to, const EVP_PKEY *from); + int (*param_cmp) (const EVP_PKEY *a, const EVP_PKEY *b); + int (*param_print) (BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx); + int (*sig_print) (BIO *out, + const X509_ALGOR *sigalg, const ASN1_STRING *sig, + int indent, ASN1_PCTX *pctx); + void (*pkey_free) (EVP_PKEY *pkey); + int (*pkey_ctrl) (EVP_PKEY *pkey, int op, long arg1, void *arg2); + /* Legacy functions for old PEM */ + int (*old_priv_decode) (EVP_PKEY *pkey, + const unsigned char **pder, int derlen); + int (*old_priv_encode) (const EVP_PKEY *pkey, unsigned char **pder); + /* Custom ASN1 signature verification */ + int (*item_verify) (EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, + X509_ALGOR *a, ASN1_BIT_STRING *sig, EVP_PKEY *pkey); + int (*item_sign) (EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, + X509_ALGOR *alg1, X509_ALGOR *alg2, + ASN1_BIT_STRING *sig); + int (*siginf_set) (X509_SIG_INFO *siginf, const X509_ALGOR *alg, + const ASN1_STRING *sig); + /* Check */ + int (*pkey_check) (const EVP_PKEY *pk); + int (*pkey_public_check) (const EVP_PKEY *pk); + int (*pkey_param_check) (const EVP_PKEY *pk); + /* Get/set raw private/public key data */ + int (*set_priv_key) (EVP_PKEY *pk, const unsigned char *priv, size_t len); + int (*set_pub_key) (EVP_PKEY *pk, const unsigned char *pub, size_t len); + int (*get_priv_key) (const EVP_PKEY *pk, unsigned char *priv, size_t *len); + int (*get_pub_key) (const EVP_PKEY *pk, unsigned char *pub, size_t *len); +} /* EVP_PKEY_ASN1_METHOD */ ; + +// EVP_PKEY_METHOD related stuff +// ============================= + +struct evp_pkey_method_st { + int pkey_id; + int flags; + int (*init) (EVP_PKEY_CTX *ctx); + int (*copy) (EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src); + void (*cleanup) (EVP_PKEY_CTX *ctx); + int (*paramgen_init) (EVP_PKEY_CTX *ctx); + int (*paramgen) (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey); + int (*keygen_init) (EVP_PKEY_CTX *ctx); + int (*keygen) (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey); + int (*sign_init) (EVP_PKEY_CTX *ctx); + int (*sign) (EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen); + int (*verify_init) (EVP_PKEY_CTX *ctx); + int (*verify) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen); + int (*verify_recover_init) (EVP_PKEY_CTX *ctx); + int (*verify_recover) (EVP_PKEY_CTX *ctx, + unsigned char *rout, size_t *routlen, + const unsigned char *sig, size_t siglen); + int (*signctx_init) (EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx); + int (*signctx) (EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + EVP_MD_CTX *mctx); + int (*verifyctx_init) (EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx); + int (*verifyctx) (EVP_PKEY_CTX *ctx, const unsigned char *sig, int siglen, + EVP_MD_CTX *mctx); + int (*encrypt_init) (EVP_PKEY_CTX *ctx); + int (*encrypt) (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); + int (*decrypt_init) (EVP_PKEY_CTX *ctx); + int (*decrypt) (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); + int (*derive_init) (EVP_PKEY_CTX *ctx); + int (*derive) (EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen); + int (*ctrl) (EVP_PKEY_CTX *ctx, int type, int p1, void *p2); + int (*ctrl_str) (EVP_PKEY_CTX *ctx, const char *type, const char *value); + int (*digestsign) (EVP_MD_CTX *ctx, unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen); + int (*digestverify) (EVP_MD_CTX *ctx, const unsigned char *sig, + size_t siglen, const unsigned char *tbs, + size_t tbslen); + int (*check) (EVP_PKEY *pkey); + int (*public_check) (EVP_PKEY *pkey); + int (*param_check) (EVP_PKEY *pkey); + + int (*digest_custom) (EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx); +} /* EVP_PKEY_METHOD */ ; + +#ifdef __cplusplus +} +#endif +#endif + +/* END: composite_ossl_lcl.h */ diff --git a/src/crypto/composite/composite_pmeth.c b/src/crypto/composite/composite_pmeth.c new file mode 100644 index 00000000..06c12e8c --- /dev/null +++ b/src/crypto/composite/composite_pmeth.c @@ -0,0 +1,1917 @@ +/* BEGIN: composite_pmeth.c */ + +// Temporary Measure until the functions are all used +#pragma GCC diagnostic ignored "-Wunused-function" + +// Composite Crypto authentication methods. +// (c) 2021 by Massimiliano Pala + +#ifndef _LIBPKI_COMPOSITE_PKEY_METH_H +#include +#endif + +#ifndef _LIBPKI_ID_H +#include +#endif + +// ============== +// Local Includes +// ============== + +#ifndef _LIBPKI_COMPOSITE_OPENSSL_LOCAL_H +#include "composite_ossl_lcl.h" +#endif + +// ====================== +// MACRO & Other Oddities +// ====================== + +#define DEBUG(args...) \ + { fprintf(stderr, "[%s:%d] %s() - ", __FILE__, __LINE__, __func__); \ + fprintf(stderr, ## args) ; fprintf(stderr,"\n"); fflush(stderr) ; } + +static const int DUMP_SIGNATURE_DATA = 0; + // Dumps the signature data to persistent files + +// ======================== +// Exported Global Variable +// ======================== + +// Temporary Measure until the functions are all used +#pragma GCC diagnostic ignored "-Wunused-function" + +#ifdef ENABLE_COMPOSITE + +// ========================= +// EVP_PKEY_METHOD Functions +// ========================= + +int EVP_PKEY_CTX_supports_sign(EVP_PKEY_CTX * ctx) { + + PKI_DEBUG("EVP_PKEY_CTX_supports_sign() called"); + if (ctx && ctx->pmeth && ctx->pmeth->sign) { + PKI_DEBUG("EVP_PKEY_CTX_supports_sign() returning PKI_OK (%p)", + ctx->pmeth->sign); + return PKI_OK; + } + + PKI_DEBUG("PMETHOD does not support sign(), returning PKI_ERR"); + return PKI_ERR; +}; + +int EVP_PKEY_CTX_supports_verify(EVP_PKEY_CTX * ctx) { + + PKI_DEBUG("EVP_PKEY_CTX_supports_verify() called"); + if (ctx && ctx->pmeth && ctx->pmeth->verify) { + PKI_DEBUG("EVP_PKEY_CTX_supports_verify() returning PKI_OK (%p)", + ctx->pmeth->verify); + return PKI_OK; + } + + PKI_DEBUG("PMETHOD does not support verify(), returning PKI_ERR"); + return PKI_ERR; +}; + +int EVP_PKEY_CTX_supports_digestsign(EVP_PKEY_CTX * ctx) { + + PKI_DEBUG("EVP_PKEY_CTX_supports_digestsign() called"); + if (ctx && ctx->pmeth && ctx->pmeth->digestsign) { + PKI_DEBUG("EVP_PKEY_CTX_supports_digestsign() returning PKI_OK (%p)", + ctx->pmeth->digestsign); + return PKI_OK; + } + PKI_DEBUG("PMETHOD does not support digestsign(), returning PKI_ERR"); + + return PKI_ERR; +}; + +int EVP_PKEY_CTX_supports_digestverify(EVP_PKEY_CTX * ctx) { + + PKI_DEBUG("EVP_PKEY_CTX_supports_digestverify() called"); + if (ctx && ctx->pmeth && ctx->pmeth->digestverify) { + PKI_DEBUG("EVP_PKEY_CTX_supports_digestverify() returning PKI_OK (%p)", + ctx->pmeth->digestsign); + return PKI_OK; + } + + PKI_DEBUG("PMETHOD does not support digestverify(), returning PKI_ERR"); + return PKI_ERR; +}; + +// Implemented +static int init(EVP_PKEY_CTX *ctx) { + + COMPOSITE_CTX *comp_ctx = NULL; + + // Allocate Memory + if ((comp_ctx = COMPOSITE_CTX_new_null()) == NULL) return 0; + + // Assigns the algorithm-specific data + // to the data field + ctx->data = comp_ctx; + + // These are used during Key Gen to display + // '.', '+', '*', '\n' during key gen + ctx->keygen_info = NULL; + ctx->keygen_info_count = 0; + + // All Done + return 1; +} + +// Implemented +static void cleanup(EVP_PKEY_CTX * ctx) { + + // Input Check + if (!ctx) return; + + // Retrieves the internal context + if (ctx->data) COMPOSITE_CTX_free((COMPOSITE_CTX *)ctx->data); + ctx->data = NULL; + + // All Done + return; +} + +// Implemented +static int keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { + + COMPOSITE_CTX * comp_ctx = NULL; + COMPOSITE_KEY * key = NULL; + + // Input Validation + if (!ctx || !ctx->data || !pkey) return 0; + + PKI_DEBUG("Generating a Composite Key"); + + // // Some extra checking for correctness + // if (ctx->pmeth->pkey_id != OBJ_txt2nid(OPENCA_ALG_PKEY_EXP_COMP_OID)) { + // PKI_DEBUG("NID is not NID_composite (%d vs. %d)", + // ctx->pmeth->pkey_id, OBJ_txt2nid(OPENCA_ALG_PKEY_EXP_COMP_OID)); + // return 0; + // } + + // Checks we have the right data and items + comp_ctx = ctx->data; + if (!comp_ctx) { + // No components present in the key + PKI_ERROR(PKI_ERR_ALGOR_SET, "Empty Stack of Keys when generating a composed key"); + return 0; + } + + // // Allocates the Composite Key + // if ((key = COMPOSITE_KEY_new_null()) == NULL) { + // PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + // return 0; + // } + + // // Processes + // for (int i = 0; i < COMPOSITE_CTX_num(comp_ctx); i++ ) { + + // EVP_PKEY * tmp_pkey = NULL; + // // Pointer to the single component's key + + // // Retrieves the i-th component + // if (!COMPOSITE_CTX_pkey_get0(comp_ctx, &tmp_pkey, i) || (tmp_pkey == NULL)) { + // PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Cannot add PKEY to Composite Key component #%d", i); + // COMPOSITE_KEY_free(key); + // return 0; + // } + + // // Adds the key in the key stack + // COMPOSITE_KEY_push(key, tmp_pkey); + // } + + // Transfer the components from the CTX + if (key->components) COMPOSITE_KEY_STACK_free(key->components); + key->components = comp_ctx->components; + comp_ctx->components = NULL; + + // Transfers the parameter + if (key->params) ASN1_INTEGER_free(key->params); + key->params = comp_ctx->params; + comp_ctx->params = NULL; + + // Resets the list of components on the CTX + comp_ctx->components = COMPOSITE_KEY_STACK_new_null(); + + // NOTE: To Get the Structure, use EVP_PKEY_get0(EVP_PKEY *k) + // NOTE: To Add the Key Structure, use EVP_PKEY_assign() + EVP_PKEY_assign_COMPOSITE(pkey, key); + + // All Done. + return 1; +} + +// Implemented +static int sign(EVP_PKEY_CTX * ctx, + unsigned char * sig, + size_t * siglen, + const unsigned char * tbs, + size_t tbslen) { + + EVP_PKEY * pkey = NULL; + // Pointer to the larger composite key + + X509_ALGORS * sig_algs = NULL; + // Pointer to the signature algorithms + + COMPOSITE_CTX * comp_ctx = NULL; + COMPOSITE_KEY * comp_key = NULL; + // Pointer to inner key structure + + unsigned char global_hash_data[EVP_MAX_MD_SIZE]; + size_t global_hash_data_len = 0; + // Buffer for hashed data (when no global hash is used + // and the algorithm still requires hashing) + + EVP_MD_CTX * md_ctx = NULL; + // Digest Context + + STACK_OF(ASN1_TYPE) *sk = NULL; + // Stack of ASN1_OCTET_STRINGs + + int signature_size = -1; + // The total signature size + + ASN1_TYPE * aType = NULL; + // ASN1 generic wrapper + + int comp_key_num = 0; + // Number of components + + const unsigned char * tbs_data; + size_t tbs_data_len = 0; + // Temporary TBS Data and Length + + const EVP_MD * global_hash; + int use_global_hash = 0; + // Flag to use the global hash + + int ret_code = 0; + // Return Code for external calls + + int total_size = 0; + // Total Signature Size + + // Input Checks + if (!ctx || !tbs) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return -1; + } + + // Gets the composite context + comp_ctx = ctx->data; + if (!comp_ctx) { + PKI_ERROR(PKI_ERR_PARAM_NULL, "No composite context found"); + return -1; + } + + // Detects the use of global has + if (comp_ctx->md && comp_ctx->md != PKI_DIGEST_ALG_NULL) { + // Sets the indicator to use the global hash + use_global_hash = 1; + global_hash = comp_ctx->md; + } + + // Gets the signature algorithms + sig_algs = comp_ctx->sig_algs; + + PKI_DEBUG("Composite X509_ALGORS: %p", sig_algs); + PKI_DEBUG("Composite X509_ALGORS: %d", sk_X509_ALGOR_num(sig_algs)); + + // Gets the internal key + pkey = EVP_PKEY_CTX_get0_pkey(ctx); + if (!pkey) { + PKI_ERROR(PKI_ERR_PARAM_NULL, "No public key found in the context"); + return -1; + } + + // Gets the internal key + comp_key = EVP_PKEY_get0(pkey); + if (!comp_key) { + PKI_ERROR(PKI_ERR_PARAM_NULL, "No composite key found in the public key"); + return -1; + } + + // Checks we have a good stack of components + comp_key_num = COMPOSITE_KEY_num(comp_key); + if (comp_key_num <= 0) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Cannot get the Composite key inner structure"); + return 0; + } + + /* WARNING: This does not account for extra space for parameters */ + signature_size = EVP_PKEY_size(ctx->pkey); + + // If no signature buffer is passed, we just return the size + if (sig == NULL) { + *siglen = (size_t)signature_size; + return 1; + } + + // ============================ + // Handles the Hash-n-Sign case + // ============================ + + if (use_global_hash) { + + PKI_DEBUG("Detected hash-n-sign algorithm (global hash: %s), hashing data", EVP_MD_name(global_hash)); + + // We need to hash the data before signing, so we + // do it once and then we sign the hash + int ossl_ret = EVP_Digest(tbs, tbslen, global_hash_data, (unsigned int *)&global_hash_data_len, global_hash, NULL); + if (ossl_ret == 0) { + PKI_DEBUG("Error while hashing data (ossl_ret=%d)", ossl_ret); + goto err; + } + // Let's point the pointers to the hashed data and its size + tbs_data = global_hash_data; + tbs_data_len = global_hash_data_len; + + PKI_DEBUG("Using the Hash-n-Sign data: %p (size: %d)", tbs_data, tbs_data_len); + + } else { + + // No global hash, we need to hash the data + // or do direct signing + tbs_data = tbs; + tbs_data_len = tbslen; + + PKI_DEBUG("Using the Direct Signing of the data: %p (size: %d)", tbs_data, tbs_data_len); + } + + // ================================ + // Components' Signature Generation + // ================================ + + // Allocates the Stack for the signatures + if ((sk = sk_ASN1_TYPE_new_null()) == NULL) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Cannot allocate the stack of signature"); + goto err; + } + + // Generates Each Signature Independently + for (int idx = 0; idx < comp_key_num; idx++) { + + PKI_X509_ALGOR_VALUE * alg = NULL; + // Temp Algorithm Pointer + + unsigned char x_hash[EVP_MAX_MD_SIZE + 1]; + size_t x_hash_len = 0; + // Buffer for hashed data (when no global hash is used + // and the algorithm still requires hashing) + + unsigned char * x_tbs_data = NULL; + size_t x_tbs_data_len = 0; + // Temp Pointers + + unsigned char * sig_buff = NULL; + size_t sig_buff_len = 0; + // Temp Pointers + + EVP_PKEY_CTX * x_pkey_ctx = NULL; + EVP_PKEY * x_pkey = NULL; + // The keypair and context references + + int x_pkey_id = 0; + int x_pkey_type = NID_undef; + int x_pkey_size = 0; + // The type of the key for the component + + int algorithm_pkey_type = 0; + int md_type = 0; + // Algorithm and MD Type + + ASN1_BIT_STRING * bit_string = NULL; + // Output Signature to be added + // to the stack of signatures + + PKI_DEBUG("[Comp #%d] Generating New Signature Component", idx); + + // Make sure we use the right data + x_tbs_data = (unsigned char *)tbs_data; + x_tbs_data_len = tbs_data_len; + + PKI_DEBUG("[Comp #%d] Initial Data Size is %lu for Component #%d", idx, x_tbs_data_len, idx); + + // Retrieves the i-th component + if ((x_pkey = COMPOSITE_KEY_get0(comp_key, idx)) == NULL) { + PKI_DEBUG("[Comp #%d] Cannot get the component from the composite key", idx); + goto err; + } + + // Retrieves the type of key + x_pkey_id = PKI_X509_KEYPAIR_VALUE_get_id(x_pkey); + x_pkey_type = EVP_PKEY_type(x_pkey_id); + if (x_pkey_type <= 0) { +#if OPENSSL_VERSION_NUMBER > 0x3000000fL + x_pkey_type = x_pkey_id; +#else + PKI_DEBUG("[Comp #%d] Cannot get the component's type from Key", idx); + goto err; +#endif // End of OPENSSL_VERSION_NUMBER > 0x3000000fL + } + + // Retrieves the i-th algorithm + if ((alg = sk_X509_ALGOR_value(sig_algs, idx)) == NULL) { + PKI_DEBUG("[Comp #%d] Cannot get the parameter from the SEQUENCE of X509_ALGORS", idx); + goto err; + } + + if (!use_global_hash) { + + PKI_DEBUG("[Comp #%d] Not Hash-n-Sign: let's check if we need to hash the data first", idx); + + // Checks we have the same algorithm for the key + OBJ_find_sigid_algs(OBJ_obj2nid(alg->algorithm), &md_type, &algorithm_pkey_type); + if (algorithm_pkey_type != x_pkey_type) { + PKI_DEBUG("[Comp #%d] Algorithm %d does not match the key's algorithm %d when processing component #%d", + idx, algorithm_pkey_type, x_pkey_type, idx); + goto err; + } + + PKI_DEBUG("[Comp #%d] Parsed Algorithm from the Sig Algs Stack: %d (md type: %d, key type: %d)", + idx, OBJ_obj2nid(alg->algorithm), md_type, algorithm_pkey_type); + + // Calculates the Digest (since we use custom digest, the data is not + // hashed when it is passed to this function) + if (md_type > 0) { + + PKI_DEBUG("[Comp #%d] Using Digest Signing (digest: %s) [tbs_data: %p, tbs_data_len: %d]", + idx, EVP_MD_name(EVP_get_digestbynid(md_type)), tbs_data, tbs_data_len); + + PKI_DEBUG("[Comp #%d] Buffer Information: x_hash: %p, x_hash_len: %lu", x_hash, x_hash_len); + + int ossl_ret = EVP_Digest(tbs_data, tbs_data_len, x_hash, (unsigned int *)&x_hash_len, EVP_get_digestbynid(md_type), NULL); + if (ossl_ret <= 0) { + PKI_DEBUG("[Comp #%d] Error while hashing data (ossl_ret=%d)", idx, ossl_ret); + goto err; + } + + x_tbs_data = x_hash; + x_tbs_data_len = x_hash_len; + + PKI_DEBUG("[Comp #%d] New data to sign afer generating the hash data (data: %p, size: %lu)", + idx, x_tbs_data, x_tbs_data_len); + + } else { + + PKI_DEBUG("[Comp #%d] Using Direct Signing for the component (data size: %d)", idx, x_tbs_data_len); + x_tbs_data = (unsigned char *)tbs; + x_tbs_data_len = tbslen; + + } + } + + // Checks we have good data pointers + if (!x_tbs_data || x_tbs_data_len <= 0) { + PKI_DEBUG("[Comp #%d] Missing data for component (x_tbs_data: %p, x_tbs_data_len: %d)", + idx, tbs_data, tbs_data_len); + goto err; + } + + // Gets the Signature's Max Size + x_pkey_size = EVP_PKEY_size(x_pkey); + if (x_pkey_size <= 0) { + PKI_DEBUG("[Comp #%d] Cannot get the size of the component signature", idx); + goto err; + } + + // Useful Information + PKI_DEBUG("[Comp #%d] ESTIMATED Signature Size for component is %d", idx, x_pkey_size); + + // Allocate the buffer for the single signature + sig_buff_len = (size_t)x_pkey_size; + if ((sig_buff = OPENSSL_malloc(sig_buff_len)) == NULL) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + goto err; + } + + // Let's build a PKEY CTX and assign it to the MD CTX + x_pkey_ctx = EVP_PKEY_CTX_new(x_pkey, NULL); + if (!x_pkey_ctx) { + PKI_DEBUG("[Comp #%d] Cannot allocate a new CTX for the component's signature operation", idx); + PKI_Free(sig_buff); + goto err; + } + + // If the PMETHOD supports direct signing use it, + // otherwise use the digest signing method + if (EVP_PKEY_CTX_supports_sign(x_pkey_ctx)) { + + // Debugging Info + PKI_DEBUG("[Comp #%d] Using the sign() mechanism", idx); + + // Initializes the Signing process + ret_code = EVP_PKEY_sign_init(x_pkey_ctx); + if (ret_code <= 0) { + PKI_DEBUG("[Comp #%d] EVP_PKEY_sign_init() failed with code %d", idx, ret_code); + PKI_Free(sig_buff); + EVP_PKEY_CTX_free(x_pkey_ctx); + goto err; + } + + // Debugging Info + PKI_DEBUG("[Comp #%d] Signing Data (tbs_data: %p, tbs_data_len: %d)", idx, x_tbs_data, x_tbs_data_len); + { + char str[256] = { 0x0 }; + for (size_t iii = 0; iii < 16; iii++) { + snprintf(str + 3*iii, 256 - 3*iii, "%02X:", x_tbs_data[iii]); + } + PKI_DEBUG("[Comp #%d] Data Dump: %s", idx, str); + } + + // Signature's generation + ret_code = EVP_PKEY_sign(x_pkey_ctx, sig_buff, (size_t *)&sig_buff_len, x_tbs_data, x_tbs_data_len); + if (ret_code <= 0) { + PKI_DEBUG("[Comp #%d] Cannot generate signature for component (code: %d)", idx, ret_code); + PKI_Free(sig_buff); + EVP_PKEY_CTX_free(x_pkey_ctx); + goto err; + } + + } else if (EVP_PKEY_CTX_supports_digestsign(x_pkey_ctx)) { + + EVP_MD_CTX * md_ctx = NULL; + // The MD context + + PKI_DEBUG("[Comp #%d] Using the digestsign() mechanism", idx, ret_code); + + // Initializes the MD context + md_ctx = EVP_MD_CTX_new(); + if (!md_ctx) { + PKI_DEBUG("[Comp #%d] Cannot allocate a new MD CTX for the signature operation", idx); + PKI_Free(sig_buff); + EVP_PKEY_CTX_free(x_pkey_ctx); + goto err; + } + + ret_code = EVP_DigestSignInit(md_ctx, NULL, NULL, NULL, x_pkey); + if (ret_code <= 0) { + PKI_DEBUG("[Comp #%d] Cannot initialize the MD CTX for the signature operation (MD: NULL)", idx); + PKI_Free(sig_buff); + EVP_PKEY_CTX_free(x_pkey_ctx); + EVP_MD_CTX_free(md_ctx); + goto err; + } + + if (x_pkey_type == PKI_ALGOR_ID_ED25519 || + x_pkey_type == PKI_ALGOR_ID_ED448) { + + PKI_DEBUG("[Comp #%d] Using special case for the ED25519/ED448 mechanism", idx, ret_code); + + // Uses the digestsign function to sign the data + ret_code = EVP_DigestSign(md_ctx, sig_buff, (size_t *)&sig_buff_len, x_tbs_data, x_tbs_data_len); + if (ret_code <= 0) { + PKI_DEBUG("[Comp #%d] Cannot generate signature (code: %d)", idx, ret_code); + PKI_Free(sig_buff); + EVP_PKEY_CTX_free(x_pkey_ctx); + EVP_MD_CTX_free(md_ctx); + goto err; + } + + } else { + + ret_code = EVP_DigestSignUpdate(md_ctx, x_tbs_data, x_tbs_data_len); + if (ret_code <= 0) { + PKI_DEBUG("[Comp #%d] Cannot update the MD CTX for the signature operation (code: %d)", idx, ret_code); + PKI_Free(sig_buff); + EVP_PKEY_CTX_free(x_pkey_ctx); + EVP_MD_CTX_free(md_ctx); + goto err; + } + + ret_code = EVP_DigestSignFinal(md_ctx, sig_buff, (size_t *)&sig_buff_len); + if (ret_code <= 0) { + PKI_DEBUG("[Comp #%d] Cannot finalize the MD CTX for the signature operation (code: %d)", idx, ret_code); + PKI_Free(sig_buff); + EVP_PKEY_CTX_free(x_pkey_ctx); + EVP_MD_CTX_free(md_ctx); + goto err; + } + } + + // // Uses the digestsign function to sign the data + // ret_code = EVP_DigestSign(md_ctx, sig_buff, (size_t *)&sig_buff_len, x_tbs_data, x_tbs_data_len); + // if (ret_code <= 0) { + // PKI_DEBUG("[Comp #%d] Cannot generate signature (code: %d)", idx, ret_code); + // PKI_Free(sig_buff); + // EVP_PKEY_CTX_free(x_pkey_ctx); + // EVP_MD_CTX_free(md_ctx); + // goto err; + // } + + // Frees the MD CTX + EVP_MD_CTX_free(md_ctx); + + // Success + PKI_DEBUG("[Comp #%d] Signature generates successfully (size: %d)", idx, sig_buff_len); + } + + // // Signature's generation + // ret_code = EVP_PKEY_sign(pkey_ctx, pnt, (size_t *)&buff_len, tbs_data, tbs_data_len); + // if (ret_code <= 0) { + // DEBUG("Cannot generate signature for %d component (EVP_PKEY_sign code is %d)", idx, ret_code); + // goto err; + // } + + // Removes the reference to the key. This is + // needed because we otherwise will have memory + // issue when calling EVP_PKEY_CTX_free() + // PKI_DEBUG("Freeing the PKEY reference (pkey: %p) - This might not be good, removing it.", x_pkey_ctx->pkey); + // pkey_ctx->pkey = NULL; + + // Free the PKEY context + if (x_pkey_ctx) EVP_PKEY_CTX_free(x_pkey_ctx); + x_pkey_ctx = NULL; // Safety + + if (DUMP_SIGNATURE_DATA == 1) { + + PKI_DEBUG("[Comp #%d] Dumping Component Signature data (%d_signature.bin)", idx, idx); + + PKI_MEM * mem = NULL; + char buff_name[1024]; + snprintf(buff_name, sizeof(buff_name), "%d_signature.bin", idx); + mem = PKI_MEM_new_data(sig_buff_len, sig_buff); + URL_put_data(buff_name, mem, NULL, NULL, 0, 0, NULL); + PKI_MEM_free(mem); + + PKI_DEBUG("[Comp #%d] Dumping Component TBS data (%d_signature_tbs.bin)", idx, idx); + + snprintf(buff_name, sizeof(buff_name), "%d_signature_tbs.bin", idx); + mem = PKI_MEM_new_data((size_t)x_tbs_data_len, x_tbs_data); + URL_put_data(buff_name, mem, NULL, NULL, 0, 0, NULL); + PKI_MEM_free(mem); + } + + // Updates the overall real size + total_size += (int)sig_buff_len; + + // Debugging Info + PKI_DEBUG("[Comp #%d] Successfully generated signature (size: %d)", idx, sig_buff_len); + PKI_DEBUG("[Comp #%d] Signature Total Size [So Far] ... %d", idx, total_size); + + if ((bit_string = ASN1_BIT_STRING_new()) == NULL) { + PKI_DEBUG("[Comp #%d] Cannot allocate the wrapping OCTET STRING for signature's %d component", idx); + PKI_Free(sig_buff); + goto err; + } + + // This sets the internal pointers + ASN1_STRING_set0(bit_string, sig_buff, (int)sig_buff_len); + sig_buff = NULL; sig_buff_len = 0; + + // Sets the flags into the signature field + bit_string->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); + bit_string->flags |= ASN1_STRING_FLAG_BITS_LEFT; + + // Let's now generate the ASN1_TYPE and add it to the stack + if ((aType = ASN1_TYPE_new()) == NULL) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Cannot Allocate a new ASN1 Type for signature wrapping"); + ASN1_STRING_free(bit_string); + goto err; + } + + // Transfer Ownership to the aType structure + ASN1_TYPE_set(aType, V_ASN1_BIT_STRING, bit_string); + bit_string = NULL; + + // Adds the component to the stack + if (!sk_ASN1_TYPE_push(sk, aType)) { + PKI_DEBUG("Cannot push the signature's %d component", idx); + ASN1_TYPE_free(aType); + goto err; + } + + // Transfers ownership + aType = NULL; + + // PKI_DEBUG("Done Processing Composite component %d, counter = %d", idx, counter); + // counter++; + } + + PKI_DEBUG("End of Signature Generation for All Components"); + + if ((*siglen = (size_t) i2d_ASN1_SEQUENCE_ANY(sk, &sig)) <= 0) { + PKI_ERROR(PKI_ERR_DATA_ASN1_ENCODING, "Cannot generate DER representation of the sequence of signatures"); + goto err; + } + + // Reporting the total size + PKI_DEBUG("Total Signature Size: %d (overhead: %d) (estimated: %d)", *siglen, ((int)*siglen - total_size), signature_size); + + if (DUMP_SIGNATURE_DATA == 1) { + + PKI_DEBUG("Dumping Global Signature data (global_signature.bin)"); + + PKI_MEM * mem = NULL; + char buff_name[1024]; + snprintf(buff_name, sizeof(buff_name), "global_signature.bin"); + mem = PKI_MEM_new_data((size_t)*siglen, sig); + URL_put_data(buff_name, mem, NULL, NULL, 0, 0, NULL); + PKI_MEM_free(mem); + + PKI_DEBUG("Dumping Global Signature TBS (global_signature_tbs.bin)"); + + snprintf(buff_name, sizeof(buff_name), "global_signature_tbs.bin"); + mem = PKI_MEM_new_data((size_t)tbs_data_len, tbs_data); + URL_put_data(buff_name, mem, NULL, NULL, 0, 0, NULL); + PKI_MEM_free(mem); + } + + // Free the stack's memory + if (sk) sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); + sk = NULL; + + // Success + return 1; + +err: + // Debugging + PKI_ERROR(PKI_ERR_SIGNATURE_CREATE, NULL); + + // Free allocated memory + if (md_ctx) EVP_MD_CTX_free(md_ctx); + md_ctx = NULL; + + if (sk) sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); + sk = NULL; // Safety + + // Error + return 0; +} + +// Implemented +static int verify(EVP_PKEY_CTX * ctx, + const unsigned char * sig, + size_t siglen, + const unsigned char * tbs, + size_t tbslen) { + + // PKI_X509_ALGOR_VALUE * algor = NULL; + // // X509_ALGOR structure + + // X509_ALGORS * params = NULL; + // // Pointer to parameters + + EVP_PKEY * pkey = EVP_PKEY_CTX_get0_pkey(ctx); + // Pointer to the key + + COMPOSITE_KEY * comp_key = pkey ? EVP_PKEY_get0(pkey) : NULL; + // Pointer to inner key structure + + COMPOSITE_CTX * comp_ctx = EVP_PKEY_CTX_get_data(ctx); + // Pointer to the context + + STACK_OF(ASN1_TYPE) *sk = NULL; + // Stack of ASN1_OCTET_STRINGs + + int ret_code = 0; + // OSSL return code + + int comp_key_num = 0; + // Number of components + + // Checks the validation policy + int successful_validations = 0; + int required_valid_components = -1; + // Number of required valid signatures + + ASN1_BIT_STRING aBitStr; + // Temp Bit String + + int pkey_id = 0; + int pkey_type = 0; + // The keypair and context references + + int use_global_hash = 0; + // Use the global hash for all components + + // Input Checks + if (!pkey || !comp_key || !comp_ctx) { + PKI_ERROR(PKI_ERR_PARAM_NULL, "Missing PKEY, Composite Key, or Composite CTX"); + return 0; + } + + // Checks the number of components + comp_key_num = comp_key ? COMPOSITE_KEY_num(comp_key) : -1; + if (comp_key_num <= 0) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Cannot get the Composite key inner structure"); + return 0; + } + + // Retrieves the PKEY type (or ID) + + pkey_id = PKI_X509_KEYPAIR_VALUE_get_id(pkey); + pkey_type = EVP_PKEY_type(pkey_id); + if (pkey_type <= 0) { +#if OPENSSL_VERSION_NUMBER > 0x3000000fL + pkey_type = pkey_id; +#else + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Cannot get the PKEY type"); + return 0; +#endif // End of OPENSSL_VERSION_NUMBER > 0x3000000fL + } + + // Check for the use of a global hash + if (comp_ctx->md && comp_ctx->md != EVP_md_null()) { + use_global_hash = 1; + } + + PKI_DEBUG("Using Global Hash: %d", use_global_hash); + + // Signature Validation Policy + if (COMPOSITE_KEY_has_kofn(comp_key)) { + // Retrieves the policy + required_valid_components = COMPOSITE_KEY_get_kofn(comp_key); + } else { + // If the policy is not set, we assume that all the components + // are required to be valid + required_valid_components = comp_key_num; + } + + PKI_DEBUG("Required Valid Components: %d", required_valid_components); + + // // Retrieve the app data (if any) + // algor = (PKI_X509_ALGOR_VALUE *)EVP_PKEY_CTX_get_app_data(ctx); + // if (!algor) { + // PKI_DEBUG("No App Data Found, using SHA512 as default."); + // PKI_DEBUG("We should add the CTRL interface to set the default MD."); + // } + + // if (algor) { + + // const ASN1_OBJECT * obj; + + // X509_ALGOR_get0(&obj, NULL, (const void **)¶ms, algor); + // PKI_DEBUG("Parsing the Parameters: #%d", sk_X509_ALGOR_num(params)); + // } + + // Let's use the aOctetStr to avoid the internal + // p8 pointers to be modified + aBitStr.data = (unsigned char *)sig; + aBitStr.length = (int) siglen; + + // Gets the Sequence from the data itself, error if + // it is not a sequence of ASN1_OCTET_STRING + if ((sk = d2i_ASN1_SEQUENCE_ANY(NULL, + (const unsigned char **)&aBitStr.data, + aBitStr.length)) <= 0) { + PKI_DEBUG("Cannot decode the composite signature."); + return 0; + } + + // Debugging + PKI_DEBUG("Signature Sequence is Unpacked (Num: %d)!", sk_ASN1_TYPE_num(sk)); + + // Checks we have the right number of components + if (sk_ASN1_TYPE_num(sk) != comp_key_num) { + PKI_ERROR(PKI_ERR_SIGNATURE_VERIFY, + "Wrong number of signature's components (%d instead of %d)", + sk_ASN1_TYPE_num(sk), comp_key_num); + return 0; + } + + // Checks the parameters, if we have any + if (!comp_ctx->sig_algs || sk_X509_ALGOR_num(comp_ctx->sig_algs) <= 0) { + PKI_DEBUG("No configured set of parameters for composite, generating default ones"); + if (!COMPOSITE_CTX_algors_new0(comp_ctx, pkey_type, comp_ctx->asn1_item, comp_key->components, NULL)) { + PKI_DEBUG("Cannot configure the validation parameters"); + return 0; + } + } else { + PKI_DEBUG("Using the configured set of parameters for composite!"); + } + + if (DUMP_SIGNATURE_DATA == 1) { + + PKI_MEM * mem = NULL; + char buff[1024]; + snprintf(buff, sizeof(buff), "global_signature_to_verify.bin"); + mem = PKI_MEM_new_data((size_t)siglen, sig); + URL_put_data(buff, mem, NULL, NULL, 0, 0, NULL); + PKI_MEM_free(mem); + + snprintf(buff, sizeof(buff), "global_data_to_verify.bin"); + mem = PKI_MEM_new_data((size_t)tbslen, tbs); + URL_put_data(buff, mem, NULL, NULL, 0, 0, NULL); + PKI_MEM_free(mem); + } + + // Resets the validations tracker + successful_validations = 0; + + // Process the internal components + for (int i = 0; i < sk_ASN1_TYPE_num(sk); i++) { + + const unsigned char * tbs_data; + size_t tbs_data_len = 0; + // Pointer to the data to be signed + + const unsigned char hashed_data[EVP_MAX_MD_SIZE]; + size_t hashed_data_len = 0; + // Pointer to the hashed data + + EVP_PKEY * comp_evp_pkey = NULL; + EVP_PKEY_CTX * comp_pkey_ctx = NULL; + const EVP_MD * comp_md; + // EVP_PKEY, EVP_PKEY_CTX, and EVP_MD for the component + + ASN1_TYPE * aType = NULL; + // ASN1 generic wrapper + + // Sets the pointers for the validations + tbs_data = tbs; + tbs_data_len = tbslen; + + PKI_DEBUG("[Comp #%d] Validating Signature Component (tbs: %p, tbslen: %d)", + i, tbs_data, tbs_data_len); + + // Returns, if no more validations are required + if (successful_validations >= required_valid_components) { + PKI_DEBUG("[Comp #%d] Required number of valid signatures (%d) reached", + i, required_valid_components); + break; + } + + // Returns, if not enough validations are possible + if (required_valid_components - successful_validations > comp_key_num - i) { + PKI_DEBUG("[Comp #%d] Required number of valid signatures (%d) not reachable", + i, required_valid_components); + goto err; + } + + // Gets the single values + if ((aType = sk_ASN1_TYPE_value(sk, i)) == NULL) { + PKI_DEBUG("[Comp #%d] Cannot get the ASN1_TYPE for signature", i); + return 0; + } + + // Checks we got the right type + if ((aType->type != V_ASN1_BIT_STRING) || (aType->value.asn1_string == NULL)) { + PKI_DEBUG("[Comp #%d] Decoding error on signature component (type: %d, value: %p)", + i, aType->type, aType->value.sequence); + return 0; + } + + if (DUMP_SIGNATURE_DATA == 1) { + + PKI_DEBUG("Dumping Signature Component #%d", i); + + PKI_MEM * mem = NULL; + char buff[1024]; + snprintf(buff, sizeof(buff), "%d_signature_to_verify.bin", i); + mem = PKI_MEM_new_data((size_t)aType->value.sequence->length, aType->value.sequence->data); + URL_put_data(buff, mem, NULL, NULL, 0, 0, NULL); + PKI_MEM_free(mem); + + snprintf(buff, sizeof(buff), "%d_data_to_verify.bin", i); + mem = PKI_MEM_new_data((size_t)tbslen, tbs); + URL_put_data(buff, mem, NULL, NULL, 0, 0, NULL); + PKI_MEM_free(mem); + } + + // Retrieves the i-th component + if ((comp_evp_pkey = COMPOSITE_KEY_get0(comp_key, i)) == NULL) { + PKI_DEBUG("[Comp #%d] Cannot get %d-th component from Key", i); + goto err; + } + + // Gets the type of the i-th component + // int comp_evp_pkey_type = PKI_X509_KEYPAIR_VALUE_get_id(comp_evp_pkey); + + // Checks if we are using a global hash-n-sign (comp_ctx->md is set) + // or if we need to use a specific hash for this component instead + // (i.e., when comp_ctx->md is NULL or EVP_md_null()) + if (use_global_hash) { + + // We are using a global hash-n-sign, so the hash was already + // calculated, we are just using the comp_md to set the algorithm + // identifier + tbs_data = tbs; + tbs_data_len = tbslen; + + PKI_DEBUG("[Comp #%d] Hash-n-Sign validation using global hash (comp_ctx->md: %s)", + i, EVP_MD_name(comp_ctx->md)); + + } else { + + X509_ALGOR * algor = NULL; + // Pointer to the algorithm identifier + + const ASN1_OBJECT * comp_sig_obj = NULL; + // Pointer to the signature algorithm + + PKI_DEBUG("[Comp #%d] Direct validation for component (No Global Hash)", i); + + // Let's get the i-th algorithm to set the identifier/parameters + if (comp_ctx->sig_algs) { + + int comp_md_nid = 0; + // NID of the MD + + PKI_DEBUG("[Comp #%d] Using Configured i-th sig_algs component from the stack", i); + + PKI_DEBUG("[Comp #%d] Getting the i-th sig_algs component from the stack", i); + algor = sk_X509_ALGOR_value(comp_ctx->sig_algs, i); + if (!algor) { + PKI_DEBUG("[Comp #%d] Cannot get the i-th sig_algs component from the stack", i); + goto err; + } + X509_ALGOR_get0(&comp_sig_obj, NULL, NULL, algor); + if (!comp_sig_obj) { + PKI_DEBUG("[Comp #%d] Cannot get the algorithm identifier from the i-th sig_algs component", i); + goto err; + } + if (!OBJ_find_sigid_algs(OBJ_obj2nid(comp_sig_obj), &comp_md_nid, NULL)) { + PKI_DEBUG("[Comp #%d] Cannot get the MD component of the algorithm identifier of the i-th sig_algs component", i); + goto err; + } + + if (NID_undef == comp_md_nid) { + + // If the MD is not defined, let's check if it is required + if (PKI_X509_KEYPAIR_VALUE_requires_digest(comp_evp_pkey)) { + PKI_DEBUG("[Comp #%d] Returned NID_undef for the MD of the i-th sig_algs component, but MD is required", i); + goto err; + } + PKI_DEBUG("[Comp #%d] Returned NID_undef for the MD of the i-th sig_algs component and it is supported", i); + comp_md = NULL; + + } else { + + comp_md = EVP_get_digestbynid(comp_md_nid); + if (!comp_md) { + PKI_DEBUG("[Comp #%d] Returned NID_undef for the MD of the i-th sig_algs component", i); + goto err; + } + } + + } else { + + PKI_DEBUG("[Comp #%d] No global sign and No configuration found for the component", i); + + // Let's check if we are required to provide a digest, if so, + // let's get the default for the component + if (PKI_X509_KEYPAIR_VALUE_requires_digest(comp_evp_pkey)) { + + // We are using a specific hash for this component, + // we just try to use the defaults + comp_md = COMPOSITE_CTX_get_default_md(comp_ctx); + if (!comp_md) { + int digest_id = NID_undef; + + digest_id = PKI_X509_KEYPAIR_VALUE_get_default_digest(comp_evp_pkey); + if (!digest_id || (comp_md = EVP_get_digestbynid(digest_id)) == NULL) { + PKI_DEBUG("[Comp #%d] Returned NID_undef for the MD of the i-th sig_algs component, but MD is required", i); + goto err; + } + } + + PKI_DEBUG("[Comp #%d] No global digest set, but found required digest for the component (MD: %s)", i, EVP_MD_name(comp_md)); + + } else { + + // Provide some debugging information + PKI_DEBUG("[Comp #%d] No global digest set, and no digest required for the i-th component", i); + comp_md = NULL; + } + + } + + // If no global digest was set and a digest is required, + // we need to calculate the digest itself + if (comp_md != NULL && comp_md != PKI_DIGEST_ALG_NULL) { + + // Let's calculate the digest for the component + PKI_DEBUG("[Comp #%d] No global digest, but component requires it. Calculating component-specific digest (%s)", + i, EVP_MD_name(comp_md)); + + // Calculates the digest of the data to be signed + if (!EVP_Digest(tbs, tbslen, (unsigned char *)hashed_data, (unsigned int *)&hashed_data_len, comp_md, NULL)) { + PKI_DEBUG("[Comp #%d] Cannot calculate the digest for component", i); + goto err; + } + + // Let's point the tbs_data to the hashed data and the + // tbs_data_len to the length of the hashed data + tbs_data = hashed_data; + tbs_data_len = hashed_data_len; + + } + } + + // Let's build a PKEY CTX and assign it to the MD CTX + comp_pkey_ctx = EVP_PKEY_CTX_new(comp_evp_pkey, NULL); + if (!comp_pkey_ctx) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "[Comp #%d] Cannot allocate the PKEY CTX component", i); + goto err; + } + + PKI_DEBUG("[Comp #%d] Data Verify: tbs_data = %p, tbs_data_len = %d bytes", + i, tbs_data, tbs_data_len); + + PKI_DEBUG("[Comp #%d] Signature Data: %d bytes", i, aType->value.asn1_string->length); + + // Debugging Info + { + char str[256] = { 0x0 }; + for (size_t iii = 0; iii < 16; iii++) { + snprintf(str + 3*iii, 256 - 3*iii, "%02X:", tbs_data[iii]); + } + PKI_DEBUG("[Comp #%d] Data Dump: %s", i, str); + } + + if (EVP_PKEY_CTX_supports_verify(comp_pkey_ctx)) { + + // Use the Verify mechanism + PKI_DEBUG("[Comp #%d] Using the verify() mechanism", i); + + // Initializes the Verify operation + ret_code = EVP_PKEY_verify_init(comp_pkey_ctx); + if (ret_code <= 0) { + PKI_DEBUG("[Comp #%d] Cannot initialize component's signature (ret code: %d)", i, ret_code); + // goto err; + } else { + // Verifies the individual signature + ret_code = EVP_PKEY_verify(comp_pkey_ctx, + aType->value.sequence->data, + (size_t)aType->value.sequence->length, + tbs_data, + (size_t)tbs_data_len); + } + + } else if (EVP_PKEY_CTX_supports_digestverify(comp_pkey_ctx)) { + + // Use the Digest Verify mechanism + PKI_DEBUG("[Comp #%d] Using the digestverify() mechanism", i); + + // Allocate a new MD CTX + EVP_MD_CTX *md_ctx = EVP_MD_CTX_new(); + if (!md_ctx) { + PKI_DEBUG("[Comp #%d] Cannot allocate a new MD CTX for signature validation", i); + EVP_PKEY_CTX_free(comp_pkey_ctx); + goto err; + } + + if (!EVP_DigestSignInit(md_ctx, NULL, NULL, NULL, comp_evp_pkey)) { + PKI_DEBUG("[Comp #%d] Cannot initialize the MD CTX for the %d component's signature operation", i); + EVP_MD_CTX_free(md_ctx); + goto err; + } + + // Uses the digestsign function to sign the data + ret_code = EVP_DigestVerify(md_ctx, + aType->value.sequence->data, + (size_t)aType->value.sequence->length, + tbs_data, + tbs_data_len); + + // Frees the MD CTX + EVP_MD_CTX_free(md_ctx); + + } else { + PKI_DEBUG("[Comp #%d] No verify mechanism is supported by the algorithm, cannot verify"); + goto err; + } + + // Removes the reference to the pkey. This is needed + // because the EVP_PKEY_CTX_free() will otherwise + // try to free the memory of the pkey + // PKI_DEBUG("Freeing the pkey from the EVP_PKEY_CTX - Check this for + // correctness (we should not need to do this!)"); + // comp_pkey_ctx->pkey = NULL; + + // Free the EVP_PKEY_CTX + if (comp_pkey_ctx) EVP_PKEY_CTX_free(comp_pkey_ctx); + comp_pkey_ctx = NULL; // Safety + + // Checks the results of the verify + if (ret_code != 1) { + PKI_DEBUG("[Comp #%d] Signature Validation failed (code: %d)", i, ret_code); + continue; + } else { + // Debugging + PKI_DEBUG("[Comp #%d] Signature Component Validated Successfully!", i); + + // Updates the tracker + successful_validations++; + } + } + + // Free the stack memory + if (sk) sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); + sk = NULL; + + // while ((aType = sk_ASN1_TYPE_pop(sk)) != NULL) { + // ASN1_TYPE_free(aType); + // } sk_ASN1_TYPE_free(sk); + // sk = NULL; // Safety + + if (successful_validations < required_valid_components) { + PKI_DEBUG("Not enough valid components (%d out of %d)", successful_validations, required_valid_components); + return 0; + } + + // Debugging + PKI_DEBUG("PMETH Verify Completed Successfully!"); + + // All Done. + return 1; + +err: + + // Debugging + PKI_DEBUG("PMETH Verify Error Condition, releasing resources."); + + // // Free the stack memory + // if (sk != NULL) { + // while ((aType = sk_ASN1_TYPE_pop(sk)) != NULL) { + // ASN1_TYPE_free(aType); + // } sk_ASN1_TYPE_free(sk); + // sk = NULL; // Safety + // } + + // Free the stack memory + if (sk) sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); + + // Error + return 0; +} + +// Implemented +static int pmeth_ctrl(EVP_PKEY_CTX *ctx, int type, int key_id, void *value) { + + // NOTE: The passed ctx does not have the PKEY + // associated with it. This means we cannot act + // on the key + + COMPOSITE_CTX * comp_ctx = ctx ? ctx->data : NULL; + // Pointer to the Composite CTX + + EVP_PKEY * pkey = ctx && ctx->pkey ? ctx->pkey : NULL;; + // Pointer to the PKEY to add/del + + COMPOSITE_KEY * comp_pkey = pkey ? EVP_PKEY_get0(pkey) : NULL; + // Pointer to the Composite Key + + // Input checks + if (!comp_ctx || !comp_pkey) { + PKI_ERROR(PKI_ERR_PARAM_NULL, "Missing CTX (%p) or PKEY (%p)", comp_ctx, comp_pkey); + return 0; + } + + // PKI_DEBUG("PKEY_CTRL: Setting (ctrl) (type = %d) (key_id = %d, value = %p)", + // type, key_id, value); + + switch (type) { + + // =================== + // OpenSSL CTRL Values + // =================== + + case EVP_PKEY_CTRL_GET_MD: { + *(const EVP_MD **)value = comp_ctx->md; + } break; + + case EVP_PKEY_CTRL_MD: { + + // Here we need to allocate the digest for each key in the + // stack (if not there, let's allocate the memory and + // initialize it) + + // Input checks + if (!value) { + PKI_DEBUG("Missing 2nd parameter (value)"); + return 0; + } + + // Sets the MD + comp_ctx->md = value; + + // All Done + return 1; + + } break; + + + case EVP_PKEY_OP_TYPE_SIG: { + // Signature is supported + return 1; + } break; + + case EVP_PKEY_CTRL_PEER_KEY: + case EVP_PKEY_CTRL_SET_DIGEST_SIZE: + case EVP_PKEY_CTRL_SET_MAC_KEY: + case EVP_PKEY_CTRL_SET_IV: { + DEBUG("ERROR: Non Supported CTRL"); + return -2; + } break; + + case EVP_PKEY_CTRL_DIGESTINIT: { + return 1; + } break; + + case EVP_PKEY_CTRL_PKCS7_ENCRYPT: + case EVP_PKEY_CTRL_PKCS7_DECRYPT: + case EVP_PKEY_CTRL_PKCS7_SIGN: + case EVP_PKEY_CTRL_CMS_ENCRYPT: + case EVP_PKEY_CTRL_CMS_DECRYPT: + case EVP_PKEY_CTRL_CMS_SIGN: + case EVP_PKEY_CTRL_CIPHER: { + // DEBUGGING + PKI_DEBUG("CTRL: type = %d, param_1 = %d, param_2 = %p", type, key_id, value); + PKI_DEBUG("CTRL: No action taken for type = %d", type); + // All Done + return 1; + } break; + + // ===================== + // COMPOSITE CTRL Values + // ===================== + + case EVP_PKEY_CTRL_COMPOSITE_PUSH: { + // Adds the Key to the internal stack + if (!COMPOSITE_KEY_STACK_push(comp_ctx->components, (EVP_PKEY *)value)) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Cannot add component (type %d) to composite key", pkey->type); + return 0; + } + // All Done + return 1; + } break; + + case EVP_PKEY_CTRL_COMPOSITE_ADD: { + // Adds the Key to the internal stack + if (!COMPOSITE_KEY_STACK_add(comp_ctx->components, (EVP_PKEY *)value, key_id)) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Cannot add component (type %d) to composite key", pkey->type); + return 0; + } + // All Done + return 1; + } break; + + case EVP_PKEY_CTRL_COMPOSITE_DEL: { + // Checks we have the key_id component + if (key_id <= 0 || key_id >= COMPOSITE_KEY_STACK_num(comp_ctx->components)) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_SIZE, "Component %d does not exists (max is %d)", + key_id, COMPOSITE_KEY_STACK_num(comp_ctx->components)); + return 0; + } + // Delete the specific item from the stack + COMPOSITE_KEY_STACK_del(comp_ctx->components, key_id); + // All Done + return 1; + } break; + + case EVP_PKEY_CTRL_COMPOSITE_POP: { + + PKI_X509_KEYPAIR_VALUE * tmp_key = NULL; + // Pointer to the value to pop + + // Checks we have at least one component + if (key_id <= 0 || key_id >= COMPOSITE_KEY_STACK_num(comp_ctx->components)) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_SIZE, "Component %d does not exists (max is %d)", + key_id, COMPOSITE_KEY_STACK_num(comp_ctx->components)); + return 0; + } + + // Pops a Key + tmp_key = COMPOSITE_KEY_STACK_pop(comp_ctx->components); + + // Free the associated memory + if (tmp_key) EVP_PKEY_free(tmp_key); + + // All Done + return 1; + } break; + + case EVP_PKEY_CTRL_COMPOSITE_CLEAR: { + // Clears all components from the key + COMPOSITE_KEY_STACK_clear(comp_ctx->components); + // All Done + return 1; + } break; + + default: { + PKI_ERROR(PKI_ERR_GENERAL, "[PKEY METHOD] Unrecognized CTRL option [%d]", type); + return 0; + } + } + + // Returns OK + return 1; +} + +// // Not Implemented +// static int ctrl_str(EVP_PKEY_CTX *ctx, const char *type, const char *value) { +// DEBUG("Not implemented, yet."); +// return 0; +// } + +// =================== +// OpenSSL 1.1.x+ Only +// =================== + +// Implemented +static int digestsign(EVP_MD_CTX * ctx, + unsigned char * sig, + size_t * siglen, + const unsigned char * tbs, + size_t tbslen) { + + int ossl_ret = 0; + // OpenSSL return code + + COMPOSITE_CTX * comp_ctx = NULL; + // Pointer to inner CTX structure + + EVP_PKEY_CTX * pctx = EVP_MD_CTX_pkey_ctx(ctx); + // PKEY context + + // const unsigned char * tbs_data; + // size_t tbs_data_len = 0; + // // Pointers to the data to be passed + // // to the generic sign() function + + // unsigned char global_hash[EVP_MAX_MD_SIZE]; + // size_t global_hashlen = 0; + // // Temp Variables + + if (!pctx) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return 0; + } + + // Gets the internal CTX + comp_ctx = (COMPOSITE_CTX *) EVP_PKEY_CTX_get_data(pctx); + if (!comp_ctx) { + PKI_DEBUG("ERROR, no internal CTX found!"); + return 0; + } + + ossl_ret = sign(pctx, sig, siglen, tbs, tbslen); + if (ossl_ret == 0) { + PKI_ERROR(PKI_ERR_SIGNATURE_CREATE, NULL); + return 0; + } + + // // Assigns the default data to be signed + // tbs_data = tbs; + // tbs_data_len = tbslen; + + // // If we use the hash-n-sign method, we need to hash the data + // // only once, let's do it before the loop in this case + // if (comp_ctx->md && comp_ctx->md != PKI_DIGEST_ALG_NULL) { + + // // Calculates the Digest (since we use custom digest, the data is not + // // hashed when it is passed to this function) + // int ossl_ret = EVP_Digest(tbs, tbslen, &global_hash[0], (unsigned int *)&global_hashlen, comp_ctx->md, NULL); + // if (ossl_ret == 0) { + // PKI_ERROR(PKI_ERR_SIGNATURE_CREATE, NULL); + // return 0; + // } + + // tbs_data = tbs; + // tbs_data_len = tbslen; + // } + + // ossl_ret = sign(pctx, sig, siglen, tbs_data, tbs_data_len); + // if (ossl_ret == 0) { + // PKI_ERROR(PKI_ERR_SIGNATURE_CREATE, NULL); + // return 0; + // } + + return 1; + +// // We need to get the algorithms from the PKEY_CTX +// EVP_PKEY * pkey = EVP_PKEY_CTX_get0_pkey(p_ctx); +// // PKEY + +// COMPOSITE_CTX * comp_ctx = p_ctx->data; +// // Composite Context + +// PKI_DEBUG("DigestSign: Data To Sign = 0x%p, Size = %lu", tbs, tbslen); +// PKI_DEBUG("Digest (EVP_md_null()? => %s) to use for signing: %s (%d)", md == EVP_md_null() ? "YES" : "NO", EVP_MD_name(md), EVP_MD_type(md)); + +// // +// // Issue: When we do not use the hash-n-sign, we need to pass the +// // digest to the sign function. This is not possible with +// // the current implementation. +// // +// // We need to create a new function that does not use the +// // digest and sign the data directly but uses a STACK of +// // values to sign. +// // +// // Let's create a new sign_ex() function with the following +// // signature: +// // +// // int sign_ex(EVP_PKEY_CTX * ctx, +// // unsigned char * sig, +// // size_t * siglen, +// // PKI_MEM_STACK * tbs_stack); +// // + +// if (comp_ctx->md) { + +// unsigned char * tbs_hash = NULL; +// unsigned int tbs_hash_len = 0; +// // Container for the Hashed value + +// // If we are using hash-n-sign, just calculate the hash +// // and use a single tbs entry in the tbs stack for all the +// // components +// md = comp_ctx->md; + +// // Hash the contents only if we have a non-NULL digest +// if (md != EVP_md_null()) { + +// PKI_MEM * tbs_mem = PKI_MEM_new_null(); +// if (!tbs_mem) { +// PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); +// return 0; +// } + +// // Calculates the Digest (since we use custom digest, the data is not +// // hashed when it is passed to this function) +// ossl_ret = EVP_Digest(tbs, tbslen, tbs_hash, &tbs_hash_len, md, NULL); +// if (ossl_ret == 0) { +// PKI_ERROR(PKI_ERR_SIGNATURE_CREATE, NULL); +// return 0; +// } + +// } else { +// tbs_hash = (unsigned char *) tbs; +// tbs_hash_len = tbslen; +// } + +// // Signs and Returns the result +// ossl_ret = sign(p_ctx, sig, siglen, tbs_hash, (size_t)tbs_hash_len); +// if (ossl_ret == 0) { +// PKI_ERROR(PKI_ERR_SIGNATURE_CREATE, NULL); +// return 0; +// } + +// // Success +// return 1; + +// } else { + +// // Here we are not using the hash-n-sign method +// } + + +// // // Calculates the Digest (since we use custom digest, the data is not +// // // hashed when it is passed to this function) +// // ossl_ret = EVP_Digest(tbs, tbslen, tbs_hash, &tbs_hash_len, EVP_MD_CTX_md(ctx), NULL); +// // if (ossl_ret == 0) { +// // PKI_ERROR(PKI_ERR_SIGNATURE_CREATE, NULL); +// // return 0; +// // } + +// // PKI_DEBUG("DigestSign: After Calculation - Data To Sign = 0x%p, Size = %lu", tbs, tbslen); + +// // PKI_DEBUG("DigestSign: After Calculation - tbs_hash_len = %d", tbs_hash_len); + +// // // Signs and Returns the result +// // ossl_ret = sign(p_ctx, sig, siglen, tbs_hash, (size_t)tbs_hash_len); +// // if (ossl_ret == 0) { +// // PKI_ERROR(PKI_ERR_SIGNATURE_CREATE, NULL); +// // return 0; +// // } + +// // Success +// return 1; + +// /* +// COMPOSITE_KEY * comp_key = EVP_PKEY_get0(ctx && ctx->pkey ? ctx->pkey : NULL); +// // Pointer to inner key structure + +// COMPOSITE_CTX * comp_ctx = ctx->data; +// // Pointer to algorithm specific CTX + +// const int signature_size = EVP_PKEY_size(ctx->pkey); +// // The total signature size + +// STACK_OF(ASN1_TYPE) *sk = NULL; +// // Stack of ASN1_OCTET_STRINGs + +// ASN1_OCTET_STRING * oct_string = NULL; +// // Output Signature to be added +// // to the stack of signatures + +// ASN1_TYPE * aType = NULL; +// // ASN1 generic wrapper + +// int comp_key_num = 0; +// // Number of components + +// unsigned char * buff = NULL; +// unsigned char * pnt = NULL; +// int buff_len = 0; +// // Temp Pointers + +// int total_size = 0; +// // Total Signature Size + +// if ((comp_key == NULL) || +// ((comp_key_num = COMPOSITE_KEY_num(comp_key)) <= 0)) { +// DEBUG("ERROR: Cannot get the Composite key inner structure"); +// return 0; +// } + +// if (sig == NULL) { +// *siglen = (size_t)signature_size; +// return 1; +// } + +// if ((size_t)signature_size > (*siglen)) { +// DEBUG("ERROR: Buffer is too small"); +// return 0; +// } + +// if ((sk = sk_ASN1_TYPE_new_null()) == NULL) { +// DEBUG("ERROR: Memory Allocation"); +// return 0; +// } + +// for (int i = 0; i < comp_key_num; i++) { + +// EVP_PKEY_CTX * pkey_ctx = NULL; + +// EVP_MD_CTX * md_ctx = NULL; + +// if (!COMPOSITE_CTX_get0(comp_ctx, i, &pkey_ctx, &md_ctx)) { +// DEBUG("ERROR: Cannot get %d-th component from CTX", i); +// return 0; +// } + +// DEBUG("Determining Signature Size for Component #%d", i); + +// // Let's get the size of the single signature +// if (EVP_PKEY_sign(pkey_ctx, NULL, (size_t *)&buff_len, tbs, tbslen) != 1) { +// DEBUG("ERROR: Null Size reported from Key Component #%d", i); +// goto err; +// } + +// // Allocate the buffer for the single signature +// if ((pnt = buff = OPENSSL_malloc(buff_len)) == NULL) { +// DEBUG("ERROR: Memory Allocation"); +// goto err; +// } + +// DEBUG("PNT = %p, BUFF = %p", pnt, buff); + +// // Generates the single signature +// if (EVP_PKEY_sign(pkey_ctx, pnt, (size_t *)&buff_len, tbs, tbslen) != 1) { +// DEBUG("ERROR: Component #%d cannot generate signatures", i); +// goto err; +// } + +// DEBUG("PNT = %p, BUFF = %p", pnt, buff); + +// // Updates the overall real size +// total_size += buff_len; + +// DEBUG("Generated Signature for Component #%d Successfully (size: %d)", i, buff_len); +// DEBUG("Signature Total Size [So Far] ... %d", total_size); + +// if ((oct_string = ASN1_OCTET_STRING_new()) == NULL) { +// DEBUG("ERROR: Memory Allocation"); +// goto err; +// } + +// // This sets the internal pointers +// ASN1_STRING_set0(oct_string, buff, buff_len); + +// // Resets the pointer and length after ownership transfer +// buff = NULL; buff_len = 0; + +// // Let's now generate the ASN1_TYPE and add it to the stack +// if ((aType = ASN1_TYPE_new()) == NULL) { +// DEBUG("ERROR: Memory Allocation"); +// goto err; +// } + +// // Transfer Ownership to the aType structure +// ASN1_TYPE_set(aType, V_ASN1_OCTET_STRING, oct_string); +// oct_string = NULL; + +// // Adds the component to the stack +// if (!sk_ASN1_TYPE_push(sk, aType)) { +// DEBUG("ERROR: Cannot push the new Type"); +// goto err; +// } + +// // Transfers ownership +// aType = NULL; +// } + +// if ((buff_len = i2d_ASN1_SEQUENCE_ANY(sk, &buff)) <= 0) { +// DEBUG("ERROR: Cannot ASN1 encode the Overall Composite Key"); +// goto err; +// } + +// // Reporting the total size +// DEBUG("Total Signature Size: %d (reported: %d)", total_size, EVP_PKEY_size(ctx->pkey)) + +// // Free the stack's memory +// while ((aType = sk_ASN1_TYPE_pop(sk)) == NULL) { +// ASN1_TYPE_free(aType); +// } +// sk_ASN1_TYPE_free(sk); +// sk = NULL; + +// // Sets the output buffer +// sig = buff; +// *siglen = buff_len; + +// // All Done +// return 1; + +// err: + +// DEBUG("ERROR: Signing failed"); + +// // Here we need to cleanup the memory + +// return 0; +// */ +} + +// Implemented +static int digestverify(EVP_MD_CTX * ctx, + const unsigned char * sig, + size_t siglen, + const unsigned char * tbs, + size_t tbslen) { + + unsigned char tbs_hash[EVP_MAX_MD_SIZE]; + unsigned int tbs_hash_len = 0; + // Container for the Hashed value + + unsigned char * tbs_data = NULL; + size_t tbs_data_len = 0; + // Pointer to the data to be signed + + int ossl_ret = 0; + // OpenSSL return code + + EVP_PKEY_CTX * p_ctx = EVP_MD_CTX_pkey_ctx(ctx); + // PKEY context + + if (!p_ctx) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return 0; + } + + COMPOSITE_CTX * comp_ctx = NULL; + // Composite Context + + // Gets the Composite Context from the EVP_PKEY_CTX + comp_ctx = EVP_PKEY_CTX_get_data(p_ctx); + if (!comp_ctx) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return 0; + } + + // Calculates the Digest only if we are using a global digest + // (i.e., the hash-n-sign is in use). This is true if the + // comp_ctx->md is not set to NULL or EVP_md_null() + if (comp_ctx->md != NULL && + comp_ctx->md != EVP_md_null()) { + + const EVP_MD * md = EVP_MD_CTX_md(ctx); + // Digest Algorithm + + if (!md) { + PKI_DEBUG("ERROR, digest was not properly initialized for hash-n-sign verfiy, let's use the CTX one"); + md = comp_ctx->md; + } + + if (md != comp_ctx->md) { + PKI_DEBUG("ERROR, digest algorithm mismatch for hash-n-sign verify"); + return 0; + } + + // Calculates the Digest (since we use custom digest, the data is not + // hashed when it is passed to this function) + ossl_ret = EVP_Digest(tbs, tbslen, tbs_hash, &tbs_hash_len, md, NULL); + if (ossl_ret == 0) { + PKI_ERROR(PKI_ERR_SIGNATURE_VERIFY, NULL); + return 0; + } + + PKI_DEBUG("Using Hash-n-Sign Algorithm (Digest: %s)", EVP_MD_name(md)); + + // Sets the pointers to the data to be validated + // to the hashed data buffer + tbs_data = tbs_hash; + tbs_data_len = tbs_hash_len; + + } else { + + // We are not using a global hash-n-sign algorithm, so we just sign the data + // directly with all the different components + tbs_data = (unsigned char *) tbs; + tbs_data_len = tbslen; + } + + // Verifies and Returns the result + ossl_ret = verify(p_ctx, sig, siglen, tbs_data, tbs_data_len); + if (ossl_ret == 0) { + PKI_ERROR(PKI_ERR_SIGNATURE_VERIFY, NULL); + return 0; + } + + // Success + return 1; +} + +// // Not Implemented +// static int check(EVP_PKEY *pkey) { +// PKI_DEBUG("Not implemented, yet."); +// return 0; +// } + +// // Not Implemented +// static int public_check(EVP_PKEY *pkey) { +// PKI_DEBUG("Not implemented, yet."); +// return 0; +// } + +// // Not Implemented +// static int param_check(EVP_PKEY *pkey) { +// PKI_DEBUG("Not implemented, yet."); +// return 0; +// } + +// // Not Implemented +// static int digest_custom(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) { +// PKI_DEBUG("Not implemented, yet. Returning Ok anyway."); +// return 1; +// } + +// ====================== +// PKEY Method Definition +// ====================== +// +// The Definition of the EVP_PKEY_METHOD is a typedef +// of the evp_pkey_method_st from: +// - OPENSSL_SRC/crypto/evp/evp_locl.h (OPENSSL_VERSION <= 1.1.0 or prior) +// - OPENSSL_SRC/crypto/include/internal/evp_int.h (OPENSSL_VERSION >= 1.1.X+) + +// NOTE: When the EVP_PKEY_FLAG_SIGCTX_CUSTOM is used, then we can +// return a NULL as a default MD, otherwise OpenSSL will stop the +// execution (see the do_sigver_init() at m_sigver.c:25) because +// it gets the default digest nid (EVP_PKEY_get_default_digest_nid()) +// and if tht returns NULL, it assumes it has no valid default +// and returns an error (NO_DEFAULT_DIGEST). + +// NOTE: The EVP_PKEY_FLAG_SIGCTX_CUSTOM, when you do not implement +// the signctx_ and verifyctx_ functions, has the side effect to not +// initialize the EVP_MD_CTX * that is passed via the EVP_DigestSign +// interface. + +EVP_PKEY_METHOD composite_pkey_meth = { + 0, // int pkey_id; // EVP_PKEY_COMPOSITE + 0, // int flags; //EVP_PKEY_FLAG_SIGCTX_CUSTOM + init, // int (*init)(EVP_PKEY_CTX *ctx); + 0, // copy, // int (*copy)(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src); + cleanup, // void (*cleanup)(EVP_PKEY_CTX *ctx); + 0, // paramgen_init, // int (*paramgen_init)(EVP_PKEY_CTX *ctx); + 0, // int (*paramgen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey); + 0, // int (*keygen_init)(EVP_PKEY_CTX *ctx); + keygen, // int (*keygen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey); + 0, // int (*sign_init) (EVP_PKEY_CTX *ctx); + sign, // int (*sign) (EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, const unsigned char *tbs, size_t tbslen); + 0, // verify_init, // int (*verify_init) (EVP_PKEY_CTX *ctx); + verify, // int (*verify) (EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen, const unsigned char *tbs, size_t tbslen); + 0, // verify_recover_init, // int (*verify_recover_init) (EVP_PKEY_CTX *ctx); + 0, // verify_recover, // int (*verify_recover) (EVP_PKEY_CTX *ctx, unsigned char *rout, size_t *routlen, const unsigned char *sig, size_t siglen); + 0, // signctx_init, // int (*signctx_init) (EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx); + 0, // signctx, // int (*signctx) (EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, EVP_MD_CTX *mctx); + 0, // verifyctx_init, // int (*verifyctx_init) (EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx); + 0, // verifyctx, // int (*verifyctx) (EVP_PKEY_CTX *ctx, const unsigned char *sig, int siglen, EVP_MD_CTX *mctx); + 0, // encrypt_init, // int (*encrypt_init) (EVP_PKEY_CTX *ctx); + 0, // encrypt, // int (*encrypt) (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char *in, size_t inlen); + 0, // decrypt_init, // int (*decrypt_init) (EVP_PKEY_CTX *ctx); + 0, // decrypt, // int (*decrypt) (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char *in, size_t inlen); + 0, // derive_init, // int (*derive_init) (EVP_PKEY_CTX *ctx); + 0, // derive, // int (*derive) (EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen); + pmeth_ctrl, // int (*ctrl) (EVP_PKEY_CTX *ctx, int type, int p1, void *p2); + 0, // int (*ctrl_str) (EVP_PKEY_CTX *ctx, const char *type, const char *value); +#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) + // These are only available on OpenSSL v1.1.X+ // + digestsign, // int (*digestsign) (EVP_MD_CTX *ctx, unsigned char *sig, size_t *siglen, const unsigned char *tbs, size_t tbslen); + digestverify, // int (*digestverify) (EVP_MD_CTX *ctx, const unsigned char *sig, size_t siglen, const unsigned char *tbs, size_t tbslen); + 0, // int (*check) (EVP_PKEY *pkey); + 0, // int (*public_check) (EVP_PKEY *pkey); + 0, // int (*param_check) (EVP_PKEY *pkey); + 0, // int (*digest_custom) (EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx); +#endif +}; + +#endif // ENABLE_COMPOSITE + +/* END: composite_pmeth.c */ diff --git a/src/crypto/composite/composite_utils.c b/src/crypto/composite/composite_utils.c new file mode 100644 index 00000000..8577f179 --- /dev/null +++ b/src/crypto/composite/composite_utils.c @@ -0,0 +1,86 @@ +// BEGIN: composite_utils.c + +// Composite Crypto authentication methods. +// (c) 2021 by Massimiliano Pala + +#ifndef _LIBPKI_COMPOSITE_UTILS_H +#include +#endif + +#ifndef _LIBPKI_COMPOSITE_KEY_H +#include +#endif + +// =============== +// Data Structures +// =============== + +#ifndef _LIBPKI_COMPOSITE_OPENSSL_LOCAL_H +#include "composite_ossl_lcl.h" +#endif + +// ================== +// Exported Functions +// ================== + +int EVP_PKEY_assign_COMPOSITE(EVP_PKEY *pkey, void *comp_key) { + + COMPOSITE_KEY * key = comp_key; + // Composite Key + + // Checks if we specified an explicit ID + if (key->algorithm <= 0) { + key->algorithm = OBJ_txt2nid(OPENCA_ALG_PKEY_EXP_COMP_NAME); + } + + PKI_DEBUG("Assigning Composite Key (KEY Algorithm: %d)", key->algorithm); + + // Checks that the crypto library understands the composite algorithm (dynamic) + if (key->algorithm <= NID_undef) { + PKI_DEBUG("Cannot assign the Composite Key (unknown algorithm)"); + return PKI_ERR; + } + + // Assigns the Key + int success = EVP_PKEY_assign(pkey, key->algorithm, comp_key); + if (success == 0) { + PKI_DEBUG("Cannot assign the Composite Key"); + return PKI_ERR; + } + + // All Done + return PKI_OK; +} + +// ========================== +// PKEY/ASN1_METHOD Auxillary +// ========================== + +int EVP_PKEY_meth_set_id(EVP_PKEY_METHOD * meth, int pkey_id, int flags) { + + // Input Check + if (!meth || pkey_id <= 0) return 0; + + // Assigns the generated IDs + meth->pkey_id = pkey_id; + + if (flags >= 0) meth->flags = flags; + + // All Done + return 1; +} + +int EVP_PKEY_asn1_meth_set_id(EVP_PKEY_ASN1_METHOD * pkey_ameth, int pkey_id) { + + // Input Check + if (!pkey_ameth || pkey_id <= 0) return 0; + + // Assigns the generated IDs + pkey_ameth->pkey_id = pkey_id; + pkey_ameth->pkey_base_id = pkey_id; + + // All Done + return 1; +} + +// END: composite_utils.c diff --git a/src/crypto/hsm/Makefile.am b/src/crypto/hsm/Makefile.am new file mode 100644 index 00000000..7ecd904e --- /dev/null +++ b/src/crypto/hsm/Makefile.am @@ -0,0 +1,40 @@ +## OpenCA Makefile - by Massimiliano Pala +## (c) 1999-2007 by Massimiliano Pala and OpenCA Project +## All Rights Reserved + +TOP = .. +include $(TOP)/global-vars + +BASE_DEFS = + +if ENABLE_OPENSSL +HSM_SOFTWARE = openssl +HSM_SOFTWARE_OBJ = $(top_builddir)/src/drivers/openssl/libpki-token-openssl.la +else +HSM_SOFTWARE = +endif + +HSM_PKCS11 = pkcs11 +HSM_PKCS11_OBJ = $(top_builddir)/src/drivers/pkcs11/libpki-token-pkcs11.la + +HSMS = $(HSM_SOFTWARE) $(HSM_PKCS11) +OBJECTS = $(HSM_SOFTWARE_OBJ) $(HSM_PKCS11_OBJ) + +SUBDIRS = $(HSMS) . + +AM_CPPFLAGS = -I$(TOP) + +SRCS = \ + hsm_main.c \ + hsm_slot.c \ + hsm_keypair.c + + +noinst_LTLIBRARIES = libpki-token.la +# noinst_LIBRARIES = libpki-token.a + +libpki_token_la_SOURCES = $(SRCS) +libpki_token_la_CFLAGS = $(BUILD_LIBPKI_CFLAGS) +# libpki_token_la_LIBADD = $(BUILD_LIBPKI_LDFLAGS) $(OBJECTS) +libpki_token_la_LIBADD = $(OBJECTS) + diff --git a/src/crypto/hsm/Makefile.in b/src/crypto/hsm/Makefile.in new file mode 100644 index 00000000..a7647e6f --- /dev/null +++ b/src/crypto/hsm/Makefile.in @@ -0,0 +1,908 @@ +# Makefile.in generated by automake 1.16.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = src/drivers +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(SHELL) $(top_srcdir)/build/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/src/libpki/config.h \ + $(top_builddir)/src/libpki/libpki_enables.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +am__DEPENDENCIES_1 = $(HSM_SOFTWARE_OBJ) $(HSM_ENGINE_OBJ) \ + $(HSM_PKCS11_OBJ) +libpki_token_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am__objects_1 = libpki_token_la-hsm_main.lo \ + libpki_token_la-hsm_slot.lo libpki_token_la-hsm_keypair.lo +am_libpki_token_la_OBJECTS = $(am__objects_1) +libpki_token_la_OBJECTS = $(am_libpki_token_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libpki_token_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(libpki_token_la_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src/libpki +depcomp = $(SHELL) $(top_srcdir)/build/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/libpki_token_la-hsm_keypair.Plo \ + ./$(DEPDIR)/libpki_token_la-hsm_main.Plo \ + ./$(DEPDIR)/libpki_token_la-hsm_slot.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libpki_token_la_SOURCES) +DIST_SOURCES = $(libpki_token_la_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir distdir-am +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +DIST_SUBDIRS = openssl engine pkcs11 . +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/build/depcomp \ + $(top_srcdir)/build/mkinstalldirs +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_DATE = @BUILD_DATE@ +BUILD_DATE_FULL = @BUILD_DATE_FULL@ +BUILD_DATE_PRETTY = @BUILD_DATE_PRETTY@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CHMOD = @CHMOD@ +CHOWN = @CHOWN@ +CP = @CP@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CPU = @CPU@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CXX = @CXX@ +CYGPATH_W = @CYGPATH_W@ +DATE = @DATE@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DESTDIR = @DESTDIR@ +DIST_NAME = @DIST_NAME@ +DIST_VERSION = @DIST_VERSION@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +GZIP = @GZIP@ +HAS_PKGCONF = @HAS_PKGCONF@ +INSTALL = @INSTALL@ +INSTALL_BUILDER = @INSTALL_BUILDER@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKE = @MAKE@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR = @MKDIR@ +MKDIR_P = @MKDIR_P@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PDFLATEX = @PDFLATEX@ +PERL = @PERL@ +PG_CONFIG = @PG_CONFIG@ +PG_CPPFLAGS = @PG_CPPFLAGS@ +PKGMK = @PKGMK@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POD2MAN = @POD2MAN@ +PWD = @PWD@ +RANLIB = @RANLIB@ +RC = @RC@ +RPM = @RPM@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TAR = @TAR@ +TODAY = @TODAY@ +VERSION = @VERSION@ +ZIP = @ZIP@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_aux_dir = @ac_aux_dir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +arch_target = @arch_target@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +composite_cflags = @composite_cflags@ +composite_ldadd = @composite_ldadd@ +composite_ldflags = @composite_ldflags@ +conf_dir = @conf_dir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +day = @day@ +dist_group = @dist_group@ +dist_user = @dist_user@ +docdir = @docdir@ +dvidir = @dvidir@ +enable_debug = @enable_debug@ +etc_dir = @etc_dir@ +exec_prefix = @exec_prefix@ +extra_checks = @extra_checks@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +hr = @hr@ +htmldir = @htmldir@ +iface_age = @iface_age@ +iface_current = @iface_current@ +iface_revision = @iface_revision@ +iface_version = @iface_version@ +include_dir = @include_dir@ +include_prefix = @include_prefix@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +kmf_cflags = @kmf_cflags@ +kmf_ldadd = @kmf_ldadd@ +kmf_libflags = @kmf_libflags@ +kmf_prefix = @kmf_prefix@ +ldap_cflags = @ldap_cflags@ +ldap_ldadd = @ldap_ldadd@ +ldap_ldflags = @ldap_ldflags@ +ldap_prefix = @ldap_prefix@ +ldap_vendor = @ldap_vendor@ +lib_major = @lib_major@ +lib_micro = @lib_micro@ +lib_minor = @lib_minor@ +lib_prefix = @lib_prefix@ +lib_revision = @lib_revision@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libpki_cflags = @libpki_cflags@ +libpki_ldadd = @libpki_ldadd@ +libpki_ldflags = @libpki_ldflags@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +min = @min@ +mkdir_p = @mkdir_p@ +mon = @mon@ +my_cflags = @my_cflags@ +my_ldadd = @my_ldadd@ +my_ldflags = @my_ldflags@ +myarch = @myarch@ +mybits = @mybits@ +mybits_install = @mybits_install@ +mysql_cflags = @mysql_cflags@ +mysql_config = @mysql_config@ +mysql_ldadd = @mysql_ldadd@ +mysql_ldflags = @mysql_ldflags@ +mysql_prefix = @mysql_prefix@ +oldincludedir = @oldincludedir@ +openssl_cflags = @openssl_cflags@ +openssl_include = @openssl_include@ +openssl_ldadd = @openssl_ldadd@ +openssl_ldflags = @openssl_ldflags@ +openssl_prefix = @openssl_prefix@ +openssl_static_libs = @openssl_static_libs@ +oqs_cflags = @oqs_cflags@ +oqs_ldadd = @oqs_ldadd@ +oqs_ldflags = @oqs_ldflags@ +oqsprov_cflags = @oqsprov_cflags@ +oqsprov_ldadd = @oqsprov_ldadd@ +oqsprov_ldflags = @oqsprov_ldflags@ +package_build = @package_build@ +package_prefix = @package_prefix@ +pdfdir = @pdfdir@ +pg_cflags = @pg_cflags@ +pg_config = @pg_config@ +pg_ldadd = @pg_ldadd@ +pg_ldflags = @pg_ldflags@ +pg_prefix = @pg_prefix@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pthread_opts = @pthread_opts@ +resolv_ldadd = @resolv_ldadd@ +rpath = @rpath@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sdkver = @sdkver@ +sec = @sec@ +sharedstatedir = @sharedstatedir@ +shlext = @shlext@ +shlib_history = @shlib_history@ +shlib_version = @shlib_version@ +srcdir = @srcdir@ +sys_cflags = @sys_cflags@ +sys_ldadd = @sys_ldadd@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +test_libs = @test_libs@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +txt_revision = @txt_revision@ +xml2_cflags = @xml2_cflags@ +xml2_config = @xml2_config@ +xml2_include = @xml2_include@ +xml2_ldadd = @xml2_ldadd@ +xml2_ldflags = @xml2_ldflags@ +xml2_prefix = @xml2_prefix@ +yr = @yr@ +TOP = .. +BASE_DEFS = +@ENABLE_OPENSSL_FALSE@HSM_SOFTWARE = +@ENABLE_OPENSSL_TRUE@HSM_SOFTWARE = openssl +@ENABLE_OPENSSL_TRUE@HSM_SOFTWARE_OBJ = $(top_builddir)/src/drivers/openssl/libpki-token-openssl.la +@ENABLE_OPENSSL_ENGINE_FALSE@HSM_ENGINE = +@ENABLE_OPENSSL_ENGINE_TRUE@HSM_ENGINE = engine +@ENABLE_OPENSSL_ENGINE_TRUE@HSM_ENGINE_OBJ = $(top_builddir)/src/drivers/engine/libpki-token-engine.la +HSM_PKCS11 = pkcs11 +HSM_PKCS11_OBJ = $(top_builddir)/src/drivers/pkcs11/libpki-token-pkcs11.la +HSMS = $(HSM_SOFTWARE) $(HSM_KMF) $(HSM_ENGINE) $(HSM_PKCS11) +OBJECTS = $(HSM_KMF_OBJ) $(HSM_SOFTWARE_OBJ) $(HSM_ENGINE_OBJ) $(HSM_PKCS11_OBJ) +SUBDIRS = $(HSMS) . +AM_CPPFLAGS = -I$(TOP) +SRCS = \ + hsm_main.c \ + hsm_slot.c \ + hsm_keypair.c + +noinst_LTLIBRARIES = libpki-token.la +# noinst_LIBRARIES = libpki-token.a +libpki_token_la_SOURCES = $(SRCS) +libpki_token_la_CFLAGS = $(BUILD_LIBPKI_CFLAGS) +# libpki_token_la_LIBADD = $(BUILD_LIBPKI_LDFLAGS) $(OBJECTS) +libpki_token_la_LIBADD = $(OBJECTS) +all: all-recursive + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/drivers/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/drivers/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libpki-token.la: $(libpki_token_la_OBJECTS) $(libpki_token_la_DEPENDENCIES) $(EXTRA_libpki_token_la_DEPENDENCIES) + $(AM_V_CCLD)$(libpki_token_la_LINK) $(libpki_token_la_OBJECTS) $(libpki_token_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_token_la-hsm_keypair.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_token_la-hsm_main.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_token_la-hsm_slot.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +libpki_token_la-hsm_main.lo: hsm_main.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_token_la_CFLAGS) $(CFLAGS) -MT libpki_token_la-hsm_main.lo -MD -MP -MF $(DEPDIR)/libpki_token_la-hsm_main.Tpo -c -o libpki_token_la-hsm_main.lo `test -f 'hsm_main.c' || echo '$(srcdir)/'`hsm_main.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_token_la-hsm_main.Tpo $(DEPDIR)/libpki_token_la-hsm_main.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hsm_main.c' object='libpki_token_la-hsm_main.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_token_la_CFLAGS) $(CFLAGS) -c -o libpki_token_la-hsm_main.lo `test -f 'hsm_main.c' || echo '$(srcdir)/'`hsm_main.c + +libpki_token_la-hsm_slot.lo: hsm_slot.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_token_la_CFLAGS) $(CFLAGS) -MT libpki_token_la-hsm_slot.lo -MD -MP -MF $(DEPDIR)/libpki_token_la-hsm_slot.Tpo -c -o libpki_token_la-hsm_slot.lo `test -f 'hsm_slot.c' || echo '$(srcdir)/'`hsm_slot.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_token_la-hsm_slot.Tpo $(DEPDIR)/libpki_token_la-hsm_slot.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hsm_slot.c' object='libpki_token_la-hsm_slot.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_token_la_CFLAGS) $(CFLAGS) -c -o libpki_token_la-hsm_slot.lo `test -f 'hsm_slot.c' || echo '$(srcdir)/'`hsm_slot.c + +libpki_token_la-hsm_keypair.lo: hsm_keypair.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_token_la_CFLAGS) $(CFLAGS) -MT libpki_token_la-hsm_keypair.lo -MD -MP -MF $(DEPDIR)/libpki_token_la-hsm_keypair.Tpo -c -o libpki_token_la-hsm_keypair.lo `test -f 'hsm_keypair.c' || echo '$(srcdir)/'`hsm_keypair.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_token_la-hsm_keypair.Tpo $(DEPDIR)/libpki_token_la-hsm_keypair.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hsm_keypair.c' object='libpki_token_la-hsm_keypair.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_token_la_CFLAGS) $(CFLAGS) -c -o libpki_token_la-hsm_keypair.lo `test -f 'hsm_keypair.c' || echo '$(srcdir)/'`hsm_keypair.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile $(LTLIBRARIES) +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-recursive + -rm -f ./$(DEPDIR)/libpki_token_la-hsm_keypair.Plo + -rm -f ./$(DEPDIR)/libpki_token_la-hsm_main.Plo + -rm -f ./$(DEPDIR)/libpki_token_la-hsm_slot.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f ./$(DEPDIR)/libpki_token_la-hsm_keypair.Plo + -rm -f ./$(DEPDIR)/libpki_token_la-hsm_main.Plo + -rm -f ./$(DEPDIR)/libpki_token_la-hsm_slot.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(am__recursive_targets) install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--depfiles check check-am clean clean-generic clean-libtool \ + clean-noinstLTLIBRARIES cscopelist-am ctags ctags-am distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am + +.PRECIOUS: Makefile + +include $(TOP)/global-vars + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/crypto/hsm/hsm_keypair.c b/src/crypto/hsm/hsm_keypair.c new file mode 100644 index 00000000..7a342e63 --- /dev/null +++ b/src/crypto/hsm/hsm_keypair.c @@ -0,0 +1,129 @@ +/* HSM Object Management Functions */ + +#include + +extern HSM_CALLBACKS openssl_hsm_callbacks; +extern HSM openssl_hsm; + +/* ------------------- Keypair Gen/Free -------------------------------- */ + +PKI_X509_KEYPAIR *HSM_X509_KEYPAIR_new( PKI_KEYPARAMS *params, + char *label, PKI_CRED *cred, HSM *hsm ) { + + PKI_X509_KEYPAIR *ret = NULL; + URL *url = NULL; + + if( hsm && !url && (hsm->type == HSM_TYPE_PKCS11) ) { + PKI_DEBUG("Label is required when using HSM"); + return NULL; + } + + if ( label ) { + if(( url = URL_new(label)) == NULL ) { + PKI_ERROR(PKI_ERR_URI_PARSE, label); + return ( NULL ); + } + }; + + ret = HSM_X509_KEYPAIR_new_url ( params, url, cred, hsm ); + + if( url ) URL_free( url ); + + return ( ret ); +} + +PKI_X509_KEYPAIR *HSM_X509_KEYPAIR_new_url( PKI_KEYPARAMS *params, + URL *url, PKI_CRED *cred, HSM *driver ) { + + PKI_X509_KEYPAIR *ret = NULL; + HSM *hsm = NULL; + + if ( !params ) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return NULL; + }; + + if( driver ) { + hsm = driver; + } else { + hsm = (HSM *) HSM_get_default(); + } + + if( hsm && hsm->callbacks && hsm->callbacks->keypair_new_url ) { + ret = hsm->callbacks->keypair_new_url(params,url,cred,hsm); + } else { + PKI_log_err("HSM does not provide key generation"); + // ret = HSM_OPENSSL_KEYPAIR_new( type, bits, url, cred, NULL ); + } + + return ( ret ); +} + + +PKI_MEM *HSM_X509_KEYPAIR_wrap ( PKI_X509_KEYPAIR *key, PKI_CRED *cred) { + + const HSM *hsm = NULL; + + if ( !key || !key->value ) return NULL; + + if ( key->hsm ) { + hsm = key->hsm; + } else { + hsm = HSM_get_default(); + } + + if ( hsm && hsm->callbacks && hsm->callbacks->key_wrap ) { + return hsm->callbacks->key_wrap ( key, cred ); + } + + return NULL; + +/* + int i = 0; + + PKI_X509 *obj = NULL; + PKI_MEM_STACK *ret_sk = NULL; + PKI_MEM *mem = NULL; + + if ( !sk ) return NULL; + + if ((ret_sk = PKI_STACK_MEM_new()) == NULL ) { + return NULL; + } + + for ( i = 0; i < PKI_STACK_X509_KEYPAIR_elements ( sk ); i++ ) { + obj = PKI_STACK_X509_KEYPAIR_get_num ( sk, i ); + + if (!obj || !obj->value ) continue; + + if ( obj->hsm ) { + if( obj->hsm && obj->hsm->callbacks && + obj->hsm->callbacks->key_wrap ) { + mem = obj->hsm->callbacks->key_wrap ( obj, + cred); + if ( mem == NULL ) break; + + PKI_STACK_MEM_push ( ret_sk, mem ); + } + } + } + + return ret_sk; +*/ +} + +PKI_X509_KEYPAIR *HSM_X509_KEYPAIR_unwrap ( PKI_MEM *mem, + URL *url, PKI_CRED *cred, HSM *hsm ) { + + PKI_X509_KEYPAIR *ret = NULL; + + if ( !hsm ) hsm = (HSM *) HSM_get_default(); + + /* Now Put the stack of objects in the HSM */ + if( hsm && hsm->callbacks && hsm->callbacks->key_unwrap ) { + ret = hsm->callbacks->key_unwrap ( mem, url, cred, hsm ); + }; + + /* Return value */ + return ret; +} diff --git a/src/crypto/hsm/hsm_main.c b/src/crypto/hsm/hsm_main.c new file mode 100644 index 00000000..64ada628 --- /dev/null +++ b/src/crypto/hsm/hsm_main.c @@ -0,0 +1,1373 @@ +/* HSM Object Management Functions */ + +#include + +// Small Hack - taps into OpenSSL internals.. needed for setting the right +// algorithm for signing + +#ifdef EVP_MD_FLAG_PKEY_METHOD_SIGNATURE +# define ENABLE_AMETH 1 +#endif + +#ifdef ENABLE_AMETH +typedef struct my_meth_st { + int pkey_id; + int pkey_base_id; + unsigned long pkey_flags; + char *pem_str; + char *info; +} LIBPKI_METH; +#endif + +/* --------------------------- Static function(s) ------------------------- */ + +/* +static int __set_algIdentifier (PKI_X509_ALGOR_VALUE * alg, + const PKI_DIGEST_ALG * digest, + const PKI_X509_KEYPAIR * key) { + + PKI_X509_KEYPAIR_VALUE *pkey = NULL; + // KeyPair Pointer + + int def_nid; + + int pkey_type = 0; + int param_type = V_ASN1_UNDEF; + // Parameter Type for Signature + + PKI_DIGEST_ALG * md = NULL; + // Digest to use + + EVP_MD_CTX *ctx = NULL; + EVP_PKEY_CTX *pkctx = NULL; + // EVP_PKEY_CTX for signing + + // Input Checks + if (!key || !key->value || !digest || !alg ) + return PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + + // Gets the KeyPair Pointer from the X509 structure + pkey = key->value; + + if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) == 2 + && def_nid == NID_undef) { + // The signing algorithm requires there to be no digest + md = NULL; + } + + if ((ctx = EVP_MD_CTX_new()) == NULL) { + PKI_log_err("Cannot Allocate Digest Context"); + return 0; + } + + if (!EVP_MD_CTX_init(ctx) || !EVP_DigestSignInit(ctx, &pkctx, md, NULL, pkey)) { + PKI_log_err("Cannot Initialize DigestSignInit"); + return 0; + } + + pkey_type = EVP_MD_CTX_type(ctx); + PKI_log_err("DEBUG: pkey_type (new) = %d (%s)", + pkey_type, PKI_ALGOR_ID_txt(pkey_type)); + + + // if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) == 2 + // && def_nid == NID_undef) { + // + // // The signing algorithm requires there to be no digest + // digest = NULL; + // + // PKI_log_err("DIGEST ALGORITHM => %p", digest); + // } else { + // PKI_log_err("DIGEST ALGORITHM => %s", + // PKI_DIGEST_ALG_get_parsed(digest)); + // } + + // Gets the Signature Algorithm + pkey_type = EVP_MD_pkey_type(digest); + PKI_log_err("DEBUG: pkey_type (old) = %d", pkey_type); + +#ifdef ENABLE_AMETH + + struct my_meth_st *ameth = NULL; + // Pointer to the aMeth structure + + // Gets the Reference to the Key's Method + if ((ameth = (struct my_meth_st *) pkey->ameth) == NULL) + return PKI_ERROR(PKI_ERR_POINTER_NULL, "Missing aMeth pointer."); + + // Gets the right parameter + if (ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL) param_type = V_ASN1_NULL; + else param_type = V_ASN1_UNDEF; + +#else // Else for aMeth + + // Special Case for RFC 2459 (Omit Parameters) + if (pkey_type == PKI_ALGOR_DSA_SHA1) param_type = V_ASN1_NULL; + else param_type = V_ASN1_UNDEF; + + if (alg->parameter) ASN1_TYPE_free(alg->parameter); + alg->parameter = NULL; + +#endif // End of aMeth + + PKI_log_err("Set Algorithm: pkey_type = %d (%s)", + pkey_type, PKI_ALGOR_ID_txt(pkey_type)); + + // Sets the Algorithms details + if (!X509_ALGOR_set0(alg, OBJ_nid2obj(pkey_type), param_type, NULL)) + return PKI_ERROR(PKI_ERR_ALGOR_SET, "Cannot set the algorithm"); + + // All Done + return PKI_OK; + +} +*/ + + +/*! \brief Returns the errno from the crypto layer */ + +unsigned long HSM_get_errno (const HSM *hsm ) +{ + const HSM *my_hsm = NULL; + + if (!hsm) my_hsm = (HSM *) HSM_OPENSSL_get_default(); + else my_hsm = hsm; + + if ( my_hsm && my_hsm->callbacks && my_hsm->callbacks->get_errno) + { + return my_hsm->callbacks->get_errno(); + } + + return 0; +} + +/*! \brief Returns the description of the passed error number from the + * crypto layer */ + +char *HSM_get_errdesc ( unsigned long err, const HSM *hsm ) +{ + const HSM *my_hsm = NULL; + + // If no hsm was provided, let's get the default one + if (!hsm) my_hsm = (HSM *) HSM_OPENSSL_get_default(); + else my_hsm = hsm; + + // If no error number was provided, let's get the latest + if (err == 0) err = HSM_get_errno(my_hsm); + + if (my_hsm && my_hsm->callbacks && my_hsm->callbacks->get_errdesc) + { + return my_hsm->callbacks->get_errdesc(err, NULL, 0); + } + + return NULL; +} + +/*! \brief Returns the default HSM structure (software) + * + * The returned HSM * points to a static structure that does not need + * to be freed. + */ + +const HSM *HSM_get_default( void ) { + return HSM_OPENSSL_get_default(); +} + +/*! \brief Allocates a new HSM structure + * + * Allocates a new HSM structure and initialize the callbacks functions. + * The driver is the crypto driver to be used (e.g., openssl or kmf), + * while the name is the name of the HSM (e.g., LunaCA3) + */ + +HSM *HSM_new( const char * const dir, + const char * const name ) { + + HSM * hsm = NULL; + char * url_s = NULL; + char * buff = NULL; + + PKI_CONFIG *conf = NULL; + char *type = NULL; + + PKI_init_all(); + + if( !name ) { + /* If no name is passed, we generate a new software token */ + return HSM_OPENSSL_new( NULL ); + } + + if((url_s = PKI_CONFIG_find_all( dir, name, PKI_DEFAULT_HSM_DIR )) + == NULL ) { + PKI_log_debug( "Can not find config file (%s/%s)\n", dir, name); + return (NULL); + } + + if((conf = PKI_CONFIG_load( url_s )) == NULL ) { + PKI_log_debug( "Can not load config from %s", url_s ); + goto err; + } + + if((buff = PKI_Malloc ( BUFF_MAX_SIZE )) == NULL ) { + goto err; + } + + /* Let's generate the right searching string with the namespace + prefix */ + if((type = PKI_CONFIG_get_value ( conf, "/hsm/type")) == NULL ) { + /* No type in the config! */ + PKI_log_debug("ERROR, No HSM type in the config!"); + type = strdup("software"); + } + + if( strcmp_nocase(type,"software") == 0 ) { + if((hsm = HSM_OPENSSL_new( conf )) == NULL ) { + PKI_log_debug("ERROR, Can not generate software HSM object!"); + } else { + hsm->type = HSM_TYPE_SOFTWARE; + } +#ifdef HAVE_ENGINE + } else if( strcmp_nocase(type,"engine") == 0 ) { + if((hsm = HSM_ENGINE_new( conf )) == NULL ) { + PKI_log_debug("ERROR, Can not generate engine HSM object!"); + } else { + hsm->type = HSM_TYPE_ENGINE; + } +#endif + } else if( strcmp_nocase(type,"pkcs11") == 0 ) { + if((hsm = HSM_PKCS11_new( conf )) == NULL ) { + PKI_log_debug("ERROR, Can not generate engine HSM object!"); + } else { + hsm->type = HSM_TYPE_PKCS11; + } +#ifdef ENABLE_KMF + } else if( strcmp_nocase(type,"kmf") == 0 ) { + if((hsm = HSM_KMF_new( conf )) == NULL ) { + PKI_log_debug("ERROR, Can not generate kmf HSM object!\n"); + } else { + hsm->type = HSM_TYPE_KMF; + } +#endif + } else { + PKI_log_debug( "Unknown HSM type (%s)", type ); + goto err; + } + + if ( ( hsm != NULL ) && (HSM_init ( hsm ) != PKI_OK) ) { + goto err; + } + + // Let' see if we can enforce the FIPS mode (optional, therefore + // errors are not fatal if PKI_is_fips_mode return PKI_ERR) + if (PKI_is_fips_mode() == PKI_OK) + { + if (HSM_set_fips_mode(hsm, 1) == PKI_OK) + { + PKI_log_debug("HSM created in FIPS mode"); + } + else + { + PKI_log_err("Can not create HSM in FIPS mode"); + goto err; + } + } + else + { + PKI_log_debug("HSM created in non-FIPS mode"); + } + + // Free memory + if (type) PKI_Free(type); + if (conf) PKI_CONFIG_free(conf); + if (url_s) PKI_Free(url_s); + + // Returns the value + return (hsm); + +err: + + // Free used memory + if (conf) PKI_CONFIG_free(conf); + if (url_s) PKI_Free(url_s); + if (hsm) HSM_free(hsm); + if (type) PKI_Free(type); + + // Returns a NULL pointer + return NULL; +} + +/*! \brief Allocates a new HSM structure and initializes it in FIPS mode + * + * Allocates a new HSM structure and initialize the callbacks functions + * in FIPS mode. The driver is the crypto driver to be used (e.g., openssl + * or kmf), while the name is the name of the HSM (e.g., LunaCA3) + * + * If the HSM does not support FIPS mode or other errors occur, this function + * returns NULL + */ + +HSM *HSM_new_fips(const char * const dir, + const char * const name) { + HSM *ret = NULL; + + // Let's invoke the normal initialization + ret = HSM_new(dir, name); + if (!ret) return NULL; + + // Checks if the HSM is operating in FIPS mode + if (PKI_is_fips_mode() == PKI_OK && HSM_is_fips_mode(ret) == PKI_ERR) + { + // Since this init requires FIPS mode, let's return an error + PKI_log_err("Can not create HSM in FIPS mode"); + HSM_free(ret); + return NULL; + } + + // Return the HSM + return ret; +} + +int HSM_free ( HSM *hsm ) { + + if( !hsm ) return (PKI_ERR); + + if( hsm && hsm->callbacks && hsm->callbacks->free ) + { + hsm->callbacks->free ( (void *) hsm, hsm->config ); + } + else + { + /* Error! The driver should provide a free callback! */ + PKI_log_err("hsm (%s) does not provide a free function!", hsm->description ); + if ( hsm ) PKI_Free ( hsm ); + + return (PKI_ERR); + } + + return (PKI_OK); +} + +/* -------------------------- HSM Initialization ----------------------- */ + + +/*! + * \brief Initializes the HSM + */ +int HSM_init( HSM *hsm ) { + + if( !hsm || !hsm->callbacks ) return (PKI_ERR); + + /* Call the init function provided by the hsm itself */ + if( hsm->callbacks->init ) + { + return (hsm->callbacks->init(hsm, hsm->config )); + } + else + { + /* No init function is provided (not needed ??!?!) */ + PKI_log_debug("hsm (%s) does not provide an init " + "function!\n", hsm->description ); + } + + return(PKI_OK); +} + +/*! + * \brief Initializes the HSM in FIPS mode, returns an error if FIPS + * mode is not available for the HSM + */ +int HSM_init_fips (HSM *hsm) +{ + // Let's do the normal initialization + if (HSM_init(hsm) == PKI_ERR) return PKI_ERR; + + // Now let's set the fips mode + if (!HSM_set_fips_mode(hsm, 1)) return PKI_ERR; + + return (PKI_OK); +} + +/* -------------------------- Access control to HSM ----------------------- */ + +int HSM_login ( HSM *hsm, PKI_CRED *cred ) { + + if (!hsm) return (PKI_ERR); + + if ( hsm->callbacks->login ) { + return ( hsm->callbacks->login(hsm, cred )); + } else { + /* No login required by the HSM */ + PKI_log_debug("No login function for selected HSM"); + } + + return ( PKI_OK ); +} + +int HSM_logout ( HSM *hsm ) { + + if (!hsm || !hsm->callbacks ) return (PKI_ERR); + + if ( hsm->callbacks && hsm->callbacks->logout ) { + return ( hsm->callbacks->logout( hsm )); + } else { + /* No login required by the HSM */ + PKI_log_debug("No login function for selected HSM"); + } + + return ( PKI_OK ); +} + + +/* -------------------------- FIPS mode for HSM ----------------------- */ + +int HSM_set_fips_mode(const HSM *hsm, int k) +{ + if (!hsm) hsm = HSM_get_default(); + if (!hsm) return PKI_ERR; + + if (hsm->callbacks && hsm->callbacks->set_fips_mode) + { + return hsm->callbacks->set_fips_mode(hsm, k); + } + else + { + // If no FIPS mode is available, let's return 0 (false) + return PKI_ERR; + } +} + +int HSM_is_fips_mode(const HSM *hsm) +{ + if (!hsm) hsm = HSM_get_default(); + if (!hsm) return PKI_ERR; + + if (hsm->callbacks && hsm->callbacks->is_fips_mode) + { + return hsm->callbacks->is_fips_mode(hsm); + } + else + { + return PKI_ERR; + } +} + +/* -------------------------- General Crypto HSM ----------------------- */ + +int HSM_set_sign_algor ( PKI_X509_ALGOR_VALUE *alg, HSM *hsm ) { + + int ret = PKI_OK; + + // Input Checks + if (!alg) return PKI_ERROR(PKI_ERR_PARAM_NULL, "No algorithm passed!"); + + // Sets the algorithm if it is an hardware token + if (hsm && hsm->callbacks && hsm->callbacks->sign_algor) { + + // Using the HSM callback + PKI_log_debug("Setting the signature algorithm for selected HSM"); + ret = hsm->callbacks->sign_algor(hsm, alg); + } + + // All Done + return (ret); +} + +/* ------------------------ General PKI Signing ---------------------------- */ + +/* !\brief Signs the data from a PKI_MEM structure by using the + * passed key and digest algorithm. + * + * This function signs the data passed in the PKI_MEM structure. + * Use PKI_DIGEST_ALG_NULL for using no hash algorithm when calculating + * the signature. + * Use NULL for the digest (PKI_DIGEST_ALG) pointer to use the data signing + * functions directly (i.e., signing the PKI_MEM data directly instead of + * first performing the digest calculation and then generating the signture + * over the digest) + * + * @param der The pointer to a PKI_MEM structure with the data to sign + * @param digest The pointer to a PKI_DIGEST_ALG method + * @param key The pointer to the PKI_X509_KEYPAIR used for signing + * @return A PKI_MEM structure with the signature value. + */ + +int PKI_X509_sign(PKI_X509 * x, + const PKI_DIGEST_ALG * digest, + const PKI_X509_KEYPAIR * key) { + + // PKI_MEM *der = NULL; + // PKI_MEM *sig = NULL; + // // Data structure for the signature + + PKI_STRING * sigPtr = NULL; + // Pointer for the Signature in the PKIX data + + int pkey_type = NID_undef; + // Key Type + + PKI_SCHEME_ID pkey_scheme = PKI_SCHEME_UNKNOWN; + // Signature Scheme + + PKI_X509_KEYPAIR_VALUE * pkey = NULL; + // Internal Value + + int sig_nid = -1; + // Signature Algorithm identifier + + // Input Checks + if (!x || !x->value || !key || !key->value ) + return PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + + // Extracts the internal value + pkey = PKI_X509_get_value(key); + if (!pkey) { + PKI_ERROR(PKI_ERR_PARAM_NULL, "Missing Key's Internal Value"); + return PKI_ERR; + } + +// // Gets the PKEY type +// pkey_id = PKI_X509_KEYPAIR_VALUE_get_id(pkey); +// pkey_type = EVP_PKEY_type(pkey_id); +// if (pkey_type == NID_undef) { +// #if OPENSSL_VERSION_NUMBER > 0x30000000L +// pkey_type = pkey_id; +// #else +// PKI_ERROR(PKI_ERR_PARAM_NULL, "Missing Key's Internal Value"); +// return PKI_ERR; +// #endif +// } + + pkey_type = PKI_X509_KEYPAIR_VALUE_get_id(pkey); + if (!pkey_type) { + PKI_DEBUG("Cannot get the key's type (nid: %d)", PKI_X509_KEYPAIR_VALUE_get_id(pkey)); + return PKI_ERR; + } + + // Gets the Signature Scheme + pkey_scheme = PKI_X509_KEYPAIR_VALUE_get_scheme(pkey); + if (pkey_scheme == PKI_SCHEME_UNKNOWN) { + PKI_ERROR(PKI_ERR_PARAM_NULL, "Scheme not recognized for key (scheme: %d, type: %d)", + PKI_SCHEME_ID_get_parsed(pkey_scheme), pkey_type); + return PKI_ERR; + } + + // Sets the default Algorithm if none is provided + if (!digest) { + PKI_DEBUG("No digest was used, getting the default for the key."); + if (PKI_SCHEME_ID_is_explicit_composite(pkey_scheme)) { + PKI_DEBUG("Explicit Composite Scheme, no digest allowed (overriding choice)"); + digest = PKI_DIGEST_ALG_NULL; + } else { + digest = PKI_DIGEST_ALG_get_default(key); + } + } + + // PKI_DEBUG("Digest Algorithm set to %s", PKI_DIGEST_ALG_get_parsed(digest)); + + // Let's make sure we do not use a digest with explicit composite + if (PKI_ID_is_explicit_composite(pkey_type, NULL)) { + // No digest is allowed + digest = PKI_DIGEST_ALG_NULL; + } + + // Handles the weirdness of OpenSSL - we want to check if the signing algorithm + // is actually allowed with the selected public key + if (digest != NULL && digest != PKI_DIGEST_ALG_NULL) { + + // Finds the associated signing algorithm identifier, if any + if (OBJ_find_sigid_by_algs(&sig_nid, EVP_MD_nid(digest), pkey_type) != 1) { + PKI_DEBUG("Cannot Get The Signing Algorithm for %s with %s", + PKI_ID_get_txt(pkey_type), digest ? PKI_DIGEST_ALG_get_parsed(digest) : "NULL"); + // Fatal Error + return PKI_ERR; + } + + } else { + + if (PKI_ID_requires_digest(pkey_type) == PKI_OK) { + PKI_DEBUG("%s scheme does not support arbitrary signing, hashing is required", + PKI_SCHEME_ID_get_parsed(pkey_scheme)); + // Error condition + return PKI_ERR; + } + + // Checks if we can use the NULL digest + if (PKI_ID_is_composite(pkey_type, NULL) || + PKI_ID_is_explicit_composite(pkey_type, NULL)) { + + // Finds the associated signing algorithm identifier, if any + if (OBJ_find_sigid_by_algs(&sig_nid, NID_undef, pkey_type) != 1) { + PKI_DEBUG("Cannot Get The Signing Algorithm for %s with %s", + PKI_ID_get_txt(pkey_type), digest ? PKI_DIGEST_ALG_get_parsed(digest) : "NULL"); + // Fatal Error + return PKI_ERR; + } + // Use the appropriate digest to avoid the OpenSSL weirdness + digest = EVP_md_null(); + + } else if (PKI_ID_is_pqc(pkey_type, NULL)) { + + // Use the Same ID for Key and Signature + sig_nid = pkey_type; + } + + // if (PKI_ID_requires_digest(EVP_PKEY_id(pkey) == PKI_OK)) { + // // If the key requires a digest, we need to find the default + // // digest algorithm for the key type + // if (PKI_ID_get_digest(EVP_PKEY_id(pkey), &scheme_id) != PKI_OK) { + // PKI_DEBUG("Cannot Get The Digest Algorithm for %s", + // PKI_ID_get_txt(PKI_X509_KEYPAIR_VALUE_get_id(pkey))); + // // Fatal Error + // return PKI_ERR; + // } + // } + // if (PKI_ID_is_explicit_composite(EVP_PKEY_id(pkey), &scheme_id) != PKI_OK) { + + // PKI_DEBUG("Got The Scheme ID => %d", scheme_id); + + // switch (scheme_id) { + + // // Algorithms that do not require hashing + // /* case PKI_SCHEME_ED448: */ + // /* case PKI_SCHEME_X25519: */ + // case PKI_SCHEME_DILITHIUM: + // case PKI_SCHEME_FALCON: + // case PKI_SCHEME_COMPOSITE: + // case PKI_SCHEME_COMBINED: + // case PKI_SCHEME_KYBER: + // case PKI_SCHEME_CLASSIC_MCELIECE: { + // // No-hashing is supported by the algorithm + // // If the find routine returns 1 it was successful, however + // // for PQC it seems to return NID_undef for the sig_nid, this fixes it + // if (sig_nid == NID_undef) sig_nid = EVP_PKEY_id(pkey); + // } break; + + + // // Hashing required + // default: + // PKI_DEBUG("%s does not support arbitrary signing, hashing is required", + // PKI_SCHEME_ID_get_parsed(scheme_id)); + // // Error condition + // return PKI_ERR; + // } + // } + } + + // // Debugging Information + // PKI_DEBUG("Signing Algorithm Is: %s", PKI_ID_get_txt(sig_nid)); + // PKI_DEBUG("Digest Signing Algorithm: %p (%s)", digest, PKI_DIGEST_ALG_get_parsed(digest)); + + // Since we are using the DER representation for signing, we need to first + // update the data structure(s) with the right OIDs - we use the default + // ASN1_item_sign() with a NULL buffer parameter to do that. + + // ASN1_item_sign behaviour: + // - signature: we must provide an ASN1_BIT_STRING pointer, the pnt->data + // will be freed and replaced with the signature data + // - pkey: we must provide an EVP_PKEY pointer + // - data: is the pointer to an internal value (e.g., a PKI_X509_VALUE + // or a PKI_X509_REQ_VALUE)) + // - type: is the pointer to the const EVP_MD structure for the hash-n-sign + // digest + + ASN1_BIT_STRING sig_asn1 = { 0x0 }; + // Pointer to the ASN1_BIT_STRING structure for the signature + + // Note that only COMPOSITE can properly handle passing the EVP_md_null() + // for indicating that we do not need a digest algorithm, however that is + // not well supported by OQS. Let's just pass NULL if the algorithm is not + // composite and the requested ditest is EVP_md_null(). + if (digest == PKI_DIGEST_ALG_NULL) { + if (!PKI_SCHEME_ID_is_composite(pkey_scheme) && + !PKI_SCHEME_ID_is_explicit_composite(pkey_scheme)) { + // The algorithm is not composite, but the digest is EVP_md_null() + PKI_DEBUG("Digest is EVP_md_null(), but the algorithm is not composite, replacing the digest with NULL"); + digest = NULL; + } + } + + // Special case for non-basic types to be signed. The main example is + // the OCSP response where we have three different internal fields + // suche as status, resp, and bs. We need to sign the bs field in + // this case. + void * item_data = NULL; + switch (x->type) { + case PKI_DATATYPE_X509_OCSP_RESP: { + PKI_X509_OCSP_RESP_VALUE * ocsp_resp = NULL; + + // For OCSP Responses we need to sign the TBSResponseData + ocsp_resp = (PKI_X509_OCSP_RESP_VALUE *) x->value; + item_data = ocsp_resp->bs; + } break; + + default: { + // Default use-case + item_data = x->value; + } break; + } + + // Sets the right OID for the signature + int success = ASN1_item_sign(x->it, + PKI_X509_get_data(x, PKI_X509_DATA_SIGNATURE_ALG1), + PKI_X509_get_data(x, PKI_X509_DATA_SIGNATURE_ALG2), + &sig_asn1, + item_data, + pkey, + digest); + + if (!success || !sig_asn1.data || !sig_asn1.length) { + PKI_DEBUG("Error while creating the signature: %s (success: %d, sig_asn1.data: %p, sig_asn1.length: %d)", + ERR_error_string(ERR_get_error(), NULL), success, sig_asn1.data, sig_asn1.length); + PKI_ERROR(PKI_ERR_SIGNATURE_CREATE, NULL); + return PKI_ERR; + } + + // EVP_MD_CTX * md_ctx_tmp = EVP_MD_CTX_new(); + // if (!md_ctx_tmp) { + // PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Can not allocate memory for the EVP_MD_CTX"); + // return PKI_ERR; + // } + + // EVP_PKEY_CTX * pkey_ctx = EVP_PKEY_CTX_new(pkey, NULL); + // if (!pkey_ctx) { + // PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Can not allocate memory for the EVP_PKEY_CTX"); + // return PKI_ERR; + // } + + // X509_ALGORS * signature_algors = sk_X509_ALGOR_new_null(); + // if (!signature_algors) { + // PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Can not allocate memory for the X509_ALGORS"); + // return PKI_ERR; + // } + + // X509_ALGOR * signature_algor = X509_ALGOR_new(); + + // EVP_MD_CTX_set_pkey_ctx(md_ctx_tmp, pkey_ctx); + + // EVP_MD_CTX_ctrl(md_ctx_tmp, EVP_MD_CTRL_SET_SIGNAME, sig_nid, NULL); + + // int success = ASN1_item_sign_ctx(x->it, + // PKI_X509_get_data(x, PKI_X509_DATA_SIGNATURE_ALG1), + // PKI_X509_get_data(x, PKI_X509_DATA_SIGNATURE_ALG2), + // &sig_asn1, + // x->value, + // md_ctx_tmp); + + // if (!success || !sig_asn1.data || !sig_asn1.length) { + // PKI_ERROR(PKI_ERR_SIGNATURE_CREATE, "Can not sign the data"); + // return PKI_ERR; + // } + + // // Retrieves the DER representation of the data to be signed + // if ((der = PKI_X509_get_tbs_asn1(x)) == NULL) { + // // Logs the issue + // PKI_DEBUG("Can not get the DER representation of the PKIX data via tbs func"); + // // Builds the DER representation in a PKI_MEM structure + // if ((der = PKI_X509_put_mem(x, + // PKI_DATA_FORMAT_ASN1, + // NULL, + // NULL )) == NULL) { + // // Logs the issue + // PKI_DEBUG("Can not get the DER representation directly, aborting."); + // // Can not encode into DER + // return PKI_ERROR(PKI_ERR_DATA_ASN1_ENCODING, NULL); + // } + // } + + // // Generates the Signature + // if ((sig = PKI_sign(der, digest, key)) == NULL) { + // // Error while creating the signature, aborting + // if (der) PKI_MEM_free(der); + // // Report the issue + // return PKI_ERROR(PKI_ERR_SIGNATURE_CREATE, NULL); + // } + + // // Debugging + // FILE * fp = fopen("signature_create.der", "w"); + // if (fp) { + // fwrite(sig->data, sig->size, 1, fp); + // fclose(fp); + // } + // fp = fopen("signed_data_create.der", "w"); + // if (fp) { + // fwrite(der->data, der->size, 1, fp); + // fclose(fp); + // } + + // // der work is finished, let's free the memory + // if (der) PKI_MEM_free(der); + // der = NULL; + + // // Gets the reference to the X509 signature field + // if ((sigPtr = PKI_X509_get_data(x, + // PKI_X509_DATA_SIGNATURE)) == NULL) { + // // Error: Can not retrieve the generated signature, aborting + // PKI_MEM_free (sig); + // // Return the error + // return PKI_ERROR(PKI_ERR_POINTER_NULL, "Can not get signature data"); + // } + + // Gets the reference to the X509 signature field + if ((sigPtr = PKI_X509_get_data(x, + PKI_X509_DATA_SIGNATURE)) == NULL) { + // Error: Can not retrieve the generated signature, aborting + if (sig_asn1.data) PKI_Free(sig_asn1.data); + // Return the error + PKI_ERROR(PKI_ERR_POINTER_NULL, "Can not get signature data"); + return PKI_ERR; + } + + // // Transfer the ownership of the generated signature data (sig) + // // to the signature field in the X509 structure (signature) + // sigPtr->data = sig->data; + // sigPtr->length = (int) sig->size; + + // Transfer the ownership of the generated signature data (sig) + // // to the signature field in the X509 structure (signature) + sigPtr->data = sig_asn1.data; + sigPtr->length = sig_asn1.length; + + // Sets the flags into the signature field + sigPtr->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); + sigPtr->flags |= ASN1_STRING_FLAG_BITS_LEFT; + + // // We can not free the data in the sig PKI_MEM because that is + // // actually owned by the signature now, so let's change the + // // data pointer and then free the PKI_MEM data structure + // sig->data = NULL; + // sig->size = 0; + + // // Now we can free the signature mem + // PKI_MEM_free(sig); + + // Success + return PKI_OK; +} + +/*! \brief General signature function on data */ + +PKI_MEM *PKI_sign(const PKI_MEM * der, + const PKI_DIGEST_ALG * alg, + const PKI_X509_KEYPAIR * key ) { + + PKI_MEM *sig = NULL; + const HSM *hsm = NULL; + + // Input check + if (!der || !der->data || !key || !key->value) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return NULL; + } + + // If no HSM is provided, let's get the default one + hsm = (key->hsm != NULL ? key->hsm : HSM_get_default()); + + // Debugging Info + PKI_DEBUG("Calling Callback with Digest = %p (Null =? %s)\n", + alg, alg == EVP_md_null() ? "Yes" : "No"); + + // Requires the use of the HSM's sign callback + if (hsm && hsm->callbacks && hsm->callbacks->sign) { + + // Generates the signature by using the HSM callback + if ((sig = hsm->callbacks->sign( + (PKI_MEM *)der, + (PKI_DIGEST_ALG *)alg, + (PKI_X509_KEYPAIR *)key)) == NULL) { + + // Error: Signature was not generated + PKI_DEBUG("Can not generate signature (returned from sign cb)"); + } + + } else { + + // There is no callback for signing the X509 structure + PKI_ERROR(PKI_ERR_SIGNATURE_CREATE_CALLBACK, + "No sign callback for key's HSM"); + + // Free Memory + PKI_MEM_free(sig); + + // All Done + return NULL; + } + + // Let's return the output of the signing function + return sig; +} + +/*! + * \brief Verifies a PKI_X509 by using a key from a certificate + */ + +int PKI_X509_verify_cert(const PKI_X509 *x, const PKI_X509_CERT *cert) { + + const PKI_X509_KEYPAIR *kval = NULL; + + PKI_X509_KEYPAIR *kp = NULL; + + int ret = -1; + + // Input Check + if (!x || !x->value || !cert || !cert->value) + return PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + + // Gets the internal value of the public key from the certificate + kval = PKI_X509_CERT_get_data(cert, PKI_X509_DATA_KEYPAIR_VALUE); + if (!kval) return PKI_ERR; + + // Use the internal value to generate a new PKI_X509_KEYPAIR + kp = PKI_X509_new_value(PKI_DATATYPE_X509_KEYPAIR, + (PKI_X509_KEYPAIR_VALUE *)kval, + NULL); + + // Checks if the operation was successful + if ( !kp ) return PKI_ERR; + + // Verifies the certificate by using the extracted public key + ret = PKI_X509_verify(x, kp); + + // Take back the ownership of the internal value (avoid freeing + // the memory when freeing the memory associated with the + // PKI_X509_KEYPAIR data structure) + kp->value = NULL; + + // Free the Memory + PKI_X509_KEYPAIR_free(kp); + + return ret; +} + +/*! + * \brief Verifies a signature on a PKI_X509 object (not for PKCS7 ones) + */ + +int PKI_X509_verify(const PKI_X509 *x, const PKI_X509_KEYPAIR *key ) { + + int ret = PKI_ERR; + const HSM *hsm = NULL; + + // PKI_MEM *data = NULL; + // PKI_MEM *sig = NULL; + + // PKI_STRING *sig_value = NULL; + // PKI_X509_ALGOR_VALUE *alg = NULL; + + // Make sure the library is initialized + PKI_init_all(); + + // Input Checks + if (!x || !x->value || !key || !key->value) { + + // Checks the X509 structure to verify + if (!x || !x->value) + return PKI_ERROR(PKI_ERR_PARAM_NULL, "Missing data to verify"); + + // Checks the key value + if (!key || !key->value) + return PKI_ERROR(PKI_ERR_PARAM_NULL, "Missing keypair to verify with"); + } + + // Gets the reference to the HSM to use + hsm = key->hsm != NULL ? key->hsm : HSM_get_default(); + + // Uses the callback to verify the signature that was copied + // in the sig (PKI_MEM) structure + if (hsm && hsm->callbacks && hsm->callbacks->asn1_verify) { + + // Debugging Info + PKI_log_debug( "HSM verify() callback called " ); + + // // Calls the callback function + // ret = hsm->callbacks->verify(data, + // sig, + // alg, + // (PKI_X509_KEYPAIR *)key ); + // Calls the callback function + ret = hsm->callbacks->asn1_verify(x, key); + + } else { + + // Experimental: use ASN1_item_verify() + // ret = ASN1_item_verify(x->it, + // PKI_X509_get_data(x, PKI_X509_DATA_SIGNATURE_ALG1), + // PKI_X509_get_data(x, PKI_X509_DATA_SIGNATURE), + // x->value, + // key->value + // ); + + ret = PKI_X509_ITEM_verify(x->it, + PKI_X509_get_data(x, PKI_X509_DATA_SIGNATURE_ALG1), + PKI_X509_get_data(x, PKI_X509_DATA_SIGNATURE), + x->value, + key->value + ); + } + + // if (success == 1) { + // PKI_DEBUG("PKI_X509_verify()::Signature Verified!"); + // } else { + // PKI_DEBUG("PKI_X509_verify()::Signature Verification Failed!"); + // } + + // // Gets the algorithm from the X509 data + // if (( alg = PKI_X509_get_data(x, PKI_X509_DATA_ALGORITHM)) == NULL) { + + // // Reports the error + // return PKI_ERROR(PKI_ERR_ALGOR_UNKNOWN, + // "Can not get algorithm from object!"); + // } + + // // Gets the DER representation of the data to be signed + + // // if ((data = PKI_X509_get_der_tbs(x)) == NULL) { + // // if ((data = PKI_X509_get_data(x, PKI_X509_DATA_TBS_MEM_ASN1)) == NULL) { + // if ((data = PKI_X509_get_tbs_asn1(x)) == NULL) { + // return PKI_ERROR(PKI_ERR_DATA_ASN1_ENCODING, + // "Can not get To Be signed object!"); + // } + + // // Gets a reference to the Signature field in the X509 structure + // if ((sig_value = PKI_X509_get_data(x, + // PKI_X509_DATA_SIGNATURE)) == NULL) { + + // // Free the memory + // PKI_MEM_free(data); + + // // We could not get the reference to the signature field + // return PKI_ERROR(PKI_ERR_POINTER_NULL, + // "Can not get Signature field from the X509 object!"); + // } + + // // Copies the signature data structure from the sig_value (PKI_STRING) + // // of the X509 structure to the sig one (PKI_MEM) + // if ((sig = PKI_MEM_new_data((size_t)sig_value->length, + // (unsigned char *)sig_value->data)) == NULL) { + + // // Free memory + // PKI_MEM_free(data); + + // // Reports the memory error + // return PKI_ERR; + // } + + // // Uses the callback to verify the signature that was copied + // // in the sig (PKI_MEM) structure + // if (hsm && hsm->callbacks && hsm->callbacks->verify) { + + // // Debugging Info + // PKI_log_debug( "HSM verify() callback called " ); + + // // Calls the callback function + // ret = hsm->callbacks->verify(data, + // sig, + // alg, + // (PKI_X509_KEYPAIR *)key ); + + // } else { + + // // // Debugging + // // FILE * fp = fopen("signature_verify.der", "w"); + // // if (fp) { + // // fwrite(sig->data, sig->size, 1, fp); + // // fclose(fp); + // // } + // // fp = fopen("signed_data_verify.der", "w"); + // // if (fp) { + // // fwrite(data->data, data->size, 1, fp); + // // fclose(fp); + // // } + + // // If there is no verify callback, let's call the internal one + // ret = PKI_verify_signature(data, sig, alg, x->it, key); + + // } + + // // Free the allocated memory + // if ( data ) PKI_MEM_free ( data ); + // if ( sig ) PKI_MEM_free ( sig ); + + // Provides some additional information in debug mode + if (ret != PKI_OK) { + PKI_DEBUG("Crypto Layer Error: %s (%d)", + HSM_get_errdesc(HSM_get_errno(hsm), hsm), + HSM_get_errno(hsm)); + } else { + PKI_DEBUG("Validation Completed Successfully!"); + } + + return ret; +} + +/*! \brief Verifies a signature */ + +int PKI_verify_signature(const PKI_MEM * data, + const PKI_MEM * sig, + const PKI_X509_ALGOR_VALUE * alg, + const ASN1_ITEM * it, + const PKI_X509_KEYPAIR * key ) { + int v_code = 0; + // OpenSSL return code + + EVP_MD_CTX *ctx = NULL; + // PKey Context + + PKI_X509_KEYPAIR_VALUE * k_val = PKI_X509_get_value(key); + // Internal representation of the key + + const PKI_DIGEST_ALG *dgst = NULL; + // Digest Algorithm + + // Input Checks + if (!data || !data->data || !sig || !sig->data || + !alg || !key || !k_val ) { + // Reports the Input Error + return PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + } + + // Gets the Digest Algorithm to verify with + if ((dgst = PKI_X509_ALGOR_VALUE_get_digest(alg)) == PKI_ID_UNKNOWN) { + // Reports the error + return PKI_ERROR(PKI_ERR_ALGOR_UNKNOWN, NULL); + } + + // PKI_DEBUG("Executing ASN1_item_verify()"); + + // ASN1_BIT_STRING signature; + // signature.data = sig->data; + // signature.length = (int)sig->size; + + // ASN1_item_verify(it, (X509_ALGOR *)alg, &signature, NULL, k_val); + // PKI_DEBUG("Done with ASN1_item_verify()"); + + // Only use digest when we have not digest id + // that was returned for the algorithm + if (dgst != NULL && dgst != EVP_md_null()) { + + EVP_PKEY_CTX * pctx = NULL; + + // Creates and Initializes a new crypto context (CTX) + if ((ctx = EVP_MD_CTX_new()) == NULL) { + // Can not alloc memory, let's report the error + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + } + + // Initializes the new CTX + EVP_MD_CTX_init(ctx); + + // Initializes the verify function + if (!EVP_DigestVerifyInit(ctx, &pctx, dgst, NULL, k_val)) { + // Error in initializing the signature verification function + PKI_DEBUG("Signature Verify Initialization (Crypto Layer Error): %s (%d)", + HSM_get_errdesc(HSM_get_errno(NULL), NULL), HSM_get_errno(NULL)); + // Done working + goto err; + } + + // Finalizes the validation + if ((v_code = EVP_DigestVerify(ctx, sig->data, sig->size, data->data, data->size)) <= 0) { + // Reports the error + PKI_DEBUG("Signature Verify Final Failed (Crypto Layer Error): %s (%d - %d)", + HSM_get_errdesc(HSM_get_errno(NULL), NULL), v_code, HSM_get_errno(NULL)); + // Done working + goto err; + } + + } else { + + EVP_PKEY_CTX * pctx = EVP_PKEY_CTX_new(key->value, NULL); + // Context for the verify operation + + // If we are in composite, we should attach the X509_ALGOR pointer + // to the application data for the PMETH verify() to pick that up + if (alg) { + PKI_DEBUG("Setting App Data (We Should use the CTRL interface?): %p", alg); + EVP_PKEY_CTX_set_app_data(pctx, (void *)alg); + } + + // Initialize the Verify operation + if ((v_code = EVP_PKEY_verify_init(pctx)) <= 0) { + PKI_ERROR(PKI_ERR_SIGNATURE_VERIFY, "cannot initialize direct (no-hash) sig verification"); + goto err; + } + + // Verifies the signature + if ((v_code = EVP_PKEY_verify(pctx, sig->data, sig->size, data->data, data->size)) <= 0) { + PKI_ERROR(PKI_ERR_SIGNATURE_VERIFY, NULL); + goto err; + } + } + + // Free the memory +#if OPENSSL_VERSION_NUMBER < 0x1010000fL + EVP_MD_CTX_cleanup(ctx); +#else + EVP_MD_CTX_reset(ctx); +#endif + EVP_MD_CTX_free(ctx); + + // All Done + return PKI_OK; + +err: + // Free Memory + if (ctx) { +#if OPENSSL_VERSION_NUMBER < 0x1010000fL + EVP_MD_CTX_cleanup(ctx); +#else + EVP_MD_CTX_reset(ctx); +#endif + EVP_MD_CTX_free(ctx); + } + + // Returns the error + return PKI_ERR; +} + +/* ----------------------- General Obj Management ------------------------ */ + +/*! \brief Gets a stack of X509 objects from the URL in the HSM */ + +PKI_X509_STACK *HSM_X509_STACK_get_url ( PKI_DATATYPE type, URL *url, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ) { + + PKI_STACK *ret = NULL; + + if( !url ) return ( NULL ); + + if( url->proto != URI_PROTO_ID ) return NULL; + + if( !hsm ) hsm = (HSM * ) HSM_get_default(); + + if( hsm && hsm->callbacks && hsm->callbacks->x509_sk_get_url ) { + ret = hsm->callbacks->x509_sk_get_url( type, url, format, cred, hsm ); + }; + + return ( ret ); +} + +/*! \brief Stores a stack of PKI_X509 objects in the specified URL/HSM */ + +int HSM_X509_STACK_put_url ( PKI_X509_STACK *sk, URL *url, + PKI_CRED *cred, HSM *hsm ) { + + int ret = PKI_OK; + + if( !url || !sk ) return PKI_ERR; + + if ( url->proto != URI_PROTO_ID ) return PKI_ERR; + + if( !hsm ) hsm = (HSM *) HSM_get_default(); + + if( hsm && hsm->callbacks && hsm->callbacks->x509_sk_add_url ) { + ret = hsm->callbacks->x509_sk_add_url( sk, url, cred, hsm ); + }; + + return ( ret ); +} + +/*! \brief Stores the contents of a stack of MEM to the specified URL/HSM */ + +int HSM_MEM_STACK_put_url ( PKI_MEM_STACK *sk, URL *url, PKI_DATATYPE type, + PKI_CRED *cred, HSM *hsm ) { + int i = 0; + int ret = PKI_OK; + + PKI_MEM *mem = NULL; + PKI_X509 *x_obj = NULL; + PKI_X509_STACK *obj_sk = NULL; + + if(( obj_sk = PKI_STACK_new_type( type )) == NULL ) { + return PKI_ERR; + } + + for ( i = 0; i < PKI_STACK_MEM_elements ( sk ); i++ ) { + PKI_X509_STACK *mem_obj_sk = NULL; + + /* Gets the PKI_MEM container from the stack */ + if((mem = PKI_STACK_MEM_get_num ( sk, i )) == NULL ) { + continue; + } + + /* Gets the objects (multiple, possibly) from each PKI_MEM */ + if((mem_obj_sk = PKI_X509_STACK_get_mem ( mem, type, + PKI_DATA_FORMAT_UNKNOWN, cred, hsm )) == NULL ) { + continue; + } + + /* Builds the stack of PKI_X509 objects */ + while ((x_obj = PKI_STACK_X509_pop ( mem_obj_sk )) != NULL ) { + /* Push the Object on the Stack */ + PKI_STACK_X509_push ( obj_sk, x_obj ); + } + } + + /* Now Put the stack of objects in the HSM */ + ret = HSM_X509_STACK_put_url ( sk, url, cred, hsm ); + + /* Clean the stack of Objects we created */ + while ( (x_obj = PKI_STACK_X509_pop ( sk )) != NULL ) { + PKI_X509_free ( x_obj ); + } + PKI_STACK_X509_free ( sk ); + + /* Return value */ + return ret; +} + +/*! \brief Deletes a Stack of Objects that are stored in a HSM */ + +int HSM_X509_STACK_del ( PKI_X509_STACK *sk ) { + + int ret = PKI_ERR; + int i = 0; + + // HSM *hsm = NULL; + // HSM *def_hsm = NULL; + + PKI_X509 *obj = NULL; + + if ( !sk ) return ( PKI_ERR ); + + for ( i = 0; i < PKI_STACK_X509_elements ( sk ); i++ ) { + obj = PKI_STACK_X509_get_num ( sk, i ); + + if (!obj || !obj->value ) continue; + + if ( obj->ref ) { + ret = HSM_X509_del_url ( obj->type, obj->ref, + obj->cred, obj->hsm ); + + if ( ret == PKI_ERR ) return PKI_ERR; + } + } + + return PKI_OK; +} + +/*! \brief Deletes the contents of the specified URL in the HSM */ + +int HSM_X509_del_url ( PKI_DATATYPE type, URL *url, PKI_CRED *cred, HSM *hsm ) { + + int ret = PKI_OK; + + if( !url ) return ( PKI_ERR ); + + if( !hsm ) hsm = (HSM *) HSM_get_default(); + + if( hsm && hsm->callbacks && hsm->callbacks->x509_del_url ) { + ret = hsm->callbacks->x509_del_url( type, url, cred, hsm ); + }; + + return ( ret ); +} + +/*! \brief Returns the callbacks for the specific HSM */ + +const PKI_X509_CALLBACKS * HSM_X509_get_cb ( PKI_DATATYPE type, HSM *hsm ) { + + if ( !hsm || !hsm->callbacks ) return HSM_OPENSSL_X509_get_cb (type); + + return hsm->callbacks->x509_get_cb ( type ); +} + diff --git a/src/crypto/hsm/hsm_slot.c b/src/crypto/hsm/hsm_slot.c new file mode 100644 index 00000000..acb37cd9 --- /dev/null +++ b/src/crypto/hsm/hsm_slot.c @@ -0,0 +1,248 @@ +/* HSM Object Management Functions */ + +#include + +/* HSM_SLOT_INFO Data Structure */ +HSM_SLOT_INFO default_slot_info = { + + /* Device Manufacturer ID */ + "Unknown", + + /* Device Description */ + "Unknown", + + /* Hardware Version */ + 1, + 0, + + /* Firmware Version */ + 1, + 0, + + /* Initialized */ + 1, + + /* Present */ + 1, + + /* Removable */ + 0, + + /* Hardware */ + 0, + + /* Token Info */ + { + /* Token Label */ + "Unknown Label", + /* ManufacturerID */ + "Unknown", + /* Model */ + "Unknown Model", + /* Serial Number */ + "0", + /* Max Sessions */ + 65535, + /* Current Sessions */ + 0, + /* Max Pin Len */ + 0, + /* Min Pin Len */ + 0, + /* Memory Pub Total */ + 0, + /* Memory Pub Free */ + 0, + /* Memory Priv Total */ + 0, + /* Memory Priv Free */ + 0, + /* HW Version Major */ + 1, + /* HW Version Minor */ + 0, + /* FW Version Major */ + 1, + /* FW Version Minor */ + 0, + /* HAS Random Number Generator (RNG) */ + 1, + /* HAS clock */ + 0, + /* Login is Required */ + 0, + /* utcTime */ + "" + } + +}; + +/* ------------- Slot Management functions --------------- */ + +unsigned long HSM_SLOT_num ( HSM *hsm ) { + + if( !hsm || !hsm->callbacks ) return ( 1 ); + + if( hsm->callbacks && hsm->callbacks->slot_num ) { + return hsm->callbacks->slot_num( hsm ); + } + + return ( 1 ); +}; + +int HSM_SLOT_select ( unsigned long num, PKI_CRED *cred, HSM *hsm ) { + + int ret = PKI_OK; + + if( !hsm ) { + return ( ret ); + } + + if( hsm && hsm->callbacks && hsm->callbacks->select_slot ) { + ret = hsm->callbacks->select_slot ( num, cred, hsm ); + } else { + PKI_log_debug("No slot select function for current HSM"); + ret = PKI_OK; + } + + return ( ret ); +} + +int HSM_SLOT_clear ( unsigned long num, PKI_CRED *cred, HSM *hsm ) { + + int ret = PKI_OK; + + if( !hsm ) { + return ( ret ); + } + + if( hsm && hsm->callbacks && hsm->callbacks->clear_slot ) { + ret = hsm->callbacks->clear_slot ( num, cred, hsm ); + } else { + PKI_log_debug ("No Slot Clear function for current HSM"); + ret = PKI_OK; + } + + return ( ret ); +} + +HSM_SLOT_INFO * HSM_SLOT_INFO_get ( unsigned long num, HSM *hsm ) { + + HSM_SLOT_INFO *ret = NULL; + + if( !hsm ) { + ret = (HSM_SLOT_INFO *) PKI_Malloc ( sizeof (HSM_SLOT_INFO)); + memcpy( ret, &default_slot_info, sizeof( HSM_SLOT_INFO )); + + snprintf(ret->manufacturerID, MANUFACTURER_ID_SIZE, + "%s", "OpenCA Labs"); + snprintf(ret->description, DESCRIPTION_SIZE, + "%s", "LibPKI Software HSM"); + + snprintf(ret->token_info.label, LABEL_SIZE, + "%s", "LibPKI Software Token"); + snprintf(ret->token_info.manufacturerID, MANUFACTURER_ID_SIZE, + "%s", "OpenCA Labs"); + snprintf(ret->token_info.model, MODEL_SIZE, + "%s", "OpenSSL Library"); + snprintf(ret->token_info.serialNumber, SERIAL_NUMBER_SIZE, + "%s", "0000:0000"); + + } else if ( hsm->callbacks && hsm->callbacks->slot_info_get ) { + ret = hsm->callbacks->slot_info_get ( num, hsm ); + } else { + ret = (HSM_SLOT_INFO *) PKI_Malloc ( sizeof (HSM_SLOT_INFO)); + memcpy( ret, &default_slot_info, sizeof( HSM_SLOT_INFO )); + }; + + return ( ret ); +}; + +int HSM_SLOT_INFO_print( unsigned long num, PKI_CRED * cred, HSM *hsm ) { + + HSM_SLOT_INFO *sl_info = NULL; + HSM_TOKEN_INFO *tk_info = NULL; + + if((sl_info = HSM_SLOT_INFO_get ( num, hsm )) == NULL ) { + PKI_log_debug("Can not get the HSM info"); + return PKI_ERR; + } + + printf("Slot [%lu] Info:\r\n", num ); + printf(" Description ........: %s\r\n", sl_info->description); + printf(" Manufacturer ID ....: %s\r\n", sl_info->manufacturerID); + printf(" Hardware Version ...: %d.%d\r\n", + sl_info->hw_version_major, sl_info->hw_version_minor ); + printf(" Firmware Version ...: %d.%d\r\n", + sl_info->fw_version_major, sl_info->fw_version_minor ); + + tk_info = &(sl_info->token_info); + + printf("\n Token Info:\n"); + printf(" Label .....................: %s\r\n", tk_info->label); + printf(" Manufacturer ID ...........: %s\r\n", tk_info->manufacturerID); + printf(" Model .....................: %s\r\n", tk_info->model); + printf(" Serial Number .............: %s\r\n", tk_info->serialNumber); + printf(" Free Pub Memory ...........: (%lu/%lu)\r\n", + tk_info->memory_pub_free, + tk_info->memory_pub_tot ); + printf(" Free Priv Memory ..........: (%lu/%lu)\r\n", + tk_info->memory_priv_free, + tk_info->memory_priv_tot ); + printf(" Hardware Version ..........: v%d.%d\r\n", + tk_info->hw_version_major, + tk_info->hw_version_minor ); + printf(" Firmware Version ..........: %d.%d\r\n", + tk_info->fw_version_major, + tk_info->fw_version_minor ); + printf(" Pin Len (Min/Max) .........: %lu/%lu\r\n", + tk_info->min_pin_len, + tk_info->max_pin_len ); + printf(" Sessions (Curr/Max) .......: %lu/%lu\r\n", + tk_info->curr_sessions, + tk_info->max_sessions ); + printf(" Token Status ..............: "); + if( sl_info->present ) printf ("Present"); + if( sl_info->removable ) printf(", Removable"); + if( sl_info->hardware ) printf(", Hardware Token"); + printf("\n"); + + if( tk_info->has_clock == 1 ) { + printf(" Token Time ................: %s\r\n", + tk_info->utcTime ); + } else { + printf(" Token Clock ...............: Yes\r\n"); + } + + if( tk_info->has_rng ) { + printf(" Random Number Generator ...: Yes\r\n"); + } else { + printf(" Random Number Generator ...: No\r\n"); + } + + printf("\r\n"); + + if( hsm && hsm->type == HSM_TYPE_PKCS11 ) { + HSM_PKCS11_get_contents_info ( num, cred, hsm ); + } + + printf("\r\n"); + + return ( PKI_OK ); +} + +void HSM_SLOT_INFO_free ( HSM_SLOT_INFO *sl_info, HSM *hsm ) { + + if( !sl_info || !hsm ) { + return; + } + + if ( hsm && hsm->callbacks && hsm->callbacks->slot_info_free ) { + hsm->callbacks->slot_info_free ( sl_info, hsm ); + } else { + PKI_Free ( sl_info ); + }; + + return; +} + diff --git a/src/crypto/hsm/openssl/Makefile.am b/src/crypto/hsm/openssl/Makefile.am new file mode 100644 index 00000000..7520b4fe --- /dev/null +++ b/src/crypto/hsm/openssl/Makefile.am @@ -0,0 +1,27 @@ +## OpenCA Makefile - by Massimiliano Pala +## (c) 1999-2009 by Massimiliano Pala and OpenCA Project +## All Rights Reserved + +TOP = ../.. +include $(TOP)/global-vars + +BASE_DEFS = + +DEFS = $(OPENCA_DEFS) + +AM_CPPFLAGS = -I$(TOP) \ + $(openssl_cflags) \ + $(libxml2_cflags) \ + $(COND_INCLUDES) + +SRCS = \ + openssl_hsm.c \ + openssl_hsm_pkey.c \ + openssl_hsm_obj.c \ + openssl_hsm_cb.c + +noinst_LTLIBRARIES = libpki-token-openssl.la + +libpki_token_openssl_la_SOURCES = $(SRCS) +libpki_token_openssl_la_CFLAGS = $(BUILD_LIBPKI_CFLAGS) + diff --git a/src/crypto/hsm/openssl/Makefile.in b/src/crypto/hsm/openssl/Makefile.in new file mode 100644 index 00000000..1feca2a9 --- /dev/null +++ b/src/crypto/hsm/openssl/Makefile.in @@ -0,0 +1,796 @@ +# Makefile.in generated by automake 1.16.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = src/drivers/openssl +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(SHELL) $(top_srcdir)/build/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/src/libpki/config.h \ + $(top_builddir)/src/libpki/libpki_enables.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +libpki_token_openssl_la_LIBADD = +am__objects_1 = libpki_token_openssl_la-openssl_hsm.lo \ + libpki_token_openssl_la-openssl_hsm_pkey.lo \ + libpki_token_openssl_la-openssl_hsm_obj.lo \ + libpki_token_openssl_la-openssl_hsm_cb.lo +am_libpki_token_openssl_la_OBJECTS = $(am__objects_1) +libpki_token_openssl_la_OBJECTS = \ + $(am_libpki_token_openssl_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libpki_token_openssl_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(libpki_token_openssl_la_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src/libpki +depcomp = $(SHELL) $(top_srcdir)/build/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = \ + ./$(DEPDIR)/libpki_token_openssl_la-openssl_hsm.Plo \ + ./$(DEPDIR)/libpki_token_openssl_la-openssl_hsm_cb.Plo \ + ./$(DEPDIR)/libpki_token_openssl_la-openssl_hsm_obj.Plo \ + ./$(DEPDIR)/libpki_token_openssl_la-openssl_hsm_pkey.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libpki_token_openssl_la_SOURCES) +DIST_SOURCES = $(libpki_token_openssl_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/build/depcomp \ + $(top_srcdir)/build/mkinstalldirs +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_DATE = @BUILD_DATE@ +BUILD_DATE_FULL = @BUILD_DATE_FULL@ +BUILD_DATE_PRETTY = @BUILD_DATE_PRETTY@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CHMOD = @CHMOD@ +CHOWN = @CHOWN@ +CP = @CP@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CPU = @CPU@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CXX = @CXX@ +CYGPATH_W = @CYGPATH_W@ +DATE = @DATE@ +DEFS = $(OPENCA_DEFS) +DEPDIR = @DEPDIR@ +DESTDIR = @DESTDIR@ +DIST_NAME = @DIST_NAME@ +DIST_VERSION = @DIST_VERSION@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +GZIP = @GZIP@ +HAS_PKGCONF = @HAS_PKGCONF@ +INSTALL = @INSTALL@ +INSTALL_BUILDER = @INSTALL_BUILDER@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKE = @MAKE@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR = @MKDIR@ +MKDIR_P = @MKDIR_P@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PDFLATEX = @PDFLATEX@ +PERL = @PERL@ +PG_CONFIG = @PG_CONFIG@ +PG_CPPFLAGS = @PG_CPPFLAGS@ +PKGMK = @PKGMK@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POD2MAN = @POD2MAN@ +PWD = @PWD@ +RANLIB = @RANLIB@ +RC = @RC@ +RPM = @RPM@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TAR = @TAR@ +TODAY = @TODAY@ +VERSION = @VERSION@ +ZIP = @ZIP@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_aux_dir = @ac_aux_dir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +arch_target = @arch_target@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +composite_cflags = @composite_cflags@ +composite_ldadd = @composite_ldadd@ +composite_ldflags = @composite_ldflags@ +conf_dir = @conf_dir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +day = @day@ +dist_group = @dist_group@ +dist_user = @dist_user@ +docdir = @docdir@ +dvidir = @dvidir@ +enable_debug = @enable_debug@ +etc_dir = @etc_dir@ +exec_prefix = @exec_prefix@ +extra_checks = @extra_checks@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +hr = @hr@ +htmldir = @htmldir@ +iface_age = @iface_age@ +iface_current = @iface_current@ +iface_revision = @iface_revision@ +iface_version = @iface_version@ +include_dir = @include_dir@ +include_prefix = @include_prefix@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +kmf_cflags = @kmf_cflags@ +kmf_ldadd = @kmf_ldadd@ +kmf_libflags = @kmf_libflags@ +kmf_prefix = @kmf_prefix@ +ldap_cflags = @ldap_cflags@ +ldap_ldadd = @ldap_ldadd@ +ldap_ldflags = @ldap_ldflags@ +ldap_prefix = @ldap_prefix@ +ldap_vendor = @ldap_vendor@ +lib_major = @lib_major@ +lib_micro = @lib_micro@ +lib_minor = @lib_minor@ +lib_prefix = @lib_prefix@ +lib_revision = @lib_revision@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libpki_cflags = @libpki_cflags@ +libpki_ldadd = @libpki_ldadd@ +libpki_ldflags = @libpki_ldflags@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +min = @min@ +mkdir_p = @mkdir_p@ +mon = @mon@ +my_cflags = @my_cflags@ +my_ldadd = @my_ldadd@ +my_ldflags = @my_ldflags@ +myarch = @myarch@ +mybits = @mybits@ +mybits_install = @mybits_install@ +mysql_cflags = @mysql_cflags@ +mysql_config = @mysql_config@ +mysql_ldadd = @mysql_ldadd@ +mysql_ldflags = @mysql_ldflags@ +mysql_prefix = @mysql_prefix@ +oldincludedir = @oldincludedir@ +openssl_cflags = @openssl_cflags@ +openssl_include = @openssl_include@ +openssl_ldadd = @openssl_ldadd@ +openssl_ldflags = @openssl_ldflags@ +openssl_prefix = @openssl_prefix@ +openssl_static_libs = @openssl_static_libs@ +oqs_cflags = @oqs_cflags@ +oqs_ldadd = @oqs_ldadd@ +oqs_ldflags = @oqs_ldflags@ +oqsprov_cflags = @oqsprov_cflags@ +oqsprov_ldadd = @oqsprov_ldadd@ +oqsprov_ldflags = @oqsprov_ldflags@ +package_build = @package_build@ +package_prefix = @package_prefix@ +pdfdir = @pdfdir@ +pg_cflags = @pg_cflags@ +pg_config = @pg_config@ +pg_ldadd = @pg_ldadd@ +pg_ldflags = @pg_ldflags@ +pg_prefix = @pg_prefix@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pthread_opts = @pthread_opts@ +resolv_ldadd = @resolv_ldadd@ +rpath = @rpath@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sdkver = @sdkver@ +sec = @sec@ +sharedstatedir = @sharedstatedir@ +shlext = @shlext@ +shlib_history = @shlib_history@ +shlib_version = @shlib_version@ +srcdir = @srcdir@ +sys_cflags = @sys_cflags@ +sys_ldadd = @sys_ldadd@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +test_libs = @test_libs@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +txt_revision = @txt_revision@ +xml2_cflags = @xml2_cflags@ +xml2_config = @xml2_config@ +xml2_include = @xml2_include@ +xml2_ldadd = @xml2_ldadd@ +xml2_ldflags = @xml2_ldflags@ +xml2_prefix = @xml2_prefix@ +yr = @yr@ +TOP = ../.. +BASE_DEFS = +AM_CPPFLAGS = -I$(TOP) \ + $(openssl_cflags) \ + $(libxml2_cflags) \ + $(COND_INCLUDES) + +SRCS = \ + openssl_hsm.c \ + openssl_hsm_pkey.c \ + openssl_hsm_obj.c \ + openssl_hsm_cb.c + +noinst_LTLIBRARIES = libpki-token-openssl.la +libpki_token_openssl_la_SOURCES = $(SRCS) +libpki_token_openssl_la_CFLAGS = $(BUILD_LIBPKI_CFLAGS) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/drivers/openssl/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/drivers/openssl/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libpki-token-openssl.la: $(libpki_token_openssl_la_OBJECTS) $(libpki_token_openssl_la_DEPENDENCIES) $(EXTRA_libpki_token_openssl_la_DEPENDENCIES) + $(AM_V_CCLD)$(libpki_token_openssl_la_LINK) $(libpki_token_openssl_la_OBJECTS) $(libpki_token_openssl_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_token_openssl_la-openssl_hsm.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_token_openssl_la-openssl_hsm_cb.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_token_openssl_la-openssl_hsm_obj.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_token_openssl_la-openssl_hsm_pkey.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +libpki_token_openssl_la-openssl_hsm.lo: openssl_hsm.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_token_openssl_la_CFLAGS) $(CFLAGS) -MT libpki_token_openssl_la-openssl_hsm.lo -MD -MP -MF $(DEPDIR)/libpki_token_openssl_la-openssl_hsm.Tpo -c -o libpki_token_openssl_la-openssl_hsm.lo `test -f 'openssl_hsm.c' || echo '$(srcdir)/'`openssl_hsm.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_token_openssl_la-openssl_hsm.Tpo $(DEPDIR)/libpki_token_openssl_la-openssl_hsm.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='openssl_hsm.c' object='libpki_token_openssl_la-openssl_hsm.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_token_openssl_la_CFLAGS) $(CFLAGS) -c -o libpki_token_openssl_la-openssl_hsm.lo `test -f 'openssl_hsm.c' || echo '$(srcdir)/'`openssl_hsm.c + +libpki_token_openssl_la-openssl_hsm_pkey.lo: openssl_hsm_pkey.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_token_openssl_la_CFLAGS) $(CFLAGS) -MT libpki_token_openssl_la-openssl_hsm_pkey.lo -MD -MP -MF $(DEPDIR)/libpki_token_openssl_la-openssl_hsm_pkey.Tpo -c -o libpki_token_openssl_la-openssl_hsm_pkey.lo `test -f 'openssl_hsm_pkey.c' || echo '$(srcdir)/'`openssl_hsm_pkey.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_token_openssl_la-openssl_hsm_pkey.Tpo $(DEPDIR)/libpki_token_openssl_la-openssl_hsm_pkey.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='openssl_hsm_pkey.c' object='libpki_token_openssl_la-openssl_hsm_pkey.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_token_openssl_la_CFLAGS) $(CFLAGS) -c -o libpki_token_openssl_la-openssl_hsm_pkey.lo `test -f 'openssl_hsm_pkey.c' || echo '$(srcdir)/'`openssl_hsm_pkey.c + +libpki_token_openssl_la-openssl_hsm_obj.lo: openssl_hsm_obj.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_token_openssl_la_CFLAGS) $(CFLAGS) -MT libpki_token_openssl_la-openssl_hsm_obj.lo -MD -MP -MF $(DEPDIR)/libpki_token_openssl_la-openssl_hsm_obj.Tpo -c -o libpki_token_openssl_la-openssl_hsm_obj.lo `test -f 'openssl_hsm_obj.c' || echo '$(srcdir)/'`openssl_hsm_obj.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_token_openssl_la-openssl_hsm_obj.Tpo $(DEPDIR)/libpki_token_openssl_la-openssl_hsm_obj.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='openssl_hsm_obj.c' object='libpki_token_openssl_la-openssl_hsm_obj.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_token_openssl_la_CFLAGS) $(CFLAGS) -c -o libpki_token_openssl_la-openssl_hsm_obj.lo `test -f 'openssl_hsm_obj.c' || echo '$(srcdir)/'`openssl_hsm_obj.c + +libpki_token_openssl_la-openssl_hsm_cb.lo: openssl_hsm_cb.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_token_openssl_la_CFLAGS) $(CFLAGS) -MT libpki_token_openssl_la-openssl_hsm_cb.lo -MD -MP -MF $(DEPDIR)/libpki_token_openssl_la-openssl_hsm_cb.Tpo -c -o libpki_token_openssl_la-openssl_hsm_cb.lo `test -f 'openssl_hsm_cb.c' || echo '$(srcdir)/'`openssl_hsm_cb.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_token_openssl_la-openssl_hsm_cb.Tpo $(DEPDIR)/libpki_token_openssl_la-openssl_hsm_cb.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='openssl_hsm_cb.c' object='libpki_token_openssl_la-openssl_hsm_cb.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_token_openssl_la_CFLAGS) $(CFLAGS) -c -o libpki_token_openssl_la-openssl_hsm_cb.lo `test -f 'openssl_hsm_cb.c' || echo '$(srcdir)/'`openssl_hsm_cb.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/libpki_token_openssl_la-openssl_hsm.Plo + -rm -f ./$(DEPDIR)/libpki_token_openssl_la-openssl_hsm_cb.Plo + -rm -f ./$(DEPDIR)/libpki_token_openssl_la-openssl_hsm_obj.Plo + -rm -f ./$(DEPDIR)/libpki_token_openssl_la-openssl_hsm_pkey.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/libpki_token_openssl_la-openssl_hsm.Plo + -rm -f ./$(DEPDIR)/libpki_token_openssl_la-openssl_hsm_cb.Plo + -rm -f ./$(DEPDIR)/libpki_token_openssl_la-openssl_hsm_obj.Plo + -rm -f ./$(DEPDIR)/libpki_token_openssl_la-openssl_hsm_pkey.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-noinstLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + +include $(TOP)/global-vars + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/crypto/hsm/openssl/openssl_hsm.c b/src/crypto/hsm/openssl/openssl_hsm.c new file mode 100644 index 00000000..3d00fc68 --- /dev/null +++ b/src/crypto/hsm/openssl/openssl_hsm.c @@ -0,0 +1,441 @@ +/* HSM Object Management Functions */ + +// Single Include +#include + +/* Callbacks for Software OpenSSL HSM */ +const HSM_CALLBACKS openssl_hsm_callbacks = { + /* Errno */ + HSM_OPENSSL_get_errno, + /* Err Descr */ + HSM_OPENSSL_get_errdesc, + /* Init */ + HSM_OPENSSL_init, + /* Free */ + HSM_OPENSSL_free, + /* Login */ + NULL, + /* Logout */ + NULL, + /* Set Algorithm */ + NULL, /* HSM_OPENSSL_algor_set, */ + /* Set fips mode */ + HSM_OPENSSL_set_fips_mode, + /* Fips operation mode */ + HSM_OPENSSL_is_fips_mode, + /* General Sign */ + NULL, /* HSM_OPENSSL_sign, */ + /* ASN1 General Sign */ + NULL, /* HSM_OPENSSL_asn1_sign, */ + /* General Verify */ + NULL, /* HSM_OPENSSL_verify, */ + /* ASN1 General Verify */ + NULL, /* HSM_OPENSSL_verify, */ + /* Key Generation */ + HSM_OPENSSL_X509_KEYPAIR_new, + /* Free Keypair Function */ + HSM_OPENSSL_X509_KEYPAIR_free, + /* Key Wrapping */ + NULL, // HSM_OPENSSL_X509_KEYPAIR_STACK_wrap, + /* Key Unwrapping */ + NULL, // HSM_OPENSSL_X509_KEYPAIR_STACK_unwrap, + /* Obj Load Function */ + NULL, // HSM_OPENSSL_X509_STACK_get_url, + /* Obj Add Function */ + NULL, // HSM_OPENSSL_X509_STACK_put_url, + /* Obj Del Function */ + NULL, /* HSM_OPENSSL_X509_STACK_del_url */ + /* Get the number of available Slots */ + NULL, // HSM_OPENSSL_SLOT_num, + /* Get Slot info */ + HSM_OPENSSL_SLOT_INFO_get, + /* Free Slot info */ + NULL, /* HSM_OPENSSL_SLOT_INFO_free */ + /* Set the current slot */ + NULL, /* HSM_OPENSSL_SLOT_select */ + /* Cleans up the current slot */ + NULL, /* HSM_OPENSSL_SLOT_clean */ + /* Get X509 Callbacks */ + HSM_OPENSSL_X509_get_cb +}; + +/* Structure for PKI_TOKEN definition */ +HSM openssl_hsm = { + + /* Version of the token */ + 1, + + /* Description of the HSM */ + "OpenSSL Software HSM", + + /* Manufacturer */ + "OpenSSL Project", + + /* Pointer to the HSM config file and parsed structure*/ + NULL, + + /* One of PKI_HSM_TYPE value */ + HSM_TYPE_SOFTWARE, + + /* URL for the ID of the driver, this is filled at load time */ + NULL, + + /* Pointer to the driver structure */ + NULL, + + /* Pointer to internal session handler */ + NULL, + + /* Credential for the HSM - usually used for the SO */ + NULL, + + /* is Logged In ? */ + 0, + + /* is Cred Set ? */ + 0, + + /* is Login Required ? */ + 0, + + /* Callbacks Structures */ + &openssl_hsm_callbacks +}; + + +HSM_SLOT_INFO openssl_slot_info = { + + /* Device Manufacturer ID */ + "OpenSSL", + + /* Device Description */ + "Software interface", + + /* Hardware Version */ + 1, + 0, + + /* Firmware Version */ + 1, + 0, + + /* Initialized */ + 1, + + /* Present */ + 1, + + /* Removable */ + 0, + + /* Hardware */ + 0, + + /* Token Info */ + { + /* Token Label */ + "Unknown Label\x0 ", + /* ManufacturerID */ + "Unknown\x0 ", + /* Model */ + "Unknown\x0 ", + /* Serial Number */ + "0\x0 ", + /* Max Sessions */ + 65535, + /* Current Sessions */ + 0, + /* Max Pin Len */ + 0, + /* Min Pin Len */ + 0, + /* Memory Pub Total */ + 0, + /* Memory Pub Free */ + 0, + /* Memory Priv Total */ + 0, + /* Memory Priv Free */ + 0, + /* HW Version Major */ + 1, + /* HW Version Minor */ + 0, + /* FW Version Major */ + 1, + /* FW Version Minor */ + 0, + /* HAS Random Number Generator (RNG) */ + 1, + /* HAS clock */ + 0, + /* Login is Required */ + 0, + /* utcTime */ + "" + } + +}; + +unsigned long HSM_OPENSSL_get_errno ( void ) +{ + unsigned long ret = 0; + + ret = ERR_get_error(); + + return ret; +} + +char * HSM_OPENSSL_get_errdesc ( unsigned long err, char *str, size_t size ) +{ + char * ret = NULL; + + if (err == 0) err = ERR_get_error(); + + if (str && size > 0) + { + ERR_error_string_n ( err, str, size ); + ret = str; + } + else ret = ERR_error_string(err, NULL); + + return ret; +} + +const HSM * HSM_OPENSSL_get_default( void ) +{ + return ((const HSM *)&openssl_hsm); +} + +HSM *HSM_OPENSSL_new ( PKI_CONFIG *conf ) +{ + HSM *hsm = NULL; + + hsm = (HSM *) PKI_Malloc ( sizeof( HSM )); + memcpy( hsm, &openssl_hsm, sizeof( HSM)); + + /* Not really needed! */ + hsm->callbacks = &openssl_hsm_callbacks; + + if( conf ) { + hsm->config = conf; + } + + hsm->type = HSM_TYPE_SOFTWARE; + + return( hsm ); +} + +int HSM_OPENSSL_free ( HSM *driver, PKI_CONFIG *conf ) { + + if( driver == NULL ) return (PKI_OK); + + return (PKI_ERR); +} + +int HSM_OPENSSL_init( HSM *driver, PKI_CONFIG *conf ) { + + if( driver == NULL ) return (PKI_ERR); + + /* Checks the FIPS mode */ + if (PKI_is_fips_mode() == PKI_OK) + { + if (HSM_OPENSSL_set_fips_mode(driver, 1) == PKI_ERR) + return PKI_ERR; + } + + /* No need for initialization of the software driver */ + return PKI_OK; +} + +/*! + * \brief Sets the fips operation mode when the parameter is != 0, + * otherwise it sets the HSM in non-fips mode + */ +int HSM_OPENSSL_set_fips_mode(const HSM *driver, int k) { + +#ifdef OPENSSL_FIPS + return (FIPS_mode_set(k) == 1 ? PKI_OK : PKI_ERR); +#else + return PKI_ERR; +#endif + +} + +/*! + * \brief Returns 0 if HSM is operating in non-FIPS mode, true (!0) if FIPS + * mode is enabled. + */ +int HSM_OPENSSL_is_fips_mode(const HSM *driver) +{ +#ifdef OPENSSL_FIPS + return (FIPS_mode() == 0 ? PKI_ERR : PKI_OK); +#else + return PKI_ERR; +#endif + +} + +/* ----------------------- General Signing function -------------------- */ + +// PKI_MEM * HSM_OPENSSL_sign(PKI_MEM * der, PKI_DIGEST_ALG * digest, PKI_X509_KEYPAIR *key) { + +// EVP_MD_CTX *ctx = NULL; +// // Digest's context + +// size_t out_size = 0; +// // size_t ossl_ret = 0; + +// PKI_MEM *out_mem = NULL; +// // Output buffer + +// EVP_PKEY *pkey = NULL; +// // Signing Key Value + +// int digestResult = -1; +// int def_nid = NID_undef; +// // OpenSSL return value + +// if (!der || !der->data || !key || !key->value) +// { +// PKI_ERROR( PKI_ERR_PARAM_NULL, NULL); +// return NULL; +// } + +// // Private Key +// pkey = PKI_X509_get_value(key); +// if (!pkey) { +// PKI_ERROR(PKI_ERR_PARAM_NULL, "Cannot retrieve the internal value of the key (PKEY)."); +// return NULL; +// } + +// // Get the Maximum size of a signature +// out_size = (size_t) EVP_PKEY_size(pkey); + +// // Gets the default digest for the key +// digestResult = EVP_PKEY_get_default_digest_nid(pkey, &def_nid); + +// // PKI_DEBUG("Requested Digest for Signing is %s", digest ? PKI_ID_get_txt(EVP_MD_nid(digest)) : "NULL"); +// // PKI_DEBUG("Checking Default Digest for PKEY %d (%s) is %d (%s) (result = %d)", +// // EVP_PKEY_id(pkey), PKI_ID_get_txt(EVP_PKEY_id(pkey)), def_nid, PKI_ID_get_txt(def_nid), digestResult); + +// // Checks for error +// if (digest == NULL && digestResult <= 0) { +// PKI_DEBUG("Cannot get the default digest for signing key (type: %d)", EVP_PKEY_id(pkey)); +// return NULL; +// } + +// // If the returned value is == 2, then the returned +// // digest is mandatory and cannot be replaced +// if (digestResult == 2 && def_nid != EVP_MD_nid(digest)) { +// // // Checks if we are in a no-hash mandatory +// // if (def_nid == NID_undef && (digest != EVP_md_null() && digest != NULL)) { +// // PKI_DEBUG("PKEY requires no hash but got one (%d)", EVP_MD_nid(digest)); +// // return NULL; +// // } +// // // Checks if we are using the mandated digest +// // if ((digest != NULL && def_nid != NID_undef) || (def_nid != EVP_MD_nid(digest))) { +// // PKI_DEBUG("PKEY requires digest (%d) but got (%d)", def_nid, EVP_MD_nid(digest)); +// // return NULL; +// // } +// PKI_DEBUG("PKEY requires %s digest (mandatory) and cannot be used with %s digest (requested).", +// def_nid == NID_undef ? "NO" : PKI_ID_get_txt(def_nid), +// digest == NULL ? "NO" : PKI_ID_get_txt(EVP_MD_nid(digest))); +// return NULL; +// } + +// // Initialize the return structure +// if ((out_mem = PKI_MEM_new ((size_t)out_size)) == NULL) { +// PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); +// return NULL; +// } + +// // Creates the context +// if ((ctx = EVP_MD_CTX_create()) == NULL) { +// PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); +// goto err; +// } + +// // Initializes the Context +// EVP_MD_CTX_init(ctx); + +// // PKI_DEBUG("MD (digest) = %p (EVP_md_null = %p) (EVP_md_null() ==> %d)", +// // digest, EVP_md_null, EVP_md_null() == digest); + +// // DEBUG +// // PKI_DEBUG("MD (digest) in DigestSignInit: %d (%s)", +// // digest ? EVP_MD_nid(digest) : NID_undef, digest ? PKI_DIGEST_ALG_get_parsed(digest) : ""); + +// // Initializes the Digest and does special processing for when the +// // EVP_md_null() is used to indicate that the NO HASH was requested +// if (!EVP_DigestSignInit(ctx, NULL /* &pctx */, EVP_md_null() == digest ? NULL : digest, NULL, pkey)) { +// PKI_ERROR(PKI_ERR_SIGNATURE_CREATE, "Cannot Initialize EVP_DigestSignInit()"); +// goto err; +// } + +// if (EVP_DigestSign(ctx, out_mem->data, &out_size, der->data, der->size) <= 0) { +// PKI_ERROR(PKI_ERR_SIGNATURE_CREATE, "Cannot generate signature via EVP_DigestSign()"); +// goto err; +// } + +// // Update the size of the signature +// out_mem->size = (size_t) out_size; + +// // // Updates the Digest calculation with the TBS data +// // if (EVP_DigestSignUpdate(ctx, +// // der->data, +// // der->size) <= 0) { +// // PKI_ERROR(PKI_ERR_SIGNATURE_CREATE, "Cannot Update EVP_DigestSignUpdate()"); +// // goto err; +// // } + +// // // Finalize the MD +// // // EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_FINALISE); + +// // // Finalizes the Signature calculation and saves it in the output buffer +// // if (EVP_DigestSignFinal(ctx, +// // out_mem->data, +// // &out_size) <= 0) { +// // PKI_ERROR(PKI_ERR_SIGNATURE_CREATE, "Cannot Finalize EVP_DigestSignFinal()"); +// // goto err; +// // } +// // else out_mem->size = (size_t) out_size; + +// // All Done +// goto end; + +// err: + +// // Error Condition, free the output's memory +// if (out_mem) PKI_MEM_free(out_mem); +// out_mem = NULL; + +// end: +// // Cleanup the context +// #if OPENSSL_VERSION_NUMBER <= 0x1010000f +// if (ctx) EVP_MD_CTX_cleanup(ctx); +// #else +// if (ctx) EVP_MD_CTX_reset(ctx); +// #endif + +// // Frees the CTX structure +// if (ctx) EVP_MD_CTX_destroy(ctx); + +// // Returns the result or NULL +// return out_mem; +// } + +/* ---------------------- OPENSSL Slot Management Functions ---------------- */ + +HSM_SLOT_INFO * HSM_OPENSSL_SLOT_INFO_get (unsigned long num, HSM *hsm) { + + HSM_SLOT_INFO *ret = NULL; + + ret = (HSM_SLOT_INFO *) PKI_Malloc ( sizeof (HSM_SLOT_INFO)); + memcpy( ret, &openssl_slot_info, sizeof( HSM_SLOT_INFO )); + + return (ret); +} + +/* -------------------- OPENSSL Callbacks Management Functions ------------- */ + diff --git a/src/crypto/hsm/openssl/openssl_hsm_cb.c b/src/crypto/hsm/openssl/openssl_hsm_cb.c new file mode 100644 index 00000000..8da2a7c9 --- /dev/null +++ b/src/crypto/hsm/openssl/openssl_hsm_cb.c @@ -0,0 +1,430 @@ +#include +#include + +#include +#include + +const PKI_X509_CALLBACKS PKI_OPENSSL_X509_KEYPAIR_CALLBACKS = { + // Memory Management + (void *) EVP_PKEY_new, // PKI_KEYPAIR_new_null + (void *) EVP_PKEY_free, // PKI_KEYPAIR_free + (void *) OPENSSL_HSM_KEYPAIR_dup, // PKI_KEYPAIR_dup + + // Data Retrieval + (void *) NULL, // PKI_KEYPAIR_get_parsed + (void *) NULL, // PKI_KEYPAIR_data; + (void *) NULL, // PKI_KEYPAIR_print_parsed; + + // Data Conversion + NULL, // (void *) PEM_write_bio_PUBKEY, // PEM format + (void *) OPENSSL_HSM_write_bio_PrivateKey, // PEM format + // (void *) PEM_write_bio_PKCS8PrivateKey, // PEM format + (void *) i2d_PrivateKey_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL, // XML format + + // Data Conversion + (void *) PEM_read_bio_PrivateKey,// PEM format + (void *) d2i_PrivateKey_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL // XML format +}; + +const PKI_X509_CALLBACKS PKI_OPENSSL_X509_CERT_CALLBACKS = { + /* Memory Management */ + (void*)X509_new, + (void*)X509_free, + (void*)X509_dup, + + /* Data Retrieval */ + (void *) PKI_X509_CERT_get_parsed, + (void *) PKI_X509_CERT_get_data, + (void *) PKI_X509_CERT_print_parsed, + + /* Data Conversion */ +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + (void *) PEM_write_bio_X509_AUX, // PEM format +#else + (void *) PEM_write_bio_X509, // PEM format +#endif + NULL, // PEM EX (encrypted) format + (void *) i2d_X509_bio, // DER format + (void *) X509_print, // TXT format + NULL, // B64 format (B64_write_bio) + NULL, // XML format + + /* Data Conversion */ + (void *) PEM_read_bio_X509_AUX, // PEM format + (void *) d2i_X509_bio, // DER format + NULL, // TXT format + NULL, // B64 format + NULL // XML format +}; + + +const PKI_X509_CALLBACKS PKI_OPENSSL_X509_REQ_CALLBACKS = { + /* Memory Management */ + (void *) X509_REQ_new, + (void *) X509_REQ_free, + (void *) X509_REQ_dup, + + /* Data Retrieval */ + (void *) PKI_X509_REQ_get_parsed, + (void *) PKI_X509_REQ_get_data, + (void *) PKI_X509_REQ_print_parsed, + + /* Data Conversion */ + (void *) PEM_write_bio_X509_REQ, // PEM format + NULL, // PEM EX (encrypted) format + (void *) i2d_X509_REQ_bio, // DER format + (void *) X509_REQ_print, // TXT format + (void *) NULL, // B64 format + (void *) NULL, // XML format + + /* Data Conversion */ + (void *) PEM_read_bio_X509_REQ, // PEM format + (void *) d2i_X509_REQ_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL // XML format +}; + +const PKI_X509_CALLBACKS PKI_OPENSSL_X509_CRL_CALLBACKS = { + /* Memory Management */ + (void *) X509_CRL_new, + (void *) X509_CRL_free, + (void *) X509_CRL_dup, + + /* Data Retrieval */ + (void *) PKI_X509_CRL_get_parsed, + (void *) PKI_X509_CRL_get_data, + (void *) NULL, // PKI_X509_CRL_print_parsed, + + /* Data Conversion */ + (void *) PEM_write_bio_X509_CRL, // PEM format + NULL, // PEM EX (encrypted) format + (void *) i2d_X509_CRL_bio, // DER format + (void *) X509_CRL_print, // TXT format + (void *) NULL, // B64 format + (void *) NULL, // XML format + + /* Data Conversion */ + (void *) PEM_read_bio_X509_CRL, // PEM format + (void *) d2i_X509_CRL_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL // XML format +}; + +const PKI_X509_CALLBACKS PKI_OPENSSL_X509_PKCS7_CALLBACKS = { + + /* Memory Management */ + (void *) PKCS7_new, + (void *) PKCS7_free, + (void *) PKCS7_dup, + + /* Data Retrieval */ + (void *) NULL, // PKI_X509_PKCS7_get_parsed; + (void *) NULL, // PKI_X509_PKCS7_get_data; + (void *) NULL, // PKI_X509_PKCS7_print_parsed; + + /* Data Conversion */ + (void *) PEM_write_bio_PKCS7, // PEM format + NULL, // PEM EX (encrypted) format + (void *) i2d_PKCS7_bio, // DER format + (void *) PKI_X509_PKCS7_VALUE_print_bio, // TXT format + (void *) NULL, // B64 format + (void *) NULL, // XML format + + /* Data Conversion */ + (void *) PEM_read_bio_PKCS7, // PEM format + (void *) d2i_PKCS7_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL // XML format +}; + + +const PKI_X509_CALLBACKS PKI_OPENSSL_X509_CMS_CALLBACKS = { + + /* Memory Management */ + (void *) PKI_X509_CMS_VALUE_new, + (void *) PKI_X509_CMS_VALUE_free, + (void *) PKI_X509_CMS_VALUE_dup, + + /* Data Retrieval */ + (void *) NULL, // PKI_X509_PKCS7_get_parsed; + (void *) NULL, // PKI_X509_PKCS7_get_data; + (void *) NULL, // PKI_X509_PKCS7_print_parsed; + + /* Data Conversion */ + (void *) PEM_write_bio_CMS, // PEM format + NULL, // PEM EX (encrypted) format + (void *) i2d_CMS_bio, // DER format + (void *) PKI_X509_CMS_VALUE_print_bio, // TXT format + (void *) NULL, // B64 format + (void *) NULL, // XML format + + /* Data Conversion */ + (void *) PEM_read_bio_CMS, // PEM format + (void *) d2i_CMS_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL // XML format +}; + + +const PKI_X509_CALLBACKS PKI_OPENSSL_X509_PKCS12_CALLBACKS = { + // Memory Management + (void *) PKCS12_new, + (void *) PKCS12_free, + (void *) NULL, + + // Data Retrieval + (void *) NULL, // PKI_X509_PKCS12_get_parsed; + (void *) NULL, // PKI_X509_PKCS12_get_data; + (void *) NULL, // PKI_X509_PKCS12_print_parsed; + + // Data Conversion + (void *) PEM_write_bio_PKCS12, // PEM format + NULL, // PEM EX (encrypted) format + (void *) i2d_PKCS12_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL, // XML format + + // Data Conversion + (void *) PEM_read_bio_PKCS12, // PEM format + (void *) d2i_PKCS12_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL // XML format +}; + +const PKI_X509_CALLBACKS PKI_OPENSSL_X509_OCSP_REQ_CALLBACKS = { + // Memory Management + (void *) OCSP_REQUEST_new, + (void *) OCSP_REQUEST_free, + (void *) NULL, + + // Data Retrieval + (void *) PKI_X509_OCSP_REQ_get_parsed, // PKI_X509_OCSP_REQ_get_parsed; + (void *) PKI_X509_OCSP_REQ_get_data, // PKI_X509_OCSP_REQ_get_data; + (void *) NULL, // PKI_X509_OCSP_REQ_print_parsed; + + // Data Conversion + (void *) PEM_write_bio_OCSP_REQ,// PEM format + NULL, // PEM EX (encrypted) format + (void *) i2d_OCSP_REQ_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL, // XML format + + // Data Conversion + (void *) PEM_read_bio_OCSP_REQ, // PEM format + (void *) d2i_OCSP_REQ_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL // XML format +}; + +const PKI_X509_CALLBACKS PKI_OPENSSL_X509_OCSP_RESP_CALLBACKS = { + // Memory Management + (void *) PKI_OCSP_RESP_new, + (void *) PKI_OCSP_RESP_free, + (void *) NULL, + + // Data Retrieval + (void *) PKI_X509_OCSP_RESP_get_parsed, + (void *) PKI_X509_OCSP_RESP_get_data, + (void *) NULL, // PKI_X509_OCSP_RESP_print_parsed; + + // Data Conversion + (void *) PEM_write_bio_PKI_X509_OCSP_RESP_VALUE, // PEM format + NULL, // PEM EX (encrypted) format + (void *) i2d_PKI_X509_OCSP_RESP_VALUE_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL, // XML format + + // Data Conversion + (void *) PEM_read_bio_PKI_X509_OCSP_RESP_VALUE,// PEM format + (void *) d2i_PKI_X509_OCSP_RESP_VALUE_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL // XML format +}; + +const PKI_X509_CALLBACKS PKI_OPENSSL_X509_XPAIR_CALLBACKS = { + // Memory Management + (void *) PKI_XPAIR_new_null, + (void *) PKI_XPAIR_free, + (void *) NULL, + + // Data Retrieval + (void *) NULL, // PKI_X509_XPAIR_get_parsed;sed; + (void *) NULL, // PKI_X509_XPAIR_get_data; + (void *) NULL, // PKI_X509_XPAIR_print_parsed; + + // Data Conversion + (void *) PEM_write_bio_PKI_XPAIR, // PEM format + NULL, // PEM EX (encrypted) format + (void *) i2d_PKI_XPAIR_bio, // DER format + (void *) PKI_XPAIR_print, // TXT format + (void *) NULL, // B64 format + (void *) NULL, // XML format + + // Data Conversion + (void *) PEM_read_bio_PKI_XPAIR,// PEM format + (void *) d2i_PKI_XPAIR_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL // XML format +}; + +const PKI_X509_CALLBACKS PKI_OPENSSL_X509_PRQP_REQ_CALLBACKS = { + // Memory Management + (void *) PKI_PRQP_REQ_new, + (void *) PKI_PRQP_REQ_free, + (void *) PKI_PRQP_REQ_dup, + + // Data Retrieval + (void *) NULL, //PKI_X509_PRQP_REQ_get_parsed, // PKI_X509_OCSP_REQ_get_parsed; + (void *) PKI_X509_PRQP_REQ_get_data, // PKI_X509_OCSP_REQ_get_data; + (void *) NULL, // PKI_X509_OCSP_REQ_print_parsed; + + // Data Conversion + (void *) PEM_write_bio_PRQP_REQ,// PEM format + NULL, // PEM EX (encrypted) format + (void *) i2d_PRQP_REQ_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL, // XML format + + // Data Conversion + (void *) PEM_read_bio_PRQP_REQ, // PEM format + (void *) d2i_PRQP_REQ_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL // XML format +}; + +const PKI_X509_CALLBACKS PKI_OPENSSL_X509_PRQP_RESP_CALLBACKS = { + // Memory Management + (void *) PKI_PRQP_RESP_new, + (void *) PKI_PRQP_RESP_free, + (void *) PKI_PRQP_RESP_dup, + + // Data Retrieval + (void *) NULL,//PKI_X509_PRQP_RESP_get_parsed, + (void *) PKI_X509_PRQP_RESP_get_data, + (void *) NULL, // PKI_X509_OCSP_RESP_print_parsed; + + // Data Conversion (write of the ->value data ) + (void *) PEM_write_bio_PRQP_RESP, // PEM format + NULL, // PEM EX (encrypted) format + (void *) i2d_PRQP_RESP_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL, // XML format + + // Data Conversion (read the ->value) + (void *) PEM_read_bio_PRQP_RESP,// PEM format + (void *) d2i_PRQP_RESP_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL // XML format +}; + + +const PKI_X509_CALLBACKS_FULL PKI_OPENSSL_X509_CALLBACKS_FULL = { + // X509_KEYPAIR + &PKI_OPENSSL_X509_KEYPAIR_CALLBACKS, + // X509_CERT + &PKI_OPENSSL_X509_CERT_CALLBACKS, + // X509_REQ + &PKI_OPENSSL_X509_REQ_CALLBACKS, + // X509_CRL + &PKI_OPENSSL_X509_CRL_CALLBACKS, + // X509_PKCS7 + &PKI_OPENSSL_X509_PKCS7_CALLBACKS, + // X509_CMS + &PKI_OPENSSL_X509_CMS_CALLBACKS, + // X509_PKCS12 + &PKI_OPENSSL_X509_PKCS12_CALLBACKS, + // X509_OCSP_REQ + &PKI_OPENSSL_X509_OCSP_REQ_CALLBACKS, + // X509_OCSP_RESP + &PKI_OPENSSL_X509_OCSP_RESP_CALLBACKS, + // X509_OCSP_XPAIR + &PKI_OPENSSL_X509_XPAIR_CALLBACKS, + // X509_OCSP_CMS + NULL, // &PKI_OPENSSL_X509_CMC_CALLBACKS, + // X509_OCSP_SCEP + &PKI_OPENSSL_X509_PKCS7_CALLBACKS, // &PKI_OPENSSL_X509_SCEP_CALLBACKS + // PRQP_REQ + &PKI_OPENSSL_X509_PRQP_REQ_CALLBACKS, + // PRQP_RESP + &PKI_OPENSSL_X509_PRQP_RESP_CALLBACKS +}; + +const PKI_X509_CALLBACKS *HSM_OPENSSL_X509_get_cb ( PKI_DATATYPE type ) { + + const PKI_X509_CALLBACKS *ret = NULL; + + switch ( type ) { + case PKI_DATATYPE_X509_KEYPAIR : + ret = &PKI_OPENSSL_X509_KEYPAIR_CALLBACKS; + break; + case PKI_DATATYPE_X509_CERT : + ret = &PKI_OPENSSL_X509_CERT_CALLBACKS; + break; + case PKI_DATATYPE_X509_REQ : + ret = &PKI_OPENSSL_X509_REQ_CALLBACKS; + break; + case PKI_DATATYPE_X509_CRL : + ret = &PKI_OPENSSL_X509_CRL_CALLBACKS; + break; + case PKI_DATATYPE_X509_PKCS7 : + ret = &PKI_OPENSSL_X509_PKCS7_CALLBACKS; + break; + case PKI_DATATYPE_X509_CMS : + ret = &PKI_OPENSSL_X509_CMS_CALLBACKS; + break; + case PKI_DATATYPE_X509_PKCS12 : + ret = &PKI_OPENSSL_X509_PKCS12_CALLBACKS; + break; + case PKI_DATATYPE_X509_OCSP_REQ : + ret = &PKI_OPENSSL_X509_OCSP_REQ_CALLBACKS; + break; + case PKI_DATATYPE_X509_OCSP_RESP : + ret = &PKI_OPENSSL_X509_OCSP_RESP_CALLBACKS; + break; + case PKI_DATATYPE_X509_XPAIR : + ret = &PKI_OPENSSL_X509_XPAIR_CALLBACKS; + break; + case PKI_DATATYPE_X509_CMS_MSG : + // TODO: Provide support for CMS + // ret = &PKI_OPENSSL_X509_CMS; + break; + case PKI_DATATYPE_EST_MSG : + // TODO: Provide support for EST + // ret = &PKI_OPENSSL_X509_CMS_CALLBACKS; + break; + case PKI_DATATYPE_SCEP_MSG : + ret = &PKI_OPENSSL_X509_PKCS7_CALLBACKS; + break; + case PKI_DATATYPE_X509_PRQP_REQ : + ret = &PKI_OPENSSL_X509_PRQP_REQ_CALLBACKS; + break; + case PKI_DATATYPE_X509_PRQP_RESP : + ret = &PKI_OPENSSL_X509_PRQP_RESP_CALLBACKS; + break; + default: + return NULL; + } + + return ret; +} diff --git a/src/crypto/hsm/openssl/openssl_hsm_obj.c b/src/crypto/hsm/openssl/openssl_hsm_obj.c new file mode 100644 index 00000000..72dae836 --- /dev/null +++ b/src/crypto/hsm/openssl/openssl_hsm_obj.c @@ -0,0 +1,22 @@ +/* openssl/pki_pkey.c */ + +#include + +/* ---------------- OpenSSL HSM Keypair get/put --------------------------- */ + +PKI_STACK * HSM_OPENSSL_OBJSK_get_url ( PKI_DATATYPE type, URL *url, + PKI_CRED *cred, void *hsm ) { + + PKI_log_debug("HSM_OPENSSL_OBJSK_get_url()::Deprecated"); + + return NULL; +} + +PKI_X509_KEYPAIR_STACK * HSM_OPENSSL_X509_KEYPAIR_get_url ( URL *url, + PKI_CRED *cred, HSM *hsm) { + + PKI_log_debug("HSM_OPENSSL_X509_KEYPAIR_get_url()::Deprecated"); + + return NULL; +} + diff --git a/src/crypto/hsm/openssl/openssl_hsm_pkey.c b/src/crypto/hsm/openssl/openssl_hsm_pkey.c new file mode 100644 index 00000000..fc1e6c54 --- /dev/null +++ b/src/crypto/hsm/openssl/openssl_hsm_pkey.c @@ -0,0 +1,1214 @@ +/* openssl/pki_pkey.c */ + +/* Internal usage only - we want to keep the lib abstract */ +#ifndef _LIBPKI_HSM_OPENSSL_PKEY_H +#define _LIBPKI_HSM_OPENSSL_PKEY_H + +#include + +PKI_RSA_KEY * _pki_rsakey_new( PKI_KEYPARAMS *kp ); +PKI_DSA_KEY * _pki_dsakey_new( PKI_KEYPARAMS *kp ); +#ifdef ENABLE_ECDSA +PKI_EC_KEY * _pki_ecdsakey_new( PKI_KEYPARAMS *kp); +#else +void * _pki_ecdsakey_new( PKI_KEYPARAMS *kp ); +#endif + +int _evp_ctx_key_generation(int pkey_type, PKI_X509_KEYPAIR_VALUE ** pkey) { + + EVP_PKEY_CTX * pctx = NULL; + // Key generation context + + // Input Checks + if (!pkey) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return PKI_ERR; + } + + if (pkey_type <= 0) { + PKI_ERROR(PKI_ERR_PARAM_RANGE, NULL); + return PKI_ERR; + } + + pctx = EVP_PKEY_CTX_new_id(pkey_type, NULL); + if (!pctx) { + PKI_DEBUG("Can not create context for key generation (%d)", pkey_type); + return PKI_ERR; + } + + if (EVP_PKEY_keygen_init(pctx) <= 0) { + PKI_DEBUG("Can not init ED448 context"); + EVP_PKEY_CTX_free(pctx); + return PKI_ERR; + } + + if (EVP_PKEY_keygen(pctx, pkey) <= 0) { + PKI_DEBUG("Can not generate ED448 key"); + EVP_PKEY_CTX_free(pctx); + return PKI_ERR; + } + + EVP_PKEY_CTX_free(pctx); + if (!*pkey) { + PKI_DEBUG("Can not generate ED448 key"); + return PKI_ERR; + } + + return PKI_OK; +} + +int _evp_ctx_key_generation_rsa(PKI_KEYPARAMS * const params, PKI_X509_KEYPAIR_VALUE ** pkey) { + + EVP_PKEY_CTX * pctx = NULL; + // Key generation context + + // Input Checks + if (!pkey || !params) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return PKI_ERR; + } + + if (params->pkey_type <= 0) { + PKI_ERROR(PKI_ERR_PARAM_RANGE, NULL); + return PKI_ERR; + } + + pctx = EVP_PKEY_CTX_new_id(params->pkey_type, NULL); + if (!pctx) { + PKI_DEBUG("Can not create context for key generation (%d)", params->pkey_type); + return PKI_ERR; + } + + // ==================== + // Set the RSA key size + // ==================== + + int bits = params->rsa.bits; + if (bits <= 0) { + if (bits <= 0) { + if (bits <= 0) bits = PKI_RSA_KEY_DEFAULT_SIZE; + } + bits = PKI_SCHEME_ID_get_bitsize(params->scheme, params->sec_bits); + } + + if (EVP_PKEY_keygen_init(pctx) <= 0) { + PKI_DEBUG("Can not init ED448 context"); + EVP_PKEY_CTX_free(pctx); + return PKI_ERR; + } + + if (EVP_PKEY_CTX_set_rsa_keygen_bits(pctx, bits) <= 0) { + PKI_DEBUG("Can not set RSA key size (%d)", bits); + EVP_PKEY_CTX_free(pctx); + return PKI_ERR; + } + params->bits = bits; + params->rsa.bits = bits; + + if (EVP_PKEY_keygen(pctx, pkey) <= 0) { + PKI_DEBUG("Can not generate ED448 key"); + EVP_PKEY_CTX_free(pctx); + return PKI_ERR; + } + + EVP_PKEY_CTX_free(pctx); + if (!*pkey) { + PKI_DEBUG("Can not generate ED448 key"); + return PKI_ERR; + } + + return PKI_OK; +} + +int _pki_rand_init( void ); + +/* End of _LIBPKI_INTERNAL_PKEY_H */ +#endif + +int _pki_rand_seed( void ) { + unsigned char seed[20]; + + if (!RAND_bytes(seed, 20)) return 0; + + RAND_seed(seed, sizeof seed); + + return(1); +} + +PKI_RSA_KEY * _pki_rsakey_new( PKI_KEYPARAMS *kp ) { + + PKI_RSA_KEY *rsa = NULL; + + int bits = PKI_RSA_KEY_DEFAULT_SIZE; + + if ( kp && kp->bits > 0 ) bits = kp->bits; + + if ( bits < PKI_RSA_KEY_MIN_SIZE ) { + PKI_DEBUG("WARNING: RSA Key size smaller than minimum safe size (%d vs. %d)", + bits, PKI_RSA_KEY_DEFAULT_SIZE); + return NULL; + } else if ( bits < PKI_RSA_KEY_DEFAULT_SIZE ) { + PKI_DEBUG("WARNING: RSA Key size smaller than default safe size (%d vs. %d)", + bits, PKI_RSA_KEY_DEFAULT_SIZE); + } + +#if OPENSSL_VERSION_NUMBER > 0x30000000L + EVP_PKEY_CTX * pkey_ctx = NULL; + EVP_PKEY * pkey = NULL; + + OSSL_LIB_CTX * ossl_libctx = PKI_init_get_ossl_library_ctx(); + + // Tries to create the context by using the key id + if ((pkey_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL)) == NULL) { + // Tries to create the context by using the name + pkey_ctx = EVP_PKEY_CTX_new_from_name(ossl_libctx, "RSA", NULL); + } + if (!pkey_ctx) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Cannot create EVP_PKEY_CTX"); + return NULL; + } + + // Initializes the key generation operation + if (EVP_PKEY_keygen_init(pkey_ctx) < 0) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Cannot init EVP_PKEY_CTX"); + EVP_PKEY_CTX_free(pkey_ctx); + return NULL; + } + + // Sets the RSA key size (parameter) + if (EVP_PKEY_CTX_set_rsa_keygen_bits(pkey_ctx, bits) < 0) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Cannot set RSA key size"); + EVP_PKEY_CTX_free(pkey_ctx); + return NULL; + } + + // Generates the new key + if (!EVP_PKEY_generate(pkey_ctx, &pkey)) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Cannot generate EVP_PKEY"); + EVP_PKEY_CTX_free(pkey_ctx); + return NULL; + } + + // Extracts the RSA key + rsa = EVP_PKEY_get1_RSA(pkey); + + // Free allocated heap memory + if (pkey) EVP_PKEY_free(pkey); + if (pkey_ctx) EVP_PKEY_CTX_free(pkey_ctx); + + if (!rsa) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Cannot extract RSA key from EVP_PKEY"); + return NULL; + } +#else + unsigned long e = RSA_F4; + // Default exponent (65537) + + BIGNUM *bne = NULL; + int ossl_rc = 0; + + if ((bne = BN_new()) != NULL) { + if (1 != BN_set_word(bne, e)) { + PKI_ERROR(PKI_ERR_GENERAL, NULL); + return NULL; + } + } else { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return NULL; + } + + if ((rsa = RSA_new()) == NULL) { + BN_free(bne); + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return NULL; + } + + if ((ossl_rc = RSA_generate_key_ex(rsa, bits, bne, NULL)) != 1 ) { + /* Error */ + BN_free(bne); + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, NULL); + return NULL; + } + + BN_free(bne); +#endif + + /* Let's return the RSA_KEY infrastructure */ + return (rsa); +}; + +PKI_DSA_KEY * _pki_dsakey_new( PKI_KEYPARAMS *kp ) { + + PKI_DSA_KEY *k = NULL; + unsigned char seed[20]; + + int bits = PKI_DSA_KEY_DEFAULT_SIZE; + + if ( kp && kp->bits > 0 ) bits = kp->bits; + + if ( bits < PKI_DSA_KEY_MIN_SIZE ) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_SIZE_SHORT, NULL); + return NULL; + }; + + if (!RAND_bytes(seed, 20)) { + /* Not enought rand ? */ + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Too low Entropy"); + return NULL; + } + + if ((k = DSA_new()) == NULL) { + // Memory Allocation Error + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Too low Entropy"); + return NULL; + } + + if (1 != DSA_generate_parameters_ex(k, bits, seed, 20, NULL, NULL, NULL)) { + if( k ) DSA_free( k ); + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Can not generated DSA params"); + return NULL; + } + + return( k ); +} + +#ifdef ENABLE_ECDSA +PKI_EC_KEY * _pki_ecdsakey_new( PKI_KEYPARAMS *kp ) { + /* ECDSA is a little more complicated than the other + schemes as it involves a group of functions. As the + purpose of this library is to provide a very hi-level + easy to use library, we will provide some hardwired + parameters. + */ + PKI_EC_KEY *k = NULL; + EC_builtin_curve *curves = NULL; + EC_GROUP *group = NULL; + size_t num_curves = 0; + int degree = 0; + + int bits = PKI_EC_KEY_DEFAULT_SIZE; + int curve = PKI_EC_KEY_CURVE_DEFAULT; + int flags = PKI_EC_KEY_ASN1_DEFAULT; + + PKI_EC_KEY_FORM form = PKI_EC_KEY_FORM_DEFAULT; + + /* Get the number of available ECDSA curves in OpenSSL */ + if ((num_curves = EC_get_builtin_curves(NULL, 0)) < 1 ) { + /* No curves available! */ + PKI_ERROR(PKI_ERR_OBJECT_CREATE, "Builtin EC curves"); + return NULL; + } + + /* Alloc the needed memory */ +#if OPENSSL_VERSION_NUMBER < 0x1010000fL + curves = OPENSSL_malloc((int)(sizeof(EC_builtin_curve) * num_curves)); +#else + curves = OPENSSL_malloc(sizeof(EC_builtin_curve) * num_curves); +#endif + + /* Check for memory allocation */ + if (curves == NULL) return NULL; + + /* Get the builtin curves */ + if (!EC_get_builtin_curves(curves, (size_t) num_curves)) + { + PKI_ERROR(PKI_ERR_OBJECT_CREATE, "Can not get builtin EC curves (%d)", num_curves); + goto err; + return NULL; + } + + /* We completely change behavior - we adopt one of the two + * curves suggested by NIST. In particular: + * - NID_secp384r1 + * - NID_secp521r1 + * For today (2008) usage, the first curve + SHA256 seems to be + * the best approach + */ + + if( kp && kp->bits > 0 ) { + bits = kp->bits; + }; + + if(bits < PKI_EC_KEY_MIN_SIZE ){ + PKI_ERROR(PKI_ERR_X509_KEYPAIR_SIZE_SHORT, "%d", bits); + return NULL; + }; + + if( kp && kp->ec.curve > 0 ) { + curve = kp->ec.curve; + } else { + if( bits <= 112 ) { + bits = 112; + curve = NID_secp112r1; + } else if( bits <= 128 ) { + bits = 128; + curve = NID_secp128r1; + } else if( bits <= 160 ) { + bits = 160; + curve = NID_secp160r1; + } else if( bits <= 192 ) { + bits = 192; + curve = NID_X9_62_prime192v1; + } else if( bits <= 224 ) { + bits = 224; + curve = NID_secp224r1; + } else if( bits <= 256 ) { + bits = 256; + curve = NID_X9_62_prime256v1; + } else if( bits <= 384 ) { + bits = 384; + curve = NID_secp384r1; + } else { + bits = 512; + curve = NID_secp521r1; + }; + }; + + /* Initialize the key */ + if ((k = EC_KEY_new()) == NULL) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, NULL); + goto err; + return NULL; + } + + if((group = EC_GROUP_new_by_curve_name(curve)) == NULL ) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Invalid Curve - %d", curve); + goto err; + return NULL; + }; + + EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); + EC_GROUP_set_point_conversion_form(group, form); + + /* Assign the group to the key */ + if (EC_KEY_set_group(k, group) == 0) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Invalid Group"); + goto err; + return NULL; + } + + /* Sets the point compression */ + if ( kp && kp->ec.form != PKI_EC_KEY_FORM_UNKNOWN ) { + form = kp->ec.form; + }; + EC_KEY_set_conv_form(k, (point_conversion_form_t)form); + + /* Sets the type of parameters, flags > 0 ==> by OID, + * flags == 0 ==> specifiedCurve + */ + if ( kp->ec.asn1flags > -1 ) { + flags = kp->ec.asn1flags; + }; + EC_KEY_set_asn1_flag(k, flags); + + /* We do not need it now, let's free the group */ + if ( group ) EC_GROUP_free( group ); + group = NULL; + + if((group = (EC_GROUP *) EC_KEY_get0_group(k)) != NULL ) { + EC_GROUP_set_asn1_flag( group, OPENSSL_EC_NAMED_CURVE ); + }; + + degree = EC_GROUP_get_degree(EC_KEY_get0_group(k)); + + if( degree < bits ) { + /* Fix the problem, let's get the right bits */ + bits = degree; + } + + // // Let's cycle through all the available curves + // // until we find one that matches (if any) + // i = (i + 1 ) % num_curves; + // + // } while ( (degree < bits ) && (i != n_start) ); + + /* Now generate the key */ + if (!EC_KEY_generate_key(k)) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, NULL ); + goto err; + return NULL; + } + + /* Verify the Key to be ok */ + if (!EC_KEY_check_key(k)) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Verify failed for ECDSA key" ); + goto err; + return NULL; + } + + // EC_KEY_set_enc_flags(k, EC_PKEY_NO_PARAMETERS); + // ecKeyPnt = (struct __ec_key_st2 *) k; + // ecKeyPnt->version = 1; + + goto end; + +err: + if( curves ) free ( curves ); + if ( group ) EC_GROUP_free( group ); + + if( k ) { + EC_KEY_free ( k ); + k = NULL; + }; + +end: + return ( k ); +} + +#else /* EVP_PKEY_EC */ + +void * _pki_ecdsakey_new( PKI_KEYPARAMS *kp ) { + PKI_ERROR(PKI_ERR_NOT_IMPLEMENTED, NULL); + return ( NULL ); +} + +#endif + +#if defined(ENABLE_OQS) || defined(ENABLE_OQSPROV) + +EVP_PKEY_CTX * _pki_get_evp_pkey_ctx(PKI_KEYPARAMS *kp) { + + EVP_PKEY_CTX *ctx = NULL; + // Key generation context to be returned + + // Input Checks + if (!kp) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return NULL; + } + + // Checks we have an algorithm Identifier + if (!kp->oqs.algId) { + PKI_DEBUG("Missing algorithm ID for OQS key generation"); + return NULL; + } + +#ifdef ENABLE_OQS + + const EVP_PKEY_ASN1_METHOD *ameth; + // ASN1 Method + + ENGINE *tmpeng = NULL; + // Temporary Engine + + int pkey_id = -1; + // PKEY ID + + // TODO: + // ===== + // + // This mechanism does not seem to be working for Kyber + // we need to update the mechanism to include Kyber and other + // algorithms. + + if ((ameth = EVP_PKEY_asn1_find(&tmpeng, kp->oqs.algId)) != NULL) { + ERR_clear_error(); + EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth); + + PKI_DEBUG("Ameth = %d, AlgId = %d", pkey_id, kp->oqs.algId); + + } else { + + PKI_log_debug("Missing ASN1 Method for algorithm '%s', using the KeyId (%d).", + PKI_ALGOR_ID_txt(kp->oqs.algId), kp->oqs.algId); + pkey_id = kp->oqs.algId; + + } + + // Generates the new context + if ((ctx = EVP_PKEY_CTX_new_id(pkey_id, NULL)) == NULL) goto err; + +#else + OSSL_LIB_CTX * libctx = PKI_init_get_ossl_library_ctx(); + // OpenSSL Library Context + + // Gets the name of the algorithm + const char * sigalg_name = PKI_ID_get_txt(kp->oqs.algId); + if (!sigalg_name) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Cannot get algorithm name"); + goto err; + } + + // Generates the new context + ctx = EVP_PKEY_CTX_new_from_name(libctx, sigalg_name, NULL); + if (!ctx) { + PKI_DEBUG("Cannot create the pkey context for algorithm '%s'", sigalg_name); + goto err; + } + +#endif + + // Let's set the operation (check EVP_PKEY_CTX_ctrl function -pmeth_lib.c:432) + // Use the EVP interface to initialize the operation (crypto/evp/pmeth_gn.c:69) + if (EVP_PKEY_keygen_init(ctx) <= 0) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Cannot Initialize Key Generation"); + goto err; + } + +#ifdef ENABLE_COMPOSITE + + // CTX operations for Composite Crypto + // + // EVP_PKEY_CTRL_COMPOSITE_PUSH + // EVP_PKEY_CTRL_COMPOSITE_POP + // EVP_PKEY_CTRL_COMPOSITE_ADD + // EVP_PKEY_CTRL_COMPOSITE_DEL + // EVP_PKEY_CTRL_COMPOSITE_CLEAR + +#ifdef ENABLE_COMBINED + if ((kp->scheme == PKI_SCHEME_COMPOSITE || + kp->scheme == PKI_SCHEME_COMBINED) + && kp->comp.k_stack != NULL) { +#else + if (kp->scheme == PKI_SCHEME_COMPOSITE + && kp->comp.k_stack != NULL) { +#endif + for (int i = 0; i < PKI_STACK_X509_KEYPAIR_elements(kp->comp.k_stack); i++) { + + PKI_X509_KEYPAIR * tmp_key = NULL; + + // Let's get the i-th PKI_X509_KEYPAIR + tmp_key = PKI_STACK_X509_KEYPAIR_get_num(kp->comp.k_stack, i); + // Now we can use the CRTL interface to pass the new keys + if (EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_COMPOSITE_PUSH, 0, tmp_key->value) <= 0) { + PKI_log_debug("Cannot add key via the CTRL interface"); + goto err; + } + } + } +#endif + + return ctx; + + err: + + PKI_log_debug("Error initializing context for [scheme: %d, algId: %d]\n", + kp->scheme, kp->oqs.algId); + + if (ctx) EVP_PKEY_CTX_free(ctx); + return NULL; +} + +#endif + +#ifdef ENABLE_COMPOSITE +PKI_COMPOSITE_KEY * _pki_composite_new( PKI_KEYPARAMS *kp ) { + + PKI_COMPOSITE_KEY *k = NULL; + const char * scheme_name = PKI_SCHEME_ID_get_parsed(kp->scheme); + if (!scheme_name) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Unknown Scheme"); + return NULL; + } + + if ((k = COMPOSITE_KEY_new()) == NULL) { + // Memory Allocation Error + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return NULL; + } + + int pkey_type = kp->pkey_type; // PKI_ID_get_by_name(PKI_SCHEME_ID_get_parsed(kp->scheme)); + if (pkey_type <= 0) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Unknown Algorithm"); + COMPOSITE_KEY_free(k); + return NULL; + } + + // Let's set the algorithm + k->algorithm = pkey_type; + + PKI_DEBUG("Creating a Composite Key"); + PKI_DEBUG("Scheme: %d (%s)", kp->scheme, PKI_SCHEME_ID_get_parsed(kp->scheme)); + PKI_DEBUG("Pkey Type: %d (%s)", pkey_type, OBJ_nid2sn(pkey_type)); + + // if (PKI_SCHEME_ID_is_explicit_composite(kp->scheme)) { + // PKI_DEBUG("Explicit Composite Key"); + // k->algorithm = pkey_type; + // } else if (PKI_SCHEME_ID_is_composite(kp->scheme)) { + // PKI_DEBUG("Gemeric Composite Key"); + // k->algorithm = pkey_type; + // } else if (PKI_SCHEME_ID_is_post_quantum(kp->scheme)) { + // PKI_DEBUG("Unknown Composite Key"); + // k->algorithm = kp->oqs.algId; + // } + + if (kp->comp.k_stack != NULL) { + + // // Clears current components (if any) + // if (k->components) COMPOSITE_KEY_clear(k); + + // // Transfers the ownership of the stack to the composite key + // k->components = kp->comp.k_stack; + + // // Let's replace the stack in the keyparams with a new one + // if ((kp->comp.k_stack = PKI_STACK_X509_KEYPAIR_new()) == NULL) { + // PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + // } + + for (int i = 0; i < PKI_STACK_X509_KEYPAIR_elements(kp->comp.k_stack); i++) { + + PKI_X509_KEYPAIR * tmp_key = NULL; + PKI_X509_KEYPAIR_VALUE * tmp_val = NULL; + + // Let's get the i-th PKI_X509_KEYPAIR + tmp_key = PKI_STACK_X509_KEYPAIR_get_num(kp->comp.k_stack, i); + if (!tmp_key) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Cannot get key from stack"); + COMPOSITE_KEY_free(k); + return NULL; + } + + // Let's get the internal value + PKI_X509_detach(tmp_key, (void **)&tmp_val, NULL, NULL); + if (!tmp_val) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Cannot get key value"); + COMPOSITE_KEY_free(k); + return NULL; + } + tmp_key->value = NULL; + + // // Free the memory associated with the PKI_X509_KEYPAIR + // PKI_X509_KEYPAIR_free(tmp_key); + tmp_key = NULL; + + // Pushes the Key onto the stack + // COMPOSITE_KEY_push(k, tmp_key->value); + if (PKI_ERR == COMPOSITE_KEY_push(k, tmp_val)) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Cannot push key onto stack"); + COMPOSITE_KEY_free(k); + return NULL; + } + + // // Now we can use the CRTL interface to pass the new keys + // if (EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_KEYGEN, + // EVP_PKEY_CTRL_COMPOSITE_PUSH, 0, tmp_key->value) <= 0) { + // PKI_log_debug("Cannot add key via the CTRL interface"); + // goto err; + // } + } + } + + // kp->comp.k_stack = NULL; + + // Adds the Parameter (k-of-n) to the key + if (kp->comp.k_of_n != NULL) { + if (k->params) ASN1_INTEGER_free(k->params); + k->params = ASN1_INTEGER_dup(kp->comp.k_of_n); + } + + // All Done. + return k; +} +#endif + +PKI_X509_KEYPAIR *HSM_OPENSSL_X509_KEYPAIR_new(PKI_KEYPARAMS * kp, + URL * url, + PKI_CRED * cred, + HSM * driver ) { + + PKI_X509_KEYPAIR *ret = NULL; + PKI_X509_KEYPAIR_VALUE * value = NULL; + // PKI_RSA_KEY *rsa = NULL; + PKI_DSA_KEY *dsa = NULL; + +#ifdef ENABLE_ECDSA + PKI_EC_KEY *ec = NULL; +#endif + +#if defined(ENABLE_OQS) || defined(ENABLE_OQSPROV) + EVP_PKEY_CTX * ctx = NULL; +#endif + +#ifdef ENABLE_COMPOSITE + COMPOSITE_KEY * composite = NULL; +#endif + +#ifdef ENABLE_COMBINED + EVP_PKEY_COMBINED * combined = NULL; +#endif + + PKI_SCHEME_ID type = PKI_SCHEME_DEFAULT; + + if (!kp) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return NULL; + } + + if ( kp && kp->scheme != PKI_SCHEME_UNKNOWN ) type = kp->scheme; + + // if ((ret = PKI_X509_new(PKI_DATATYPE_X509_KEYPAIR, driver)) == NULL) { + // PKI_ERROR(PKI_ERR_OBJECT_CREATE, "KeyPair"); + // return NULL; + // } + + // if((ret->value = (PKI_X509_KEYPAIR_VALUE *) EVP_PKEY_new()) == NULL ) { + // PKI_ERROR(PKI_ERR_OBJECT_CREATE, "KeyPair Value"); + // return NULL; + // } + + if( _pki_rand_seed() == 0 ) { + /* Probably low level of randomization available */ + PKI_log_debug("WARNING, low rand available!"); + } + + switch (type) { + +#ifdef ENABLE_ED448 + case PKI_SCHEME_ED448: { + int success = _evp_ctx_key_generation(PKI_ALGOR_ID_ED448, &value); + if (!success) { + PKI_DEBUG("Cannot generate the ED448 key"); + goto err; + } + } break; +#endif + +#ifdef ENABLE_X448 + case PKI_SCHEME_X448: { + int success = _evp_ctx_key_generation(PKI_ALGOR_ID_X448, &value); + if (!success) { + PKI_DEBUG("Cannot generate the X448 key"); + goto err; + } + } break; +#endif + +#ifdef ENABLE_ED25519 + case PKI_SCHEME_ED25519: { + int success = _evp_ctx_key_generation(PKI_ALGOR_ID_ED25519, &value); + if (!success) { + PKI_DEBUG("Cannot generate the ED448 key"); + goto err; + } + } break; +#endif + +#ifdef ENABLE_X25519 + case PKI_SCHEME_X25519: { + int success = _evp_ctx_key_generation(PKI_ALGOR_ID_X25519, &value); + if (!success) { + PKI_DEBUG("Cannot generate the ED448 key"); + goto err; + } + } break; +#endif + + case PKI_SCHEME_RSAPSS: + case PKI_SCHEME_RSA: { + // if ((rsa = _pki_rsakey_new( kp )) == NULL ) { + // PKI_DEBUG("Cannot generate the RSA key"); + // goto err; + // } + // if (!EVP_PKEY_assign_RSA((EVP_PKEY *) value, rsa)) { + // PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Can not assign RSA key"); + // if( rsa ) RSA_free( rsa ); + // goto err; + // } + int success = _evp_ctx_key_generation_rsa(kp, &value); + if (!success) { + PKI_DEBUG("Cannot generate the RSA key"); + goto err; + } + } break; + + case PKI_SCHEME_DSA: { + if ((dsa = _pki_dsakey_new( kp )) == NULL ) { + PKI_DEBUG("Cannot generate the DSA key"); + goto err; + } + if (!DSA_generate_key( dsa )) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, NULL); + goto err; + } + if ((value = (PKI_X509_KEYPAIR_VALUE *) EVP_PKEY_new()) == NULL ) { + PKI_ERROR(PKI_ERR_OBJECT_CREATE, "KeyPair Value"); + return NULL; + } + if (!EVP_PKEY_assign_DSA(value, dsa)) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Can not assign DSA key"); + if( dsa ) DSA_free ( dsa ); + goto err; + } + dsa=NULL; + } break; + +#ifdef ENABLE_ECDSA + + case PKI_SCHEME_ECDSA: { + if ((ec = _pki_ecdsakey_new( kp )) == NULL ) { + PKI_DEBUG("Cannot generate the ECDSA key"); + goto err; + } + if ((value = (PKI_X509_KEYPAIR_VALUE *) EVP_PKEY_new()) == NULL ) { + PKI_ERROR(PKI_ERR_OBJECT_CREATE, "KeyPair Value"); + return NULL; + } + if (!EVP_PKEY_assign_EC_KEY(value, ec)){ + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Can not assign ECDSA key"); + if( ec ) EC_KEY_free ( ec ); + goto err; + } + } break; + +#ifdef ENABLE_COMPOSITE + + // Generic Composite + case PKI_SCHEME_COMPOSITE: + // Explicit Composite + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_RSA: + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_P256: + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_BRAINPOOL256: + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_ED25519: + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_P384: + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_BRAINPOOL384: + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_ED448: + case PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_P256: + case PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_BRAINPOOL256: + case PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_ED25519: + case PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_RSA: + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_FALCON1024_P521: + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_FALCON1024_RSA: { + + if ((composite = _pki_composite_new(kp)) == NULL) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Can not initiate keypair generation"); + goto err; + } + if ((value = (PKI_X509_KEYPAIR_VALUE *) EVP_PKEY_new()) == NULL ) { + PKI_ERROR(PKI_ERR_OBJECT_CREATE, "KeyPair Value"); + return NULL; + } + if (!EVP_PKEY_assign_COMPOSITE(value, composite)) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Can not assign COMPOSITE key"); + if (composite) COMPOSITE_KEY_free(composite); + goto err; + } + } break; +#endif + +#ifdef ENABLE_COMBINED + case PKI_SCHEME_COMBINED: + if ((combined = _pki_combined_new(kp)) == NULL) { + if (ret) HSM_OPENSSL_X509_KEYPAIR_free(ret); + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Can not initiate keypair generation"); + return NULL; + }; + if ((value = (PKI_X509_KEYPAIR_VALUE *) EVP_PKEY_new()) == NULL ) { + PKI_ERROR(PKI_ERR_OBJECT_CREATE, "KeyPair Value"); + return NULL; + } + if (!EVP_PKEY_assign_COMBINED(value, combined)) { + if (ret) HSM_OPENSSL_X509_KEYPAIR_free(ret); + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Can not assign COMBINED key"); + if (combined) COMBINED_KEY_free(combined); + return NULL; + } + combined=NULL; + break; +#endif + +#endif // ENABLE_ECDSA + + default: + +#if defined(ENABLE_OQS) || defined(ENABLE_OQSPROV) + if ((ctx = _pki_get_evp_pkey_ctx(kp)) == NULL) { + PKI_DEBUG("Cannot generate the PQC key"); + goto err; + } + if (EVP_PKEY_keygen(ctx, &value) <= 0) { + if (ctx) EVP_PKEY_CTX_free(ctx); + goto err; + } + EVP_PKEY_CTX_free(ctx); + ctx = NULL; + +#else + /* No recognized scheme */ + PKI_ERROR(PKI_ERR_HSM_SCHEME_UNSUPPORTED, "%d", type ); + goto err; + +#endif // ENABLE_OQS || ENABLE_OQSPROV + + } + + // Checks that a Key was generated + if (!value) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Can not generate keypair"); + goto err; + } + + // Allocates the PKI_X509_KEYPAIR structure + if ((ret = PKI_X509_new(PKI_DATATYPE_X509_KEYPAIR, driver)) == NULL) { + PKI_ERROR(PKI_ERR_OBJECT_CREATE, "KeyPair"); + return NULL; + } + + /* Sets the value in the PKI_X509_KEYPAIR structure */ + if (PKI_ERR == PKI_X509_attach(ret, PKI_DATATYPE_X509_KEYPAIR, value, driver)) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Can not attach keypair"); + goto err; + } + + // Sets the requirement for the digest in the key + if (PKI_SCHEME_ID_requires_digest(type)) { + ret->signature_digest_required = 1; + } + + /* Let's return the PKEY infrastructure */ + return ret; + +err: + + // Memory Cleanup + if (value) EVP_PKEY_free(value); + if (ret) PKI_X509_KEYPAIR_free(ret); + +#if defined(ENABLE_OQS) || defined(ENABLE_OQSPROV) + if (ctx) EVP_PKEY_CTX_free(ctx); +#endif // ENABLE_OQS || ENABLE_OQSPROV + + // Error + return NULL; +} + +/* Key Free function */ +void HSM_OPENSSL_X509_KEYPAIR_free ( PKI_X509_KEYPAIR *pkey ) { + + if( !pkey) return; + + PKI_X509_free ( pkey ); + + return; +} + +// OpenSSL Fix +// When writing PEM formatted Keys the wrong version "0" is +// used by the default EVP_PKEY_ write functions for EC keys, +// we have to provide our own function until OpenSSL solve +// this issue + +int OPENSSL_HSM_write_bio_PrivateKey (BIO * bp, + EVP_PKEY * x, + const EVP_CIPHER * enc, + unsigned char * out_buffer, + int klen, + pem_password_cb * cb, + void * u) { + + int ret = PKI_ERR; + // Return value + + // Input Check + if (!x || !bp) return PKI_ERR; + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + // Let's get the scheme of the key + PKI_SCHEME_ID pkey_scheme = PKI_X509_KEYPAIR_VALUE_get_scheme(x); + if (!pkey_scheme) { + PKI_DEBUG("ERROR, can not get the scheme of key (key id: %d)", + PKI_X509_KEYPAIR_VALUE_get_id(x)); + return PKI_ERR; + } + // Let's get the type of the key + int pkey_type = PKI_ID_UNKNOWN; + switch (pkey_scheme) { + +#ifdef ENABLE_ECDSA + + // EC + case PKI_SCHEME_ED25519: { + pkey_type = EVP_PKEY_ED25519; + } break; + + case PKI_SCHEME_X25519: { + pkey_type = EVP_PKEY_X25519; + } break; + + case PKI_SCHEME_ED448: { + pkey_type = EVP_PKEY_ED448; + } break; + + case PKI_SCHEME_X448: { + pkey_type = EVP_PKEY_X448; + } break; + + case PKI_SCHEME_ECDSA: { + pkey_type = EVP_PKEY_EC; + } break; + +#endif // End of ENABLE_ECDSA + + default: { + // Nothing to do here + pkey_type = PKI_X509_KEYPAIR_VALUE_get_id(x); + } break; + } +#else // OpenSSL 1.1.1 + // Let's get the type of key + int pkey_type = EVP_PKEY_type(PKI_X509_KEYPAIR_VALUE_get_id(x)); +#endif // End of OPENSSL_VERSION_NUMBER >= 0x30000000L + + + // Different functions depending on the Key type + switch(pkey_type) + { + +#ifdef ENABLE_ECDSA + case EVP_PKEY_EC: { +# if OPENSSL_VERSION_NUMBER >= 0x30000000L + ret = PEM_write_bio_ECPrivateKey(bp, + EVP_PKEY_get0_EC_KEY(x), enc, (unsigned char *) out_buffer, klen, cb, u); +# elif OPENSSL_VERSION_NUMBER < 0x1010000fL + ret = PEM_write_bio_ECPrivateKey(bp, + x->pkey.ec, enc, (unsigned char *) out_buffer, klen, cb, u); +# else + ret = PEM_write_bio_ECPrivateKey(bp, + EVP_PKEY_get0_EC_KEY(x), enc, (unsigned char *) out_buffer, klen, cb, u); +# endif + if (!ret) { + PKI_DEBUG("Internal Error while encoding EC Key (PEM)."); + return PKI_ERR; + } + } break; +#endif + + default: { + if ((ret = PEM_write_bio_PKCS8PrivateKey(bp, x, enc, + (char *) out_buffer, klen, cb, u)) != 1) { + // Debug Info + PKI_DEBUG("Key Type NOT supported (%d)", pkey_type); + // Error Condition + return PKI_ERR; + } + } + } + + // All Done + return ret; +} + +// OpenSSL Fix +// +// Strangely enough OpenSSL does not provide an EVP_PKEY_dup() +// function, we supply it + +EVP_PKEY *OPENSSL_HSM_KEYPAIR_dup(EVP_PKEY *kVal) +{ + EVP_PKEY *ret = NULL; + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + + ret = EVP_PKEY_dup(kVal); + +#else + + int pkey_type = PKI_X509_KEYPAIR_VALUE_get_id(kVal); + if(!kVal) return NULL; + + if ((ret = EVP_PKEY_new()) == NULL) return NULL; + + if (!EVP_PKEY_copy_parameters(ret, kVal)) return NULL; + + switch (pkey_type) + { + + case EVP_PKEY_RSA: { + RSA *rsa = NULL; +// #if OPENSSL_VERSION_NUMBER >= 0x30000000L +// if (((rsa = EVP_PKEY_get1_RSA(kVal)) == NULL) || +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + if (((rsa = EVP_PKEY_get0_RSA(kVal)) == NULL) || +#else + if (((rsa = (RSA *)EVP_PKEY_get0(kVal)) == NULL) || +#endif + (!EVP_PKEY_set1_RSA(ret, rsa))) { + PKI_DEBUG("ERROR, can not duplicate the RSA key"); + return NULL; + } + } break; + + case EVP_PKEY_DH: { + DH *dh = NULL; +// #if OPENSSL_VERSION_NUMBER >= 0x30000000L +// if ( ((dh = EVP_PKEY_get1_DH(kVal)) == NULL) || +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + if ( ((dh = EVP_PKEY_get0_DH(kVal)) == NULL) || +#else + if ( ((dh = (DH *)EVP_PKEY_get0(kVal)) == NULL) || +#endif + (!EVP_PKEY_set1_DH(ret, dh))) { + PKI_DEBUG("ERROR, can not duplicate the DH key"); + return NULL; + } + } break; + +#ifdef ENABLE_ECDSA + case EVP_PKEY_EC: { + EC_KEY * ec = NULL; +// #if OPENSSL_VERSION_NUMBER >= 0x30000000L +// if (((ec = EVP_PKEY_get1_EC_KEY(kVal)) == NULL) || +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + if (((ec = EVP_PKEY_get0_EC_KEY(kVal)) == NULL) || +#else + if (((ec = (EC_KEY *)EVP_PKEY_get0(kVal)) == NULL) || +#endif + (!EVP_PKEY_set1_EC_KEY(ret, ec))) { + PKI_DEBUG("ERROR, can not duplicate the ECDSA key"); + return NULL; + } + } break; +#endif + +#ifdef ENABLE_DSA + case EVP_PKEY_DSA: { + DSA *dsa = NULL; +// #if OPENSSL_VERSION_NUMBER >= 0x30000000L +// if ( ((dsa = EVP_PKEY_get1_DSA(kVal)) == NULL) || +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + if ( ((dsa = EVP_PKEY_get0_DSA(kVal)) == NULL) || +#else + if ( ((dsa = (DSA *)EVP_PKEY_get0(kVal)) == NULL) || +#endif + (!EVP_PKEY_set1_DSA(ret, dsa))) { + PKI_DEBUG("ERROR, can not duplicate the DSA key"); + return NULL; + } + } break; +#endif + + default: { + PKI_MEM * mem = PKI_X509_KEYPAIR_VALUE_get_p8(kVal); + if (!mem) { + PKI_DEBUG("ERROR, can not serialize the key to PKCS8 format."); + return NULL; + } + + // Free the memory associated with the PKI_X509_KEYPAIR + if (ret) EVP_PKEY_free(ret); + + // Let's create a new PKI_X509_KEYPAIR from the PKCS8 data + ret = PKI_X509_KEYPAIR_VALUE_new_p8(mem); + if (!ret) { + PKI_DEBUG("ERROR, can not deserialize the key from PKCS8 format."); + return NULL; + } + + // Returns the newly allocated key + return ret; + + } break; + } + + // Update the reference for the PKEY + if (!EVP_PKEY_up_ref(kVal)) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Cannot update PKEY references"); + return NULL; + } +#endif + + + // All Done + return ret; +}; + diff --git a/src/crypto/hsm/pkcs11/Makefile.am b/src/crypto/hsm/pkcs11/Makefile.am new file mode 100644 index 00000000..05e6acd1 --- /dev/null +++ b/src/crypto/hsm/pkcs11/Makefile.am @@ -0,0 +1,45 @@ +## OpenCA Makefile - by Massimiliano Pala +## (c) 1999-2007 by Massimiliano Pala and OpenCA Project +## All Rights Reserved + +TOP = ../.. +include $(TOP)/global-vars + +BASE_DEFS = + +DEFS = $(OPENCA_DEFS) + +AM_CPPFLAGS = -I$(TOP) \ + $(pkcs11_cflags) \ + $(libxml2_cflags) \ + $(COND_INCLUDES) + +SRCS = \ + pkcs11_hsm.c \ + pkcs11_hsm_pkey.c \ + pkcs11_hsm_obj.c \ + utils/pkcs11_init.c + +## pkcs11_hsm_pkey.c \ +## pkcs11_hsm_engine.c +## pkcs11_hsm_sign.c \ + +# noinst_LTLIBRARIES = libpki-token.la +noinst_LTLIBRARIES = libpki-token-pkcs11.la + +libpki_token_pkcs11_la_SOURCES = $(SRCS) + +libpki_token_pkcs11_la_CFLAGS = $(BUILD_LIBPKI_CFLAGS) + +# libpki_token_pkcs11_la_LIBADD = $(BUILD_LIBPKI_LDFLAGS) + +# libpki_token_a_LDFLAGS = -version-info 1:0:0 + +# $(OPENCA_INCLUDE_LIBS) \ +# $(pkcs11_cflags) $(pkcs11_libs) + +#pki_token_a_LIBADD = \ +# $(pkcs11_cflags) $(pkcs11_libs) \ +# $(libxml2_cflags) $(libxml2_libs) \ +# $(OPENCA_INCLUDE_LIBS) + diff --git a/src/crypto/hsm/pkcs11/Makefile.in b/src/crypto/hsm/pkcs11/Makefile.in new file mode 100644 index 00000000..32117417 --- /dev/null +++ b/src/crypto/hsm/pkcs11/Makefile.in @@ -0,0 +1,823 @@ +# Makefile.in generated by automake 1.16.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = src/drivers/pkcs11 +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(SHELL) $(top_srcdir)/build/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/src/libpki/config.h \ + $(top_builddir)/src/libpki/libpki_enables.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +libpki_token_pkcs11_la_LIBADD = +am__dirstamp = $(am__leading_dot)dirstamp +am__objects_1 = libpki_token_pkcs11_la-pkcs11_hsm.lo \ + libpki_token_pkcs11_la-pkcs11_hsm_pkey.lo \ + libpki_token_pkcs11_la-pkcs11_hsm_obj.lo \ + utils/libpki_token_pkcs11_la-pkcs11_init.lo +am_libpki_token_pkcs11_la_OBJECTS = $(am__objects_1) +libpki_token_pkcs11_la_OBJECTS = $(am_libpki_token_pkcs11_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libpki_token_pkcs11_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(libpki_token_pkcs11_la_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src/libpki +depcomp = $(SHELL) $(top_srcdir)/build/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = \ + ./$(DEPDIR)/libpki_token_pkcs11_la-pkcs11_hsm.Plo \ + ./$(DEPDIR)/libpki_token_pkcs11_la-pkcs11_hsm_obj.Plo \ + ./$(DEPDIR)/libpki_token_pkcs11_la-pkcs11_hsm_pkey.Plo \ + utils/$(DEPDIR)/libpki_token_pkcs11_la-pkcs11_init.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libpki_token_pkcs11_la_SOURCES) +DIST_SOURCES = $(libpki_token_pkcs11_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/build/depcomp \ + $(top_srcdir)/build/mkinstalldirs +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_DATE = @BUILD_DATE@ +BUILD_DATE_FULL = @BUILD_DATE_FULL@ +BUILD_DATE_PRETTY = @BUILD_DATE_PRETTY@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CHMOD = @CHMOD@ +CHOWN = @CHOWN@ +CP = @CP@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CPU = @CPU@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CXX = @CXX@ +CYGPATH_W = @CYGPATH_W@ +DATE = @DATE@ +DEFS = $(OPENCA_DEFS) +DEPDIR = @DEPDIR@ +DESTDIR = @DESTDIR@ +DIST_NAME = @DIST_NAME@ +DIST_VERSION = @DIST_VERSION@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +GZIP = @GZIP@ +HAS_PKGCONF = @HAS_PKGCONF@ +INSTALL = @INSTALL@ +INSTALL_BUILDER = @INSTALL_BUILDER@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKE = @MAKE@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR = @MKDIR@ +MKDIR_P = @MKDIR_P@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PDFLATEX = @PDFLATEX@ +PERL = @PERL@ +PG_CONFIG = @PG_CONFIG@ +PG_CPPFLAGS = @PG_CPPFLAGS@ +PKGMK = @PKGMK@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POD2MAN = @POD2MAN@ +PWD = @PWD@ +RANLIB = @RANLIB@ +RC = @RC@ +RPM = @RPM@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TAR = @TAR@ +TODAY = @TODAY@ +VERSION = @VERSION@ +ZIP = @ZIP@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_aux_dir = @ac_aux_dir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +arch_target = @arch_target@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +composite_cflags = @composite_cflags@ +composite_ldadd = @composite_ldadd@ +composite_ldflags = @composite_ldflags@ +conf_dir = @conf_dir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +day = @day@ +dist_group = @dist_group@ +dist_user = @dist_user@ +docdir = @docdir@ +dvidir = @dvidir@ +enable_debug = @enable_debug@ +etc_dir = @etc_dir@ +exec_prefix = @exec_prefix@ +extra_checks = @extra_checks@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +hr = @hr@ +htmldir = @htmldir@ +iface_age = @iface_age@ +iface_current = @iface_current@ +iface_revision = @iface_revision@ +iface_version = @iface_version@ +include_dir = @include_dir@ +include_prefix = @include_prefix@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +kmf_cflags = @kmf_cflags@ +kmf_ldadd = @kmf_ldadd@ +kmf_libflags = @kmf_libflags@ +kmf_prefix = @kmf_prefix@ +ldap_cflags = @ldap_cflags@ +ldap_ldadd = @ldap_ldadd@ +ldap_ldflags = @ldap_ldflags@ +ldap_prefix = @ldap_prefix@ +ldap_vendor = @ldap_vendor@ +lib_major = @lib_major@ +lib_micro = @lib_micro@ +lib_minor = @lib_minor@ +lib_prefix = @lib_prefix@ +lib_revision = @lib_revision@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libpki_cflags = @libpki_cflags@ +libpki_ldadd = @libpki_ldadd@ +libpki_ldflags = @libpki_ldflags@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +min = @min@ +mkdir_p = @mkdir_p@ +mon = @mon@ +my_cflags = @my_cflags@ +my_ldadd = @my_ldadd@ +my_ldflags = @my_ldflags@ +myarch = @myarch@ +mybits = @mybits@ +mybits_install = @mybits_install@ +mysql_cflags = @mysql_cflags@ +mysql_config = @mysql_config@ +mysql_ldadd = @mysql_ldadd@ +mysql_ldflags = @mysql_ldflags@ +mysql_prefix = @mysql_prefix@ +oldincludedir = @oldincludedir@ +openssl_cflags = @openssl_cflags@ +openssl_include = @openssl_include@ +openssl_ldadd = @openssl_ldadd@ +openssl_ldflags = @openssl_ldflags@ +openssl_prefix = @openssl_prefix@ +openssl_static_libs = @openssl_static_libs@ +oqs_cflags = @oqs_cflags@ +oqs_ldadd = @oqs_ldadd@ +oqs_ldflags = @oqs_ldflags@ +oqsprov_cflags = @oqsprov_cflags@ +oqsprov_ldadd = @oqsprov_ldadd@ +oqsprov_ldflags = @oqsprov_ldflags@ +package_build = @package_build@ +package_prefix = @package_prefix@ +pdfdir = @pdfdir@ +pg_cflags = @pg_cflags@ +pg_config = @pg_config@ +pg_ldadd = @pg_ldadd@ +pg_ldflags = @pg_ldflags@ +pg_prefix = @pg_prefix@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pthread_opts = @pthread_opts@ +resolv_ldadd = @resolv_ldadd@ +rpath = @rpath@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sdkver = @sdkver@ +sec = @sec@ +sharedstatedir = @sharedstatedir@ +shlext = @shlext@ +shlib_history = @shlib_history@ +shlib_version = @shlib_version@ +srcdir = @srcdir@ +sys_cflags = @sys_cflags@ +sys_ldadd = @sys_ldadd@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +test_libs = @test_libs@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +txt_revision = @txt_revision@ +xml2_cflags = @xml2_cflags@ +xml2_config = @xml2_config@ +xml2_include = @xml2_include@ +xml2_ldadd = @xml2_ldadd@ +xml2_ldflags = @xml2_ldflags@ +xml2_prefix = @xml2_prefix@ +yr = @yr@ +TOP = ../.. +BASE_DEFS = +AM_CPPFLAGS = -I$(TOP) \ + $(pkcs11_cflags) \ + $(libxml2_cflags) \ + $(COND_INCLUDES) + +SRCS = \ + pkcs11_hsm.c \ + pkcs11_hsm_pkey.c \ + pkcs11_hsm_obj.c \ + utils/pkcs11_init.c + + +# noinst_LTLIBRARIES = libpki-token.la +noinst_LTLIBRARIES = libpki-token-pkcs11.la +libpki_token_pkcs11_la_SOURCES = $(SRCS) +libpki_token_pkcs11_la_CFLAGS = $(BUILD_LIBPKI_CFLAGS) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/drivers/pkcs11/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/drivers/pkcs11/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } +utils/$(am__dirstamp): + @$(MKDIR_P) utils + @: > utils/$(am__dirstamp) +utils/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) utils/$(DEPDIR) + @: > utils/$(DEPDIR)/$(am__dirstamp) +utils/libpki_token_pkcs11_la-pkcs11_init.lo: utils/$(am__dirstamp) \ + utils/$(DEPDIR)/$(am__dirstamp) + +libpki-token-pkcs11.la: $(libpki_token_pkcs11_la_OBJECTS) $(libpki_token_pkcs11_la_DEPENDENCIES) $(EXTRA_libpki_token_pkcs11_la_DEPENDENCIES) + $(AM_V_CCLD)$(libpki_token_pkcs11_la_LINK) $(libpki_token_pkcs11_la_OBJECTS) $(libpki_token_pkcs11_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + -rm -f utils/*.$(OBJEXT) + -rm -f utils/*.lo + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_token_pkcs11_la-pkcs11_hsm.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_token_pkcs11_la-pkcs11_hsm_obj.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_token_pkcs11_la-pkcs11_hsm_pkey.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@utils/$(DEPDIR)/libpki_token_pkcs11_la-pkcs11_init.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +libpki_token_pkcs11_la-pkcs11_hsm.lo: pkcs11_hsm.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_token_pkcs11_la_CFLAGS) $(CFLAGS) -MT libpki_token_pkcs11_la-pkcs11_hsm.lo -MD -MP -MF $(DEPDIR)/libpki_token_pkcs11_la-pkcs11_hsm.Tpo -c -o libpki_token_pkcs11_la-pkcs11_hsm.lo `test -f 'pkcs11_hsm.c' || echo '$(srcdir)/'`pkcs11_hsm.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_token_pkcs11_la-pkcs11_hsm.Tpo $(DEPDIR)/libpki_token_pkcs11_la-pkcs11_hsm.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pkcs11_hsm.c' object='libpki_token_pkcs11_la-pkcs11_hsm.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_token_pkcs11_la_CFLAGS) $(CFLAGS) -c -o libpki_token_pkcs11_la-pkcs11_hsm.lo `test -f 'pkcs11_hsm.c' || echo '$(srcdir)/'`pkcs11_hsm.c + +libpki_token_pkcs11_la-pkcs11_hsm_pkey.lo: pkcs11_hsm_pkey.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_token_pkcs11_la_CFLAGS) $(CFLAGS) -MT libpki_token_pkcs11_la-pkcs11_hsm_pkey.lo -MD -MP -MF $(DEPDIR)/libpki_token_pkcs11_la-pkcs11_hsm_pkey.Tpo -c -o libpki_token_pkcs11_la-pkcs11_hsm_pkey.lo `test -f 'pkcs11_hsm_pkey.c' || echo '$(srcdir)/'`pkcs11_hsm_pkey.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_token_pkcs11_la-pkcs11_hsm_pkey.Tpo $(DEPDIR)/libpki_token_pkcs11_la-pkcs11_hsm_pkey.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pkcs11_hsm_pkey.c' object='libpki_token_pkcs11_la-pkcs11_hsm_pkey.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_token_pkcs11_la_CFLAGS) $(CFLAGS) -c -o libpki_token_pkcs11_la-pkcs11_hsm_pkey.lo `test -f 'pkcs11_hsm_pkey.c' || echo '$(srcdir)/'`pkcs11_hsm_pkey.c + +libpki_token_pkcs11_la-pkcs11_hsm_obj.lo: pkcs11_hsm_obj.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_token_pkcs11_la_CFLAGS) $(CFLAGS) -MT libpki_token_pkcs11_la-pkcs11_hsm_obj.lo -MD -MP -MF $(DEPDIR)/libpki_token_pkcs11_la-pkcs11_hsm_obj.Tpo -c -o libpki_token_pkcs11_la-pkcs11_hsm_obj.lo `test -f 'pkcs11_hsm_obj.c' || echo '$(srcdir)/'`pkcs11_hsm_obj.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_token_pkcs11_la-pkcs11_hsm_obj.Tpo $(DEPDIR)/libpki_token_pkcs11_la-pkcs11_hsm_obj.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pkcs11_hsm_obj.c' object='libpki_token_pkcs11_la-pkcs11_hsm_obj.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_token_pkcs11_la_CFLAGS) $(CFLAGS) -c -o libpki_token_pkcs11_la-pkcs11_hsm_obj.lo `test -f 'pkcs11_hsm_obj.c' || echo '$(srcdir)/'`pkcs11_hsm_obj.c + +utils/libpki_token_pkcs11_la-pkcs11_init.lo: utils/pkcs11_init.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_token_pkcs11_la_CFLAGS) $(CFLAGS) -MT utils/libpki_token_pkcs11_la-pkcs11_init.lo -MD -MP -MF utils/$(DEPDIR)/libpki_token_pkcs11_la-pkcs11_init.Tpo -c -o utils/libpki_token_pkcs11_la-pkcs11_init.lo `test -f 'utils/pkcs11_init.c' || echo '$(srcdir)/'`utils/pkcs11_init.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) utils/$(DEPDIR)/libpki_token_pkcs11_la-pkcs11_init.Tpo utils/$(DEPDIR)/libpki_token_pkcs11_la-pkcs11_init.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='utils/pkcs11_init.c' object='utils/libpki_token_pkcs11_la-pkcs11_init.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_token_pkcs11_la_CFLAGS) $(CFLAGS) -c -o utils/libpki_token_pkcs11_la-pkcs11_init.lo `test -f 'utils/pkcs11_init.c' || echo '$(srcdir)/'`utils/pkcs11_init.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + -rm -rf utils/.libs utils/_libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f utils/$(DEPDIR)/$(am__dirstamp) + -rm -f utils/$(am__dirstamp) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/libpki_token_pkcs11_la-pkcs11_hsm.Plo + -rm -f ./$(DEPDIR)/libpki_token_pkcs11_la-pkcs11_hsm_obj.Plo + -rm -f ./$(DEPDIR)/libpki_token_pkcs11_la-pkcs11_hsm_pkey.Plo + -rm -f utils/$(DEPDIR)/libpki_token_pkcs11_la-pkcs11_init.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/libpki_token_pkcs11_la-pkcs11_hsm.Plo + -rm -f ./$(DEPDIR)/libpki_token_pkcs11_la-pkcs11_hsm_obj.Plo + -rm -f ./$(DEPDIR)/libpki_token_pkcs11_la-pkcs11_hsm_pkey.Plo + -rm -f utils/$(DEPDIR)/libpki_token_pkcs11_la-pkcs11_init.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-noinstLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + +include $(TOP)/global-vars + +# libpki_token_pkcs11_la_LIBADD = $(BUILD_LIBPKI_LDFLAGS) + +# libpki_token_a_LDFLAGS = -version-info 1:0:0 + +# $(OPENCA_INCLUDE_LIBS) \ +# $(pkcs11_cflags) $(pkcs11_libs) + +#pki_token_a_LIBADD = \ +# $(pkcs11_cflags) $(pkcs11_libs) \ +# $(libxml2_cflags) $(libxml2_libs) \ +# $(OPENCA_INCLUDE_LIBS) + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/crypto/hsm/pkcs11/pkcs11_hsm.c b/src/crypto/hsm/pkcs11/pkcs11_hsm.c new file mode 100644 index 00000000..b9c41e37 --- /dev/null +++ b/src/crypto/hsm/pkcs11/pkcs11_hsm.c @@ -0,0 +1,1114 @@ +/* HSM Object Management Functions */ + +#include +#include +#include +#include + +/* Callbacks for Software OpenSSL HSM */ +HSM_CALLBACKS pkcs11_hsm_callbacks = { + /* Errno */ + NULL, + /* Err Descr */ + NULL, + /* Init */ + HSM_PKCS11_init, + /* Free */ + HSM_PKCS11_free, + /* Login */ + HSM_PKCS11_login, + /* Logout */ + HSM_PKCS11_logout, + /* Set Algorithm */ + HSM_PKCS11_sign_algor_set, + /* Set fips mode */ + HSM_PKCS11_set_fips_mode, + /* Fips operation mode */ + HSM_PKCS11_is_fips_mode, + /* General Sign */ + NULL, /* HSM_PKCS11_sign, */ + /* ASN1 General Sign */ + NULL, /* HSM_PKCS11_asn1_sign, */ + /* General Verify */ + NULL, /* HSM_PKCS11_verify */ + /* ASN1 General Verify */ + NULL, /* HSM_PKCS11_asn1_verify */ + /* Key Generation */ + HSM_PKCS11_KEYPAIR_new, + /* Free Keypair Function */ + HSM_PKCS11_KEYPAIR_free, + /* Key Wrapping */ + NULL, + /* Key Un-Wrapping */ + NULL, + /* Object stack Get Function */ + HSM_PKCS11_OBJSK_get_url, + /* Object stack Add (import) Function */ + HSM_PKCS11_OBJSK_add_url, + /* Object stack Del (remove) Function */ + HSM_PKCS11_OBJSK_del_url, + /* Get the number of available Slots */ + HSM_PKCS11_SLOT_num, + /* Get Slot info */ + HSM_PKCS11_SLOT_INFO_get, + /* Free Slot info */ + HSM_PKCS11_SLOT_INFO_free, + /* Set the current slot */ + HSM_PKCS11_SLOT_select, + /* Cleans up the current slot */ + HSM_PKCS11_SLOT_clear, + /* Gets X509 Callbacks */ + HSM_OPENSSL_X509_get_cb, +}; + +/* Structure for PKI_TOKEN definition */ +HSM pkcs11_hsm = { + + /* Version of the HSM */ + 1, + + /* Description of the HSM */ + "PKCS11 Generic HSM", + + /* Manufacturer */ + "OpenCA Project", + + /* Pointer to the HSM config file and parsed structure*/ + NULL, + + /* One of PKI_HSM_TYPE value */ + HSM_TYPE_PKCS11, + + /* URL for the ID of the driver, this is filled at load time */ + NULL, + + /* Pointer to the driver structure */ + NULL, + + /* Pointer to the session */ + NULL, + + /* Pointer to the credentials */ + NULL, + + /* is Logged In ? */ + 0, + + /* is Cred Set ? */ + 0, + + /* is Login Required ? */ + 1, + + /* Callbacks Structures */ + &pkcs11_hsm_callbacks +}; + + +/* ------------- PKCS11 LIBPKI Callbacks Functions --------------------- */ + +HSM *HSM_PKCS11_new ( PKI_CONFIG *conf ) { + + HSM *hsm = NULL; + char *cryptoki_id = NULL; + + if ((hsm = (HSM *) PKI_Malloc ( sizeof( HSM ))) == NULL) + return NULL; + + memcpy( hsm, &pkcs11_hsm, sizeof( HSM)); + + /* Not really needed! */ + hsm->callbacks = &pkcs11_hsm_callbacks; + + /* Now we want to load the lib - this should exists, at least!!! */ + + /* Let's get the ID for the HSM */ + if((cryptoki_id = PKI_CONFIG_get_value( conf, "/hsm/id" )) == NULL ) { + PKI_log_debug("ERROR, Can not get ENGINE id from conf!\n"); + goto err; + } + + if((hsm->id = URL_new ( cryptoki_id )) == NULL ) { + PKI_log_debug("ERROR, Can not convert id into URI (%s)", + cryptoki_id); + goto err; + } + + /* cryptoki_id is no more of use, let's free the memory */ + PKI_Free ( cryptoki_id ); + cryptoki_id = NULL; + + if((hsm->driver = (void *) + _pki_pkcs11_load_module( hsm->id->addr, conf))==NULL) { + PKI_log_err("Can not init PKCS11 lib"); + goto err; + } + + /* The PKCS11 interface need to be initialized */ + if(( HSM_PKCS11_init ( hsm, conf )) == PKI_ERR ) { + PKI_log_err("Can not initialize PKCS11 (%s)", hsm->id->addr ); + goto err; + }; + + if((hsm->session = (void *) PKI_Malloc ( sizeof (CK_SESSION_HANDLE))) + == NULL ) { + PKI_log_err("HSM_PKCS11_new()::Memory Allocation error for" + "CK_SESSION_HANDLE"); + goto err; + } + + return( hsm ); + +err: + + if (cryptoki_id) PKI_Free(cryptoki_id); + if (hsm) HSM_PKCS11_free(hsm, conf); + + return NULL; +} + +int HSM_PKCS11_free ( HSM *hsm, PKI_CONFIG *conf ) { + + PKCS11_HANDLER *handle = NULL; + CK_RV rv = CKR_OK; + int ret = PKI_OK; + + if (hsm == NULL) return (PKI_OK); + + ret = HSM_PKCS11_logout(hsm); + if (ret != PKI_OK) + { + // This is a non-fatal error, so let's just log it and continue + PKI_log_debug("HSM_PKCS11_free()::Failed to logout from the HSM"); + } + + if((handle = _hsm_get_pkcs11_handler(hsm)) != NULL ) { + + // Check if the Finalize function is available + if (handle->callbacks && handle->callbacks->C_Finalize) + { + rv = handle->callbacks->C_Finalize( NULL_PTR ); + if (!rv) PKI_log_debug("HSM_PKCS11_free()::Failed to call C_Finalize"); + if (rv != CKR_OK) PKI_log_debug("%s()::Failed to call C_Finalize(0X%8.8X)", __PRETTY_FUNCTION__, rv); + } + + // Close reference to shared lib + dlclose(handle->sh_lib); + + // Free list of callbacks + if( handle->callbacks ) { + // PKI_Free ( handle->callbacks ); + } + + // Free list of mechanisms + if (handle->mech_list) PKI_Free(handle->mech_list); + + } else { + PKI_log_debug("HSM_PKCS11_free():: Can't get handler!"); + } + + // Free the Session Info + if (hsm->session) PKI_Free(hsm->session); + + // Free the ID + if (hsm->id) URL_free(hsm->id); + + // Free the Driver + if (hsm->driver) PKI_Free(hsm->driver); + + // Set the mutex to an invalid value + // NOTE: The call to pthread_mutext_destroy() seem + // to cause issues on some platforms, need investigation + // pthread_mutex_destroy ( &handle->pkcs11_mutex ); + // pthread_cond_destroy ( &handle->pkcs11_cond ); + + // Free the Memory + PKI_Free(handle); + + // All Done + return (PKI_OK); +} + +int HSM_PKCS11_login(HSM *hsm, PKI_CRED *cred) { + + PKCS11_HANDLER *lib = NULL; + CK_RV rv; + + unsigned char *pwd = NULL; + + if (!hsm) return ( PKI_OK ); + + if ((lib = _hsm_get_pkcs11_handler(hsm)) == NULL ) + { + PKI_log_debug("HSM_PKCS11_login():: Can't get handler!"); + return PKI_ERR; + } + + if (lib->logged_in == 1) + { + PKI_log_debug ( "HSM_PKCS11_login()::Already Logged in"); + return PKI_OK; + } + + if (cred == NULL) + { + pwd = (unsigned char *) getpass("Please enter your password: "); + } + else if ((pwd = (unsigned char *) cred->password) == NULL) + { + PKI_log_debug("No Password Provided for Login"); + } + + if (pwd && strlen((const char*) pwd) > 0) + { + unsigned char *tmp_s = NULL; + size_t tmp_s_len = 0; + + tmp_s = pwd; + tmp_s_len = strlen ( (const char *) pwd ); + + rv = lib->callbacks->C_Login(lib->session, CKU_USER, + (CK_UTF8CHAR *) tmp_s, tmp_s_len ); + } else { + char *tmp_s = NULL; + CK_ULONG tmp_s_len = 0; + + rv = lib->callbacks->C_Login(lib->session, CKU_USER, + (CK_UTF8CHAR *) tmp_s, tmp_s_len ); + } + + if ( rv == CKR_USER_ALREADY_LOGGED_IN ) { + PKI_log_debug( "User Already logged in!"); + } else if( rv == CKR_PIN_INCORRECT ) { + PKI_log_err ( "ERROR, Pin '%s' Incorrect (0X%8.8X)", pwd, rv); + return ( PKI_ERR ); + } else if ( rv != CKR_OK ) { + PKI_log_err ( "ERROR, Unknown (0X%8.8X)", rv); + return ( PKI_ERR ); + } + + lib->logged_in = 1; + + return PKI_OK; +} + +int HSM_PKCS11_logout(HSM *hsm) { + + PKCS11_HANDLER *lib = NULL; + CK_RV rv; + + if (!hsm) return(PKI_OK); + + if((lib = _hsm_get_pkcs11_handler(hsm)) == NULL ) { + PKI_log_debug("%s():: Can't get handler!", __PRETTY_FUNCTION__); + return PKI_ERR; + } + + rv = lib->callbacks->C_Logout(lib->session); + if( rv && rv != CKR_SESSION_CLOSED && + rv != CKR_SESSION_HANDLE_INVALID && + rv != CKR_USER_NOT_LOGGED_IN && + rv != CKR_CRYPTOKI_NOT_INITIALIZED ) { + + PKI_log_err("%s()::can't logout from current session " + "(0x%8.8X)", __PRETTY_FUNCTION__, rv ); + return PKI_ERR; + } else { + lib->logged_in = 0; + } + + return PKI_OK; +} + +int HSM_PKCS11_init( HSM *hsm, PKI_CONFIG *conf ) { + + CK_RV rv = CKR_OK; + PKCS11_HANDLER *handle = NULL; + CK_INFO info; + + char *tmp = NULL; + + if (hsm == NULL) { + return PKI_ERROR(PKI_ERR_PARAM_NULL, "Missing Driver argument"); + } + + // Gets the pkcs11 hander + handle = (PKCS11_HANDLER *) hsm->driver; + + // Initialize MUTEX for non-atomic operations + if (pthread_mutex_init( &handle->pkcs11_mutex, NULL ) != 0 ) { + return PKI_ERROR(PKI_ERR_HSM_INIT, "Error while initializing mutex (%s:%d)"); + } + + // Initialize COND variable for non-atomic operations + if (pthread_cond_init( &handle->pkcs11_cond, NULL ) != 0 ) { + return PKI_ERROR(PKI_ERR_HSM_INIT, "Error while initializing cond variable"); + } + + rv = (handle->callbacks->C_Initialize)(NULL_PTR); + if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED)) { + return PKI_ERROR(PKI_ERR_HSM_INIT, "C_Initialize failed with 0x%8.8X", rv); + } + + /* Let's get Info for the Current Loaded Module */ + if((rv = (handle->callbacks->C_GetInfo)(&info)) != CKR_OK ) { + return PKI_ERROR(PKI_ERR_HSM_INIT, "C_GetInfo failed with 0x%8.8X", rv); + } + + // Sets the Info for the version + handle->hsm_info.version_major = info.cryptokiVersion.major; + handle->hsm_info.version_minor = info.cryptokiVersion.minor; + + // Gets the Manufacturer Info + strncpy(handle->hsm_info.manufacturerID, + (const char *) info.manufacturerID, + sizeof( handle->hsm_info.manufacturerID) ); + handle->hsm_info.manufacturerID[sizeof(handle->hsm_info.manufacturerID)-1] = '\x0'; + + // Gets the HSM description + strncpy(handle->hsm_info.description, + (const char *) info.libraryDescription, + sizeof( handle->hsm_info.description) ); + handle->hsm_info.description[sizeof(handle->hsm_info.description)-1] = + '\x0'; + + // Let's remove the ugly spaces at the end of the maufacturerID + tmp = handle->hsm_info.manufacturerID + + sizeof(handle->hsm_info.manufacturerID) - 2; + + while( tmp > handle->hsm_info.manufacturerID ) { + if( tmp[0] == ' ' ) { + tmp[0] = '\x0'; + } else { + break; + } + tmp--; + } + + /* Let's remove the ugly spaces at the end of the description */ + tmp = handle->hsm_info.description + + sizeof(handle->hsm_info.description) - 2; + + while( tmp > handle->hsm_info.description ) { + if( tmp[0] == ' ' ) { + tmp[0] = '\x0'; + } else { + break; + } + tmp--; + } + + // Gets the Library Info + handle->hsm_info.lib_version_major = info.libraryVersion.major; + handle->hsm_info.lib_version_minor = info.libraryVersion.minor; + + PKI_log_debug("HSM INFO::Manufacturer %s (v%d.%d)", + handle->hsm_info.manufacturerID, + handle->hsm_info.version_major, + handle->hsm_info.version_minor ); + + PKI_log_debug("HSM INFO::Library %s (v%d.%d)", + handle->hsm_info.description, + handle->hsm_info.lib_version_major, + handle->hsm_info.lib_version_minor ); + + return PKI_OK; +} + +int HSM_PKCS11_sign_algor_set (HSM *hsm, PKI_X509_ALGOR_VALUE *algor) { + + PKCS11_HANDLER *lib = NULL; + + PKI_ALGOR_ID id; + + int ret = PKI_OK; + + if (!algor || !hsm) { + return PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + } + + if ((id = PKI_X509_ALGOR_VALUE_get_id(algor)) == PKI_ALGOR_ID_UNKNOWN ) { + return PKI_ERROR(PKI_ERR_ALGOR_UNKNOWN, NULL); + } + + /* Get a VALID PKCS11_HANDLER pointer */ + if((lib = _hsm_get_pkcs11_handler ( hsm )) == NULL ) { + return PKI_ERROR(PKI_ERR_HSM_INIT, "Can't get PKCS#11 handler!"); + } + + switch ( id ) { + +#ifdef ENABLE_DSA_SHA1 + case PKI_ALGOR_ID_DSA_SHA1: + if((ret = HSM_PKCS11_check_mechanism ( lib, + CKM_DSA_SHA1 )) == PKI_OK ) { + lib->mech_curr = CKM_DSA_SHA1; + } + break; +#endif + +#ifdef ENABLE_DSA_SHA224 + case PKI_ALGOR_ID_DSA_SHA224: + if((ret = HSM_PKCS11_check_mechanism ( lib, + CKM_DSA_SHA224 )) == PKI_OK ) { + lib->mech_curr = CKM_DSA_SHA224; + } + break; +#endif + +#ifdef ENABLE_DSA_SHA256 + case PKI_ALGOR_ID_DSA_SHA256: + if((ret = HSM_PKCS11_check_mechanism ( lib, + CKM_DSA_SHA256 )) == PKI_OK ) { + lib->mech_curr = CKM_DSA_SHA256; + } + break; +#endif + +#ifdef ENABLE_DSA_SHA384 + case PKI_ALGOR_ID_DSA_SHA384: + if((ret = HSM_PKCS11_check_mechanism ( lib, + CKM_DSA_SHA384 )) == PKI_OK ) { + lib->mech_curr = CKM_DSA_SHA384; + } + break; +#endif + +#ifdef ENABLE_DSA_SHA512 + case PKI_ALGOR_ID_DSA_SHA512: + if((ret = HSM_PKCS11_check_mechanism ( lib, + CKM_DSA_SHA512 )) == PKI_OK ) { + lib->mech_curr = CKM_DSA_SHA512; + } + break; +#endif + +#ifdef ENABLE_MD5 + case PKI_ALGOR_ID_RSA_MD5: + if((ret = HSM_PKCS11_check_mechanism( lib, + CKM_MD5_RSA_PKCS)) == PKI_OK ) { + lib->mech_curr = CKM_MD5_RSA_PKCS; + } + break; +#endif + +#ifdef ENABLE_SHA2 + case PKI_ALGOR_ID_RSA_SHA224: + if((ret = HSM_PKCS11_check_mechanism( lib, + CKM_SHA224_RSA_PKCS)) == PKI_OK ) { + lib->mech_curr = CKM_SHA224_RSA_PKCS; + } + break; + + case PKI_ALGOR_ID_RSA_SHA256: + if((ret = HSM_PKCS11_check_mechanism( lib, + CKM_SHA256_RSA_PKCS)) == PKI_OK ) { + lib->mech_curr = CKM_SHA256_RSA_PKCS; + } + break; + + case PKI_ALGOR_ID_RSA_SHA384: + if((ret = HSM_PKCS11_check_mechanism( lib, + CKM_SHA384_RSA_PKCS)) == PKI_OK ) { + lib->mech_curr = CKM_SHA384_RSA_PKCS; + } + break; + case PKI_ALGOR_ID_RSA_SHA512: + if((ret = HSM_PKCS11_check_mechanism( lib, + CKM_SHA512_RSA_PKCS)) == PKI_OK ) { + lib->mech_curr = CKM_SHA512_RSA_PKCS; + } + break; +#endif + +#ifdef ENABLE_RSA_RIPEMD128 + case PKI_ALGOR_ID_RSA_RIPEMD128: + if((ret = HSM_PKCS11_check_mechanism( lib, + CKM_RIPEMD128_RSA_PKCS)) == PKI_OK ) { + lib->mech_curr = CKM_RIPEMD128_RSA_PKCS; + } + break; +#endif + +#ifdef ENABLE_RSA_RIPEMD160 + case PKI_ALGOR_ID_RSA_RIPEMD160: + if((ret = HSM_PKCS11_check_mechanism( lib, + CKM_RIPEMD160_RSA_PKCS)) == PKI_OK ) { + lib->mech_curr = CKM_RIPEMD160_RSA_PKCS; + } + break; +#endif + +#ifdef ENABLE_ECDSA_SHA1 + case PKI_ALGOR_ID_ECDSA_SHA1: + if((ret = HSM_PKCS11_check_mechanism ( lib, + CKM_ECDSA_SHA1)) == PKI_OK ) { + lib->mech_curr = CKM_ECDSA_SHA1; + } + break; +#endif // ENABLE_ECDSA_SHA1 + +#ifdef ENABLE_SHA2 + case PKI_ALGOR_ID_ECDSA_SHA224: + if((ret = HSM_PKCS11_check_mechanism ( lib, + CKM_ECDSA_SHA224)) == PKI_OK ) { + lib->mech_curr = CKM_ECDSA_SHA224; + } + break; + + case PKI_ALGOR_ID_ECDSA_SHA256: + if((ret = HSM_PKCS11_check_mechanism ( lib, + CKM_ECDSA_SHA256)) == PKI_OK ) { + lib->mech_curr = CKM_ECDSA_SHA256; + } + break; + + case PKI_ALGOR_ID_ECDSA_SHA384: + if((ret = HSM_PKCS11_check_mechanism ( lib, + CKM_ECDSA_SHA384)) == PKI_OK ) { + lib->mech_curr = CKM_ECDSA_SHA384; + } + break; + + case PKI_ALGOR_ID_ECDSA_SHA512: + if((ret = HSM_PKCS11_check_mechanism ( lib, + CKM_ECDSA_SHA512)) == PKI_OK ) { + lib->mech_curr = CKM_ECDSA_SHA512; + } + break; +#endif // ENABLE_SHA2 + + default: + ret = PKI_ERR; + break; + } + + /* + if( ret == PKI_ERR ) { + PKI_log_debug("HSM_PKCS11_algor_set():: ERROR :: End " + "(Algor = %d - ret = %d)", lib->mech_curr, ret ); + } + */ + + return ( ret ); +} + +int HSM_PKCS11_set_fips_mode(const HSM *driver, int k) +{ + PKCS11_HANDLER *lib = NULL; + if (!driver) return PKI_ERR; + + if ((lib = _hsm_get_pkcs11_handler ((HSM *)driver)) == NULL) + { + PKI_log_err("HSM_PKCS11_set_fips_mode()::Can't get a valid " + "PKCS11 handler from driver!"); + return (PKI_ERR); + } + + PKI_DEBUG("Not implemented, yet."); + return PKI_ERR; +} + +int HSM_PKCS11_is_fips_mode(const HSM *driver) +{ + PKCS11_HANDLER *lib = NULL; + if (!driver) return PKI_ERR; + + if ((lib = _hsm_get_pkcs11_handler((HSM *)driver)) == NULL) + { + PKI_log_err("HSM_PKCS11_set_fips_mode()::Can't get a valid " + "PKCS11 handler from driver!"); + return (PKI_ERR); + } + PKI_DEBUG("Not implemented, yet."); + return PKI_ERR; +} + +/* -------------------------- Sign/Verify Functions ----------------------- */ + +/* +int HSM_PKCS11_sign (PKI_OBJTYPE type, + void *x, + void *it_pp, + PKI_ALGOR *alg, + PKI_STRING *bit, + PKI_X509_KEYPAIR *key, + PKI_DIGEST_ALG *digest, + HSM *driver ) { + + int ret = 0; + ASN1_ITEM *it = NULL; + + if( !x || !key ) { + PKI_log_debug("Missing required param for signature generation " + "(Software HSM)"); + + if( !x ) PKI_log_debug ( "Missing data to sign!"); + if( !key ) PKI_log_debug( "Missing Key to sign with!"); + + return ( PKI_ERR ); + } + + if( !digest ) digest = PKI_DIGEST_ALG_SHA1; + + ERR_clear_error(); + + switch ( type ) { + case PKI_OBJTYPE_X509_REQ: + ret = X509_REQ_sign( (X509_REQ *) x, + (EVP_PKEY *) key, (EVP_MD *) digest ); + break; + case PKI_OBJTYPE_X509_CERT: + ret = X509_sign( (X509 *) x, (EVP_PKEY *) key, + (EVP_MD *) digest ); + break; + case PKI_OBJTYPE_X509_CRL: + ret = X509_CRL_sign( (X509_CRL *) x, (EVP_PKEY *) key, + (EVP_MD *) digest ); + break; + case PKI_OBJTYPE_PKCS7: + case PKI_OBJTYPE_PKCS12: + case PKI_OBJTYPE_PKI_MSG: + case PKI_OBJTYPE_SCEP_MSG: + case PKI_OBJTYPE_CMS_MSG: + PKI_log_debug("HSM::DRIVER::PKCS11::OBJ sign not " + "supported for this type, yet!"); + ret = 0; + break; + default: + if( !it_pp || !bit || !alg ) { + PKI_log_debug("Missing required params to " + "complete the generic signature"); + return ( PKI_ERR ); + } + + it = (ASN1_ITEM *) it_pp; + ret = ASN1_item_sign(it, alg, NULL, + bit, x, (EVP_PKEY *) key, (EVP_MD *) digest ); + break; + } + + if( ret == 0 ) { + PKI_log_debug("ERROR::Software::sign()::%s", + ERR_error_string(ERR_get_error(), NULL)); + return( PKI_ERR ); + } + + PKI_log_debug("Signature successful ( Software HSM )"); + + return ( PKI_OK ); +} + +int HSM_PKCS11_verify ( PKI_OBJTYPE type, void *x, + PKI_X509_KEYPAIR *key, HSM *hsm ) { + + int ret = 0; + EVP_PKEY *pp = NULL; + X509_ALGOR *alg = NULL; + + void * sig = NULL; + void * data = NULL; + + ASN1_ITEM *it = NULL; + + if( !x || !key ) { + PKI_log_debug("PKI_verify() - Missing resp or key!"); + return (PKI_ERR); + } + + pp = (EVP_PKEY *) key; + + ERR_clear_error(); + + switch ( type ) { + case PKI_OBJTYPE_X509_REQ: + it = (ASN1_ITEM *) ASN1_ITEM_rptr(X509_REQ_INFO); + sig = ((X509_REQ *) x)->signature; + data = ((X509_REQ *) x)->req_info; + alg = ((X509_REQ *) x)->sig_alg; + break; + case PKI_OBJTYPE_X509_CERT: + it = (ASN1_ITEM *) ASN1_ITEM_rptr(X509_CINF); + sig = ((X509 *)x)->signature; + data = ((X509 *)x)->cert_info; + alg = ((X509 *)x)->sig_alg; + break; + case PKI_OBJTYPE_X509_CRL: + it = (ASN1_ITEM *) ASN1_ITEM_rptr(X509_CRL_INFO); + sig = ((X509_CRL *)x)->signature; + data = ((X509_CRL *)x)->crl; + alg = ((X509_CRL *)x)->sig_alg; + break; + case PKI_OBJTYPE_PKI_PRQP_REQ: + it = (ASN1_ITEM *) ASN1_ITEM_rptr(TBS_REQ_DATA); + sig = ((PKI_PRQP_REQ *)x)->prqpSignature->signature; + data = ((PKI_PRQP_REQ *)x)->requestData; + alg = ((PKI_PRQP_REQ *)x)->prqpSignature->signatureAlgorithm; + break; + case PKI_OBJTYPE_PKI_PRQP_RESP: + it = (ASN1_ITEM *) ASN1_ITEM_rptr(TBS_RESP_DATA); + sig = ((PKI_PRQP_RESP *)x)->prqpSignature->signature; + data = ((PKI_PRQP_RESP *)x)->respData; + alg = ((PKI_PRQP_RESP *)x)->prqpSignature->signatureAlgorithm; + break; + case PKI_OBJTYPE_PKCS7: + case PKI_OBJTYPE_PKCS12: + case PKI_OBJTYPE_PKI_MSG: + case PKI_OBJTYPE_SCEP_MSG: + case PKI_OBJTYPE_CMS_MSG: + PKI_log_debug("HSM::DRIVER::PKCS11::OBJ verify not " + "supported for this type, yet!"); + return( PKI_ERR ); + break; + default: + return ( PKI_ERR ); + } + + if( !it || !alg || !sig || !data || !pp ) return ( PKI_ERR ); + + if(( ret = ASN1_item_verify((const ASN1_ITEM *)it, alg, sig, data, + pp )) == 0 ) { + + PKI_log_debug( "PKI_verify() - [%d] ERROR:%s", ret, + ERR_error_string(ERR_get_error(), NULL )); + + return ( PKI_ERR ); + } + + PKI_log_debug( "PKI_verify() - OK"); + + return ( PKI_OK ); + +} +*/ + +/*--------------------------- SLOT Management Functions --------------- */ + +unsigned long HSM_PKCS11_SLOT_num ( HSM * hsm ) { + + PKCS11_HANDLER *lib = NULL; + CK_RV rv = CKR_OK; + + CK_ULONG ret = 0; + + PKI_log_debug( "HSM_PKCS11_SLOT_num()::start (%p)", hsm ); + + /* Get a VALID PKCS11_HANDLER pointer */ + if((lib = _hsm_get_pkcs11_handler ( hsm )) == NULL ) { + return ( 0 ); + } + + /* Checks that the library implements the callback */ + if( lib->callbacks->C_GetSlotList == NULL ) { + PKI_DEBUG( "HSM_PKCS11_SLOT_num()::no C_GetSlotList" ); + return( 1 ); + } + + /* Get the number of Slots available */ + if((rv = lib->callbacks->C_GetSlotList( (CK_BYTE) 1, + NULL, &ret )) != CKR_OK) { + PKI_DEBUG("C_GetSlotList failed with 0%8.8X", rv ); + return( 0 ); + } + + return ( (unsigned long) ret ); + +} + +HSM_SLOT_INFO * HSM_PKCS11_SLOT_INFO_get(unsigned long num, HSM *hsm) { + + PKCS11_HANDLER *lib = NULL; + CK_RV rv = CKR_OK; + + CK_MECHANISM_TYPE_PTR mech_list = NULL; + + CK_SLOT_INFO info; + HSM_SLOT_INFO *ret = NULL; + + CK_ULONG slot_num = 0; + + PKI_log_debug("HSM_PKCS11_SLOT_info()::start"); + + /* Get a VALID PKCS11_HANDLER pointer */ + if((lib = _hsm_get_pkcs11_handler(hsm)) == NULL ) { + return ( NULL ); + } + + /* Let's get Info for the Current Loaded Module */ + slot_num = (CK_ULONG) num; + if((rv = lib->callbacks->C_GetSlotInfo(slot_num, &info)) != CKR_OK ) { + PKI_log_debug("Can not get Info from PKCS11 library" ); + PKI_log_debug("Returned Value is 0x%8.8X (OK is 0x%8.8X)", rv, CKR_OK ); + return ( PKI_ERR ); + }; + + if((ret = PKI_Malloc ( sizeof( HSM_SLOT_INFO ))) == NULL ) + return ( NULL ); + + ret->hw_version_major = info.hardwareVersion.major; + ret->hw_version_minor = info.hardwareVersion.minor; + ret->fw_version_major = info.firmwareVersion.major; + ret->fw_version_minor = info.firmwareVersion.minor; + + _strncpyClip(ret->manufacturerID, (char *) info.manufacturerID, + MANUFACTURER_ID_SIZE ); + _strncpyClip(ret->description, (char *) info.slotDescription, + DESCRIPTION_SIZE ); + + ret->present = 0; + ret->removable = 0; + ret->hardware = 0; + + if( info.flags & CKF_TOKEN_PRESENT ) ret->present = 1; + if( info.flags & CKF_REMOVABLE_DEVICE ) ret->removable = 1; + if( info.flags & CKF_HW_SLOT ) ret->hardware = 1; + + if( ret->present == 0 ) { + PKI_log_err("HSM SLOT [%ld]::Token not Present!", num); + goto err; + } + + if((_hsm_pkcs11_get_token_info(num, &(ret->token_info), + lib)) != PKI_OK ) { + PKI_log_debug("HSM SLOT INFO [%ld]::" + "Error in getting token information", num); + + return ( ret ); + } + + /* Get the number of Supported Mechanisms */ + /* + if((rv = lib->callbacks->C_GetSlotInfo( slot_num, &slot_info )) + != CKR_OK ) { + PKI_log_err ( "HSM SLOT INFO [%d]::Can not get slot details " + "(C_GetSlotInfo failed with %d)", + slot_num, rv ); + goto err; + } + + if((rv = lib->callbacks->C_GetMechanismList( slot_num, NULL_PTR, + &mech_num )) != CKR_OK ) { + PKI_log_err( "HSM SLOT INFO [%d]::Can not get the number of" + " algorithms (C_GetMechanismList failed with %d)", + slot_num, rv); + goto err; + } + + PKI_log_debug("HSM_SLOT_INFO [%d]::Mech Num is %d (rv = %d)", + slot_num, mech_num, rv ); + + if(( mech_list = PKI_Malloc( mech_num * + sizeof(CK_MECHANISM_TYPE))) == NULL ) { + PKI_log_err("HSM SLOT INFO [%d]::Memory allocation!", slot_num); + goto err; + } + + rv = lib->callbacks->C_GetMechanismList(slot_num, + mech_list, &mech_num ); + if( rv != CKR_OK ) { + PKI_log_debug("C_GetMechanismList::Failed (%d::%d)", + slot_num, rv ); + goto err; + } + + for ( i = 0; i < mech_num ; i++ ) { + PKI_log_debug("HSM SLOT INFO [%d]:: MECH %d is 0x%8.8X\n", + slot_num, i, mech_list[i] ); + } + */ + + return ( ret ); + +err: + PKI_log_debug( "HSM SLOT INFO::CALLED ERROR - Returning NULL" ); + if ( mech_list ) PKI_Free ( mech_list ); + if ( ret ) PKI_Free ( ret ); + return ( NULL ); + +} + +void HSM_PKCS11_SLOT_INFO_free ( HSM_SLOT_INFO *sl_info, HSM *hsm ) { + if (!sl_info ) return; + + PKI_Free ( sl_info ); + + return; +} + +int HSM_PKCS11_SLOT_select (unsigned long num, PKI_CRED *cred, HSM *hsm) { + + CK_RV rv = CKR_OK; + PKCS11_HANDLER *lib = NULL; + + /* Get a VALID PKCS11_HANDLER pointer */ + if((lib = _hsm_get_pkcs11_handler ( hsm )) == NULL ) { + PKI_log_debug("HSM_PKCS11_SLOT_select()::Can't get a valid " + "PKCS11 handler from driver!"); + return ( PKI_ERR ); + } + + /* Get a new session */ + if( HSM_PKCS11_session_new( num, &lib->session, + CKF_SERIAL_SESSION, lib ) != PKI_OK ) { + PKI_log_debug("%s()::Can not initiate a new session", + __PRETTY_FUNCTION__); + return ( PKI_ERR ); + } + + /* Sets the Slot ID */ + lib->slot_id = num; + + /* Get the Mechanism List */ + if((rv = lib->callbacks->C_GetMechanismList( lib->slot_id, NULL_PTR, + &lib->mech_num )) != CKR_OK ) { + PKI_log_debug("%s()::PKCS11/C_GetMechanismList failed with " + "0x%8.8X", __PRETTY_FUNCTION__, rv ); + return PKI_ERR; + } + + if(( lib->mech_list = PKI_Malloc( lib->mech_num * + sizeof(CK_MECHANISM_TYPE))) == NULL ) { + return PKI_ERR_MEMORY_ALLOC; + } + + rv = lib->callbacks->C_GetMechanismList(lib->slot_id, + lib->mech_list, + &lib->mech_num); + if( rv != CKR_OK ) { + PKI_log_debug("C_GetMechanismList::Failed (%d::0x%8.8X)", + lib->slot_id, rv ); + goto end; + } + +end: + return ( PKI_OK ); +} + +int HSM_PKCS11_SLOT_clear (unsigned long slot_id, PKI_CRED *cred, HSM *driver){ + + PKCS11_HANDLER *lib = NULL; + + CK_OBJECT_HANDLE hObject; + CK_ULONG ulObjectCount; + + CK_RV rv; + + CK_SESSION_HANDLE *session = NULL; + + if( !driver ) return (PKI_ERR); + + if(( lib = _hsm_get_pkcs11_handler ( driver)) == NULL ) { + return ( PKI_ERR ); + } + + if( HSM_PKCS11_session_new( slot_id, &lib->session, + CKF_SERIAL_SESSION | CKF_RW_SESSION, lib ) != PKI_OK ) { + return ( PKI_ERR ); + } + + session = &lib->session; + + if ( HSM_PKCS11_login ( driver, cred ) == PKI_ERR ) { + return ( PKI_ERR ); + } + + /* + rv = lib->callbacks->C_Login(lib->key, CKU_USER, + (CK_UTF8CHAR *) cred->password, + cred->password ? strlen(cred->password) : 0); + + if ( rv == CKR_USER_ALREADY_LOGGED_IN ) { + PKI_log_debug("[Get Info] User Already Logged in"); + } else if ( rv != CKR_OK ) { + PKI_log_debug("[Get Info] Login Failed with 0x%8.8X", rv ); + return ( PKI_ERR ); + } + */ + + if((rv = lib->callbacks->C_FindObjectsInit(*session, NULL, 0)) + != CKR_OK ) { + PKI_log_debug("C_FindObjectsInit::Failed with 0x%8.8X", rv ); + return ( PKI_ERR ); + } + + while ( 1 ) { + rv = lib->callbacks->C_FindObjects(lib->session, &hObject, + 1, &ulObjectCount ); + if( rv != CKR_OK || ulObjectCount == 0 ) { + PKI_log_debug("C_FindObjects::Failed with 0x%8.8X", rv); + break; + } + + if((rv = lib->callbacks->C_DestroyObject(lib->session, hObject)) + != CKR_OK ) { + PKI_log_debug("HSM_PKCS11_clear()::Can not destroy " + "object (0x%8.8X)", rv ); + continue; + } + } + + if(( rv = lib->callbacks->C_FindObjectsFinal(lib->session)) != CKR_OK){ + PKI_log_debug("HSM_PKCS11_clear()::Can not destroy " + "object (0x%8.8X)", rv ); + } + + HSM_PKCS11_session_close ( &lib->session, lib ); + + return ( PKI_OK ); +} + +int HSM_PKCS11_SLOT_elements (unsigned long slot_id, PKI_CRED *cred, + HSM *driver){ + + PKCS11_HANDLER *lib = NULL; + + CK_OBJECT_HANDLE hObject; + CK_ULONG ulObjectCount; + + CK_RV rv; + + CK_SESSION_HANDLE *session = NULL; + int count = 0; + + if( !driver ) return (PKI_ERR); + + if(( lib = _hsm_get_pkcs11_handler ( driver)) == NULL ) { + return ( PKI_ERR ); + } + + if( HSM_PKCS11_session_new( slot_id, &lib->session, + CKF_SERIAL_SESSION | CKF_RW_SESSION, lib ) != PKI_OK ) { + return ( PKI_ERR ); + } + + session = &lib->session; + + if ( HSM_PKCS11_login ( driver, cred ) == PKI_ERR ) { + return ( PKI_ERR ); + } + + if((rv = lib->callbacks->C_FindObjectsInit(*session, NULL, 0)) + != CKR_OK ) { + PKI_log_debug("C_FindObjectsInit::Failed with 0x%8.8X", rv ); + return ( PKI_ERR ); + } + + while ( 1 ) { + rv = lib->callbacks->C_FindObjects(lib->session, &hObject, + 1, &ulObjectCount ); + if( rv != CKR_OK || ulObjectCount == 0 ) { + PKI_log_debug("C_FindObjects::Failed with 0x%8.8X", rv); + break; + } + count++; + } + + if(( rv = lib->callbacks->C_FindObjectsFinal(lib->session)) != CKR_OK){ + PKI_log_debug("HSM_PKCS11_clear()::Can not destroy " + "object (0x%8.8X)", rv ); + } + + HSM_PKCS11_session_close ( &lib->session, lib ); + + return ( count ); +} diff --git a/src/crypto/hsm/pkcs11/pkcs11_hsm_obj.c b/src/crypto/hsm/pkcs11/pkcs11_hsm_obj.c new file mode 100644 index 00000000..c09cc18b --- /dev/null +++ b/src/crypto/hsm/pkcs11/pkcs11_hsm_obj.c @@ -0,0 +1,1366 @@ +/* drivers/pkcs11/pkcs11_hsm_obj.c */ + +#include + +/* -------------------- Internal Function --------------------------------- */ +int _get_der ( void *data, int objType, int type, unsigned char **ret ) { + + int len = 0; + + X509_NAME * name = NULL; + ASN1_INTEGER * serial = NULL; + + switch (type) { + + case PKI_X509_DATA_SUBJECT: { + name = X509_get_subject_name((X509 *)data); + if (name) len = i2d_X509_NAME(name, ret); + } break; + + case PKI_X509_DATA_ISSUER: { + name = X509_get_issuer_name((X509 *)data); + if (name) len = i2d_X509_NAME(name, ret); + } break; + + case PKI_X509_DATA_SERIAL: { + serial = X509_get_serialNumber((X509 *)data); + if (serial) i2d_ASN1_INTEGER(serial, ret); + } break; + + default: { + return 0; + } + } + + return len; +} + +/* ------------------ PKCS11 HSM Keypair get/put -------------------------- */ + +PKI_X509_STACK * HSM_PKCS11_OBJSK_get_url ( PKI_DATATYPE type, URL *url, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ) { + + void * ret = NULL; + + if( !url ) return ( NULL ); + + switch ( type ) { + case PKI_DATATYPE_X509_KEYPAIR: + ret = (void *) HSM_PKCS11_KEYPAIR_get_url ( url, + format, cred, hsm ); + break; + default: + ret = (void *) HSM_PKCS11_STACK_get_url ( type, url, + format, cred, hsm ); + } + + return ( ret ); +} + +int HSM_PKCS11_OBJSK_add_url ( PKI_X509_STACK *sk, + URL *url, PKI_CRED *cred, HSM *hsm ) { + + int ret = PKI_OK; + PKI_X509 * x = NULL; + + if( !url ) return ( PKI_ERR ); + + if ( !sk || (PKI_STACK_X509_elements ( sk ) <= 0) ) return PKI_ERR; + + if((x = PKI_STACK_X509_get_num ( sk, 0 )) == NULL ) { + return PKI_ERR; + } + + switch ( x->type ) { + case PKI_DATATYPE_X509_KEYPAIR: + ret = HSM_PKCS11_KEYPAIR_STACK_add_url ( + sk, url, cred, hsm ); + break; + default: + ret = HSM_PKCS11_STACK_add_url (sk, url, cred, hsm); + } + + return ( ret ); +} + +int HSM_PKCS11_OBJSK_del_url ( PKI_DATATYPE type, + URL *url, PKI_CRED *cred, HSM *hsm){ + + CK_ULONG objClass = CKO_DATA; + CK_RV rv; + + PKCS11_HANDLER *lib = NULL; + + CK_OBJECT_HANDLE hObject; + CK_ULONG ulObjectCount; + + int rc = 0; + + /* Check the Input */ + if( (url == NULL ) || (url->addr == NULL )) return ( PKI_ERR ); + + /* We need a valid driver */ + if( !hsm ) { + PKI_log_debug ( "HSM_PKCS11_OBJSK_del_url()::ERROR, no " + "hsm driver provided!"); + return ( PKI_ERR ); + } + + if ((lib = _hsm_get_pkcs11_handler ( hsm )) == NULL ) { + PKI_log_debug ("HSM_PKCS11_OBJSK_del()::No handler"); + return ( PKI_ERR ); + } + + if( url->proto != URI_PROTO_ID ) { + /* The PKCS11 driver can load only id:// keypairs! */ + return ( PKI_ERR ); + } + + if( HSM_PKCS11_session_new( lib->slot_id, &lib->session, + CKF_SERIAL_SESSION | CKF_RW_SESSION, lib ) != PKI_OK ) { + PKI_log_debug ("Can not get a new Session!"); + return ( PKI_ERR ); + } + + /* Login into the device - do nothing if we are already logged in */ + if(( HSM_PKCS11_login ( hsm, cred )) == PKI_ERR ) { + PKI_log_debug("HSM_PKCS11_OBJSK_del_url()::ERROR, can not " + "login to device!"); + return ( PKI_ERR ); + } + + rc = pthread_mutex_lock( &lib->pkcs11_mutex ); + if (rc != 0) + { + PKI_log_err("HSM_PKCS11_OBJSK_del()::pthread_mutex_lock() failed with %d", rc); + return PKI_ERR; + } + + while ((rv = lib->callbacks->C_FindObjectsInit(lib->session, + NULL, 0)) == CKR_OPERATION_ACTIVE) + { + rc = pthread_cond_wait ( &lib->pkcs11_cond, + &lib->pkcs11_mutex ); + + if (rc != 0) + { + PKI_log_err("HSM_PKCS11_OBJSK_del_url(): ERROR %d: wait on cond variable", + rc); + } + } + + if( rv != CKR_OK ) { + pthread_cond_broadcast( &lib->pkcs11_cond ); + pthread_mutex_unlock( &lib->pkcs11_mutex ); + + return ( PKI_ERR ); + } + + while ( 1 ) { + rv = lib->callbacks->C_FindObjects(lib->session, &hObject, + 1, &ulObjectCount ); + + if( rv != CKR_OK || ulObjectCount == 0 ) { + PKI_log_debug("[Find] - Find Exiting (rv=0x%8.8X - " + "ulObjectCount = %lu)", rv, ulObjectCount ); + break; + } + + if(( url != NULL ) && ( url->addr != NULL ) && + (strlen(url->addr) > 0) ) { + char *buf = NULL; + char *p = url->addr; + + /* Check the object's ID */ + if((HSM_PKCS11_get_attr_sn( &hObject, &lib->session, + CKA_LABEL, &buf, lib )) > 0) { + + if ( ( !buf ) || (strcmp ( buf, p ) != 0 )) { + // PKI_log_debug("LABEL::Continue" + // " (%s != %s)", buf, p ); + PKI_Free ( buf ); + continue; + } + PKI_Free ( buf ); + } else { + /* No label found, but user provided one! */ + continue; + } + }; + + if( (url != NULL) && (url->path != NULL) && + (strlen(url->path) > 0)) { + BIGNUM *bn = NULL; + char *buf = NULL; + + /* Check the object's ID */ + HSM_PKCS11_get_attr_bn( &hObject, &lib->session, + CKA_ID, &bn, lib ); + if( bn ) { + if( BN_num_bytes ( bn ) > 0 ) { + buf = BN_bn2hex ( bn ); + } + BN_free ( bn ); + } + + if ( buf ) { + if ( strcmp ( buf, url->path ) != 0 ) { + // PKI_log_debug("ID::Continue " + // "(%s != %s)", buf, url->path ); + PKI_Free ( buf ); + continue; + } + PKI_Free ( buf ); + } else { + /* No label found, but user provided one! */ + continue; + } + } + + if ( type != PKI_DATATYPE_ANY ) { + /* Now let's check the Type */ + CK_ULONG objId = 0; + + switch ( type ) { + case PKI_DATATYPE_X509_CERT: + case PKI_DATATYPE_X509_CA: + case PKI_DATATYPE_X509_OTHER: + case PKI_DATATYPE_X509_TRUSTED: + break; + case PKI_DATATYPE_PRIVKEY: + objClass = CKO_PRIVATE_KEY; + break; + case PKI_DATATYPE_PUBKEY: + objClass = CKO_PUBLIC_KEY; + break; + case PKI_DATATYPE_X509_CRL: + case PKI_DATATYPE_X509_REQ: + case PKI_DATATYPE_X509_CMS: + case PKI_DATATYPE_X509_PKCS7: + case PKI_DATATYPE_X509_PKCS12: + default: + objClass = CKO_DATA; + } + + if((HSM_PKCS11_get_attr_ckulong(&hObject, &lib->session, + CKA_CLASS, &objId, lib )) > 0) { + + if ( objId != objClass ) { + // PKI_log_debug("CLASS::Continue " + // "(%d != %d)", objId, objClass); + continue; + } + } + } + + /* Now we should delete the object! */ + if((rv = lib->callbacks->C_DestroyObject(lib->session, hObject)) + != CKR_OK ) { + PKI_log_debug("HSM_PKCS11_del_obj()::Can not destroy " + "object (0x%8.8X)", rv ); + } + } + /* Cleanup the memory for Templates */ + // HSM_PKCS11_clean_template ( templ, (int) idx ); + + if((rv = lib->callbacks->C_FindObjectsFinal(lib->session)) != CKR_OK ) { + PKI_log_debug ("Error in Find Finalize (0x%8.8X)", rv); + pthread_cond_broadcast( &lib->pkcs11_cond ); + pthread_mutex_unlock( &lib->pkcs11_mutex ); + + return ( PKI_ERR ); + } + + pthread_cond_signal( &lib->pkcs11_cond ); + pthread_mutex_unlock( &lib->pkcs11_mutex ); + + return ( PKI_OK ); + +} +/* ------------------------ Internal Functions -------------------------- */ + +PKI_X509_STACK *HSM_PKCS11_KEYPAIR_get_url( URL *url, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ) { + + PKI_X509_KEYPAIR *ret = NULL; + PKI_X509_KEYPAIR_VALUE *val = NULL; + PKI_X509_KEYPAIR_STACK *ret_sk = NULL; + + CK_ATTRIBUTE templ[32]; + CK_ULONG idx = 0; + + CK_ULONG keyType = CKK_RSA; + CK_OBJECT_HANDLE *pubKey = NULL; + CK_OBJECT_HANDLE *privKey = NULL; + + PKCS11_HANDLER *lib = NULL; + + PKI_RSA_KEY *rsa = NULL; + + /* Check the Input */ + if( !url || !url->addr ) return ( NULL ); + + /* We need a valid driver */ + if( !hsm ) { + PKI_ERROR(PKI_ERR_HSM_POINTER_NULL, NULL); + return ( NULL ); + } + + if ((lib = _hsm_get_pkcs11_handler ( hsm )) == NULL ) { + PKI_ERROR(PKI_ERR_HSM_PKCS11_LIB_POINTER_NULL, NULL); + return NULL; + } + + /* And valid credentials */ + /* + if( cred && cred->password ) { + pp = (char *) cred->password; + } + */ + + if( url->proto != URI_PROTO_ID ) { + /* The PKCS11 driver can load only id:// keypairs! */ + return ( NULL ); + } + + /* We need an R/W session for accessing private keys */ + if( HSM_PKCS11_session_new( lib->slot_id, &lib->session, + CKF_SERIAL_SESSION | CKF_RW_SESSION, lib ) != PKI_OK ) { + return ( PKI_ERR ); + } + + PKI_log_debug("HSM_PKCS11_KEYPAIR_get_url()::Got a New Session"); + + /* Login into the device - do nothing if we are already logged in */ + if(( HSM_PKCS11_login ( hsm, cred )) == PKI_ERR ) { + PKI_log_debug("HSM_PKCS11_KEYPAIR_get_url()::ERROR, can not " + "login to device!"); + return ( NULL ); + } + + PKI_log_debug("HSM_PKCS11_KEYPAIR_get_url()::Logged In"); + + /* Build the template in order to search for the private key + we need */ + idx = 0; + HSM_PKCS11_set_attr_int(CKA_CLASS, CKO_PRIVATE_KEY, &templ[idx++]); + PKI_log_debug("HSM_PKCS11_KEYPAIR_get_url()::Adding Label for Search %s (%d)", + url->addr, strlen(url->addr) ); + HSM_PKCS11_set_attr_sn(CKA_LABEL, url->addr, strlen(url->addr), + &templ[idx++]); + if ( url->path != NULL ) { + BIGNUM *bn = NULL; + + if(BN_hex2bn(&bn, url->path) > 0 ) { + HSM_PKCS11_set_attr_bn(CKA_ID, bn, &templ[idx++]); + if( bn ) BN_free (bn); + } + } + + if((privKey = HSM_PKCS11_get_obj( templ, (int) idx, lib, + &lib->session )) == NULL ) { + PKI_log_debug("HSM_PKCS11_KEYPAIR_get_url()::Priv Key not Found (%s)!", + url->addr); + return ( NULL ); + } + + /* Cleanup the memory for Templates */ + HSM_PKCS11_clean_template ( templ, (int) idx ); + + PKI_log_debug("HSM_PKCS11_KEYPAIR_get_url()::Private Key found (%s)!", + url->addr); + + /* Login into the device - do nothing if we are already logged in */ + /* + if(( HSM_PKCS11_login ( driver, cred )) == PKI_ERR ) { + PKI_log_debug("HSM_PKCS11_KEYPAIR_get_url()::ERROR, can not " + "login to device!"); + return ( NULL ); + } + */ + + if ( url->path == NULL ) { + BIGNUM *bn = NULL; + + HSM_PKCS11_get_attr_bn(privKey, &lib->session, + CKA_ID, &bn, lib ); + + if( bn ) { + if( BN_num_bytes ( bn ) > 0 ) { + url->path = BN_bn2hex ( bn ); + } + BN_free ( bn ); + } + } + + // HSM_PKCS11_session_close ( &lib->session, lib ); + + /* We need an R/W session for accessing private keys */ + /* + if( HSM_PKCS11_session_new( lib->slot_id, &lib->session, + CKF_SERIAL_SESSION | CKF_RW_SESSION, lib ) != PKI_OK ) { + PKI_log_err ( "DEBUG::%s:%d", __FILE__, __LINE__ ); + return ( PKI_ERR ); + } + */ + + idx = 0; + HSM_PKCS11_set_attr_int(CKA_CLASS, CKO_PUBLIC_KEY, &templ[idx++]); + // HSM_PKCS11_set_attr_sn(CKA_LABEL, url->addr, strlen(url->addr), + // &templ[idx++]); + if ( url->path != NULL ) { + BIGNUM *bn = NULL; + + if(BN_hex2bn(&bn, url->path)) { + + HSM_PKCS11_set_attr_bn ( CKA_ID, bn, &templ[idx++]); + + /* + char *str = NULL; + int str_len = 0; + + str_len = BN_num_bytes( bn ); + if( str_len ) str = PKI_Malloc ( str_len ); + + if( str ) { + HSM_PKCS11_set_attr_sn(CKA_ID, str, str_len, + &templ[idx++]); + } + */ + } + + if( bn ) BN_free ( bn ); + } + + if((pubKey = HSM_PKCS11_get_obj( templ, (int) idx, + lib, &lib->session )) == NULL ) { + + PKI_log_debug("HSM_PKCS11_KEYPAIR_get_url()::Public Key not Found (%s)!", + url->addr); + return ( NULL ); + } + + PKI_log_debug("HSM_PKCS11_KEYPAIR_get_url()::Public Key found (%s)!", + url->addr ); + + /* Cleanup the memory for Templates */ + HSM_PKCS11_clean_template ( templ, (int) idx ); + + HSM_PKCS11_get_attr_ckulong( privKey, &lib->session, + CKA_KEY_TYPE, &keyType, lib ); + + if( keyType == CKK_RSA ) { + + BIGNUM *e_bn = NULL; + BIGNUM *n_bn = NULL; + + if ((rsa = RSA_new()) == NULL) return NULL; + + if( HSM_PKCS11_get_attr_bn(pubKey, + &lib->session, + CKA_PUBLIC_EXPONENT, + &e_bn, + lib) == PKI_ERR){ + // Reports the error + PKI_log_debug("Can not retrieve pub exponent from " + "key (%s)", url->addr); + // Free the memory + RSA_free ( rsa ); + + // Returns NULL + return NULL; + } + + if( HSM_PKCS11_get_attr_bn( pubKey, &lib->session, + CKA_MODULUS, &n_bn, lib) == PKI_ERR){ + // Reports the error + PKI_log_debug ( "Can not retrieve modulus from key %s", + url->addr); + // Free Memory + if (e_bn) BN_free(e_bn); + RSA_free ( rsa ); + + // Returns NULL + return NULL; + } + +#if OPENSSL_VERSION_NUMBER < 0x1010000fL + + // OpenSSL old assign method + rsa->n = n_bn; + rsa->e = e_bn; + + // Sets the Flags + rsa->flags |= RSA_FLAG_SIGN_VER; +#else + // OpenSSL v1.1.x+ assign method + if (!RSA_set0_key(rsa, n_bn, e_bn, NULL)) { + PKI_log_debug("Can not assign internal RSA values " + "for key %s", url->addr); + + // Free Memory + if (e_bn) BN_free(e_bn); + if (n_bn) BN_free(n_bn); + RSA_free(rsa); + + // Returns NULL + return NULL; + } + + // No Setting of the flags as the RSA_FLAG_SIGN_VER + // has been removed in OpenSSL v1.1.x+ + // RSA_set_flags(rsa, RSA_FLAG_SIGN_VER); +#endif + + /* Let's get the Attributes from the Keypair and store into the + key's pointer */ + RSA_set_method(rsa, HSM_PKCS11_get_rsa_method()); + + /* Push the priv and pub key handlers to the rsa->ex_data */ + RSA_set_ex_data( rsa, KEYPAIR_DRIVER_HANDLER_IDX, hsm ); + RSA_set_ex_data( rsa, KEYPAIR_PRIVKEY_HANDLER_IDX, privKey ); + RSA_set_ex_data( rsa, KEYPAIR_PUBKEY_HANDLER_IDX, pubKey ); + + if((val = (PKI_X509_KEYPAIR_VALUE *) EVP_PKEY_new()) == NULL ) { + PKI_log_debug ( "Memory Error"); + RSA_free ( rsa ); + return ( NULL ); + } + + if(!EVP_PKEY_assign_RSA( (EVP_PKEY *) val, rsa)) { + PKI_log_debug ( "Can not assing RSA key to Keypair!"); + EVP_PKEY_free ( val ); + RSA_free ( rsa ); + return ( NULL ); + } + + } else if ( keyType == CKK_DSA ) { + PKI_log_debug("HSM_PKCS11_KEYPAIR_get_url()::" + "DSA support missing!"); + return NULL; + } else if ( keyType == CKK_EC ) { +#ifdef ENABLE_ECDSA + PKI_log_debug("HSM_PKCS11_KEYPAIR_get_url()::" + "EC support not available, yet!"); +#else + PKI_log_debug("HSM_PKCS11_KEYPAIR_get_url()::" + "library does not have EC support!"); +#endif + return NULL; + } + + if ((ret = PKI_X509_new(PKI_DATATYPE_X509_KEYPAIR, hsm)) == NULL) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + if ( val ) EVP_PKEY_free ( val ); + return (NULL); + } + + ret->value = val; + + /* Allocate the STACK for the return values */ + if((ret_sk = PKI_STACK_X509_KEYPAIR_new()) == NULL ) { + /* Big trouble! */ + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + if (ret) PKI_X509_KEYPAIR_free(ret); + return ( NULL ); + } + + PKI_STACK_X509_KEYPAIR_push( ret_sk, ret ); + + PKI_log_debug( "HSM_PKCS11_KEYPAIR_get_url()::Keypair loaded success!"); + + return ( ret_sk ); +} + +/* --------------------------- General STACK get/put ----------------------- */ + +PKI_X509_STACK *HSM_PKCS11_STACK_get_url( PKI_DATATYPE type, URL *url, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ) { + + PKI_STACK *ret_sk = NULL; + + CK_ATTRIBUTE templ[32]; + CK_ULONG idx = 0; + CK_ULONG objClass; + CK_RV rv; + + int rc = 0; + + PKCS11_HANDLER *lib = NULL; + + CK_OBJECT_HANDLE hObject; + CK_ULONG ulObjectCount; + + char myLabel[512]; + + if((type == PKI_DATATYPE_X509_KEYPAIR) || + (type == PKI_DATATYPE_SECRET_KEY )) { + return HSM_PKCS11_KEYPAIR_get_url( url, format, cred, hsm ); + } + + /* Check the Input */ + if( !url || !url->addr ) return ( NULL ); + + /* We need a valid driver */ + if( !hsm ) { + PKI_ERROR(PKI_ERR_HSM_POINTER_NULL, NULL); + return NULL; + } + + if ((lib = _hsm_get_pkcs11_handler ( hsm )) == NULL ) { + PKI_ERROR(PKI_ERR_HSM_PKCS11_LIB_POINTER_NULL, NULL); + return NULL; + } + + if( url->proto != URI_PROTO_ID ) { + /* The PKCS11 driver can load only id:// keypairs! */ + return ( NULL ); + } + + /* We need an R/W session only for accessing private keys, AFAIK. + * Therefore now we do not use CKF_RW_SESSION as a flag. */ + if( HSM_PKCS11_session_new( lib->slot_id, &lib->session, + CKF_SERIAL_SESSION, lib ) != PKI_OK ) { + return ( NULL ); + } + + /* Login into the device - do nothing if we are already logged in */ + if(( HSM_PKCS11_login ( hsm, cred )) == PKI_ERR ) { + PKI_log_debug("HSM_PKCS11_STACK_get_url()::ERROR, can not " + "login to device!"); + return ( NULL ); + } + + /* Build the template in order to search for the object + we need */ + memset(myLabel, 0x0, sizeof(myLabel)); + strncpy(myLabel, url->addr, sizeof(myLabel) - 1); + switch ( type ) { + case PKI_DATATYPE_X509_CERT: + objClass = CKO_CERTIFICATE; + ret_sk = PKI_STACK_X509_CERT_new(); + break; + case PKI_DATATYPE_X509_CRL: + objClass = CKO_DATA; + strncat(myLabel, "'s CRL", sizeof(myLabel) - 1); + ret_sk = PKI_STACK_X509_CRL_new(); + break; + case PKI_DATATYPE_X509_REQ: + objClass = CKO_DATA; + strncat(myLabel, "'s Request", sizeof(myLabel) - 1); + ret_sk = PKI_STACK_X509_REQ_new(); + break; + case PKI_DATATYPE_X509_CA: + objClass = CKO_CERTIFICATE; + strncat(myLabel, "'s CA", sizeof(myLabel) - 1); + ret_sk = PKI_STACK_X509_CERT_new(); + break; + case PKI_DATATYPE_X509_TRUSTED: + objClass = CKO_CERTIFICATE; + strncat(myLabel, "'s TA Cert", sizeof(myLabel) - 1); + ret_sk = PKI_STACK_X509_CERT_new(); + break; + case PKI_DATATYPE_X509_OTHER: + objClass = CKO_CERTIFICATE; + strncat(myLabel, "'s Other Cert", sizeof(myLabel) - 1); + ret_sk = PKI_STACK_X509_CERT_new(); + break; + case PKI_DATATYPE_X509_PKCS7: + objClass = CKO_SECRET_KEY; + ret_sk = PKI_STACK_X509_KEYPAIR_new(); + break; + case PKI_DATATYPE_X509_PKCS12: + objClass = CKO_SECRET_KEY; + ret_sk = PKI_STACK_X509_KEYPAIR_new(); + break; + case PKI_DATATYPE_CRED: + default: + ret_sk = PKI_STACK_X509_new(); + objClass = CKO_DATA; + break; + } + + idx = 0; + HSM_PKCS11_set_attr_int(CKA_CLASS, objClass, &templ[idx++]); + HSM_PKCS11_set_attr_sn(CKA_LABEL, myLabel, strlen(myLabel), + &templ[idx++]); + HSM_PKCS11_set_attr_sn(CKA_APPLICATION, myLabel, strlen(myLabel), + &templ[idx++]); + + if ( url->path != NULL ) { + HSM_PKCS11_set_attr_sn(CKA_ID, url->path, + strlen( url->path ), &templ[idx++]); + } + + rc = pthread_mutex_lock( &lib->pkcs11_mutex ); + if (rc != 0) + { + PKI_log_err("HSM_PKCS11_STACK_get_url()::pthread_mutex_lock() failed with %d at %s:%d", + rc, __FILE__, __LINE__); + return PKI_ERR; + } + + while(( rv = lib->callbacks->C_FindObjectsInit(lib->session, + templ, idx)) == CKR_OPERATION_ACTIVE) + { + rc = pthread_cond_wait(&lib->pkcs11_cond, &lib->pkcs11_mutex); + if (rc != 0) + { + PKI_log_err("HSM_PKCS11_STACK_get_url(): ERROR %d: wait on cond variable", rc); + } + } + + if( rv != CKR_OK ) { + PKI_log_debug("HSM_PKCS11_STACK_get_url()::" + "Error in Find Initialization (0x%8.8X)", rv); + pthread_cond_broadcast( &lib->pkcs11_cond ); + pthread_mutex_unlock( &lib->pkcs11_mutex ); + + return ( PKI_ERR ); + } + + while ( 1 ) { + PKI_MEM *mem = NULL; + PKI_STACK *tmp_sk = NULL; + void * x = NULL; + CK_ULONG size = 0; + + rv = lib->callbacks->C_FindObjects(lib->session, &hObject, + 1, &ulObjectCount ); + + if( rv != CKR_OK || ulObjectCount == 0 ) { + // PKI_log_debug("[Find] - Find Exiting (rv=0x%8.8X - " + // "ulObjectCount = %lu", rv, ulObjectCount ); + break; + } + + if(( mem = PKI_MEM_new_null()) == NULL ) { + return ( NULL ); + } + + HSM_PKCS11_get_attribute (&hObject, &lib->session, + CKA_VALUE, (void **) &mem->data, &size, lib ); + mem->size = (size_t) size; + + switch ( type ) { + case PKI_DATATYPE_X509_OTHER: + case PKI_DATATYPE_X509_TRUSTED: + case PKI_DATATYPE_X509_CA: + case PKI_DATATYPE_X509_CERT: + // tmp_sk = PKI_X509_CERT_STACK_get_mem(mem, cred); + // break; + case PKI_DATATYPE_X509_CRL: + // tmp_sk = PKI_X509_CRL_STACK_get_mem(mem, cred); + // break; + case PKI_DATATYPE_X509_REQ: + // tmp_sk = PKI_X509_REQ_STACK_get_mem(mem, cred); + // break; + case PKI_DATATYPE_X509_CMS: + case PKI_DATATYPE_X509_PKCS7: + case PKI_DATATYPE_X509_PKCS12: + tmp_sk = PKI_X509_STACK_get_mem(mem, type, + format, cred, hsm ); + break; + case PKI_DATATYPE_CRED: + default: + break; + } + + if ( !tmp_sk ) { + continue; + } + + while((x = PKI_STACK_pop(tmp_sk)) != NULL ) { + PKI_X509 *n_obj = NULL; + n_obj = PKI_X509_new ( type, hsm ); + if( n_obj ) { + n_obj->value = x; + PKI_STACK_push (ret_sk, n_obj ); + } + } + + if( tmp_sk ) PKI_STACK_free ( tmp_sk ); + if( mem ) PKI_MEM_free ( mem ); + + } + /* Cleanup the memory for Templates */ + HSM_PKCS11_clean_template ( templ, (int) idx ); + + if((rv = lib->callbacks->C_FindObjectsFinal(lib->session)) != CKR_OK ) { + PKI_log_debug ("Error in Find Finalize (0x%8.8X)", rv); + pthread_cond_broadcast( &lib->pkcs11_cond ); + pthread_mutex_unlock( &lib->pkcs11_mutex ); + + return ( PKI_ERR ); + } + + pthread_cond_signal( &lib->pkcs11_cond ); + pthread_mutex_unlock( &lib->pkcs11_mutex ); + + return ( ret_sk ); +} + +int HSM_PKCS11_STACK_add_url( PKI_X509_STACK *sk, URL *url, + PKI_CRED *cred, HSM *hsm ) { + + char myLabel[2048]; + + CK_ATTRIBUTE templ[32]; + + CK_ULONG idx = 0; + // CK_ULONG objClass; + + PKCS11_HANDLER *lib = NULL; + CK_OBJECT_HANDLE *obj = NULL; + + // int (*func)() = NULL; + PKI_X509 * x = NULL; + int path_len = 0; + + if ( !sk || !url ) return ( PKI_ERR ); + + /* We need a valid driver */ + if( !hsm ) { + PKI_log_debug ( "HSM_PKCS11_STACK_add_url()::ERROR, no " + "hsm driver provided!"); + return ( PKI_ERR ); + } + + if ((lib = _hsm_get_pkcs11_handler ( hsm )) == NULL ) { + PKI_log_debug ("HSM_PKCS11_STACK_add_url()::No handler"); + return ( PKI_ERR ); + } + + if( url->proto != URI_PROTO_ID ) { + /* The PKCS11 driver can load only id:// keypairs! */ + PKI_log_debug ("HSM_PKCS11_STACK_add_url()::Wrong protocol!"); + return ( PKI_ERR ); + } + + /* We need an R/W session for creating objects on Token */ + if( HSM_PKCS11_session_new( lib->slot_id, &lib->session, + CKF_SERIAL_SESSION | CKF_RW_SESSION, lib ) != PKI_OK ) { + return ( PKI_ERR ); + } + + /* Login into the device - do nothing if we are already logged in */ + if(( HSM_PKCS11_login ( hsm, cred )) == PKI_ERR ) { + PKI_log_debug("HSM_PKCS11_STACK_put_url()::ERROR, can not " + "login to device!"); + return ( PKI_ERR ); + } + + memset(myLabel, 0x0, sizeof(myLabel)); + strncpy(myLabel, url->addr, sizeof(myLabel) - 1); + + if( url->path ) { + path_len = (int) strlen( url->path ); + } + + while ( ( x = PKI_STACK_pop( sk )) != NULL ) { + + int ret = PKI_OK; + + idx = 0; + + switch (x->type) + { + case PKI_DATATYPE_X509_CERT: + idx = (CK_ULONG) + HSM_PKCS11_X509_CERT_get_template(templ, x, + myLabel, (int) strlen(myLabel), url->path, path_len); + break; + case PKI_DATATYPE_X509_CRL: + // objClass = CKO_DATA; + // func = i2d_X509_CRL; + strncat(myLabel, "'s CRL", sizeof(myLabel) - 1); + break; + case PKI_DATATYPE_X509_REQ: + // objClass = CKO_DATA; + // func = i2d_X509_REQ; + strncat(myLabel, "'s Request", sizeof(myLabel) - 1); + break; + case PKI_DATATYPE_X509_CA: + idx = (CK_ULONG) + HSM_PKCS11_X509_CERT_get_template ( + templ, x, myLabel, (int) strlen(myLabel), + url->path, path_len ); + break; + case PKI_DATATYPE_X509_TRUSTED: + idx = (CK_ULONG) + HSM_PKCS11_X509_CERT_get_template ( + templ, x, + myLabel, (int) strlen(myLabel), + url->path, path_len ); + break; + case PKI_DATATYPE_X509_OTHER: + idx = (CK_ULONG) + HSM_PKCS11_X509_CERT_get_template ( + templ, x, + myLabel, (int) strlen(myLabel), + url->path, path_len ); + break; + case PKI_DATATYPE_SECRET_KEY: + // objClass = CKO_SECRET_KEY; + // func = NULL; + break; + case PKI_DATATYPE_X509_PKCS7: + case PKI_DATATYPE_X509_PKCS12: + case PKI_DATATYPE_CRED: + default: + // objClass = CKO_DATA; + // func = NULL; + break; + } + + if( ret == 0 ) { + PKI_log_debug ("ERROR, can not get obj template!"); + return ( PKI_ERR ); + } + + if(( obj = HSM_PKCS11_create_obj( &lib->session, templ, + (int) idx, lib)) == NULL) { + PKI_log_debug("HSM_PKCS11_STACK_add_url()::Object " + "Create Failed!"); + HSM_PKCS11_clean_template ( templ, (int) idx ); + return ( PKI_ERR ); + } else { + PKI_log_debug("HSM_PKCS11_STACK_add_url()::Object " + "create successful (%p)", obj ); + } + + /* Let's clean the memory associated with the template */ + HSM_PKCS11_clean_template ( templ, (int) idx ); + + /* Let's fix the Object ID */ + if( url->path ) { + BIGNUM *id_num = NULL; + unsigned char *tmp_s = NULL; + int id_num_len = 0; + + if((BN_hex2bn(&id_num, url->path )) == 0 ) { + PKI_log_debug("ERROR, can not convert %s " + "to BIGNUM", url->path ); + } else { + idx = 0; + if((id_num_len = BN_num_bytes(id_num)) > 0 ) { + tmp_s = PKI_Malloc((size_t) id_num_len); + BN_bn2bin( id_num, tmp_s ); + + HSM_PKCS11_save_attr_sn ( obj, CKA_ID, + (char *) tmp_s, id_num_len, + &lib->session, lib ); + if( tmp_s ) PKI_Free ( tmp_s ); + } + } + + if( id_num ) BN_free ( id_num ); + + } else if ( x->type == PKI_DATATYPE_X509_CERT ) { + CK_OBJECT_HANDLE *pKey = NULL; + char *key_id = NULL; + int key_id_len = 0; + + if((pKey = HSM_PKCS11_X509_CERT_find_private_key ( + (PKI_X509_CERT *)x, &lib->session, lib )) + == NULL ) { + /* Nothing more to do - let's go to the + * next object */ + PKI_Free ( obj ); + continue; + } + + if((key_id_len = HSM_PKCS11_get_attr_sn( pKey, + &lib->session, CKA_ID, &key_id, lib)) > 0) { + HSM_PKCS11_save_attr_sn( obj, CKA_ID, + key_id, key_id_len, &lib->session,lib); + } + } + + /* Let's free the memory associated to the obj */ + PKI_Free ( obj ); + + } + + return ( PKI_OK ); +} + +int HSM_PKCS11_KEYPAIR_STACK_add_url ( PKI_X509_STACK *sk, URL *url, + PKI_CRED *cred, HSM *hsm ) { + + int i = 0; + + if( !sk ) return ( PKI_ERR ); + + for( i = 0; i < PKI_STACK_elements( sk ); i++ ) { + PKI_X509_KEYPAIR *pk = NULL; + + if(( pk = (PKI_X509_KEYPAIR *) PKI_STACK_get_num(sk, i))==NULL){ + return( PKI_ERR ); + } + if(HSM_PKCS11_KEYPAIR_add_url(pk, url, cred, hsm) == PKI_ERR) { + return ( PKI_ERR ); + } + } + + return ( PKI_OK ); +}; + +int HSM_PKCS11_KEYPAIR_add_url ( PKI_X509_KEYPAIR *x_key, URL *url, + PKI_CRED *cred, HSM *hsm ) { + + PKI_X509_KEYPAIR_VALUE *pk = NULL; + RSA *rsa = NULL; + int n = 0; + + CK_ATTRIBUTE templ[32]; + CK_OBJECT_HANDLE *obj = NULL; + + PKCS11_HANDLER *lib = NULL; + + BIGNUM *id_num = NULL; + + char *id = NULL; + int id_len = 8; + + char *label = NULL; + + if( !x_key || !x_key->value ) return PKI_ERR; + + pk = x_key->value; + + if( !pk || ((rsa = EVP_PKEY_get1_RSA((EVP_PKEY *) pk)) == NULL) ) { + return ( PKI_ERR ); + } + + /* We need a valid driver */ + if( !hsm ) { + PKI_log_debug ( "HSM_PKCS11_KEYPAIR_add_url()::ERROR, no " + "hsm driver provided!"); + return ( PKI_ERR ); + } + + if ((lib = _hsm_get_pkcs11_handler ( hsm )) == NULL ) { + PKI_log_debug ("HSM_PKCS11_KEYPAIR_add_url()::No handler"); + return ( PKI_ERR ); + } + + if( url->proto != URI_PROTO_ID ) { + /* The PKCS11 driver can load only id:// keypairs! */ + PKI_log_debug ("HSM_PKCS11_KEYPAIR_add_url()::Wrong protocol!"); + return ( PKI_ERR ); + } + + /* We need an R/W session for creating objects on Token */ + if( HSM_PKCS11_session_new( lib->slot_id, &lib->session, + CKF_SERIAL_SESSION | CKF_RW_SESSION, lib ) != PKI_OK ) { + return ( PKI_ERR ); + } + + /* Login into the device - do nothing if we are already logged in */ + if(( HSM_PKCS11_login ( hsm, cred )) == PKI_ERR ) { + PKI_log_debug("HSM_PKCS11_KEYPAIR_put_url()::ERROR, can not " + "login to device!"); + return ( PKI_ERR ); + } + + /* Check for the Label */ + if ( (url->addr) && (strlen(url->addr) > 0) ) { + label = url->addr; + } + + /* Check for the ID */ + if ( (url->path) && (strlen(url->path) > 0) ) { + if((BN_hex2bn(&id_num, url->path )) == 0 ) { + PKI_log_debug("ERROR, can not convert %s to BIGNUM", + url->path ); + goto err; + } + if((id_len = BN_num_bytes(id_num)) < 0 ) { + goto err; + } + id = PKI_Malloc ( (size_t ) id_len ); + BN_bn2bin( id_num, (unsigned char *) id ); + } else { + id_len = 10; + if((id = PKI_Malloc ( (size_t) id_len )) == NULL ) { + PKI_log_err ("Memory Error"); + goto err; + } + + if( RAND_bytes( (unsigned char *) id, id_len) == 0 ) { + PKI_log_debug("ERROR, can not generate RAND bytes!"); + goto err; + } + } + + /* Now set the template for the Private Key */ + n = 0; + HSM_PKCS11_set_attr_int( CKA_CLASS, CKO_PRIVATE_KEY, &templ[n++]); + HSM_PKCS11_set_attr_int( CKA_KEY_TYPE, CKK_RSA, &templ[n++]); + HSM_PKCS11_set_attr_bool( CKA_TOKEN, CK_TRUE, &templ[n++]); + HSM_PKCS11_set_attr_bool( CKA_SENSITIVE, CK_TRUE, &templ[n++]); + HSM_PKCS11_set_attr_bool( CKA_PRIVATE, CK_TRUE, &templ[n++]); + + HSM_PKCS11_set_attr_bool( CKA_UNWRAP, CK_TRUE, &templ[n++]); + HSM_PKCS11_set_attr_bool( CKA_DECRYPT, CK_TRUE, &templ[n++]); + HSM_PKCS11_set_attr_bool( CKA_SIGN, CK_TRUE, &templ[n++]); + HSM_PKCS11_set_attr_bool( CKA_SIGN_RECOVER, CK_TRUE, &templ[n++]); + +#if OPENSSL_VERSION_NUMBER < 0x1010000fL + HSM_PKCS11_set_attr_bn(CKA_MODULUS, rsa->n, &templ[n++]); + HSM_PKCS11_set_attr_bn(CKA_PUBLIC_EXPONENT, rsa->e, &templ[n++]); + HSM_PKCS11_set_attr_bn(CKA_PRIVATE_EXPONENT, rsa->d, &templ[n++]); + HSM_PKCS11_set_attr_bn(CKA_PRIME_1, rsa->p, &templ[n++]); + HSM_PKCS11_set_attr_bn(CKA_PRIME_2, rsa->q, &templ[n++]); + HSM_PKCS11_set_attr_bn(CKA_EXPONENT_1, rsa->dmp1, &templ[n++]); + HSM_PKCS11_set_attr_bn(CKA_EXPONENT_2, rsa->dmq1, &templ[n++]); + HSM_PKCS11_set_attr_bn(CKA_COEFFICIENT, rsa->iqmp, &templ[n++]); +#else + const BIGNUM * n_bn; + const BIGNUM * e_bn; + const BIGNUM * d_bn; + + const BIGNUM * p_bn; + const BIGNUM * q_bn; + const BIGNUM * dmp1_bn; + const BIGNUM * dmq1_bn; + const BIGNUM * iqmp_bn; + + // Gets the References to the required internal attributes + RSA_get0_key(rsa, &n_bn, &e_bn, &d_bn); + RSA_get0_factors(rsa, &p_bn, &q_bn); + RSA_get0_crt_params(rsa, &dmp1_bn, &dmq1_bn, &iqmp_bn); + + // Sets the attributes + HSM_PKCS11_set_attr_bn(CKA_MODULUS, n_bn, &templ[n++]); + HSM_PKCS11_set_attr_bn(CKA_PUBLIC_EXPONENT, e_bn, &templ[n++]); + HSM_PKCS11_set_attr_bn(CKA_PRIVATE_EXPONENT, d_bn, &templ[n++]); + HSM_PKCS11_set_attr_bn(CKA_PRIME_1, p_bn, &templ[n++]); + HSM_PKCS11_set_attr_bn(CKA_PRIME_2, q_bn, &templ[n++]); + HSM_PKCS11_set_attr_bn(CKA_EXPONENT_1, dmp1_bn, &templ[n++]); + HSM_PKCS11_set_attr_bn(CKA_EXPONENT_2, dmq1_bn, &templ[n++]); + HSM_PKCS11_set_attr_bn(CKA_COEFFICIENT, iqmp_bn, &templ[n++]); +#endif + + HSM_PKCS11_set_attr_bool( CKA_EXTRACTABLE, CK_FALSE, &templ[n++]); + HSM_PKCS11_set_attr_bool( CKA_MODIFIABLE, CK_TRUE, &templ[n++]); + HSM_PKCS11_set_attr_bool( CKA_DERIVE, CK_FALSE, &templ[n++]); + + if ( label != NULL ) { + HSM_PKCS11_set_attr_sn(CKA_LABEL, label, + strlen(label), &templ[n++]); + } + + if ( id_len > 0 ) { + HSM_PKCS11_set_attr_sn(CKA_ID, id, (size_t)id_len, &templ[n++]); + } + + if((obj = HSM_PKCS11_create_obj( &lib->session, templ, n, lib))==NULL) { + PKI_log_debug("HSM_PKCS11_store_pub_key()::Object Create " + "Failed!"); + goto err; + } + + HSM_PKCS11_clean_template ( templ, n ); + + /* This is the template for the Public Key */ + n = 0; + HSM_PKCS11_set_attr_int( CKA_CLASS, CKO_PUBLIC_KEY, &templ[n++]); + HSM_PKCS11_set_attr_int( CKA_KEY_TYPE, CKK_RSA, &templ[n++]); + + HSM_PKCS11_set_attr_bool( CKA_TOKEN, CK_TRUE, &templ[n++]); + HSM_PKCS11_set_attr_bool( CKA_ENCRYPT, CK_TRUE, &templ[n++]); + HSM_PKCS11_set_attr_bool( CKA_VERIFY, CK_TRUE, &templ[n++]); + HSM_PKCS11_set_attr_bool( CKA_WRAP, CK_TRUE, &templ[n++]); + +#if OPENSSL_VERSION_NUMBER < 0x1010000fL + HSM_PKCS11_set_attr_bn(CKA_MODULUS, rsa->n, &templ[n++]); + HSM_PKCS11_set_attr_bn(CKA_PUBLIC_EXPONENT, rsa->e, &templ[n++]); +#else + HSM_PKCS11_set_attr_bn(CKA_MODULUS, n_bn, &templ[n++]); + HSM_PKCS11_set_attr_bn(CKA_PUBLIC_EXPONENT, e_bn, &templ[n++]); +#endif + + if (id_len > 0) HSM_PKCS11_set_attr_sn(CKA_ID, id, + (size_t)id_len, &templ[n++]); + + if ( label != NULL ) HSM_PKCS11_set_attr_sn(CKA_LABEL, label, + strlen(label), &templ[n++]); + + if((obj = HSM_PKCS11_create_obj( &lib->session, templ, n, lib))==NULL) { + PKI_log_debug("HSM_PKCS11_store_pub_key()::Object Create " + "Failed!"); + goto err; + } + + HSM_PKCS11_clean_template ( templ, n ); + + if ( id_num ) BN_free ( id_num ); + if ( id ) PKI_Free ( id ); + + return ( PKI_OK ); + +err: + if ( id_num ) BN_free ( id_num ); + if ( id ) PKI_Free ( id ); + + if ( n > 0 ) HSM_PKCS11_clean_template ( templ, n ); + + return PKI_ERR; +} + +/* ------------------------ get Template(s) functions --------------------- */ +int HSM_PKCS11_X509_CERT_get_template (CK_ATTRIBUTE *templ, PKI_X509_CERT *x, + char *label, int label_len, + char *id, int id_len ) { + + int idx = 0; + int len = 0; + PKI_MEM *mem = NULL; + unsigned char * value = NULL; + + if( !templ || !x || !x->value ) return ( PKI_ERR ); + + idx = 0; + HSM_PKCS11_set_attr_int( CKA_CLASS, CKO_CERTIFICATE, &templ[idx++]); + HSM_PKCS11_set_attr_int( CKA_CERTIFICATE_TYPE, CKC_X_509, + &templ[idx++]); + HSM_PKCS11_set_attr_bool( CKA_TOKEN, CK_TRUE, &templ[idx++]); + + if ( label ) { + HSM_PKCS11_set_attr_sn ( CKA_LABEL, label, strlen(label), + &templ[idx++] ); + } + + if((len = _get_der ( x->value, PKI_DATATYPE_X509_CERT, + PKI_X509_DATA_SUBJECT, &value )) > 0 ) { + if( value ) { + HSM_PKCS11_set_attr_sn( CKA_SUBJECT, + (char *) value, (size_t) len, &templ[idx++]); + PKI_Free ( value ); + value = NULL; + } else { + PKI_log_debug("ERROR, can not get the cert Subject!"); + HSM_PKCS11_clean_template( templ, idx ); + return ( 0 ); + } + } + + if( label ) { + HSM_PKCS11_set_attr_sn ( CKA_ID, label, (size_t) label_len, + &templ[idx++] ); + } + + value = NULL; + if ( ( mem = PKI_X509_put_mem(x, PKI_DATA_FORMAT_ASN1, + NULL, NULL )) != NULL) { + // if ( (len = i2d_X509( x->value, &value )) > 0 ) { + // if( value ) { + HSM_PKCS11_set_attr_sn(CKA_VALUE, (char *) mem->data, + (size_t) mem->size, &templ[idx++]); + PKI_MEM_free ( mem ); + } else { + PKI_log_debug("ERROR, can not convert cert to DER!"); + HSM_PKCS11_clean_template ( templ, idx ); + return ( PKI_ERR ); + } + + return ( idx ); +} + +CK_OBJECT_HANDLE * HSM_PKCS11_X509_CERT_find_private_key ( PKI_X509_CERT *x, + CK_SESSION_HANDLE *hSession, PKCS11_HANDLER *lib ) { + + const PKI_X509_KEYPAIR_VALUE *pk = NULL; + + CK_ATTRIBUTE templ[32]; + CK_OBJECT_HANDLE *ret = NULL; + + int idx = 0; + int key_type; + + if( !x || !x->value || !hSession || !lib || !lib->callbacks ) + return ( NULL ); + + if((pk = PKI_X509_CERT_get_data( x, PKI_X509_DATA_KEYPAIR_VALUE )) + == NULL ) { + /* No key - we can not find the private one! */ + return ( NULL ); + } + + /* Let's create the template for searching the Key */ + idx = 0; + HSM_PKCS11_set_attr_int( CKA_CLASS, CKO_PRIVATE_KEY, &templ[idx++]); + +// #if OPENSSL_VERSION_NUMBER > 0x30000000L +// key_type = EVP_PKEY_type(PKI_X509_KEYPAIR_VALUE_get_id(pk)); +// #elif OPENSSL_VERSION_NUMBER < 0x1010000fL +// key_type = EVP_PKEY_type ( ((EVP_PKEY*)pk)->type ); +// #else +// key_type = EVP_PKEY_type(EVP_PKEY_id(pk)); +// #endif + key_type = PKI_X509_KEYPAIR_VALUE_get_id(pk); + if (key_type == EVP_PKEY_RSA) + { + PKI_RSA_KEY * rsa = NULL; + + // Set Key Type + HSM_PKCS11_set_attr_int(CKA_KEY_TYPE, CKK_RSA,&templ[idx++]); + + // Gets the reference to the RSA key + if ((rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)pk)) == NULL) goto err; + +#if OPENSSL_VERSION_NUMBER < 0x1010000fL + + // Sets the parameters in the template + HSM_PKCS11_set_attr_bn(CKA_MODULUS, rsa->n, &templ[idx++]); + HSM_PKCS11_set_attr_bn(CKA_PUBLIC_EXPONENT, rsa->e, + &templ[idx++]); +#else + const BIGNUM * n_bn; + const BIGNUM * e_bn; + const BIGNUM * d_bn; + + // Gets the RSA public parameters + RSA_get0_key(rsa, &n_bn, &e_bn, &d_bn); + + // Sets the parameters in the template + HSM_PKCS11_set_attr_bn(CKA_MODULUS, n_bn, &templ[idx++]); + HSM_PKCS11_set_attr_bn(CKA_PUBLIC_EXPONENT, e_bn, &templ[idx++]); +#endif + // Free the memory from the get1 operation + if (rsa) RSA_free(rsa); + + } + else if ( key_type == EVP_PKEY_DSA ) + { + // PKI_DSA_KEY *dsa = NULL; + // dsa = EVP_PKEY_get1_DSA ( (EVP_PKEY *) pk ); + PKI_log_debug ( "DEBUG::DSA Code Missing (%s:%d)!", __FILE__, __LINE__ ); +#ifdef ENABLE_ECDSA + } + else if ( key_type == EVP_PKEY_EC ) + { + // PKI_EC_KEY *ecdsa = NULL; + // ecdsa = EVP_PKEY_get1_EC_KEY ( (EVP_PKEY *) pk ); + PKI_log_debug ("DEBUG::ECDSA Code Missing (%s:%d)!", + __FILE__, __LINE__ ); +#endif + } + else + { + PKI_log_debug ("%s:%d::Key format unknown", __FILE__, __LINE__); + goto err; + } + + ret = HSM_PKCS11_get_obj ( templ, idx, lib, &lib->session ); + + HSM_PKCS11_clean_template( templ, idx ); + + return ( ret ); +err: + HSM_PKCS11_clean_template( templ, idx ); + return ( NULL ); +} + diff --git a/src/crypto/hsm/pkcs11/pkcs11_hsm_pkey.c b/src/crypto/hsm/pkcs11/pkcs11_hsm_pkey.c new file mode 100644 index 00000000..d1f0f7e9 --- /dev/null +++ b/src/crypto/hsm/pkcs11/pkcs11_hsm_pkey.c @@ -0,0 +1,1438 @@ +/* pkcs11/pki_pkey.c */ + +#include +#include + +/* Internal usage only - we want to keep the lib abstract */ +#ifndef _LIBPKI_HSM_PKCS11_PKEY_H +#define _LIBPKI_HSM_PKCS11_PKEY_H + +#define PKI_RSA_KEY RSA +#define PKI_DSA_KEY DSA + +#ifdef ENABLE_ECDSA +#define PKI_EC_KEY EC_KEY +#endif + +#define PKI_RSA_KEY_MIN_SIZE 1024 +#define PKI_DSA_KEY_MIN_SIZE 1024 +#define PKI_EC_KEY_MIN_SIZE 128 + +#define RSA_SIGNATURE_MAX_SIZE 8192 + +PKI_RSA_KEY * _pki_pkcs11_rsakey_new( PKI_KEYPARAMS *kp, URL *url, + PKCS11_HANDLER *lib, void *driver ); + +PKI_DSA_KEY * _pki_pkcs11_dsakey_new( PKI_KEYPARAMS *kp, URL *url, + PKCS11_HANDLER *lib, void *driver ); +#ifdef ENABLE_ECDSA +PKI_EC_KEY * _pki_pkcs11_ecdsakey_new( PKI_KEYPARAMS *kp, + URL *url, PKCS11_HANDLER *lib, void *driver ); +#else +void * _pki_pkcs11_ecdsakey_new( PKI_KEYPARAMS *kp, + URL *url, PKCS11_HANDLER *lib, void *driver ); +#endif + +int _pki_pkcs11_rand_init( void ); + +/* End of _LIBPKI_INTERNAL_PKEY_H */ +#endif + + +// Definition for the RSA Key Generation Mechs +#define RSA_MECH_LIST_SIZE 2 +static CK_MECHANISM RSA_MECH_LIST[RSA_MECH_LIST_SIZE] = { + {CKM_RSA_X9_31_KEY_PAIR_GEN, NULL_PTR, 0 }, + {CKM_RSA_PKCS_KEY_PAIR_GEN, NULL_PTR, 0 } +}; + +#ifdef ENABLE_ECDSA +// Definitions for the ECDSA Key Generation Mechs +#define EC_MECH_LIST_SIZE 1 +static CK_MECHANISM EC_MECH_LIST[EC_MECH_LIST_SIZE] = { + {CKM_EC_KEY_PAIR_GEN, NULL_PTR, 0} +}; +#endif + +#ifdef __DISABLED__ +// Currently Disabled +// Definitions for the DSA Key Generation Mechs +#define DSA_MECH_LIST_SIZE 1 +static CK_MECHANISM DSA_MECH_LIST[DSA_MECH_LIST_SIZE] = { + {CKM_DSA_KEY_PAIR_GEN, NULL_PTR, 0} +} +#endif + +/* ---------------------------- Functions -------------------------------- */ + +int _pki_pkcs11_rand_seed( void ) { + unsigned char seed[20]; + + if (!RAND_bytes(seed, 20)) return 0; + RAND_seed(seed, sizeof seed); + + return(1); +} + +/* +size_t _get_key_id ( char *id, size_t size ) { + + unsigned char id_rand[1024]; + int rand_len = 0; + int n = 0; + + BIGNUM *bn; + + if( BN_hex2bn(&bn, id) == 0 ) { + return ( 0 ); + } + + if( RAND_bytes( id_rand, rand_len) == 0 ) { + return ( 0 ); + } + + memset( id, 0x0, size ); + for( n = 0; n < rand_len; n++ ) { + char * dest = NULL; + + dest = (char *) id + n*2 + n; + sprintf(dest, "%2.2x", (CK_BYTE) id_rand[n] ); + + if( n < sizeof(id_rand)-1 ) dest[2] = ':'; + } + + return ( strlen(id) ); +} +*/ + +PKI_RSA_KEY * _pki_pkcs11_rsakey_new( PKI_KEYPARAMS *kp, URL *url, + PKCS11_HANDLER *lib, void *driver) { + + PKI_RSA_KEY *ret = NULL; + + CK_OBJECT_HANDLE *handler_pubkey = NULL; + CK_OBJECT_HANDLE *handler_privkey = NULL; + + CK_ATTRIBUTE privTemp[32]; + CK_ATTRIBUTE pubTemp[32]; + + CK_RV rv; + + CK_MECHANISM * RSA_MECH_PTR = NULL; + + CK_ULONG i = 0; + CK_ULONG n = 0; + + CK_ULONG bits = 0; + + size_t label_len = 0; + + unsigned char *data = NULL; + CK_BYTE *esp = NULL; + CK_ULONG size = 0; + + BIGNUM *bn = NULL; + BIGNUM *id_num = NULL; + + char *id = NULL; + int id_len = 8; + + int idx = 0; + + if ( !url || !url->addr ) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return ( NULL ); + } + + label_len = strlen( url->addr ); + + /* Check the min size for the key */ + if ( kp ) { + if( kp->bits < PKI_RSA_KEY_MIN_SIZE ) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_SIZE_SHORT, NULL); + } else { + bits = (CK_ULONG) kp->bits; + } + } else { + bits = PKI_RSA_KEY_DEFAULT_SIZE; + } + + // Look for a supported key generation mechanism + for (idx = 0; idx < RSA_MECH_LIST_SIZE; idx++) { + + // Checks if the mechanism is supported + if (HSM_PKCS11_check_mechanism(lib, + RSA_MECH_LIST[idx].mechanism) == PKI_OK) { + + // Set the pointer to the supported mechanism + RSA_MECH_PTR = &RSA_MECH_LIST[idx]; + + // Debugging Information + PKI_DEBUG("Found RSA KEY GEN MECHANISM 0x%8.8X", + RSA_MECH_LIST[idx].mechanism); + + // Breaks out of the loop + break; + + } else { + + // Let's provide debug information for not-supported mechs + PKI_DEBUG("RSA KEY GEN MECHANISM 0x%8.8X not supported", + RSA_MECH_LIST[idx].mechanism); + } + } + + // If no key gen algors are supported, abort + if (RSA_MECH_PTR == NULL) { + PKI_ERROR(PKI_ERR_HSM_KEYPAIR_GENERATE, "No KeyGen Mechanisms supported!"); + return NULL; + } + +PKI_DEBUG("BITS FOR KEY GENERATION %lu (def: %lu)", bits, PKI_RSA_KEY_DEFAULT_SIZE); + + if (kp && kp->rsa.exponent > 3) { + // TO be Implemented + } else { + if( BN_hex2bn(&bn, "10001") == 0 ) { + PKI_log_debug("ERROR, can not convert 10001 to BIGNUM"); + return ( NULL ); + } + } + + if( url->path != NULL ) { + if((BN_hex2bn(&id_num, url->path )) == 0 ) { + PKI_log_debug("ERROR, can not convert %s to BIGNUM", + url->path ); + return ( NULL ); + } + if((id_len = BN_num_bytes(id_num)) < 0 ) { + if ( bn ) BN_free ( bn ); + if ( id_num ) BN_free ( id_num ); + return ( NULL ); + } + id = PKI_Malloc ( (size_t ) id_len ); + BN_bn2bin( id_num, (unsigned char *) id ); + } else { + id_len = 10; + if((id = PKI_Malloc ( (size_t) id_len )) == NULL ) { + if ( bn ) BN_free ( bn ); + return ( NULL ); + } + + if( RAND_bytes( (unsigned char *) id, id_len) == 0 ) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Can not generate RAND bytes"); + if( bn ) BN_free ( bn ); + return ( NULL ); + } + } + + PKI_DEBUG("Setting the Bits to %lu", bits); + + /* Setting Attributes for the public Key Template */ + n = 0; + //HSM_PKCS11_set_attr_int( CKA_CLASS, CKO_PUBLIC_KEY, &pubTemp[n++]); + //HSM_PKCS11_set_attr_int( CKA_KEY_TYPE, CKK_RSA, &pubTemp[n++]); + HSM_PKCS11_set_attr_int( CKA_MODULUS_BITS, bits, &pubTemp[n++]); + + HSM_PKCS11_set_attr_bool( CKA_TOKEN, CK_TRUE, &pubTemp[n++]); + HSM_PKCS11_set_attr_bool( CKA_ENCRYPT, CK_TRUE, &pubTemp[n++]); + HSM_PKCS11_set_attr_bool( CKA_VERIFY, CK_TRUE, &pubTemp[n++]); + HSM_PKCS11_set_attr_bool( CKA_WRAP, CK_TRUE, &pubTemp[n++]); + + HSM_PKCS11_set_attr_bn(CKA_PUBLIC_EXPONENT, bn, &pubTemp[n++]); + HSM_PKCS11_set_attr_sn(CKA_LABEL, url->addr, label_len, &pubTemp[n++]); + HSM_PKCS11_set_attr_sn(CKA_ID, id, (size_t) id_len, &pubTemp[n++]); + + /* Setting Attributes for the private Key Template */ + i = 0; + //HSM_PKCS11_set_attr_int( CKA_CLASS, CKO_PRIVATE_KEY, &privTemp[i++]); + //HSM_PKCS11_set_attr_int( CKA_KEY_TYPE, CKK_RSA, &privTemp[i++]); + //HSM_PKCS11_set_attr_int( CKA_MODULUS_BITS, bits, &privTemp[i++]); + + HSM_PKCS11_set_attr_bool( CKA_TOKEN, CK_TRUE, &privTemp[i++]); + HSM_PKCS11_set_attr_bool( CKA_PRIVATE, CK_TRUE, &privTemp[i++]); + HSM_PKCS11_set_attr_bool( CKA_SENSITIVE, CK_TRUE, &privTemp[i++]); + HSM_PKCS11_set_attr_bool( CKA_DECRYPT, CK_TRUE, &privTemp[i++]); + HSM_PKCS11_set_attr_bool( CKA_SIGN, CK_TRUE, &privTemp[i++]); + // HSM_PKCS11_set_attr_bool( CKA_NEVER_EXTRACTABLE, CK_TRUE, + // &privTemp[i++]); + // HSM_PKCS11_set_attr_bool( CKA_EXTRACTABLE, CK_FALSE, &privTemp[i++]); + HSM_PKCS11_set_attr_bool( CKA_UNWRAP, CK_TRUE, &privTemp[i++]); + + // HSM_PKCS11_set_attr_bn(CKA_PUBLIC_EXPONENT, bn, &privTemp[i++]); + HSM_PKCS11_set_attr_sn(CKA_LABEL, url->addr, label_len, &privTemp[i++]); + HSM_PKCS11_set_attr_sn(CKA_ID, id, (size_t) id_len, &privTemp[i++]); + + /* Allocate the handlers for pub and priv keys */ + handler_pubkey = (CK_OBJECT_HANDLE *) PKI_Malloc ( + sizeof( CK_OBJECT_HANDLE )); + handler_privkey = (CK_OBJECT_HANDLE *) PKI_Malloc ( + sizeof( CK_OBJECT_HANDLE )); + + if( !handler_pubkey || !handler_privkey ) { + if ( bn ) BN_free ( bn ); + if ( esp ) PKI_Free ( esp ); + return ( NULL ); + } + + PKI_log_debug("HSM_PKCS11_KEYPAIR_new()::Generating a new Key ... "); + rv = lib->callbacks->C_GenerateKeyPair ( + lib->session, RSA_MECH_PTR, + pubTemp, n, + privTemp, i, + handler_pubkey, + handler_privkey); + + if( rv != CKR_OK ) { + if ( rv == CKR_MECHANISM_INVALID ) { + PKI_log_err("HSM_PKCS11_KEYPAIR_new()::RSA Algorithm " + "is not supported by the Token" ); + } else { + PKI_log_debug ("HSM_PKCS11_KEYPAIR_new()::Failed with " + "code 0x%8.8X", rv ); + }; + if ( bn ) BN_free ( bn ); + if ( esp ) PKI_Free ( esp ); + return ( NULL ); + } + + /* Clean up the Memory we are not using anymore */ + if ( bn ) BN_free ( bn ); + if ( esp ) PKI_Free ( esp ); + + /* Generate a new RSA container */ + if((ret = RSA_new()) == NULL ) { + goto err; + }; + + if( HSM_PKCS11_get_attribute ( handler_pubkey, &lib->session, + CKA_PUBLIC_EXPONENT, (void **) &data, + &size, lib ) != PKI_OK ) { + goto err; + }; + +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + RSA_set0_key(ret, NULL, BN_bin2bn( data, (int) size, NULL), NULL); +#else + ret->e = BN_bin2bn( data, (int) size, NULL ); +#endif + PKI_Free ( data ); + data = NULL; + + if( HSM_PKCS11_get_attribute ( handler_pubkey, &lib->session, + CKA_MODULUS, (void **) &data, &size, lib ) != PKI_OK ) { + goto err; + }; + +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + RSA_set0_key(ret, BN_bin2bn(data, (int) size, NULL), NULL, NULL); +#else + ret->n = BN_bin2bn( data, (int) size, NULL ); +#endif + PKI_Free ( data ); + data = NULL; + + /* Let's get the Attributes from the Keypair and store into the + key's pointer */ + RSA_set_method( ret, HSM_PKCS11_get_rsa_method()); + +#ifdef RSA_FLAG_SIGN_VER +# if OPENSSL_VERSION_NUMBER >= 0x1010000fL + RSA_set_flags( ret, RSA_FLAG_SIGN_VER); +# else + ret->flags |= RSA_FLAG_SIGN_VER; +# endif +#endif + + /* Push the priv and pub key handlers to the rsa->ex_data */ + RSA_set_ex_data( ret, KEYPAIR_DRIVER_HANDLER_IDX, driver ); + RSA_set_ex_data( ret, KEYPAIR_PRIVKEY_HANDLER_IDX, handler_privkey ); + RSA_set_ex_data( ret, KEYPAIR_PUBKEY_HANDLER_IDX, handler_pubkey ); + + /* Cleanup the memory for Templates */ + HSM_PKCS11_clean_template ( pubTemp, (int) n ); + HSM_PKCS11_clean_template ( privTemp, (int) i ); + + /* Let's return the RSA_KEY infrastructure */ + return (ret); + +err: + if( ret ) RSA_free ((RSA *) ret ); + + if ( handler_pubkey ) { + if((rv = lib->callbacks->C_DestroyObject( lib->session, + *handler_pubkey )) != CKR_OK ) { + PKI_log_debug ("HSM_PKCS11_KEYPAIR_new()::Failed to delete " + "pubkey object"); + }; + PKI_Free ( handler_pubkey ); + } + + if( handler_privkey ) { + if((rv = lib->callbacks->C_DestroyObject( lib->session, + *handler_privkey)) != CKR_OK ) { + PKI_log_debug ("HSM_PKCS11_KEYPAIR_new()::Failed to delete " + "privkey object"); + }; + PKI_Free ( handler_privkey ); + } + + PKI_log_debug("HSM_PKCS11_KEYPAIR_new()::Key material DELETED!"); + + return ( NULL ); + +} + +PKI_DSA_KEY * _pki_pkcs11_dsakey_new( PKI_KEYPARAMS *kp, URL *url, + PKCS11_HANDLER *lib, void *driver ) { + PKI_DSA_KEY *k = NULL; + // unsigned char seed[20]; + + PKI_ERROR(PKI_ERR_NOT_IMPLEMENTED, NULL); + + + return( k ); +} + +#ifdef ENABLE_ECDSA +PKI_EC_KEY * _pki_pkcs11_ecdsakey_new(PKI_KEYPARAMS * kp, + URL * url, + PKCS11_HANDLER * lib, + void * driver) { + + PKI_EC_KEY * ret = NULL; + + CK_OBJECT_HANDLE *handler_pubkey = NULL; + CK_OBJECT_HANDLE *handler_privkey = NULL; + + CK_ATTRIBUTE privTemp[32]; + CK_ATTRIBUTE pubTemp[32]; + + CK_RV rv; + + CK_ULONG i = 0; + CK_ULONG n = 0; + + CK_ULONG bits = 0; + + size_t label_len = 0; + + unsigned char *data = NULL; + CK_BYTE *esp = NULL; + CK_ULONG size = 0; + + BIGNUM *bn = NULL; + BIGNUM *id_num = NULL; + + CK_MECHANISM * EC_MECH_PTR = NULL; + int idx = 0; + + char *id = NULL; + int id_len = 8; + + if ( !url || !url->addr ) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return ( NULL ); + } + + label_len = strlen( url->addr ); + + /* Check the min size for the key */ + if ( kp ) { + if( kp->bits < PKI_EC_KEY_MIN_SIZE ) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_SIZE_SHORT, NULL); + }; + } else { + bits = PKI_EC_KEY_DEFAULT_SIZE; + } + + // Look for a supported key generation mechanism + for (idx = 0; idx < EC_MECH_LIST_SIZE; idx++) { + + // Checks if the mechanism is supported + if (HSM_PKCS11_check_mechanism(lib, + EC_MECH_LIST[idx].mechanism) == PKI_OK) { + + // Set the pointer to the supported mechanism + EC_MECH_PTR = &EC_MECH_LIST[idx]; + + // Debugging Information + PKI_DEBUG("Found EC KEY GEN MECHANISM 0x%8.8X", + EC_MECH_LIST[idx].mechanism); + + // Breaks out of the loop + break; + + } else { + + // Let's provide debug information for not-supported mechs + PKI_DEBUG("EC KEY GEN MECHANISM 0x%8.8X not supported", + RSA_MECH_LIST[idx].mechanism); + } + } + + // If no key gen algors are supported, abort + if (EC_MECH_PTR == NULL) { + PKI_ERROR(PKI_ERR_HSM_KEYPAIR_GENERATE, "No KeyGen Mechanisms supported!"); + return NULL; + } + +PKI_DEBUG("BITS FOR KEY GENERATION %lu (def: %lu)", bits, PKI_EC_KEY_DEFAULT_SIZE); + + if ( kp && kp->rsa.exponent > 3) { + // TO be Implemented + } else { + if( BN_hex2bn(&bn, "10001") == 0 ) { + PKI_log_debug("ERROR, can not convert 10001 to BIGNUM"); + return ( NULL ); + } + } + + if( url->path != NULL ) { + if((BN_hex2bn(&id_num, url->path )) == 0 ) { + PKI_log_debug("ERROR, can not convert %s to BIGNUM", + url->path ); + return ( NULL ); + } + if((id_len = BN_num_bytes(id_num)) < 0 ) { + if ( bn ) BN_free ( bn ); + if ( id_num ) BN_free ( id_num ); + return ( NULL ); + } + id = PKI_Malloc ( (size_t ) id_len ); + BN_bn2bin( id_num, (unsigned char *) id ); + } else { + id_len = 10; + if((id = PKI_Malloc ( (size_t) id_len )) == NULL ) { + if ( bn ) BN_free ( bn ); + return ( NULL ); + } + + if( RAND_bytes( (unsigned char *) id, id_len) == 0 ) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Can not generate RAND bytes"); + if( bn ) BN_free ( bn ); + return ( NULL ); + } + } + + PKI_DEBUG("Setting the Bits to %lu", bits); + + /* Setting Attributes for the public Key Template */ + n = 0; + //HSM_PKCS11_set_attr_int( CKA_CLASS, CKO_PUBLIC_KEY, &pubTemp[n++]); + //HSM_PKCS11_set_attr_int( CKA_KEY_TYPE, CKK_RSA, &pubTemp[n++]); + HSM_PKCS11_set_attr_int( CKA_MODULUS_BITS, bits, &pubTemp[n++]); + + HSM_PKCS11_set_attr_bool( CKA_TOKEN, CK_TRUE, &pubTemp[n++]); + HSM_PKCS11_set_attr_bool( CKA_ENCRYPT, CK_TRUE, &pubTemp[n++]); + HSM_PKCS11_set_attr_bool( CKA_VERIFY, CK_TRUE, &pubTemp[n++]); + HSM_PKCS11_set_attr_bool( CKA_WRAP, CK_TRUE, &pubTemp[n++]); + + HSM_PKCS11_set_attr_bn(CKA_PUBLIC_EXPONENT, bn, &pubTemp[n++]); + HSM_PKCS11_set_attr_sn(CKA_LABEL, url->addr, label_len, &pubTemp[n++]); + HSM_PKCS11_set_attr_sn(CKA_ID, id, (size_t) id_len, &pubTemp[n++]); + + /* Setting Attributes for the private Key Template */ + i = 0; + //HSM_PKCS11_set_attr_int( CKA_CLASS, CKO_PRIVATE_KEY, &privTemp[i++]); + //HSM_PKCS11_set_attr_int( CKA_KEY_TYPE, CKK_RSA, &privTemp[i++]); + //HSM_PKCS11_set_attr_int( CKA_MODULUS_BITS, bits, &privTemp[i++]); + + HSM_PKCS11_set_attr_bool( CKA_TOKEN, CK_TRUE, &privTemp[i++]); + HSM_PKCS11_set_attr_bool( CKA_PRIVATE, CK_TRUE, &privTemp[i++]); + HSM_PKCS11_set_attr_bool( CKA_SENSITIVE, CK_TRUE, &privTemp[i++]); + HSM_PKCS11_set_attr_bool( CKA_DECRYPT, CK_TRUE, &privTemp[i++]); + HSM_PKCS11_set_attr_bool( CKA_SIGN, CK_TRUE, &privTemp[i++]); + // HSM_PKCS11_set_attr_bool( CKA_NEVER_EXTRACTABLE, CK_TRUE, + // &privTemp[i++]); + // HSM_PKCS11_set_attr_bool( CKA_EXTRACTABLE, CK_FALSE, &privTemp[i++]); + HSM_PKCS11_set_attr_bool( CKA_UNWRAP, CK_TRUE, &privTemp[i++]); + + // HSM_PKCS11_set_attr_bn(CKA_PUBLIC_EXPONENT, bn, &privTemp[i++]); + HSM_PKCS11_set_attr_sn(CKA_LABEL, url->addr, label_len, &privTemp[i++]); + HSM_PKCS11_set_attr_sn(CKA_ID, id, (size_t) id_len, &privTemp[i++]); + + /* Allocate the handlers for pub and priv keys */ + handler_pubkey = (CK_OBJECT_HANDLE *) PKI_Malloc ( + sizeof( CK_OBJECT_HANDLE )); + handler_privkey = (CK_OBJECT_HANDLE *) PKI_Malloc ( + sizeof( CK_OBJECT_HANDLE )); + + if( !handler_pubkey || !handler_privkey ) { + if ( bn ) BN_free ( bn ); + if ( esp ) PKI_Free ( esp ); + return ( NULL ); + } + + PKI_log_debug("Generating a new Key ... "); + rv = lib->callbacks->C_GenerateKeyPair ( + lib->session, EC_MECH_PTR, + pubTemp, n, + privTemp, i, + handler_pubkey, + handler_privkey); + + if( rv != CKR_OK ) { + + if ( rv == CKR_MECHANISM_INVALID ) { + PKI_ERROR(PKI_ERR_HSM_SET_ALGOR, + "EC Algorithm is not supported by the Token"); + } else { + PKI_log_debug ("Failed with code 0x%8.8X", rv ); + } + + if ( bn ) BN_free ( bn ); + if ( esp ) PKI_Free ( esp ); + + return ( NULL ); + } + + /* Clean up the Memory we are not using anymore */ + if ( bn ) BN_free ( bn ); + if ( esp ) PKI_Free ( esp ); + + /* Generate a new RSA container */ + if((ret = EC_KEY_new()) == NULL ) goto err; + + if( HSM_PKCS11_get_attribute(handler_pubkey, + &lib->session, + CKA_PUBLIC_EXPONENT, + (void **) &data, + &size, + lib) != PKI_OK ) { + goto err; + } + + EC_KEY_set_private_key(ret, BN_bin2bn( data, (int) size, NULL)); + PKI_Free(data); + data = NULL; + + if( HSM_PKCS11_get_attribute(handler_pubkey, + &lib->session, + CKA_MODULUS, + (void **) &data, + &size, + lib) != PKI_OK ) { + goto err; + } + + EC_KEY_set_public_key(ret, (const EC_POINT *) NULL); + PKI_Free ( data ); + data = NULL; + +/* + ECDSA_set_method(ret, HSM_PKCS11_get_ecdsa_method()); + +#ifdef RSA_FLAG_SIGN_VER +# if OPENSSL_VERSION_NUMBER >= 0x1010000fL + RSA_set_flags( ret, RSA_FLAG_SIGN_VER); +# else + ret->flags |= RSA_FLAG_SIGN_VER; +# endif +#endif + + // Push the priv and pub key handlers to the rsa->ex_data + EC_KEY_set_ex_data( ret, KEYPAIR_DRIVER_HANDLER_IDX, driver ); + EC_KEY_set_ex_data( ret, KEYPAIR_PRIVKEY_HANDLER_IDX, handler_privkey ); + EC_KEY_set_ex_data( ret, KEYPAIR_PUBKEY_HANDLER_IDX, handler_pubkey ); + + // Cleanup the memory for Templates + HSM_PKCS11_clean_template ( pubTemp, (int) n ); + HSM_PKCS11_clean_template ( privTemp, (int) i ); +*/ + + // Let's return the RSA_KEY infrastructure + return (ret); + +err: + if (ret) EC_KEY_free(ret); + + if ( handler_pubkey ) { + if((rv = lib->callbacks->C_DestroyObject( lib->session, + *handler_pubkey )) != CKR_OK ) { + PKI_log_debug ("Failed to delete pubkey object"); + } + PKI_Free(handler_pubkey); + } + + if( handler_privkey ) { + if((rv = lib->callbacks->C_DestroyObject(lib->session, + *handler_privkey)) != CKR_OK) { + PKI_log_debug ("Failed to delete privkey object"); + } + PKI_Free(handler_privkey); + } + + return NULL; +} + +#else /* EVP_PKEY_EC */ + +void * _pki_pkcs11_ecdsakey_new( PKI_KEYPARAMS *kp, + URL *url, PKCS11_HANDLER *lib, void *driver ) { + PKI_ERROR(PKI_ERR_NOT_IMPLEMENTED, NULL); + return ( NULL ); +} + +#endif + + +PKI_X509_KEYPAIR *HSM_PKCS11_KEYPAIR_new( PKI_KEYPARAMS *kp, + URL *url, PKI_CRED *cred, HSM *driver ) { + + PKCS11_HANDLER *lib = NULL; + PKI_SCHEME_ID type = PKI_SCHEME_DEFAULT; + + /* + CK_MECHANISM DSA_MECH = { + CKM_DSA_KEY_PAIR_GEN, NULL_PTR, 0 }; + + CK_MECHANISM ECDSA_MECH = { + CKM_ECDSA_KEY_PAIR_GEN, NULL_PTR, 0 }; + */ + + /* Return EVP Key */ + PKI_X509_KEYPAIR *ret = NULL; + PKI_X509_KEYPAIR_VALUE *val = NULL; + + /* If a RSA Key is generated we use the RSA pointer*/ + PKI_RSA_KEY *rsa = NULL; + + /* If a DSA Key is generated we use the DSA pointer*/ + PKI_DSA_KEY *dsa = NULL; + +#ifdef ENABLE_ECDSA + /* If an ECDSA Key is generated we use the DSA pointer*/ + PKI_EC_KEY *ecdsa = NULL; +#endif + + PKI_log_debug("HSM_PKCS11_KEYPAIR_new()::Start!"); + + if ((lib = _hsm_get_pkcs11_handler ( driver )) == NULL ) { + PKI_log_debug("HSM_PKCS11_KEYPAIR_new()::Can not get handler"); + return NULL; + } + /* + if((val = (PKI_X509_KEYPAIR *) EVP_PKEY_new()) == NULL ) { + return NULL; + } + */ + + /* + if( _pki_pkcs11_rand_seed() == 0 ) { + PKI_log_debug("WARNING, low rand available!"); + } + */ + + if ( kp && kp->scheme != PKI_SCHEME_UNKNOWN ) type = kp->scheme; + + switch (type) { + case PKI_SCHEME_RSA: + break; + + // case PKI_SCHEME_DSA: + // case PKI_SCHEME_ECDSA: + default: + PKI_ERROR(PKI_ERR_HSM_SCHEME_UNSUPPORTED, "Scheme %d", type ); + return ( NULL ); + } + + /* + PKI_log_debug("HSM_PKCS11_KEYPAIR_new()::Closing existing key session"); + rv = lib->callbacks->C_CloseSession( lib->session ); + */ + + if(( HSM_PKCS11_session_new( lib->slot_id, &lib->session, + CKF_SERIAL_SESSION | CKF_RW_SESSION, lib )) == PKI_ERR ) { + + PKI_log_debug("HSM_PKCS11_KEYPAIR_new()::Failed in opening a " + "new session (R/W) with the token" ); + return ( NULL ); + }; + + /* + PKI_log_debug("HSM_PKCS11_KEYPAIR_new()::Opening new R/W key session"); + if((rv = lib->callbacks->C_OpenSession (lib->slot_id, + CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL, NULL, + &(lib->session))) != CKR_OK ) { + PKI_log_debug("HSM_PKCS11_KEYPAIR_new()::Failed in opening a " + "new session (R/W) with the token" ); + return ( NULL ); + } + */ + + if( HSM_PKCS11_login ( driver, cred ) == PKI_ERR ) { + HSM_PKCS11_session_close ( &lib->session, lib ); + return ( PKI_ERR ); + } + + /* + PKI_log_debug("HSM_PKCS11_KEYPAIR_new()::Logging in" ); + rv = lib->callbacks->C_Login(lib->session, CKU_USER, + (CK_UTF8CHAR *) cred->password, + cred->password ? strlen(cred->password) : 0); + */ + + /* + if ( rv == CKR_USER_ALREADY_LOGGED_IN ) { + PKI_log_debug( "HSM_PKCS11_SLOT_select()::User Already logged " + "in!"); + } else if( rv == CKR_PIN_INCORRECT ) { + PKI_log_err ( "HSM_PKCS11_SLOT_select()::Can not login " + "- Pin Incorrect (0X%8.8X) [%s]", rv, cred->password); + return ( PKI_ERR ); + } else if ( rv != CKR_OK ) { + PKI_log_err ( "HSM_PKCS11_SLOT_select()::Can not login " + "- General Error (0X%8.8X)", rv); + return ( PKI_ERR ); + } + */ + + /* Generate the EVP_PKEY that will allow it to make use of it */ + if((val = (PKI_X509_KEYPAIR_VALUE *) EVP_PKEY_new()) == NULL ) { + HSM_PKCS11_session_close ( &lib->session, lib ); + PKI_ERROR(PKI_ERR_OBJECT_CREATE, "KeyPair value"); + return NULL; + } + + switch( type ) { + + case PKI_SCHEME_RSA: + if ((rsa = _pki_pkcs11_rsakey_new ( kp, url, + lib, driver)) == NULL ) { + HSM_PKCS11_session_close ( &lib->session, lib ); + return ( NULL ); + }; + if(!EVP_PKEY_assign_RSA( (EVP_PKEY *) val, rsa)) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Can not assign RSA key"); + if( rsa ) RSA_free ( rsa ); + if( val ) EVP_PKEY_free( (EVP_PKEY *) val ); + HSM_PKCS11_session_close ( &lib->session, lib ); + return ( NULL ); + } + break; + + case PKI_SCHEME_DSA: + if ((dsa = _pki_pkcs11_dsakey_new ( kp, url, + lib, driver)) == NULL ) { + HSM_PKCS11_session_close ( &lib->session, lib ); + return ( NULL ); + }; + if(!EVP_PKEY_assign_DSA( (EVP_PKEY *) val, dsa)) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Can not assign DSA key"); + if( dsa ) DSA_free ( dsa ); + if( val ) EVP_PKEY_free( (EVP_PKEY *) val ); + HSM_PKCS11_session_close ( &lib->session, lib ); + return ( NULL ); + } + break; + +#ifdef ENABLE_ECDSA + case PKI_SCHEME_ECDSA: + if ((ecdsa = _pki_pkcs11_ecdsakey_new ( kp, url, + lib, driver)) == NULL ) { + HSM_PKCS11_session_close ( &lib->session, lib ); + return ( NULL ); + }; + if(!EVP_PKEY_assign_EC_KEY( (EVP_PKEY *) val, ecdsa)) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Can not assign ECDSA key"); + if( ecdsa ) EC_KEY_free ( ecdsa ); + if( val ) EVP_PKEY_free( (EVP_PKEY *) val ); + HSM_PKCS11_session_close ( &lib->session, lib ); + return ( NULL ); + } + break; +#endif + default: + PKI_ERROR(PKI_ERR_HSM_SCHEME_UNSUPPORTED, "%d", type); + if ( val ) EVP_PKEY_free ( (EVP_PKEY *) val ); + HSM_PKCS11_session_close ( &lib->session, lib ); + return ( NULL ); + } + + HSM_PKCS11_session_close ( &lib->session, lib ); + + if (( ret = PKI_X509_new ( PKI_DATATYPE_X509_KEYPAIR, driver)) == NULL){ + PKI_ERROR(PKI_ERR_OBJECT_CREATE, NULL ); + if ( val ) EVP_PKEY_free ( (EVP_PKEY *) val ); + if ( val ) EVP_PKEY_free ( val ); + return NULL; + } + + ret->value = val; + + /* Let's return the PKI_X509_KEYPAIR infrastructure */ + return ( ret ); + +} + +/* Key Free function */ +void HSM_PKCS11_KEYPAIR_free ( PKI_X509_KEYPAIR *pkey ) { + + if( !pkey ) return; + + PKI_X509_free (pkey); + + return; +} + +/* ----------------------------- RSA Callback Methods ----------------- */ + +const RSA_METHOD * HSM_PKCS11_get_rsa_method ( void ) { + +#if OPENSSL_VERSION_NUMBER < 0x1010000fL + + static RSA_METHOD ret; + + ret = *RSA_get_default_method(); + + // Sets the name + ret.name = "LibPKI PKCS#11 RSA"; + + // Implemented Methods + ret.rsa_sign = HSM_PKCS11_rsa_sign; + + // Not Implemented Methods + ret.rsa_priv_enc = NULL; + ret.rsa_priv_dec = NULL; + + return &ret; + +#else + + static RSA_METHOD * r_pnt = NULL; + // Static Pointer to the new PKCS11 RSA Method + + // If the pointer is empty, let's get a new method + if (!r_pnt) { + + // Duplicate the default method + if ((r_pnt = RSA_meth_dup(RSA_get_default_method())) != NULL) { + + // Sets the name + RSA_meth_set1_name(r_pnt, "LibPKI PKCS#11 RSA"); + + // Sets the sign to use the PKCS#11 version + RSA_meth_set_sign(r_pnt, HSM_PKCS11_rsa_sign); + + // Sets not implemented calls + RSA_meth_set_priv_enc(r_pnt, NULL); + RSA_meth_set_priv_dec(r_pnt, NULL); + } + } + + // All Done + return r_pnt; + +#endif + +} + +const EC_KEY_METHOD * HSM_PKCS11_get_ecdsa_method ( void ) { + + static EC_KEY_METHOD * r_pnt = NULL; +#ifdef ENABLE_ECDSA + if (!r_pnt) { + +#if OPENSSL_VERSION_NUMBER < 0x1010000fL + + // ECDSA METHOD - it is required since OpenSSL is + // actually missing the duplication of the METHOD + /* + static ECDSA_METHOD ret = { + "PKCS#11 ECDSA method", // const char *name; + HSM_PKCS11_ecdsa_sign, // ECDSA_SIG *(*ecdsa_do_sign)(const unsigned char *dgst, int dgst_len, const BIGNUM *inv, + // const BIGNUM *rp, EC_KEY *eckey); + HSM_PKCS11_ecdsa_sign_setup, // int (*ecdsa_sign_setup)(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, BIGNUM **r); + NULL, // int (*ecdsa_do_verify)(const unsigned char *dgst, int dgst_len, const ECDSA_SIG *sig, + // EC_KEY *eckey); + 0, // int flags; + NULL // char *app_data; + }; + */ + + + if ((r_pnt = ECDSA_METHOD_new(ECDSA_get_default_method())) == NULL) + return NULL; + + ECDSA_METHOD_set_name(r_pnt, "LibPKI PKCS#11 ECDSA"); + ECDSA_METHOD_set_sign(r_pnt, HSM_PKCS11_ecdsa_sign); + + // ECDSA_METHOD_set_sign_setup(r_pnt, HSM_PKCS11_ecdsa_sign_setup); + // ECDSA_METHOD_set_verify(&ret, NULL); + +#else + if ((r_pnt = EC_KEY_METHOD_new(EC_KEY_get_default_method())) == NULL) + return NULL; + + // Sets the sign method + EC_KEY_METHOD_set_sign(r_pnt, + HSM_PKCS11_ecdsa_sign, //int (*sign)(int type, const unsigned char *dgst, + // int dlen, unsigned char *sig, + // unsigned int *siglen, + // const BIGNUM *kinv, const BIGNUM *r, + // EC_KEY *eckey) + NULL, //int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, + // BIGNUM **kinvp, BIGNUM **rp) + NULL //ECDSA_SIG *(*sign_sig)(const unsigned char *dgst, + // int dgst_len, + // const BIGNUM *in_kinv, + // const BIGNUM *in_r, + // EC_KEY *eckey) + ); +#endif + } +#endif + return r_pnt; + +} + +int HSM_PKCS11_rsa_sign ( int type, const unsigned char *m, unsigned int m_len, + unsigned char *sigret, unsigned int *siglen, const RSA *rsa ) { + + PKCS11_HANDLER *lib = NULL; + CK_OBJECT_HANDLE *pHandle = NULL; + HSM *driver = NULL; + + CK_MECHANISM RSA_MECH = { CKM_RSA_PKCS, NULL_PTR, 0 }; + + unsigned char *p = NULL; + unsigned char *s = NULL; + unsigned char *tmps = NULL; + +#if OPENSSL_VERSION_NUMBER < 0x1010000fL + X509_SIG sig; + X509_SIG * sig_pnt = &sig; +#else + X509_SIG * sig_pnt = X509_SIG_new(); +#endif + + + int i, j, rc; + + int keysize = 0; + CK_ULONG ck_sigsize = 0; + + CK_RV rv = CKR_OK; + + unsigned char *buf = NULL; + + /* Default checks for mis-passed pointers */ + if (!m || !sigret || !siglen || !rsa || !sig_pnt) goto err; + + /* Retrieves the reference to the hsm */ + if((driver = (HSM *) RSA_get_ex_data (rsa, KEYPAIR_DRIVER_HANDLER_IDX)) + == NULL ) { + PKI_ERROR(PKI_ERR_POINTER_NULL, "Can't get PKCS#11 Driver Handle"); + goto err; + } + + /* Retrieves the privkey object handler */ + if((pHandle = (CK_OBJECT_HANDLE *) RSA_get_ex_data (rsa, + KEYPAIR_PRIVKEY_HANDLER_IDX)) == NULL ) { + PKI_ERROR(PKI_ERR_POINTER_NULL, "Can't get PrivateKey Handle"); + goto err; + } + + if ((lib = _hsm_get_pkcs11_handler ( driver )) == NULL ) { + PKI_ERROR(PKI_ERR_POINTER_NULL, "Can not get PKCS#11 Library handler"); + goto err; + } + + if(( HSM_PKCS11_session_new( lib->slot_id, &lib->session, + CKF_SERIAL_SESSION, lib )) == PKI_ERR ) { + PKI_log_debug("Failed to open a new session (R/W) with the token"); + goto err; + } + + /* Now we need to check the real encoding */ +#if OPENSSL_VERSION_NUMBER < 0x1010000fL + ASN1_OCTET_STRING digest; + ASN1_TYPE parameter; + X509_ALGOR algor; + + sig.algor = &algor; + if((sig.algor->algorithm = OBJ_nid2obj(type)) == NULL ) { + PKI_log_debug("HSM_PKCS11_rsa_sign()::Algor not recognized"); + return ( 0 ); + } + + if( algor.algorithm->length == 0 ) { + PKI_log_debug("HSM_PKCS11_rsa_sign()::Algor length is 0"); + return ( 0 ); + } + + parameter.type = V_ASN1_NULL; + parameter.value.ptr = NULL; + sig.algor->parameter = ¶meter; + + sig.digest = &digest; + sig.digest->data = (unsigned char *) m; + sig.digest->length = (int) m_len; + + i = i2d_X509_SIG(sig_pnt, NULL); + +#else + X509_ALGOR * alg = NULL; + ASN1_OCTET_STRING * data = NULL; + + // Allocates a new signature + if ((sig_pnt = X509_SIG_new()) == NULL) goto err; + + // Gets the modifiable algorithm and digest pointers + X509_SIG_getm(sig_pnt, &alg, &data); + + // Sets the algorithm + if (!X509_ALGOR_set0(alg, OBJ_nid2obj(type), V_ASN1_NULL, NULL)) goto err; + + // Sets the digest data + if (!ASN1_OCTET_STRING_set(data, (unsigned char *)m, (int) m_len)) goto err; + + // Gets the size of the DER encoded signature + i = i2d_X509_SIG(sig_pnt, NULL); +#endif + + if((keysize = RSA_size ( rsa )) == 0 ) { + PKI_log_debug("HSM_PKCS11_rsa_sign()::KEY size is 0"); + goto err; + } + + j=RSA_size(rsa); + if( i > ( j - RSA_PKCS1_PADDING_SIZE )) { + PKI_log_debug("HSM_PKCS11_rsa_sign()::Digest too big"); + goto err; + } + + if((tmps = ( unsigned char *) PKI_Malloc ((unsigned int) j + 1 )) + == NULL ) { + PKI_log_debug("HSM_PKCS11_rsa_sign()::Memory alloc error!"); + return (0); + } + + p = tmps; + i2d_X509_SIG(sig_pnt, &p); + s = tmps; + + rc = pthread_mutex_lock( &lib->pkcs11_mutex ); + PKI_log_debug( "pthread_mutex_lock()::RC=%d", rc ); + + while(( rv = lib->callbacks->C_SignInit(lib->session, + &RSA_MECH, *pHandle)) == CKR_OPERATION_ACTIVE ) { + int rc = 0; + + rc = pthread_cond_wait( &lib->pkcs11_cond, &lib->pkcs11_mutex ); + PKI_log_debug( "pthread_cond_wait()::RC=%d", rc ); + } + + if( rv != CKR_OK ) { + PKI_log_debug("HSM_PKCS11_rsa_sign()::SignInit " + "(2) failed with code 0x%8.8X", rv ); + pthread_cond_signal( &lib->pkcs11_cond ); + pthread_mutex_unlock( &lib->pkcs11_mutex ); + + goto err; + } + + ck_sigsize = *siglen; + PKI_log_debug("HSM_PKCS11_rsa_sign()::i = %d, siglen = %d, " + "sigret = %d (%p)", i, ck_sigsize, sizeof(sigret), sigret ); + + /* Let's exagerate for now... */ + buf = PKI_Malloc (RSA_SIGNATURE_MAX_SIZE); + PKI_log_debug("HSM_PKCS11_rsa_sign():: DEBUG %d", __LINE__ ); + + ck_sigsize = RSA_SIGNATURE_MAX_SIZE; + + PKI_log_debug("HSM_PKCS11_rsa_sign():: DEBUG %d", __LINE__ ); + // if((rv = lib->callbacks->C_Sign( lib->session, (CK_BYTE *) m, + // m_len, sigret, &ck_sigsize)) != CKR_OK ) { + if((rv = lib->callbacks->C_Sign( lib->session, (CK_BYTE *) s, + (CK_ULONG) i, buf, &ck_sigsize)) != CKR_OK ) { + PKI_log_err("HSM_PKCS11_rsa_sign()::Sign failed with 0x%8.8X", + rv); + if( rv == CKR_BUFFER_TOO_SMALL ) { + /* The sign session has to be terminated */ + /* To Be Done (TBD) */ + PKI_log_err("HSM_PKCS11_rsa_sign()::Buffer too ", + "small (%s:%d)", __FILE__, __LINE__ ); + } + + pthread_cond_signal( &lib->pkcs11_cond ); + pthread_mutex_unlock( &lib->pkcs11_mutex ); + + PKI_log_debug("HSM_PKCS11_rsa_sign():: DEBUG %d", __LINE__ ); + + goto err; + } + + pthread_cond_signal( &lib->pkcs11_cond ); + pthread_mutex_unlock( &lib->pkcs11_mutex ); + + PKI_log_debug("HSM_PKCS11_rsa_sign():: DEBUG %d", __LINE__ ); + *siglen = (unsigned int) ck_sigsize; + PKI_log_debug("HSM_PKCS11_rsa_sign():: DEBUG %d", __LINE__ ); + + PKI_log_debug("HSM_PKCS11_rsa_sign():: BUF Written = %d", ck_sigsize ); + memcpy(sigret, buf, *siglen); + + // Free allocated memory + if (tmps) PKI_Free ( tmps ); + if (buf) PKI_Free ( buf ); + +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + if (sig_pnt) X509_SIG_free(sig_pnt); + sig_pnt = NULL; +#endif + + // Returns Success (1 is success in OpenSSL) + return 1; + +err: + // Frees associated memory + if (tmps) PKI_Free(tmps); + if (buf) PKI_Free(buf); + +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + if (sig_pnt) X509_SIG_free(sig_pnt); + sig_pnt = NULL; +#endif + + + // Returns the error (0 is error in OpenSSL) + return 0; +} + +#if OPENSSL_VERSION_NUMBER < 0x1010000fL + +ECDSA_SIG *HSM_PKCS11_ecdsa_sign(const unsigned char *dgst, int dgst_len, + const BIGNUM *inv, const BIGNUM *rp, EC_KEY *eckey) { + + PKI_ERROR(PKI_ERR_NOT_IMPLEMENTED, NULL); + return 0; +} + +#else + +int HSM_PKCS11_ecdsa_sign ( int type, const unsigned char *dgst, int dlen, + unsigned char *sig, unsigned int *siglen, const BIGNUM *kinv, const BIGNUM *r, + EC_KEY *eckey ) { + + PKI_ERROR(PKI_ERR_NOT_IMPLEMENTED, NULL); + return 0; + +/* +int HSM_PKCS11_ecdsa_sign ( int type, const unsigned char *m, unsigned int m_len, + unsigned char *sigret, unsigned int *siglen, const RSA *rsa ) { + + PKCS11_HANDLER *lib = NULL; + CK_OBJECT_HANDLE *pHandle = NULL; + HSM *driver = NULL; + + CK_MECHANISM EC_MECH = { CKM_RSA_PKCS, NULL_PTR, 0 }; + + unsigned char *p = NULL; + unsigned char *s = NULL; + unsigned char *tmps = NULL; + +#if OPENSSL_VERSION_NUMBER < 0x1010000fL + X509_SIG sig; + X509_SIG * sig_pnt = &sig; +#else + X509_SIG * sig_pnt = X509_SIG_new(); +#endif + + + int i, j, rc; + + int keysize = 0; + CK_ULONG ck_sigsize = 0; + + CK_RV rv = CKR_OK; + + unsigned char *buf = NULL; + + // Default checks for mis-passed pointers + if (!m || !sigret || !siglen || !rsa || !sig_pnt) goto err; + + // Retrieves the reference to the hsm + if((driver = (HSM *) RSA_get_ex_data (rsa, KEYPAIR_DRIVER_HANDLER_IDX)) + == NULL ) { + PKI_ERROR(PKI_ERR_POINTER_NULL, "Can't get PKCS#11 Driver Handle"); + goto err; + } + + // Retrieves the privkey object handler + if((pHandle = (CK_OBJECT_HANDLE *) RSA_get_ex_data (rsa, + KEYPAIR_PRIVKEY_HANDLER_IDX)) == NULL ) { + PKI_ERROR(PKI_ERR_POINTER_NULL, "Can't get PrivateKey Handle"); + goto err; + } + + if ((lib = _hsm_get_pkcs11_handler ( driver )) == NULL ) { + PKI_ERROR(PKI_ERR_POINTER_NULL, "Can not get PKCS#11 Library handler"); + goto err; + } + + if(( HSM_PKCS11_session_new( lib->slot_id, &lib->session, + CKF_SERIAL_SESSION, lib )) == PKI_ERR ) { + PKI_log_debug("Failed to open a new session (R/W) with the token"); + goto err; + } + + // Now we need to check the real encoding +#if OPENSSL_VERSION_NUMBER < 0x1010000fL + ASN1_OCTET_STRING digest; + ASN1_TYPE parameter; + X509_ALGOR algor; + + sig.algor = &algor; + if((sig.algor->algorithm = OBJ_nid2obj(type)) == NULL ) { + PKI_log_debug("HSM_PKCS11_rsa_sign()::Algor not recognized"); + return ( 0 ); + } + + if( algor.algorithm->length == 0 ) { + PKI_log_debug("HSM_PKCS11_rsa_sign()::Algor length is 0"); + return ( 0 ); + } + + parameter.type = V_ASN1_NULL; + parameter.value.ptr = NULL; + sig.algor->parameter = ¶meter; + + sig.digest = &digest; + sig.digest->data = (unsigned char *) m; + sig.digest->length = (int) m_len; + + i = i2d_X509_SIG(sig_pnt, NULL); + +#else + X509_ALGOR * alg = NULL; + ASN1_OCTET_STRING * data = NULL; + + // Allocates a new signature + if ((sig_pnt = X509_SIG_new()) == NULL) goto err; + + // Gets the modifiable algorithm and digest pointers + X509_SIG_getm(sig_pnt, &alg, &data); + + // Sets the algorithm + if (!X509_ALGOR_set0(alg, OBJ_nid2obj(type), V_ASN1_NULL, NULL)) goto err; + + // Sets the digest data + if (!ASN1_OCTET_STRING_set(data, (unsigned char *)m, (int) m_len)) goto err; + + // Gets the size of the DER encoded signature + i = i2d_X509_SIG(sig_pnt, NULL); +#endif + + if((keysize = RSA_size ( rsa )) == 0 ) { + PKI_log_debug("HSM_PKCS11_rsa_sign()::KEY size is 0"); + goto err; + } + + j=RSA_size(rsa); + if( i > ( j - RSA_PKCS1_PADDING_SIZE )) { + PKI_log_debug("HSM_PKCS11_rsa_sign()::Digest too big"); + goto err; + } + + if((tmps = ( unsigned char *) PKI_Malloc ((unsigned int) j + 1 )) + == NULL ) { + PKI_log_debug("HSM_PKCS11_rsa_sign()::Memory alloc error!"); + return (0); + } + + p = tmps; + i2d_X509_SIG(sig_pnt, &p); + s = tmps; + + rc = pthread_mutex_lock( &lib->pkcs11_mutex ); + PKI_log_debug( "pthread_mutex_lock()::RC=%d", rc ); + + while(( rv = lib->callbacks->C_SignInit(lib->session, + &RSA_MECH, *pHandle)) == CKR_OPERATION_ACTIVE ) { + int rc = 0; + + rc = pthread_cond_wait( &lib->pkcs11_cond, &lib->pkcs11_mutex ); + PKI_log_debug( "pthread_cond_wait()::RC=%d", rc ); + } + + if( rv != CKR_OK ) { + PKI_log_debug("HSM_PKCS11_rsa_sign()::SignInit " + "(2) failed with code 0x%8.8X", rv ); + pthread_cond_signal( &lib->pkcs11_cond ); + pthread_mutex_unlock( &lib->pkcs11_mutex ); + + goto err; + } + + ck_sigsize = *siglen; + PKI_log_debug("HSM_PKCS11_rsa_sign()::i = %d, siglen = %d, " + "sigret = %d (%p)", i, ck_sigsize, sizeof(sigret), sigret ); + + // Let's exagerate for now... + buf = PKI_Malloc (RSA_SIGNATURE_MAX_SIZE); + PKI_log_debug("HSM_PKCS11_rsa_sign():: DEBUG %d", __LINE__ ); + + ck_sigsize = RSA_SIGNATURE_MAX_SIZE; + + PKI_log_debug("HSM_PKCS11_rsa_sign():: DEBUG %d", __LINE__ ); + // if((rv = lib->callbacks->C_Sign( lib->session, (CK_BYTE *) m, + // m_len, sigret, &ck_sigsize)) != CKR_OK ) { + if((rv = lib->callbacks->C_Sign( lib->session, (CK_BYTE *) s, + (CK_ULONG) i, buf, &ck_sigsize)) != CKR_OK ) { + PKI_log_err("HSM_PKCS11_rsa_sign()::Sign failed with 0x%8.8X", + rv); + if( rv == CKR_BUFFER_TOO_SMALL ) { + // The sign session has to be terminated + // To Be Done (TBD) + PKI_log_err("HSM_PKCS11_rsa_sign()::Buffer too ", + "small (%s:%d)", __FILE__, __LINE__ ); + } + + pthread_cond_signal( &lib->pkcs11_cond ); + pthread_mutex_unlock( &lib->pkcs11_mutex ); + + PKI_log_debug("HSM_PKCS11_rsa_sign():: DEBUG %d", __LINE__ ); + + goto err; + } + + pthread_cond_signal( &lib->pkcs11_cond ); + pthread_mutex_unlock( &lib->pkcs11_mutex ); + + PKI_log_debug("HSM_PKCS11_rsa_sign():: DEBUG %d", __LINE__ ); + *siglen = (unsigned int) ck_sigsize; + PKI_log_debug("HSM_PKCS11_rsa_sign():: DEBUG %d", __LINE__ ); + + PKI_log_debug("HSM_PKCS11_rsa_sign():: BUF Written = %d", ck_sigsize ); + memcpy(sigret, buf, *siglen); + + // Free allocated memory + if (tmps) PKI_Free ( tmps ); + if (buf) PKI_Free ( buf ); + +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + if (sig_pnt) X509_SIG_free(sig_pnt); +#endif + + // Returns Success (1 is success in OpenSSL) + return 1; + +err: + // Frees associated memory + if (tmps) PKI_Free(tmps); + if (buf) PKI_Free(buf); + +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + if (sig_pnt) X509_SIG_free(sig_pnt); +#endif + + // Returns the error (0 is error in OpenSSL) + return 0; +*/ + +} + +#endif diff --git a/src/crypto/hsm/pkcs11/utils/pkcs11_init.c b/src/crypto/hsm/pkcs11/utils/pkcs11_init.c new file mode 100644 index 00000000..9565c0e6 --- /dev/null +++ b/src/crypto/hsm/pkcs11/utils/pkcs11_init.c @@ -0,0 +1,1071 @@ + +/* General Include for LibPKI */ +#include + +/* Dynamic library loading function */ +#include + +int _strncpyClip( char *dst, char *orig, size_t size ) { + + char *i = NULL; + + if( !dst || !orig || size <= 0 ) return (PKI_ERR); + + i = dst + size - 1; + strncpy( dst, orig, size ); + while( i > dst ) { + if( *i == ' ' ) { + *i = '\x0'; + } else { + break; + } + i--; + } + + return ( PKI_OK ); +} + +/* ------- Function to get a PKCS11_HANDLER from the HSM -------- */ + +PKCS11_HANDLER * _hsm_get_pkcs11_handler ( void * hsm_void ) { + + PKCS11_HANDLER *lib = NULL; + HSM * hsm = NULL; + + hsm = (HSM *) hsm_void; + + if ( ( hsm == NULL ) || ( hsm->driver == NULL )) return ( NULL ); + + if (( lib = hsm->driver ) == NULL ) { + return ( NULL ); + } + + if ( ( lib->sh_lib == NULL ) || ( lib->callbacks == NULL )) { + return ( NULL ); + } + + return ( lib ); +} + +PKCS11_HANDLER * _pki_pkcs11_load_module( const char *filename, + PKI_CONFIG * conf ) { + + PKCS11_HANDLER *ret = NULL; + CK_RV rv = CKR_OK; + CK_RV (* PKI_C_GetFunctionList )(CK_FUNCTION_LIST_PTR_PTR); + char *error = NULL; + + if( (conf == NULL) || (filename == NULL) ) { + PKI_log_err("Missing params for pkcs11 init!"); + return ( NULL ); + }; + + if(( ret = PKI_Malloc ( sizeof( PKCS11_HANDLER ))) == NULL ) { + PKI_log_debug ( "ERROR::Memory allocation" ); + return ( NULL ); + }; + + dlerror(); /* Clears previous errors */ + if((ret->sh_lib = dlopen( filename, RTLD_NOW )) == NULL ) { + PKI_log_err("Can not load lib file (%s)::%s", filename, + dlerror()); + + PKI_Free ( ret ); + return ( NULL ); + } + + /* Now we want to get the pointer to get the list of available + * callbacks */ + // (CK_RV (*)(CK_FUNCTION_LIST_PTR_PTR)) + // *(void **) (&PKI_C_GetFunctionList) = + // dlsym(handle, "C_GetFunctionList"); + + PKI_C_GetFunctionList = dlsym(ret->sh_lib, "C_GetFunctionList"); + + if((error = dlerror()) != NULL ) { + PKI_log_debug("ERROR:Missing C_GetFunctionList in %s (%s)", + filename, error); + goto err; + } + + if(( rv = PKI_C_GetFunctionList(&(ret->callbacks))) != CKR_OK ) { + PKI_log_debug("ERROR::Can not get list of funcs from %s", + filename ); + goto err; + } + + if( ret->callbacks == NULL ) { + PKI_log_debug("ERROR::Can not get list of funcs from %s", + filename ); + goto err; + }; + + return ( ret ); + +err: + if( ret && ret->sh_lib ) { + dlclose( ret->sh_lib ); + }; + if ( ret ) { + PKI_Free ( ret ); + } + + return (NULL); +} + + +int _hsm_pkcs11_get_token_info( unsigned long slot_id, + HSM_TOKEN_INFO *tk_info, PKCS11_HANDLER *lib ) { + + CK_ULONG slot_num = 0; + CK_TOKEN_INFO info; + CK_RV rv = CKR_OK; + + if ( (tk_info == NULL) || ( lib == NULL )) { + return ( PKI_ERR ); + } + + slot_num = (CK_ULONG) slot_id; + if((rv = lib->callbacks->C_GetTokenInfo(slot_num, &info)) != CKR_OK ) { + PKI_log_debug("Can not get Info from PKCS11 library" ); + return ( PKI_ERR ); + }; + + _strncpyClip(tk_info->label, (char *)info.label, LABEL_SIZE ); + _strncpyClip(tk_info->manufacturerID, (char *)info.manufacturerID, + MANUFACTURER_ID_SIZE ); + _strncpyClip(tk_info->model, (char *)info.model, MODEL_SIZE ); + _strncpyClip(tk_info->serialNumber, (char *)info.serialNumber, + SERIAL_NUMBER_SIZE ); + + /* Session Information */ + tk_info->max_sessions = info.ulMaxSessionCount ; + tk_info->curr_sessions = info.ulSessionCount ; + + /* PIN details */ + tk_info->max_pin_len = info.ulMaxPinLen ; + tk_info->min_pin_len = info.ulMinPinLen ; + + /* Memory */ + tk_info->memory_pub_tot = info.ulTotalPublicMemory ; + tk_info->memory_pub_free = info.ulFreePublicMemory ; + tk_info->memory_priv_tot = info.ulTotalPrivateMemory ; + tk_info->memory_priv_free = info.ulFreePrivateMemory ; + + /* Version Numbers */ + tk_info->hw_version_major = info.hardwareVersion.major ; + tk_info->hw_version_minor = info.hardwareVersion.minor ; + tk_info->fw_version_major = info.firmwareVersion.major ; + tk_info->fw_version_minor = info.firmwareVersion.minor ; + + /* Time */ + _strncpyClip( tk_info->utcTime, (char *)info.utcTime, 16 ); + + if( info.flags & CKF_RNG ) { + tk_info->has_rng = 1; + } + + // if( info.flags & CFK_CLOCK_ON_TOKEN ) { + tk_info->has_clock = 1; + // } + + if( info.flags & CKF_LOGIN_REQUIRED ) { + tk_info->login_required = 1; + } + + /* + PKI_log_debug( "TOKEN INFO: Label (%s)", tk_info->label ); + PKI_log_debug( "TOKEN INFO: Manufacturer ID (%s)", + tk_info->manufacturerID); + PKI_log_debug( "TOKEN INFO: Model (%s)", tk_info->model ); + PKI_log_debug( "TOKEN INFO: SerialNumber (%s)", tk_info->serialNumber); + + PKI_log_debug( "TOKEN INFO: Sessions (%d/%d)", tk_info->max_sessions, + tk_info->curr_sessions ); + PKI_log_debug( "TOKEN INFO: Free Public Memory (%d/%d)", + tk_info->memory_pub_free, + tk_info->memory_pub_tot ); + PKI_log_debug( "TOKEN INFO: Free Private Memory (%d/%d)", + tk_info->memory_priv_free, + tk_info->memory_priv_tot ); + PKI_log_debug( "TOKEN INFO: HW Version (v%d.%d)", + tk_info->hw_version_major, + tk_info->hw_version_minor ); + PKI_log_debug( "TOKEN INFO: FW Version (v%d.%d)", + tk_info->fw_version_major, + tk_info->fw_version_minor ); + */ + + /* Get the Info about the Token */ + return ( PKI_OK ); +} + +CK_OBJECT_HANDLE * HSM_PKCS11_get_obj( CK_ATTRIBUTE *templ, + int size, PKCS11_HANDLER *lib, CK_SESSION_HANDLE *session ) { + + CK_OBJECT_HANDLE * ret = NULL; + CK_ULONG ulObjectCount; + + CK_RV rv; + int rc = 0; + + if( !lib || !session || !templ ) return ( NULL ); + + rc = pthread_mutex_lock ( &lib->pkcs11_mutex ); + PKI_log_debug("%d::HSM_PKCS11_get_obj()::RC=%d", __LINE__, rc ); + while ((rv = lib->callbacks->C_FindObjectsInit( *session, + templ, (size_t) size)) == CKR_OPERATION_ACTIVE ) { + rc =pthread_cond_wait ( &lib->pkcs11_cond, &lib->pkcs11_mutex ); + PKI_log_debug("%d::HSM_PKCS11_get_obj()::RC=%d", __LINE__, rc ); + } + + if( rv != CKR_OK ) { + PKI_log_debug("HSM_PKCS11_get_obj::Error in " + "Find Initialization (0x%8.8X)", rv ); + + pthread_cond_signal( &lib->pkcs11_cond ); + pthread_mutex_unlock( &lib->pkcs11_mutex ); + + return ( NULL ); + } + + /* + while (rv == CKR_OPERATION_ACTIVE ) { + pthread_mutex_lock( &lib->pkcs11_mutex ); + mutex_acquired = 1; + + if((rv = lib->callbacks->C_FindObjectsInit( *session, + templ, size)) != + CKR_OPERATION_ACTIVE ) { + PKI_log_debug("HSM_PKCS11_get_obj::Error in " + "Find Initialization (0x%8.8X)", rv ); + + break; + } + + pthread_cond_signal( &lib->pkcs11_cond ); + pthread_mutex_unlock( &lib->pkcs11_mutex ); + mutex_acquired = 0; + + } + + if( rv != CKR_OK ) { + PKI_log_debug("HSM_PKCS11_get_obj::Error in " + "Find Initialization (0x%8.8X)", rv ); + + if( mutex_acquired == 1 ) { + pthread_cond_signal( &lib->pkcs11_cond ); + pthread_mutex_unlock( &lib->pkcs11_mutex ); + } + return ( NULL ); + } + */ + + if((ret = (CK_OBJECT_HANDLE *) PKI_Malloc ( sizeof( + CK_OBJECT_HANDLE ))) == NULL ) { + + rv = lib->callbacks->C_FindObjectsFinal( *session ); + + pthread_cond_signal( &lib->pkcs11_cond ); + pthread_mutex_unlock( &lib->pkcs11_mutex ); + + return ( NULL ); + } + + rv = lib->callbacks->C_FindObjects(*session, ret, 1, &ulObjectCount ); + + if( rv != CKR_OK || ulObjectCount == 0 ) { + PKI_log_debug("HSM_PKCS11_get_obj():: Not Found (rv=0x%8.8X - " + "ulObjectCount = %lu", rv, ulObjectCount ); + if ( ret ) PKI_Free ( ret ); + + rv = lib->callbacks->C_FindObjectsFinal( *session ); + + pthread_cond_signal( &lib->pkcs11_cond ); + pthread_mutex_unlock( &lib->pkcs11_mutex ); + return ( NULL ); + } + + rv = lib->callbacks->C_FindObjectsFinal( *session ); + + pthread_cond_signal( &lib->pkcs11_cond ); + pthread_mutex_unlock( &lib->pkcs11_mutex ); + + return ( ret ); +} + +int HSM_PKCS11_get_contents_info( unsigned long slot_id, PKI_CRED *cred, + void *driver ) { + + PKCS11_HANDLER *lib = NULL; + + CK_OBJECT_HANDLE hObject; + CK_ULONG ulObjectCount; + + CK_ULONG obj_type_val; + CK_BBOOL bool_val; + + char * obj_type = NULL; + CK_RV rv; + + CK_SESSION_HANDLE *session = NULL; + + CK_OBJECT_CLASS priv = CKO_PRIVATE_KEY; + CK_ATTRIBUTE attr[] = { + { CKA_CLASS, &priv, sizeof(priv) }, + }; + + int objID = 0; + + if( !driver ) return (PKI_ERR); + + if(( lib = _hsm_get_pkcs11_handler ( driver)) == NULL ) { + return ( PKI_ERR ); + } + + session = &lib->session; + if( HSM_PKCS11_session_new( slot_id, session, + CKF_SERIAL_SESSION | CKF_RW_SESSION, lib ) != PKI_OK ) { + return ( PKI_ERR ); + } + + if( HSM_PKCS11_login ( driver, cred ) == PKI_ERR ) { + return ( PKI_ERR ); + } + + if((rv = lib->callbacks->C_FindObjectsInit(*session, attr, 0)) + != CKR_OK ) { + PKI_DEBUG("Error in Find Initialization"); + return ( PKI_ERR ); + } + + while ( 1 ) { + char *buf = NULL; + + rv = lib->callbacks->C_FindObjects(*session, &hObject, + 1, &ulObjectCount ); + + if( rv != CKR_OK || ulObjectCount == 0 ) { + PKI_DEBUG("Find Exiting (rv=0x%8.8X - ulObjectCount = %lu", rv, ulObjectCount ); + break; + } + + if( objID == 0 ) printf(" List of Token Objects:\n\n"); + + if((HSM_PKCS11_get_attr_ckulong( &hObject, session, + CKA_CLASS, &obj_type_val, lib )) == PKI_OK ) { + + switch ( obj_type_val ) { + case CKO_PRIVATE_KEY: + obj_type = "Private Key"; + break; + case CKO_PUBLIC_KEY: + obj_type = "Public Key"; + break; + case CKO_SECRET_KEY: + obj_type = "Secret Key"; + break; + case CKO_CERTIFICATE: + obj_type = "Certificate"; + break; + case CKO_DATA: + obj_type = "Raw Data"; + break; + case CKO_VENDOR_DEFINED: + obj_type = "Vendor Defined"; + break; + default: + obj_type = "Unknown"; + } + } + + objID++; + printf(" * New Object (%d): %s\n", objID, obj_type); + if((HSM_PKCS11_get_attr_bool( &hObject, session, + CKA_PRIVATE, &bool_val, lib )) == PKI_OK ) { + printf( " Private ....................: %s\n", + bool_val ? "Yes" : "No" ); + } + + if((HSM_PKCS11_get_attr_bool( &hObject, session, + CKA_PRIVATE, &bool_val, lib )) == PKI_OK ) { + printf( " Modifiable .................: %s\n", + bool_val ? "Yes" : "No" ); + } + + if((HSM_PKCS11_get_attr_sn( &hObject, session, + CKA_LABEL, &buf, lib )) > 0) { + printf( " Label ......................: %s (%lu)\n", + ( buf != NULL ) ? buf : "n/a" , (size_t) strlen(buf)); + PKI_Free ( buf ); + buf = NULL; + } else { + printf( " Label ......................: ERROR!\n"); + } + + if( obj_type_val == CKO_PUBLIC_KEY ) { + BIGNUM *bn = NULL; + + printf( " Public Exponent ............: 0x"); + if( HSM_PKCS11_get_attr_bn( &hObject, session, + CKA_PUBLIC_EXPONENT, &bn, lib ) == PKI_OK ) { + BN_print_fp( stdout, bn ); + if( bn ) BN_free ( bn ); + bn = NULL; + } else { + printf ("Error!"); + } + + printf( "\n"); + + printf( " ID .........................: "); + if(HSM_PKCS11_get_attr_bn( &hObject, session, + CKA_ID, &bn, lib ) == PKI_OK ) { + BN_print_fp( stdout, bn ); + if( bn ) BN_free ( bn ); + bn = NULL; + } else { + printf ("Error!"); + } + printf( "\n"); + + /* + HSM_PKCS11_get_attr_sn( &hObject, session, + CKA_ID, (char **) &label, lib ); + printf( " ID (hex bytes) .............: "); + + line = 0; + len = strlen ( label ); + for( i=0; i < len; i++ ) { + printf("%c", label[i]); + line++; + if( line > 23 ) { + printf("\n "); + line = 0; + } + } printf("\n"); + if ( label ) PKI_Free ( label ); + */ + + } else if ( obj_type_val == CKO_PRIVATE_KEY ) { + BIGNUM *bn = NULL; + + printf( " Object Type ................: Private Key\n"); + printf( " Public Exponent ............: 0x"); + if( HSM_PKCS11_get_attr_bn( &hObject, session, + CKA_PUBLIC_EXPONENT, &bn, lib ) == PKI_OK ) { + BN_print_fp( stdout, bn ); + if( bn ) BN_free ( bn ); + bn = NULL; + } else { + printf("Error!"); + } + printf( "\n"); + + printf( " ID .........................: "); + if( HSM_PKCS11_get_attr_bn( &hObject, session, + CKA_ID, &bn, lib ) == PKI_OK ) { + BN_print_fp( stdout, bn ); + if( bn ) BN_free ( bn ); + bn = NULL; + } else { + printf("Error!"); + } + printf( "\n"); + + /* + HSM_PKCS11_get_attr_sn( &hObject, session, + CKA_ID, (char **) &label, lib ); + printf( " ID (hex bytes) .............: "); + + line = 0; + len = strlen(label); + for( i = 0; i < len; i++ ) { + printf("%c", label[i]); + line++; + if( line > 23 ) { + printf("\n "); + line = 0; + } + } printf("\n"); + if ( label ) PKI_Free ( label ); + */ + + } else if ( obj_type_val == CKO_CERTIFICATE ) { + BIGNUM *bn = NULL; + + if( HSM_PKCS11_get_attr_bn( &hObject, session, + CKA_ID, &bn, lib ) == PKI_OK ) { + printf( " ID (%2.2d) ....................: ", + BN_num_bytes(bn) ); + BN_print_fp( stdout, bn ); + if( bn ) BN_free ( bn ); + bn = NULL; + } else { + printf( " ID (0) ....................: Error!"); + } + + printf( "\n"); + + bn = NULL; + + } else if ( obj_type_val == CKO_SECRET_KEY ) { + } else if ( obj_type_val == CKO_VENDOR_DEFINED ) { + } else { + } + + HSM_PKCS11_get_attr_bool( &hObject, session, + CKA_TOKEN, &bool_val, lib); + printf( " Object on Token ............: %s\n", + bool_val ? "Yes" : "No" ); + HSM_PKCS11_get_attr_bool( &hObject, session, + CKA_LOCAL, &bool_val, lib); + printf( " On Board Generated .........: %s\n", + bool_val ? "Yes" : "No" ); + HSM_PKCS11_get_attr_bool( &hObject, session, + CKA_NEVER_EXTRACTABLE, &bool_val, lib); + printf( " Object Never Extractable ...: %s\n", + bool_val ? "Yes" : "No" ); + HSM_PKCS11_get_attr_bool( &hObject, session, + CKA_EXTRACTABLE, &bool_val, lib); + printf( " Object Extractable .........: %s\n", + bool_val ? "Yes" : "No" ); + HSM_PKCS11_get_attr_bool( &hObject, session, + CKA_ALWAYS_SENSITIVE, &bool_val, lib); + printf( " Object Always Sensitive ....: %s\n", + bool_val ? "Yes" : "No" ); + printf("\n"); + } + + if ( objID == 0 ) printf ( " No Objects on Token\n\n" ); + + if((rv = lib->callbacks->C_FindObjectsFinal(*session)) != CKR_OK ) { + PKI_log_debug ("_hsm_pkcs11_get_keys_info()::Error in Find " + "Finalize"); + return ( PKI_ERR ); + } + + HSM_PKCS11_session_close( session, lib ); + + return (PKI_OK); +} + +int HSM_PKCS11_session_new( unsigned long slot_id, CK_SESSION_HANDLE *hSession, + int flags, PKCS11_HANDLER *lib ) { + + CK_RV rv; + + CK_SESSION_INFO session_info; + + // Input checks + if (!hSession || !lib) return PKI_ERR; + + // Default flags + if (flags == 0) flags = CKF_SERIAL_SESSION; + + // Clears the memory + memset(&session_info, 0, sizeof(CK_SESSION_INFO)); + + // Gets the Session Info + if(( rv = lib->callbacks->C_GetSessionInfo(*hSession, &session_info)) + == CKR_OK ) { + + // If flags are the same, we are successful + if (session_info.flags == flags) return PKI_OK; + + // If flags are not the same, let's log the condition + PKI_log_debug("%s()::Session flags returned " + "from C_GetSessionInfo() differ from given argument: " + "Prev=0x%8.8X, Curr=0x%8.8X", __PRETTY_FUNCTION__, + session_info.flags, flags); + } else { + PKI_log_debug("%s()::C_GetSessionInfo failed: Error: [0x%8.8X]", + __PRETTY_FUNCTION__, rv); + } + + + // If we reach this point, then the current session is either + // not valid or has different flags set + if((rv = lib->callbacks->C_OpenSession (slot_id, + (CK_FLAGS) flags, NULL, NULL, hSession)) != CKR_OK ) { + PKI_log_debug("%s()::Failed opening a new session " + "(flags = 0x%x) with the token (slot=%d) " + "Error: [0x%8.8X]", __PRETTY_FUNCTION__, + flags, slot_id, rv ); + return PKI_ERR; + } + + // All Done + return ( PKI_OK ); +} + +int HSM_PKCS11_session_close( CK_SESSION_HANDLE *hSession, PKCS11_HANDLER *lib){ + + CK_RV rv; + CK_SESSION_INFO session_info; + + if (!lib || !hSession ) return ( PKI_ERR ); + + if(( rv = lib->callbacks->C_GetSessionInfo(*hSession, &session_info)) + == CKR_OK ) { + if((rv = lib->callbacks->C_CloseSession( *hSession )) + != CKR_OK ) { + PKI_log_debug("HSM_PKCS11_session_close()::Error in " + "closing session" ); + return ( PKI_ERR ); + } + } + + return ( PKI_OK ); +} + + +int HSM_PKCS11_check_mechanism ( PKCS11_HANDLER *lib, CK_MECHANISM_TYPE mech ) { + + int ret = PKI_ERR; + int i = 0; + + if( !lib || !lib->mech_list ) { + PKI_log_debug( "HSM_PKCS11_check_mechanism()::no lib " + "or lib->mech_list!" ); + return (PKI_ERR); + } + + for ( i = 0 ; i < lib->mech_num ; i++ ) { + /* PKI_log_debug ("HSM_PKCS11_check_mech():: Checking 0x%8.8X " + "(for 0x%8.8X) [%d/%d]", lib->mech_list[i], mech, + i, lib->mech_num ); + */ + + if( lib->mech_list[i] == mech ) { + /* + PKI_log_debug("HSM_PKCS11_check_mech()::Found 0x%8.8X " + "(%d)!", lib->mech_list[i], i ); + */ + return (PKI_OK); + } + } + + return ( ret ); +} + +int HSM_PKCS11_get_attribute (CK_OBJECT_HANDLE *hPkey, + CK_SESSION_HANDLE *hSession, CK_ATTRIBUTE_TYPE attribute, + void **data, CK_ULONG *size, PKCS11_HANDLER *lib ) { + + CK_RV rv; + CK_ATTRIBUTE pTemplate[1]; + CK_BYTE *p = NULL; + + if( !hPkey || !hSession || !lib || !lib->callbacks || + !lib->callbacks->C_GetAttributeValue ) { + return ( PKI_ERR ); + } + + pTemplate[0].type = attribute; + pTemplate[0].pValue = NULL; + pTemplate[0].ulValueLen = 0; + + /* Let's get the size of the attribute */ + if(( rv = lib->callbacks->C_GetAttributeValue(*hSession, *hPkey, + pTemplate, 1 )) != CKR_OK ) { + PKI_DEBUG("Failed 0x%8.8X", rv); + return ( PKI_ERR ); + } + + if( pTemplate[0].ulValueLen <= 0 ) { + PKI_DEBUG("Attribute is Empty!"); + return ( PKI_ERR ); + } + + if((p = (CK_BYTE *) PKI_Malloc ( pTemplate[0].ulValueLen )) == NULL ) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return PKI_ERR_MEMORY_ALLOC; + } + + pTemplate[0].pValue = p; + *size = pTemplate[0].ulValueLen; + + /* Now that we know the size, let's get the attribute */ + if(( rv = lib->callbacks->C_GetAttributeValue( *hSession, *hPkey, + pTemplate, 1 )) != CKR_OK ) { + PKI_DEBUG("PKCS11/C_GetAttributeValue Failed (0x%8.8X)", rv ); + PKI_Free ( p ); + return ( PKI_ERR ); + } + + *data = p; + + return ( PKI_OK ); +} + +int HSM_PKCS11_get_attr_bool ( CK_OBJECT_HANDLE *hObj, + CK_SESSION_HANDLE *hSession, CK_ATTRIBUTE_TYPE attribute, + CK_BBOOL *val, PKCS11_HANDLER *lib ) { + + CK_BBOOL *data = NULL; + CK_ULONG size = 0; + + if( !hObj || !hSession || !val || !lib ) { + return ( PKI_ERR ); + } + + if( HSM_PKCS11_get_attribute( hObj, hSession, attribute, + ( void **) &data, &size, lib ) != PKI_OK ) { + return ( PKI_ERR ); + } + + if ( data ) { + *val = *data; + PKI_Free ( data ); + } + + return ( PKI_OK ); +} + +int HSM_PKCS11_get_attr_ckulong ( CK_OBJECT_HANDLE *hObj, + CK_SESSION_HANDLE *hSession, CK_ATTRIBUTE_TYPE attribute, + CK_ULONG *val, PKCS11_HANDLER *lib ) { + + CK_ULONG *data = NULL; + CK_ULONG size = 0; + CK_ULONG i = 0; + + if( !hObj || !hSession || !val || !lib ) { + return ( PKI_ERR ); + } + + if( HSM_PKCS11_get_attribute( hObj, hSession, attribute, + (void **) &data, &size, lib ) != PKI_OK ) { + return ( PKI_ERR ); + } + + if( data ) { + for ( i = size; i < sizeof(CK_ULONG); i++ ) { + *data = 0x0; + } + *val = *data; + PKI_Free ( data ); + } + + return ( PKI_OK ); +} + +int HSM_PKCS11_get_attr_bn ( CK_OBJECT_HANDLE *hObj, + CK_SESSION_HANDLE *hSession, CK_ATTRIBUTE_TYPE attribute, + BIGNUM **val, PKCS11_HANDLER *lib ) { + + unsigned char *data = NULL; + CK_ULONG size = 0; + + if( !hObj || !hSession || !val || !lib ) { + return ( PKI_ERR ); + } + + if( HSM_PKCS11_get_attribute( hObj, hSession, attribute, + (void **) &data, &size, lib ) != PKI_OK ) { + return ( PKI_ERR ); + } + + if( *val ) { + BN_bin2bn(data, (int) size, *val); + } else { + *val = BN_bin2bn(data, (int) size, NULL); + } + + // Let's free the memory + if (data) PKI_Free(data); + + // All Done + return PKI_OK; +} + +int HSM_PKCS11_get_attr_sn ( CK_OBJECT_HANDLE *hObj, + CK_SESSION_HANDLE *hSession, CK_ATTRIBUTE_TYPE attribute, + char **val, PKCS11_HANDLER *lib ) { + + char *data = NULL; + size_t real_size = 0; + CK_ULONG size = 0; + + if( !hObj || !hSession || !val || !lib ) { + return ( PKI_ERR ); + } + + if( HSM_PKCS11_get_attribute( hObj, hSession, attribute, + ( void **) &data, &size, lib ) != PKI_OK ) { + return ( PKI_ERR ); + } + + real_size = (size_t) size; + + if ( data != NULL ) { + char *tmp = NULL; + + if( (tmp = PKI_Malloc ( real_size + 1 )) == NULL ) { + PKI_Free ( data ); + return ( PKI_ERR ); + } + memcpy(tmp, data, real_size); + memset(&tmp[real_size], '\x0', 1); + + PKI_Free ( data ); + + *val = tmp; + } + + return ((int)real_size ); +} + +int HSM_PKCS11_set_attr_bool (CK_ATTRIBUTE_TYPE type, + CK_BBOOL value, CK_ATTRIBUTE *attribute ) { + + if ( !attribute ) return ( PKI_ERR ); + + attribute->type = type; + attribute->pValue = (void *) PKI_Malloc ( sizeof(CK_BBOOL) ); + memcpy(attribute->pValue, &value, sizeof(value)); + attribute->ulValueLen = sizeof( value ); + + return PKI_OK; + +} + +int HSM_PKCS11_set_attr_int ( CK_ATTRIBUTE_TYPE type, + CK_ULONG value, CK_ATTRIBUTE *attribute ) { + + if ( !attribute ) return ( PKI_ERR ); + + attribute->type = type; + attribute->pValue = (void *) PKI_Malloc ( sizeof(CK_ULONG)); + memcpy(attribute->pValue, &value, sizeof(value)); + attribute->ulValueLen = sizeof( value ); + + return PKI_OK; +} + +int HSM_PKCS11_set_attr_sn ( CK_ATTRIBUTE_TYPE type, char *value, + size_t len, CK_ATTRIBUTE *attribute) { + + if ( !attribute ) return ( PKI_ERR ); + + if ( len == 0 ) len = strlen( value ); + + attribute->type = type; + attribute->pValue = (void *) PKI_Malloc( len ); + memcpy( attribute->pValue, value, len); + attribute->ulValueLen = len; + + return PKI_OK; +} + +int HSM_PKCS11_set_attr_bn ( CK_ATTRIBUTE_TYPE type, const BIGNUM *bn, + CK_ATTRIBUTE *attribute) { + + int len = 0; + + if( !attribute || !bn ) return (PKI_ERR); + + if((len = BN_num_bytes(bn)) < 1 ) { + return ( PKI_ERR ); + } + + if((attribute->pValue = PKI_Malloc ( (size_t) len )) == NULL ) { + return (PKI_ERR); + } + + if((len = BN_bn2bin(bn, attribute->pValue)) < 0 ) { + /* Big trouble in little s! */ + if ( attribute->pValue ) PKI_Free ( attribute->pValue ); + attribute->pValue = NULL; + + return ( PKI_ERR ); + } + + attribute->type = type; + attribute->ulValueLen = (size_t) len; + + return ( PKI_OK ); +} + +/* --------------------- Save Attributes to Objects ----------------------- */ + +int HSM_PKCS11_save_attribute (CK_OBJECT_HANDLE *obj, + CK_ATTRIBUTE *templ, int idx , CK_SESSION_HANDLE *hSession, + PKCS11_HANDLER *lib ) { + + CK_RV rv = CKR_OK; + + if( !obj || !templ || !lib || !lib->callbacks || + !lib->callbacks->C_SetAttributeValue ) { + return PKI_ERR; + } + + rv = lib->callbacks->C_SetAttributeValue ( *hSession, *obj, + templ, (CK_ULONG) idx ); + + if( rv != CKR_OK ) { + PKI_log_err ("C_SetAttributeValue()::Failed with 0x%8.8X", rv); + return PKI_ERR; + } + + return PKI_OK; +} + +int HSM_PKCS11_save_attr_bool (CK_OBJECT_HANDLE *obj, CK_ATTRIBUTE_TYPE type, + CK_BBOOL value, CK_SESSION_HANDLE *hSession, + PKCS11_HANDLER *lib ) { + + CK_ATTRIBUTE attribute[1]; + int ret = PKI_OK; + + if( !obj || !hSession || !lib ) return (PKI_ERR); + + attribute[0].type = type; + attribute[0].pValue = (void *) PKI_Malloc ( sizeof(CK_BBOOL) ); + memcpy(attribute[0].pValue, &value, sizeof(value)); + attribute[0].ulValueLen = sizeof( value ); + + ret = HSM_PKCS11_save_attribute ( obj, attribute, 1, hSession, lib ); + + HSM_PKCS11_clean_template ( attribute, 1 ); + + return ( ret ); +} + +int HSM_PKCS11_save_attr_int ( CK_OBJECT_HANDLE *obj, CK_ATTRIBUTE_TYPE type, + int value, CK_SESSION_HANDLE *hSession, + PKCS11_HANDLER *lib ) { + + CK_ATTRIBUTE attribute[1]; + int ret = PKI_OK; + + if( !obj || !hSession || !lib ) return (PKI_ERR); + + attribute[0].type = type; + attribute[0].pValue = (void *) PKI_Malloc ( sizeof(int)); + memcpy(attribute[0].pValue, &value, sizeof(value)); + attribute[0].ulValueLen = sizeof( value ); + + ret = HSM_PKCS11_save_attribute( obj, attribute, 1, hSession, lib ); + + HSM_PKCS11_clean_template ( attribute, 1 ); + + return ( ret ); + +} + +int HSM_PKCS11_save_attr_sn ( CK_OBJECT_HANDLE *obj, CK_ATTRIBUTE_TYPE type, + char *value, int len, CK_SESSION_HANDLE *hSession, + PKCS11_HANDLER *lib ) { + + CK_ATTRIBUTE attribute[1]; + int ret = PKI_OK; + + if( !obj || !hSession || !lib ) return (PKI_ERR); + + if ( (len == 0) && (value != NULL) ) { + len = (int ) strlen( value ); + } + + if ( value == NULL ) len = 0; + + attribute[0].type = type; + attribute[0].pValue = (void *) PKI_Malloc( (size_t) len ); + memcpy( attribute[0].pValue, value, (size_t) len); + attribute[0].ulValueLen = (size_t) len; + + ret = HSM_PKCS11_save_attribute ( obj, attribute, 1, hSession, lib ); + + HSM_PKCS11_clean_template( attribute, 1 ); + + return ( ret ); +} + +int HSM_PKCS11_save_attr_bn ( CK_OBJECT_HANDLE *obj, CK_ATTRIBUTE_TYPE type, + BIGNUM *bn, CK_SESSION_HANDLE *hSession, + PKCS11_HANDLER *lib ) { + + CK_ATTRIBUTE attribute[1]; + int ret = PKI_OK; + int len = 0; + + if( !obj || !hSession || !lib || !bn ) return (PKI_ERR); + + if((len = BN_num_bytes(bn)) < 1 ) { + return ( PKI_ERR ); + } + + if((attribute[0].pValue = PKI_Malloc ( (size_t) len )) == NULL ) { + return (PKI_ERR); + } + + if((len = BN_bn2bin(bn, attribute[0].pValue)) < 0 ) { + /* Big trouble in little s! */ + if ( attribute[0].pValue ) PKI_Free ( attribute[0].pValue ); + attribute[0].pValue = NULL; + + return ( PKI_ERR ); + } + + attribute[0].type = type; + attribute[0].ulValueLen = (size_t) len; + + ret = HSM_PKCS11_save_attribute( obj, attribute, 1, hSession, lib ); + + HSM_PKCS11_clean_template( attribute, 1 ); + + return ( ret ); +} + +/* -------------------- Object Creation Function(s) ---------------------- */ + +CK_OBJECT_HANDLE *HSM_PKCS11_create_obj ( CK_SESSION_HANDLE *hSession, + CK_ATTRIBUTE *templ, int size, PKCS11_HANDLER *lib ) { + + CK_OBJECT_HANDLE *ret = NULL; + CK_RV rv = CKR_OK; + CK_ULONG objSize = 0; + + if( !hSession ) return ( NULL ); + + ret = (CK_OBJECT_HANDLE *) PKI_Malloc ( sizeof (CK_OBJECT_HANDLE)); + if( !ret ) return ( NULL ); + + objSize = (CK_ULONG) size; + + if((rv = lib->callbacks->C_CreateObject( *hSession, + templ, objSize, ret )) == CKR_OK ) { + + PKI_log_debug("HSM_PKCS11_create_obj()::Success!"); + } else { + PKI_log_debug("HSM_PKCS11_create_obj()::Failed with 0x%8.8X", + rv); + if ( ret ) PKI_Free ( ret ); + return ( NULL ); + } + + return ( ret ); +} + +/* ---------------------- Clean up memory in a template ------------------- */ +void HSM_PKCS11_clean_template ( CK_ATTRIBUTE *templ, int n ) { + + int i = 0; + CK_ATTRIBUTE *attr = NULL; + + if( !templ ) return; + + for(i = 0; i < n; i++ ) { + attr = &templ[i]; + + if ( !attr ) return; + + if ( !attr->pValue ) continue; + + if (attr->pValue) PKI_Free (attr->pValue); + } + + return; +} + diff --git a/src/crypto/hsm/wolfssl/Makefile.am b/src/crypto/hsm/wolfssl/Makefile.am new file mode 100644 index 00000000..20a70c19 --- /dev/null +++ b/src/crypto/hsm/wolfssl/Makefile.am @@ -0,0 +1,27 @@ +## OpenCA Makefile - by Massimiliano Pala +## (c) 1999-2009 by Massimiliano Pala and OpenCA Project +## All Rights Reserved + +TOP = ../.. +include $(TOP)/global-vars + +BASE_DEFS = + +DEFS = $(OPENCA_DEFS) + +AM_CPPFLAGS = -I$(TOP) \ + $(wolfssl_cflags) \ + $(libxml2_cflags) \ + $(COND_INCLUDES) + +SRCS = \ + wolfssl_hsm.c \ + wolfssl_hsm_pkey.c \ + wolfssl_hsm_obj.c \ + wolfssl_hsm_cb.c + +noinst_LTLIBRARIES = libpki-token-openssl.la + +libpki_token_wolfssl_la_SOURCES = $(SRCS) +libpki_token_wolfssl_la_CFLAGS = $(BUILD_LIBPKI_CFLAGS) + diff --git a/src/crypto/hsm/wolfssl/wolfssl_hsm.c b/src/crypto/hsm/wolfssl/wolfssl_hsm.c new file mode 100644 index 00000000..3d00fc68 --- /dev/null +++ b/src/crypto/hsm/wolfssl/wolfssl_hsm.c @@ -0,0 +1,441 @@ +/* HSM Object Management Functions */ + +// Single Include +#include + +/* Callbacks for Software OpenSSL HSM */ +const HSM_CALLBACKS openssl_hsm_callbacks = { + /* Errno */ + HSM_OPENSSL_get_errno, + /* Err Descr */ + HSM_OPENSSL_get_errdesc, + /* Init */ + HSM_OPENSSL_init, + /* Free */ + HSM_OPENSSL_free, + /* Login */ + NULL, + /* Logout */ + NULL, + /* Set Algorithm */ + NULL, /* HSM_OPENSSL_algor_set, */ + /* Set fips mode */ + HSM_OPENSSL_set_fips_mode, + /* Fips operation mode */ + HSM_OPENSSL_is_fips_mode, + /* General Sign */ + NULL, /* HSM_OPENSSL_sign, */ + /* ASN1 General Sign */ + NULL, /* HSM_OPENSSL_asn1_sign, */ + /* General Verify */ + NULL, /* HSM_OPENSSL_verify, */ + /* ASN1 General Verify */ + NULL, /* HSM_OPENSSL_verify, */ + /* Key Generation */ + HSM_OPENSSL_X509_KEYPAIR_new, + /* Free Keypair Function */ + HSM_OPENSSL_X509_KEYPAIR_free, + /* Key Wrapping */ + NULL, // HSM_OPENSSL_X509_KEYPAIR_STACK_wrap, + /* Key Unwrapping */ + NULL, // HSM_OPENSSL_X509_KEYPAIR_STACK_unwrap, + /* Obj Load Function */ + NULL, // HSM_OPENSSL_X509_STACK_get_url, + /* Obj Add Function */ + NULL, // HSM_OPENSSL_X509_STACK_put_url, + /* Obj Del Function */ + NULL, /* HSM_OPENSSL_X509_STACK_del_url */ + /* Get the number of available Slots */ + NULL, // HSM_OPENSSL_SLOT_num, + /* Get Slot info */ + HSM_OPENSSL_SLOT_INFO_get, + /* Free Slot info */ + NULL, /* HSM_OPENSSL_SLOT_INFO_free */ + /* Set the current slot */ + NULL, /* HSM_OPENSSL_SLOT_select */ + /* Cleans up the current slot */ + NULL, /* HSM_OPENSSL_SLOT_clean */ + /* Get X509 Callbacks */ + HSM_OPENSSL_X509_get_cb +}; + +/* Structure for PKI_TOKEN definition */ +HSM openssl_hsm = { + + /* Version of the token */ + 1, + + /* Description of the HSM */ + "OpenSSL Software HSM", + + /* Manufacturer */ + "OpenSSL Project", + + /* Pointer to the HSM config file and parsed structure*/ + NULL, + + /* One of PKI_HSM_TYPE value */ + HSM_TYPE_SOFTWARE, + + /* URL for the ID of the driver, this is filled at load time */ + NULL, + + /* Pointer to the driver structure */ + NULL, + + /* Pointer to internal session handler */ + NULL, + + /* Credential for the HSM - usually used for the SO */ + NULL, + + /* is Logged In ? */ + 0, + + /* is Cred Set ? */ + 0, + + /* is Login Required ? */ + 0, + + /* Callbacks Structures */ + &openssl_hsm_callbacks +}; + + +HSM_SLOT_INFO openssl_slot_info = { + + /* Device Manufacturer ID */ + "OpenSSL", + + /* Device Description */ + "Software interface", + + /* Hardware Version */ + 1, + 0, + + /* Firmware Version */ + 1, + 0, + + /* Initialized */ + 1, + + /* Present */ + 1, + + /* Removable */ + 0, + + /* Hardware */ + 0, + + /* Token Info */ + { + /* Token Label */ + "Unknown Label\x0 ", + /* ManufacturerID */ + "Unknown\x0 ", + /* Model */ + "Unknown\x0 ", + /* Serial Number */ + "0\x0 ", + /* Max Sessions */ + 65535, + /* Current Sessions */ + 0, + /* Max Pin Len */ + 0, + /* Min Pin Len */ + 0, + /* Memory Pub Total */ + 0, + /* Memory Pub Free */ + 0, + /* Memory Priv Total */ + 0, + /* Memory Priv Free */ + 0, + /* HW Version Major */ + 1, + /* HW Version Minor */ + 0, + /* FW Version Major */ + 1, + /* FW Version Minor */ + 0, + /* HAS Random Number Generator (RNG) */ + 1, + /* HAS clock */ + 0, + /* Login is Required */ + 0, + /* utcTime */ + "" + } + +}; + +unsigned long HSM_OPENSSL_get_errno ( void ) +{ + unsigned long ret = 0; + + ret = ERR_get_error(); + + return ret; +} + +char * HSM_OPENSSL_get_errdesc ( unsigned long err, char *str, size_t size ) +{ + char * ret = NULL; + + if (err == 0) err = ERR_get_error(); + + if (str && size > 0) + { + ERR_error_string_n ( err, str, size ); + ret = str; + } + else ret = ERR_error_string(err, NULL); + + return ret; +} + +const HSM * HSM_OPENSSL_get_default( void ) +{ + return ((const HSM *)&openssl_hsm); +} + +HSM *HSM_OPENSSL_new ( PKI_CONFIG *conf ) +{ + HSM *hsm = NULL; + + hsm = (HSM *) PKI_Malloc ( sizeof( HSM )); + memcpy( hsm, &openssl_hsm, sizeof( HSM)); + + /* Not really needed! */ + hsm->callbacks = &openssl_hsm_callbacks; + + if( conf ) { + hsm->config = conf; + } + + hsm->type = HSM_TYPE_SOFTWARE; + + return( hsm ); +} + +int HSM_OPENSSL_free ( HSM *driver, PKI_CONFIG *conf ) { + + if( driver == NULL ) return (PKI_OK); + + return (PKI_ERR); +} + +int HSM_OPENSSL_init( HSM *driver, PKI_CONFIG *conf ) { + + if( driver == NULL ) return (PKI_ERR); + + /* Checks the FIPS mode */ + if (PKI_is_fips_mode() == PKI_OK) + { + if (HSM_OPENSSL_set_fips_mode(driver, 1) == PKI_ERR) + return PKI_ERR; + } + + /* No need for initialization of the software driver */ + return PKI_OK; +} + +/*! + * \brief Sets the fips operation mode when the parameter is != 0, + * otherwise it sets the HSM in non-fips mode + */ +int HSM_OPENSSL_set_fips_mode(const HSM *driver, int k) { + +#ifdef OPENSSL_FIPS + return (FIPS_mode_set(k) == 1 ? PKI_OK : PKI_ERR); +#else + return PKI_ERR; +#endif + +} + +/*! + * \brief Returns 0 if HSM is operating in non-FIPS mode, true (!0) if FIPS + * mode is enabled. + */ +int HSM_OPENSSL_is_fips_mode(const HSM *driver) +{ +#ifdef OPENSSL_FIPS + return (FIPS_mode() == 0 ? PKI_ERR : PKI_OK); +#else + return PKI_ERR; +#endif + +} + +/* ----------------------- General Signing function -------------------- */ + +// PKI_MEM * HSM_OPENSSL_sign(PKI_MEM * der, PKI_DIGEST_ALG * digest, PKI_X509_KEYPAIR *key) { + +// EVP_MD_CTX *ctx = NULL; +// // Digest's context + +// size_t out_size = 0; +// // size_t ossl_ret = 0; + +// PKI_MEM *out_mem = NULL; +// // Output buffer + +// EVP_PKEY *pkey = NULL; +// // Signing Key Value + +// int digestResult = -1; +// int def_nid = NID_undef; +// // OpenSSL return value + +// if (!der || !der->data || !key || !key->value) +// { +// PKI_ERROR( PKI_ERR_PARAM_NULL, NULL); +// return NULL; +// } + +// // Private Key +// pkey = PKI_X509_get_value(key); +// if (!pkey) { +// PKI_ERROR(PKI_ERR_PARAM_NULL, "Cannot retrieve the internal value of the key (PKEY)."); +// return NULL; +// } + +// // Get the Maximum size of a signature +// out_size = (size_t) EVP_PKEY_size(pkey); + +// // Gets the default digest for the key +// digestResult = EVP_PKEY_get_default_digest_nid(pkey, &def_nid); + +// // PKI_DEBUG("Requested Digest for Signing is %s", digest ? PKI_ID_get_txt(EVP_MD_nid(digest)) : "NULL"); +// // PKI_DEBUG("Checking Default Digest for PKEY %d (%s) is %d (%s) (result = %d)", +// // EVP_PKEY_id(pkey), PKI_ID_get_txt(EVP_PKEY_id(pkey)), def_nid, PKI_ID_get_txt(def_nid), digestResult); + +// // Checks for error +// if (digest == NULL && digestResult <= 0) { +// PKI_DEBUG("Cannot get the default digest for signing key (type: %d)", EVP_PKEY_id(pkey)); +// return NULL; +// } + +// // If the returned value is == 2, then the returned +// // digest is mandatory and cannot be replaced +// if (digestResult == 2 && def_nid != EVP_MD_nid(digest)) { +// // // Checks if we are in a no-hash mandatory +// // if (def_nid == NID_undef && (digest != EVP_md_null() && digest != NULL)) { +// // PKI_DEBUG("PKEY requires no hash but got one (%d)", EVP_MD_nid(digest)); +// // return NULL; +// // } +// // // Checks if we are using the mandated digest +// // if ((digest != NULL && def_nid != NID_undef) || (def_nid != EVP_MD_nid(digest))) { +// // PKI_DEBUG("PKEY requires digest (%d) but got (%d)", def_nid, EVP_MD_nid(digest)); +// // return NULL; +// // } +// PKI_DEBUG("PKEY requires %s digest (mandatory) and cannot be used with %s digest (requested).", +// def_nid == NID_undef ? "NO" : PKI_ID_get_txt(def_nid), +// digest == NULL ? "NO" : PKI_ID_get_txt(EVP_MD_nid(digest))); +// return NULL; +// } + +// // Initialize the return structure +// if ((out_mem = PKI_MEM_new ((size_t)out_size)) == NULL) { +// PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); +// return NULL; +// } + +// // Creates the context +// if ((ctx = EVP_MD_CTX_create()) == NULL) { +// PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); +// goto err; +// } + +// // Initializes the Context +// EVP_MD_CTX_init(ctx); + +// // PKI_DEBUG("MD (digest) = %p (EVP_md_null = %p) (EVP_md_null() ==> %d)", +// // digest, EVP_md_null, EVP_md_null() == digest); + +// // DEBUG +// // PKI_DEBUG("MD (digest) in DigestSignInit: %d (%s)", +// // digest ? EVP_MD_nid(digest) : NID_undef, digest ? PKI_DIGEST_ALG_get_parsed(digest) : ""); + +// // Initializes the Digest and does special processing for when the +// // EVP_md_null() is used to indicate that the NO HASH was requested +// if (!EVP_DigestSignInit(ctx, NULL /* &pctx */, EVP_md_null() == digest ? NULL : digest, NULL, pkey)) { +// PKI_ERROR(PKI_ERR_SIGNATURE_CREATE, "Cannot Initialize EVP_DigestSignInit()"); +// goto err; +// } + +// if (EVP_DigestSign(ctx, out_mem->data, &out_size, der->data, der->size) <= 0) { +// PKI_ERROR(PKI_ERR_SIGNATURE_CREATE, "Cannot generate signature via EVP_DigestSign()"); +// goto err; +// } + +// // Update the size of the signature +// out_mem->size = (size_t) out_size; + +// // // Updates the Digest calculation with the TBS data +// // if (EVP_DigestSignUpdate(ctx, +// // der->data, +// // der->size) <= 0) { +// // PKI_ERROR(PKI_ERR_SIGNATURE_CREATE, "Cannot Update EVP_DigestSignUpdate()"); +// // goto err; +// // } + +// // // Finalize the MD +// // // EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_FINALISE); + +// // // Finalizes the Signature calculation and saves it in the output buffer +// // if (EVP_DigestSignFinal(ctx, +// // out_mem->data, +// // &out_size) <= 0) { +// // PKI_ERROR(PKI_ERR_SIGNATURE_CREATE, "Cannot Finalize EVP_DigestSignFinal()"); +// // goto err; +// // } +// // else out_mem->size = (size_t) out_size; + +// // All Done +// goto end; + +// err: + +// // Error Condition, free the output's memory +// if (out_mem) PKI_MEM_free(out_mem); +// out_mem = NULL; + +// end: +// // Cleanup the context +// #if OPENSSL_VERSION_NUMBER <= 0x1010000f +// if (ctx) EVP_MD_CTX_cleanup(ctx); +// #else +// if (ctx) EVP_MD_CTX_reset(ctx); +// #endif + +// // Frees the CTX structure +// if (ctx) EVP_MD_CTX_destroy(ctx); + +// // Returns the result or NULL +// return out_mem; +// } + +/* ---------------------- OPENSSL Slot Management Functions ---------------- */ + +HSM_SLOT_INFO * HSM_OPENSSL_SLOT_INFO_get (unsigned long num, HSM *hsm) { + + HSM_SLOT_INFO *ret = NULL; + + ret = (HSM_SLOT_INFO *) PKI_Malloc ( sizeof (HSM_SLOT_INFO)); + memcpy( ret, &openssl_slot_info, sizeof( HSM_SLOT_INFO )); + + return (ret); +} + +/* -------------------- OPENSSL Callbacks Management Functions ------------- */ + diff --git a/src/crypto/hsm/wolfssl/wolfssl_hsm_cb.c b/src/crypto/hsm/wolfssl/wolfssl_hsm_cb.c new file mode 100644 index 00000000..8da2a7c9 --- /dev/null +++ b/src/crypto/hsm/wolfssl/wolfssl_hsm_cb.c @@ -0,0 +1,430 @@ +#include +#include + +#include +#include + +const PKI_X509_CALLBACKS PKI_OPENSSL_X509_KEYPAIR_CALLBACKS = { + // Memory Management + (void *) EVP_PKEY_new, // PKI_KEYPAIR_new_null + (void *) EVP_PKEY_free, // PKI_KEYPAIR_free + (void *) OPENSSL_HSM_KEYPAIR_dup, // PKI_KEYPAIR_dup + + // Data Retrieval + (void *) NULL, // PKI_KEYPAIR_get_parsed + (void *) NULL, // PKI_KEYPAIR_data; + (void *) NULL, // PKI_KEYPAIR_print_parsed; + + // Data Conversion + NULL, // (void *) PEM_write_bio_PUBKEY, // PEM format + (void *) OPENSSL_HSM_write_bio_PrivateKey, // PEM format + // (void *) PEM_write_bio_PKCS8PrivateKey, // PEM format + (void *) i2d_PrivateKey_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL, // XML format + + // Data Conversion + (void *) PEM_read_bio_PrivateKey,// PEM format + (void *) d2i_PrivateKey_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL // XML format +}; + +const PKI_X509_CALLBACKS PKI_OPENSSL_X509_CERT_CALLBACKS = { + /* Memory Management */ + (void*)X509_new, + (void*)X509_free, + (void*)X509_dup, + + /* Data Retrieval */ + (void *) PKI_X509_CERT_get_parsed, + (void *) PKI_X509_CERT_get_data, + (void *) PKI_X509_CERT_print_parsed, + + /* Data Conversion */ +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + (void *) PEM_write_bio_X509_AUX, // PEM format +#else + (void *) PEM_write_bio_X509, // PEM format +#endif + NULL, // PEM EX (encrypted) format + (void *) i2d_X509_bio, // DER format + (void *) X509_print, // TXT format + NULL, // B64 format (B64_write_bio) + NULL, // XML format + + /* Data Conversion */ + (void *) PEM_read_bio_X509_AUX, // PEM format + (void *) d2i_X509_bio, // DER format + NULL, // TXT format + NULL, // B64 format + NULL // XML format +}; + + +const PKI_X509_CALLBACKS PKI_OPENSSL_X509_REQ_CALLBACKS = { + /* Memory Management */ + (void *) X509_REQ_new, + (void *) X509_REQ_free, + (void *) X509_REQ_dup, + + /* Data Retrieval */ + (void *) PKI_X509_REQ_get_parsed, + (void *) PKI_X509_REQ_get_data, + (void *) PKI_X509_REQ_print_parsed, + + /* Data Conversion */ + (void *) PEM_write_bio_X509_REQ, // PEM format + NULL, // PEM EX (encrypted) format + (void *) i2d_X509_REQ_bio, // DER format + (void *) X509_REQ_print, // TXT format + (void *) NULL, // B64 format + (void *) NULL, // XML format + + /* Data Conversion */ + (void *) PEM_read_bio_X509_REQ, // PEM format + (void *) d2i_X509_REQ_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL // XML format +}; + +const PKI_X509_CALLBACKS PKI_OPENSSL_X509_CRL_CALLBACKS = { + /* Memory Management */ + (void *) X509_CRL_new, + (void *) X509_CRL_free, + (void *) X509_CRL_dup, + + /* Data Retrieval */ + (void *) PKI_X509_CRL_get_parsed, + (void *) PKI_X509_CRL_get_data, + (void *) NULL, // PKI_X509_CRL_print_parsed, + + /* Data Conversion */ + (void *) PEM_write_bio_X509_CRL, // PEM format + NULL, // PEM EX (encrypted) format + (void *) i2d_X509_CRL_bio, // DER format + (void *) X509_CRL_print, // TXT format + (void *) NULL, // B64 format + (void *) NULL, // XML format + + /* Data Conversion */ + (void *) PEM_read_bio_X509_CRL, // PEM format + (void *) d2i_X509_CRL_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL // XML format +}; + +const PKI_X509_CALLBACKS PKI_OPENSSL_X509_PKCS7_CALLBACKS = { + + /* Memory Management */ + (void *) PKCS7_new, + (void *) PKCS7_free, + (void *) PKCS7_dup, + + /* Data Retrieval */ + (void *) NULL, // PKI_X509_PKCS7_get_parsed; + (void *) NULL, // PKI_X509_PKCS7_get_data; + (void *) NULL, // PKI_X509_PKCS7_print_parsed; + + /* Data Conversion */ + (void *) PEM_write_bio_PKCS7, // PEM format + NULL, // PEM EX (encrypted) format + (void *) i2d_PKCS7_bio, // DER format + (void *) PKI_X509_PKCS7_VALUE_print_bio, // TXT format + (void *) NULL, // B64 format + (void *) NULL, // XML format + + /* Data Conversion */ + (void *) PEM_read_bio_PKCS7, // PEM format + (void *) d2i_PKCS7_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL // XML format +}; + + +const PKI_X509_CALLBACKS PKI_OPENSSL_X509_CMS_CALLBACKS = { + + /* Memory Management */ + (void *) PKI_X509_CMS_VALUE_new, + (void *) PKI_X509_CMS_VALUE_free, + (void *) PKI_X509_CMS_VALUE_dup, + + /* Data Retrieval */ + (void *) NULL, // PKI_X509_PKCS7_get_parsed; + (void *) NULL, // PKI_X509_PKCS7_get_data; + (void *) NULL, // PKI_X509_PKCS7_print_parsed; + + /* Data Conversion */ + (void *) PEM_write_bio_CMS, // PEM format + NULL, // PEM EX (encrypted) format + (void *) i2d_CMS_bio, // DER format + (void *) PKI_X509_CMS_VALUE_print_bio, // TXT format + (void *) NULL, // B64 format + (void *) NULL, // XML format + + /* Data Conversion */ + (void *) PEM_read_bio_CMS, // PEM format + (void *) d2i_CMS_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL // XML format +}; + + +const PKI_X509_CALLBACKS PKI_OPENSSL_X509_PKCS12_CALLBACKS = { + // Memory Management + (void *) PKCS12_new, + (void *) PKCS12_free, + (void *) NULL, + + // Data Retrieval + (void *) NULL, // PKI_X509_PKCS12_get_parsed; + (void *) NULL, // PKI_X509_PKCS12_get_data; + (void *) NULL, // PKI_X509_PKCS12_print_parsed; + + // Data Conversion + (void *) PEM_write_bio_PKCS12, // PEM format + NULL, // PEM EX (encrypted) format + (void *) i2d_PKCS12_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL, // XML format + + // Data Conversion + (void *) PEM_read_bio_PKCS12, // PEM format + (void *) d2i_PKCS12_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL // XML format +}; + +const PKI_X509_CALLBACKS PKI_OPENSSL_X509_OCSP_REQ_CALLBACKS = { + // Memory Management + (void *) OCSP_REQUEST_new, + (void *) OCSP_REQUEST_free, + (void *) NULL, + + // Data Retrieval + (void *) PKI_X509_OCSP_REQ_get_parsed, // PKI_X509_OCSP_REQ_get_parsed; + (void *) PKI_X509_OCSP_REQ_get_data, // PKI_X509_OCSP_REQ_get_data; + (void *) NULL, // PKI_X509_OCSP_REQ_print_parsed; + + // Data Conversion + (void *) PEM_write_bio_OCSP_REQ,// PEM format + NULL, // PEM EX (encrypted) format + (void *) i2d_OCSP_REQ_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL, // XML format + + // Data Conversion + (void *) PEM_read_bio_OCSP_REQ, // PEM format + (void *) d2i_OCSP_REQ_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL // XML format +}; + +const PKI_X509_CALLBACKS PKI_OPENSSL_X509_OCSP_RESP_CALLBACKS = { + // Memory Management + (void *) PKI_OCSP_RESP_new, + (void *) PKI_OCSP_RESP_free, + (void *) NULL, + + // Data Retrieval + (void *) PKI_X509_OCSP_RESP_get_parsed, + (void *) PKI_X509_OCSP_RESP_get_data, + (void *) NULL, // PKI_X509_OCSP_RESP_print_parsed; + + // Data Conversion + (void *) PEM_write_bio_PKI_X509_OCSP_RESP_VALUE, // PEM format + NULL, // PEM EX (encrypted) format + (void *) i2d_PKI_X509_OCSP_RESP_VALUE_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL, // XML format + + // Data Conversion + (void *) PEM_read_bio_PKI_X509_OCSP_RESP_VALUE,// PEM format + (void *) d2i_PKI_X509_OCSP_RESP_VALUE_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL // XML format +}; + +const PKI_X509_CALLBACKS PKI_OPENSSL_X509_XPAIR_CALLBACKS = { + // Memory Management + (void *) PKI_XPAIR_new_null, + (void *) PKI_XPAIR_free, + (void *) NULL, + + // Data Retrieval + (void *) NULL, // PKI_X509_XPAIR_get_parsed;sed; + (void *) NULL, // PKI_X509_XPAIR_get_data; + (void *) NULL, // PKI_X509_XPAIR_print_parsed; + + // Data Conversion + (void *) PEM_write_bio_PKI_XPAIR, // PEM format + NULL, // PEM EX (encrypted) format + (void *) i2d_PKI_XPAIR_bio, // DER format + (void *) PKI_XPAIR_print, // TXT format + (void *) NULL, // B64 format + (void *) NULL, // XML format + + // Data Conversion + (void *) PEM_read_bio_PKI_XPAIR,// PEM format + (void *) d2i_PKI_XPAIR_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL // XML format +}; + +const PKI_X509_CALLBACKS PKI_OPENSSL_X509_PRQP_REQ_CALLBACKS = { + // Memory Management + (void *) PKI_PRQP_REQ_new, + (void *) PKI_PRQP_REQ_free, + (void *) PKI_PRQP_REQ_dup, + + // Data Retrieval + (void *) NULL, //PKI_X509_PRQP_REQ_get_parsed, // PKI_X509_OCSP_REQ_get_parsed; + (void *) PKI_X509_PRQP_REQ_get_data, // PKI_X509_OCSP_REQ_get_data; + (void *) NULL, // PKI_X509_OCSP_REQ_print_parsed; + + // Data Conversion + (void *) PEM_write_bio_PRQP_REQ,// PEM format + NULL, // PEM EX (encrypted) format + (void *) i2d_PRQP_REQ_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL, // XML format + + // Data Conversion + (void *) PEM_read_bio_PRQP_REQ, // PEM format + (void *) d2i_PRQP_REQ_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL // XML format +}; + +const PKI_X509_CALLBACKS PKI_OPENSSL_X509_PRQP_RESP_CALLBACKS = { + // Memory Management + (void *) PKI_PRQP_RESP_new, + (void *) PKI_PRQP_RESP_free, + (void *) PKI_PRQP_RESP_dup, + + // Data Retrieval + (void *) NULL,//PKI_X509_PRQP_RESP_get_parsed, + (void *) PKI_X509_PRQP_RESP_get_data, + (void *) NULL, // PKI_X509_OCSP_RESP_print_parsed; + + // Data Conversion (write of the ->value data ) + (void *) PEM_write_bio_PRQP_RESP, // PEM format + NULL, // PEM EX (encrypted) format + (void *) i2d_PRQP_RESP_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL, // XML format + + // Data Conversion (read the ->value) + (void *) PEM_read_bio_PRQP_RESP,// PEM format + (void *) d2i_PRQP_RESP_bio, // DER format + (void *) NULL, // TXT format + (void *) NULL, // B64 format + (void *) NULL // XML format +}; + + +const PKI_X509_CALLBACKS_FULL PKI_OPENSSL_X509_CALLBACKS_FULL = { + // X509_KEYPAIR + &PKI_OPENSSL_X509_KEYPAIR_CALLBACKS, + // X509_CERT + &PKI_OPENSSL_X509_CERT_CALLBACKS, + // X509_REQ + &PKI_OPENSSL_X509_REQ_CALLBACKS, + // X509_CRL + &PKI_OPENSSL_X509_CRL_CALLBACKS, + // X509_PKCS7 + &PKI_OPENSSL_X509_PKCS7_CALLBACKS, + // X509_CMS + &PKI_OPENSSL_X509_CMS_CALLBACKS, + // X509_PKCS12 + &PKI_OPENSSL_X509_PKCS12_CALLBACKS, + // X509_OCSP_REQ + &PKI_OPENSSL_X509_OCSP_REQ_CALLBACKS, + // X509_OCSP_RESP + &PKI_OPENSSL_X509_OCSP_RESP_CALLBACKS, + // X509_OCSP_XPAIR + &PKI_OPENSSL_X509_XPAIR_CALLBACKS, + // X509_OCSP_CMS + NULL, // &PKI_OPENSSL_X509_CMC_CALLBACKS, + // X509_OCSP_SCEP + &PKI_OPENSSL_X509_PKCS7_CALLBACKS, // &PKI_OPENSSL_X509_SCEP_CALLBACKS + // PRQP_REQ + &PKI_OPENSSL_X509_PRQP_REQ_CALLBACKS, + // PRQP_RESP + &PKI_OPENSSL_X509_PRQP_RESP_CALLBACKS +}; + +const PKI_X509_CALLBACKS *HSM_OPENSSL_X509_get_cb ( PKI_DATATYPE type ) { + + const PKI_X509_CALLBACKS *ret = NULL; + + switch ( type ) { + case PKI_DATATYPE_X509_KEYPAIR : + ret = &PKI_OPENSSL_X509_KEYPAIR_CALLBACKS; + break; + case PKI_DATATYPE_X509_CERT : + ret = &PKI_OPENSSL_X509_CERT_CALLBACKS; + break; + case PKI_DATATYPE_X509_REQ : + ret = &PKI_OPENSSL_X509_REQ_CALLBACKS; + break; + case PKI_DATATYPE_X509_CRL : + ret = &PKI_OPENSSL_X509_CRL_CALLBACKS; + break; + case PKI_DATATYPE_X509_PKCS7 : + ret = &PKI_OPENSSL_X509_PKCS7_CALLBACKS; + break; + case PKI_DATATYPE_X509_CMS : + ret = &PKI_OPENSSL_X509_CMS_CALLBACKS; + break; + case PKI_DATATYPE_X509_PKCS12 : + ret = &PKI_OPENSSL_X509_PKCS12_CALLBACKS; + break; + case PKI_DATATYPE_X509_OCSP_REQ : + ret = &PKI_OPENSSL_X509_OCSP_REQ_CALLBACKS; + break; + case PKI_DATATYPE_X509_OCSP_RESP : + ret = &PKI_OPENSSL_X509_OCSP_RESP_CALLBACKS; + break; + case PKI_DATATYPE_X509_XPAIR : + ret = &PKI_OPENSSL_X509_XPAIR_CALLBACKS; + break; + case PKI_DATATYPE_X509_CMS_MSG : + // TODO: Provide support for CMS + // ret = &PKI_OPENSSL_X509_CMS; + break; + case PKI_DATATYPE_EST_MSG : + // TODO: Provide support for EST + // ret = &PKI_OPENSSL_X509_CMS_CALLBACKS; + break; + case PKI_DATATYPE_SCEP_MSG : + ret = &PKI_OPENSSL_X509_PKCS7_CALLBACKS; + break; + case PKI_DATATYPE_X509_PRQP_REQ : + ret = &PKI_OPENSSL_X509_PRQP_REQ_CALLBACKS; + break; + case PKI_DATATYPE_X509_PRQP_RESP : + ret = &PKI_OPENSSL_X509_PRQP_RESP_CALLBACKS; + break; + default: + return NULL; + } + + return ret; +} diff --git a/src/crypto/hsm/wolfssl/wolfssl_hsm_obj.c b/src/crypto/hsm/wolfssl/wolfssl_hsm_obj.c new file mode 100644 index 00000000..72dae836 --- /dev/null +++ b/src/crypto/hsm/wolfssl/wolfssl_hsm_obj.c @@ -0,0 +1,22 @@ +/* openssl/pki_pkey.c */ + +#include + +/* ---------------- OpenSSL HSM Keypair get/put --------------------------- */ + +PKI_STACK * HSM_OPENSSL_OBJSK_get_url ( PKI_DATATYPE type, URL *url, + PKI_CRED *cred, void *hsm ) { + + PKI_log_debug("HSM_OPENSSL_OBJSK_get_url()::Deprecated"); + + return NULL; +} + +PKI_X509_KEYPAIR_STACK * HSM_OPENSSL_X509_KEYPAIR_get_url ( URL *url, + PKI_CRED *cred, HSM *hsm) { + + PKI_log_debug("HSM_OPENSSL_X509_KEYPAIR_get_url()::Deprecated"); + + return NULL; +} + diff --git a/src/crypto/hsm/wolfssl/wolfssl_hsm_pkey.c b/src/crypto/hsm/wolfssl/wolfssl_hsm_pkey.c new file mode 100644 index 00000000..fc1e6c54 --- /dev/null +++ b/src/crypto/hsm/wolfssl/wolfssl_hsm_pkey.c @@ -0,0 +1,1214 @@ +/* openssl/pki_pkey.c */ + +/* Internal usage only - we want to keep the lib abstract */ +#ifndef _LIBPKI_HSM_OPENSSL_PKEY_H +#define _LIBPKI_HSM_OPENSSL_PKEY_H + +#include + +PKI_RSA_KEY * _pki_rsakey_new( PKI_KEYPARAMS *kp ); +PKI_DSA_KEY * _pki_dsakey_new( PKI_KEYPARAMS *kp ); +#ifdef ENABLE_ECDSA +PKI_EC_KEY * _pki_ecdsakey_new( PKI_KEYPARAMS *kp); +#else +void * _pki_ecdsakey_new( PKI_KEYPARAMS *kp ); +#endif + +int _evp_ctx_key_generation(int pkey_type, PKI_X509_KEYPAIR_VALUE ** pkey) { + + EVP_PKEY_CTX * pctx = NULL; + // Key generation context + + // Input Checks + if (!pkey) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return PKI_ERR; + } + + if (pkey_type <= 0) { + PKI_ERROR(PKI_ERR_PARAM_RANGE, NULL); + return PKI_ERR; + } + + pctx = EVP_PKEY_CTX_new_id(pkey_type, NULL); + if (!pctx) { + PKI_DEBUG("Can not create context for key generation (%d)", pkey_type); + return PKI_ERR; + } + + if (EVP_PKEY_keygen_init(pctx) <= 0) { + PKI_DEBUG("Can not init ED448 context"); + EVP_PKEY_CTX_free(pctx); + return PKI_ERR; + } + + if (EVP_PKEY_keygen(pctx, pkey) <= 0) { + PKI_DEBUG("Can not generate ED448 key"); + EVP_PKEY_CTX_free(pctx); + return PKI_ERR; + } + + EVP_PKEY_CTX_free(pctx); + if (!*pkey) { + PKI_DEBUG("Can not generate ED448 key"); + return PKI_ERR; + } + + return PKI_OK; +} + +int _evp_ctx_key_generation_rsa(PKI_KEYPARAMS * const params, PKI_X509_KEYPAIR_VALUE ** pkey) { + + EVP_PKEY_CTX * pctx = NULL; + // Key generation context + + // Input Checks + if (!pkey || !params) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return PKI_ERR; + } + + if (params->pkey_type <= 0) { + PKI_ERROR(PKI_ERR_PARAM_RANGE, NULL); + return PKI_ERR; + } + + pctx = EVP_PKEY_CTX_new_id(params->pkey_type, NULL); + if (!pctx) { + PKI_DEBUG("Can not create context for key generation (%d)", params->pkey_type); + return PKI_ERR; + } + + // ==================== + // Set the RSA key size + // ==================== + + int bits = params->rsa.bits; + if (bits <= 0) { + if (bits <= 0) { + if (bits <= 0) bits = PKI_RSA_KEY_DEFAULT_SIZE; + } + bits = PKI_SCHEME_ID_get_bitsize(params->scheme, params->sec_bits); + } + + if (EVP_PKEY_keygen_init(pctx) <= 0) { + PKI_DEBUG("Can not init ED448 context"); + EVP_PKEY_CTX_free(pctx); + return PKI_ERR; + } + + if (EVP_PKEY_CTX_set_rsa_keygen_bits(pctx, bits) <= 0) { + PKI_DEBUG("Can not set RSA key size (%d)", bits); + EVP_PKEY_CTX_free(pctx); + return PKI_ERR; + } + params->bits = bits; + params->rsa.bits = bits; + + if (EVP_PKEY_keygen(pctx, pkey) <= 0) { + PKI_DEBUG("Can not generate ED448 key"); + EVP_PKEY_CTX_free(pctx); + return PKI_ERR; + } + + EVP_PKEY_CTX_free(pctx); + if (!*pkey) { + PKI_DEBUG("Can not generate ED448 key"); + return PKI_ERR; + } + + return PKI_OK; +} + +int _pki_rand_init( void ); + +/* End of _LIBPKI_INTERNAL_PKEY_H */ +#endif + +int _pki_rand_seed( void ) { + unsigned char seed[20]; + + if (!RAND_bytes(seed, 20)) return 0; + + RAND_seed(seed, sizeof seed); + + return(1); +} + +PKI_RSA_KEY * _pki_rsakey_new( PKI_KEYPARAMS *kp ) { + + PKI_RSA_KEY *rsa = NULL; + + int bits = PKI_RSA_KEY_DEFAULT_SIZE; + + if ( kp && kp->bits > 0 ) bits = kp->bits; + + if ( bits < PKI_RSA_KEY_MIN_SIZE ) { + PKI_DEBUG("WARNING: RSA Key size smaller than minimum safe size (%d vs. %d)", + bits, PKI_RSA_KEY_DEFAULT_SIZE); + return NULL; + } else if ( bits < PKI_RSA_KEY_DEFAULT_SIZE ) { + PKI_DEBUG("WARNING: RSA Key size smaller than default safe size (%d vs. %d)", + bits, PKI_RSA_KEY_DEFAULT_SIZE); + } + +#if OPENSSL_VERSION_NUMBER > 0x30000000L + EVP_PKEY_CTX * pkey_ctx = NULL; + EVP_PKEY * pkey = NULL; + + OSSL_LIB_CTX * ossl_libctx = PKI_init_get_ossl_library_ctx(); + + // Tries to create the context by using the key id + if ((pkey_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL)) == NULL) { + // Tries to create the context by using the name + pkey_ctx = EVP_PKEY_CTX_new_from_name(ossl_libctx, "RSA", NULL); + } + if (!pkey_ctx) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Cannot create EVP_PKEY_CTX"); + return NULL; + } + + // Initializes the key generation operation + if (EVP_PKEY_keygen_init(pkey_ctx) < 0) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Cannot init EVP_PKEY_CTX"); + EVP_PKEY_CTX_free(pkey_ctx); + return NULL; + } + + // Sets the RSA key size (parameter) + if (EVP_PKEY_CTX_set_rsa_keygen_bits(pkey_ctx, bits) < 0) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Cannot set RSA key size"); + EVP_PKEY_CTX_free(pkey_ctx); + return NULL; + } + + // Generates the new key + if (!EVP_PKEY_generate(pkey_ctx, &pkey)) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Cannot generate EVP_PKEY"); + EVP_PKEY_CTX_free(pkey_ctx); + return NULL; + } + + // Extracts the RSA key + rsa = EVP_PKEY_get1_RSA(pkey); + + // Free allocated heap memory + if (pkey) EVP_PKEY_free(pkey); + if (pkey_ctx) EVP_PKEY_CTX_free(pkey_ctx); + + if (!rsa) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Cannot extract RSA key from EVP_PKEY"); + return NULL; + } +#else + unsigned long e = RSA_F4; + // Default exponent (65537) + + BIGNUM *bne = NULL; + int ossl_rc = 0; + + if ((bne = BN_new()) != NULL) { + if (1 != BN_set_word(bne, e)) { + PKI_ERROR(PKI_ERR_GENERAL, NULL); + return NULL; + } + } else { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return NULL; + } + + if ((rsa = RSA_new()) == NULL) { + BN_free(bne); + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return NULL; + } + + if ((ossl_rc = RSA_generate_key_ex(rsa, bits, bne, NULL)) != 1 ) { + /* Error */ + BN_free(bne); + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, NULL); + return NULL; + } + + BN_free(bne); +#endif + + /* Let's return the RSA_KEY infrastructure */ + return (rsa); +}; + +PKI_DSA_KEY * _pki_dsakey_new( PKI_KEYPARAMS *kp ) { + + PKI_DSA_KEY *k = NULL; + unsigned char seed[20]; + + int bits = PKI_DSA_KEY_DEFAULT_SIZE; + + if ( kp && kp->bits > 0 ) bits = kp->bits; + + if ( bits < PKI_DSA_KEY_MIN_SIZE ) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_SIZE_SHORT, NULL); + return NULL; + }; + + if (!RAND_bytes(seed, 20)) { + /* Not enought rand ? */ + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Too low Entropy"); + return NULL; + } + + if ((k = DSA_new()) == NULL) { + // Memory Allocation Error + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Too low Entropy"); + return NULL; + } + + if (1 != DSA_generate_parameters_ex(k, bits, seed, 20, NULL, NULL, NULL)) { + if( k ) DSA_free( k ); + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Can not generated DSA params"); + return NULL; + } + + return( k ); +} + +#ifdef ENABLE_ECDSA +PKI_EC_KEY * _pki_ecdsakey_new( PKI_KEYPARAMS *kp ) { + /* ECDSA is a little more complicated than the other + schemes as it involves a group of functions. As the + purpose of this library is to provide a very hi-level + easy to use library, we will provide some hardwired + parameters. + */ + PKI_EC_KEY *k = NULL; + EC_builtin_curve *curves = NULL; + EC_GROUP *group = NULL; + size_t num_curves = 0; + int degree = 0; + + int bits = PKI_EC_KEY_DEFAULT_SIZE; + int curve = PKI_EC_KEY_CURVE_DEFAULT; + int flags = PKI_EC_KEY_ASN1_DEFAULT; + + PKI_EC_KEY_FORM form = PKI_EC_KEY_FORM_DEFAULT; + + /* Get the number of available ECDSA curves in OpenSSL */ + if ((num_curves = EC_get_builtin_curves(NULL, 0)) < 1 ) { + /* No curves available! */ + PKI_ERROR(PKI_ERR_OBJECT_CREATE, "Builtin EC curves"); + return NULL; + } + + /* Alloc the needed memory */ +#if OPENSSL_VERSION_NUMBER < 0x1010000fL + curves = OPENSSL_malloc((int)(sizeof(EC_builtin_curve) * num_curves)); +#else + curves = OPENSSL_malloc(sizeof(EC_builtin_curve) * num_curves); +#endif + + /* Check for memory allocation */ + if (curves == NULL) return NULL; + + /* Get the builtin curves */ + if (!EC_get_builtin_curves(curves, (size_t) num_curves)) + { + PKI_ERROR(PKI_ERR_OBJECT_CREATE, "Can not get builtin EC curves (%d)", num_curves); + goto err; + return NULL; + } + + /* We completely change behavior - we adopt one of the two + * curves suggested by NIST. In particular: + * - NID_secp384r1 + * - NID_secp521r1 + * For today (2008) usage, the first curve + SHA256 seems to be + * the best approach + */ + + if( kp && kp->bits > 0 ) { + bits = kp->bits; + }; + + if(bits < PKI_EC_KEY_MIN_SIZE ){ + PKI_ERROR(PKI_ERR_X509_KEYPAIR_SIZE_SHORT, "%d", bits); + return NULL; + }; + + if( kp && kp->ec.curve > 0 ) { + curve = kp->ec.curve; + } else { + if( bits <= 112 ) { + bits = 112; + curve = NID_secp112r1; + } else if( bits <= 128 ) { + bits = 128; + curve = NID_secp128r1; + } else if( bits <= 160 ) { + bits = 160; + curve = NID_secp160r1; + } else if( bits <= 192 ) { + bits = 192; + curve = NID_X9_62_prime192v1; + } else if( bits <= 224 ) { + bits = 224; + curve = NID_secp224r1; + } else if( bits <= 256 ) { + bits = 256; + curve = NID_X9_62_prime256v1; + } else if( bits <= 384 ) { + bits = 384; + curve = NID_secp384r1; + } else { + bits = 512; + curve = NID_secp521r1; + }; + }; + + /* Initialize the key */ + if ((k = EC_KEY_new()) == NULL) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, NULL); + goto err; + return NULL; + } + + if((group = EC_GROUP_new_by_curve_name(curve)) == NULL ) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Invalid Curve - %d", curve); + goto err; + return NULL; + }; + + EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); + EC_GROUP_set_point_conversion_form(group, form); + + /* Assign the group to the key */ + if (EC_KEY_set_group(k, group) == 0) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Invalid Group"); + goto err; + return NULL; + } + + /* Sets the point compression */ + if ( kp && kp->ec.form != PKI_EC_KEY_FORM_UNKNOWN ) { + form = kp->ec.form; + }; + EC_KEY_set_conv_form(k, (point_conversion_form_t)form); + + /* Sets the type of parameters, flags > 0 ==> by OID, + * flags == 0 ==> specifiedCurve + */ + if ( kp->ec.asn1flags > -1 ) { + flags = kp->ec.asn1flags; + }; + EC_KEY_set_asn1_flag(k, flags); + + /* We do not need it now, let's free the group */ + if ( group ) EC_GROUP_free( group ); + group = NULL; + + if((group = (EC_GROUP *) EC_KEY_get0_group(k)) != NULL ) { + EC_GROUP_set_asn1_flag( group, OPENSSL_EC_NAMED_CURVE ); + }; + + degree = EC_GROUP_get_degree(EC_KEY_get0_group(k)); + + if( degree < bits ) { + /* Fix the problem, let's get the right bits */ + bits = degree; + } + + // // Let's cycle through all the available curves + // // until we find one that matches (if any) + // i = (i + 1 ) % num_curves; + // + // } while ( (degree < bits ) && (i != n_start) ); + + /* Now generate the key */ + if (!EC_KEY_generate_key(k)) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, NULL ); + goto err; + return NULL; + } + + /* Verify the Key to be ok */ + if (!EC_KEY_check_key(k)) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Verify failed for ECDSA key" ); + goto err; + return NULL; + } + + // EC_KEY_set_enc_flags(k, EC_PKEY_NO_PARAMETERS); + // ecKeyPnt = (struct __ec_key_st2 *) k; + // ecKeyPnt->version = 1; + + goto end; + +err: + if( curves ) free ( curves ); + if ( group ) EC_GROUP_free( group ); + + if( k ) { + EC_KEY_free ( k ); + k = NULL; + }; + +end: + return ( k ); +} + +#else /* EVP_PKEY_EC */ + +void * _pki_ecdsakey_new( PKI_KEYPARAMS *kp ) { + PKI_ERROR(PKI_ERR_NOT_IMPLEMENTED, NULL); + return ( NULL ); +} + +#endif + +#if defined(ENABLE_OQS) || defined(ENABLE_OQSPROV) + +EVP_PKEY_CTX * _pki_get_evp_pkey_ctx(PKI_KEYPARAMS *kp) { + + EVP_PKEY_CTX *ctx = NULL; + // Key generation context to be returned + + // Input Checks + if (!kp) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return NULL; + } + + // Checks we have an algorithm Identifier + if (!kp->oqs.algId) { + PKI_DEBUG("Missing algorithm ID for OQS key generation"); + return NULL; + } + +#ifdef ENABLE_OQS + + const EVP_PKEY_ASN1_METHOD *ameth; + // ASN1 Method + + ENGINE *tmpeng = NULL; + // Temporary Engine + + int pkey_id = -1; + // PKEY ID + + // TODO: + // ===== + // + // This mechanism does not seem to be working for Kyber + // we need to update the mechanism to include Kyber and other + // algorithms. + + if ((ameth = EVP_PKEY_asn1_find(&tmpeng, kp->oqs.algId)) != NULL) { + ERR_clear_error(); + EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth); + + PKI_DEBUG("Ameth = %d, AlgId = %d", pkey_id, kp->oqs.algId); + + } else { + + PKI_log_debug("Missing ASN1 Method for algorithm '%s', using the KeyId (%d).", + PKI_ALGOR_ID_txt(kp->oqs.algId), kp->oqs.algId); + pkey_id = kp->oqs.algId; + + } + + // Generates the new context + if ((ctx = EVP_PKEY_CTX_new_id(pkey_id, NULL)) == NULL) goto err; + +#else + OSSL_LIB_CTX * libctx = PKI_init_get_ossl_library_ctx(); + // OpenSSL Library Context + + // Gets the name of the algorithm + const char * sigalg_name = PKI_ID_get_txt(kp->oqs.algId); + if (!sigalg_name) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Cannot get algorithm name"); + goto err; + } + + // Generates the new context + ctx = EVP_PKEY_CTX_new_from_name(libctx, sigalg_name, NULL); + if (!ctx) { + PKI_DEBUG("Cannot create the pkey context for algorithm '%s'", sigalg_name); + goto err; + } + +#endif + + // Let's set the operation (check EVP_PKEY_CTX_ctrl function -pmeth_lib.c:432) + // Use the EVP interface to initialize the operation (crypto/evp/pmeth_gn.c:69) + if (EVP_PKEY_keygen_init(ctx) <= 0) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Cannot Initialize Key Generation"); + goto err; + } + +#ifdef ENABLE_COMPOSITE + + // CTX operations for Composite Crypto + // + // EVP_PKEY_CTRL_COMPOSITE_PUSH + // EVP_PKEY_CTRL_COMPOSITE_POP + // EVP_PKEY_CTRL_COMPOSITE_ADD + // EVP_PKEY_CTRL_COMPOSITE_DEL + // EVP_PKEY_CTRL_COMPOSITE_CLEAR + +#ifdef ENABLE_COMBINED + if ((kp->scheme == PKI_SCHEME_COMPOSITE || + kp->scheme == PKI_SCHEME_COMBINED) + && kp->comp.k_stack != NULL) { +#else + if (kp->scheme == PKI_SCHEME_COMPOSITE + && kp->comp.k_stack != NULL) { +#endif + for (int i = 0; i < PKI_STACK_X509_KEYPAIR_elements(kp->comp.k_stack); i++) { + + PKI_X509_KEYPAIR * tmp_key = NULL; + + // Let's get the i-th PKI_X509_KEYPAIR + tmp_key = PKI_STACK_X509_KEYPAIR_get_num(kp->comp.k_stack, i); + // Now we can use the CRTL interface to pass the new keys + if (EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_COMPOSITE_PUSH, 0, tmp_key->value) <= 0) { + PKI_log_debug("Cannot add key via the CTRL interface"); + goto err; + } + } + } +#endif + + return ctx; + + err: + + PKI_log_debug("Error initializing context for [scheme: %d, algId: %d]\n", + kp->scheme, kp->oqs.algId); + + if (ctx) EVP_PKEY_CTX_free(ctx); + return NULL; +} + +#endif + +#ifdef ENABLE_COMPOSITE +PKI_COMPOSITE_KEY * _pki_composite_new( PKI_KEYPARAMS *kp ) { + + PKI_COMPOSITE_KEY *k = NULL; + const char * scheme_name = PKI_SCHEME_ID_get_parsed(kp->scheme); + if (!scheme_name) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Unknown Scheme"); + return NULL; + } + + if ((k = COMPOSITE_KEY_new()) == NULL) { + // Memory Allocation Error + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return NULL; + } + + int pkey_type = kp->pkey_type; // PKI_ID_get_by_name(PKI_SCHEME_ID_get_parsed(kp->scheme)); + if (pkey_type <= 0) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Unknown Algorithm"); + COMPOSITE_KEY_free(k); + return NULL; + } + + // Let's set the algorithm + k->algorithm = pkey_type; + + PKI_DEBUG("Creating a Composite Key"); + PKI_DEBUG("Scheme: %d (%s)", kp->scheme, PKI_SCHEME_ID_get_parsed(kp->scheme)); + PKI_DEBUG("Pkey Type: %d (%s)", pkey_type, OBJ_nid2sn(pkey_type)); + + // if (PKI_SCHEME_ID_is_explicit_composite(kp->scheme)) { + // PKI_DEBUG("Explicit Composite Key"); + // k->algorithm = pkey_type; + // } else if (PKI_SCHEME_ID_is_composite(kp->scheme)) { + // PKI_DEBUG("Gemeric Composite Key"); + // k->algorithm = pkey_type; + // } else if (PKI_SCHEME_ID_is_post_quantum(kp->scheme)) { + // PKI_DEBUG("Unknown Composite Key"); + // k->algorithm = kp->oqs.algId; + // } + + if (kp->comp.k_stack != NULL) { + + // // Clears current components (if any) + // if (k->components) COMPOSITE_KEY_clear(k); + + // // Transfers the ownership of the stack to the composite key + // k->components = kp->comp.k_stack; + + // // Let's replace the stack in the keyparams with a new one + // if ((kp->comp.k_stack = PKI_STACK_X509_KEYPAIR_new()) == NULL) { + // PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + // } + + for (int i = 0; i < PKI_STACK_X509_KEYPAIR_elements(kp->comp.k_stack); i++) { + + PKI_X509_KEYPAIR * tmp_key = NULL; + PKI_X509_KEYPAIR_VALUE * tmp_val = NULL; + + // Let's get the i-th PKI_X509_KEYPAIR + tmp_key = PKI_STACK_X509_KEYPAIR_get_num(kp->comp.k_stack, i); + if (!tmp_key) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Cannot get key from stack"); + COMPOSITE_KEY_free(k); + return NULL; + } + + // Let's get the internal value + PKI_X509_detach(tmp_key, (void **)&tmp_val, NULL, NULL); + if (!tmp_val) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Cannot get key value"); + COMPOSITE_KEY_free(k); + return NULL; + } + tmp_key->value = NULL; + + // // Free the memory associated with the PKI_X509_KEYPAIR + // PKI_X509_KEYPAIR_free(tmp_key); + tmp_key = NULL; + + // Pushes the Key onto the stack + // COMPOSITE_KEY_push(k, tmp_key->value); + if (PKI_ERR == COMPOSITE_KEY_push(k, tmp_val)) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Cannot push key onto stack"); + COMPOSITE_KEY_free(k); + return NULL; + } + + // // Now we can use the CRTL interface to pass the new keys + // if (EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_KEYGEN, + // EVP_PKEY_CTRL_COMPOSITE_PUSH, 0, tmp_key->value) <= 0) { + // PKI_log_debug("Cannot add key via the CTRL interface"); + // goto err; + // } + } + } + + // kp->comp.k_stack = NULL; + + // Adds the Parameter (k-of-n) to the key + if (kp->comp.k_of_n != NULL) { + if (k->params) ASN1_INTEGER_free(k->params); + k->params = ASN1_INTEGER_dup(kp->comp.k_of_n); + } + + // All Done. + return k; +} +#endif + +PKI_X509_KEYPAIR *HSM_OPENSSL_X509_KEYPAIR_new(PKI_KEYPARAMS * kp, + URL * url, + PKI_CRED * cred, + HSM * driver ) { + + PKI_X509_KEYPAIR *ret = NULL; + PKI_X509_KEYPAIR_VALUE * value = NULL; + // PKI_RSA_KEY *rsa = NULL; + PKI_DSA_KEY *dsa = NULL; + +#ifdef ENABLE_ECDSA + PKI_EC_KEY *ec = NULL; +#endif + +#if defined(ENABLE_OQS) || defined(ENABLE_OQSPROV) + EVP_PKEY_CTX * ctx = NULL; +#endif + +#ifdef ENABLE_COMPOSITE + COMPOSITE_KEY * composite = NULL; +#endif + +#ifdef ENABLE_COMBINED + EVP_PKEY_COMBINED * combined = NULL; +#endif + + PKI_SCHEME_ID type = PKI_SCHEME_DEFAULT; + + if (!kp) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return NULL; + } + + if ( kp && kp->scheme != PKI_SCHEME_UNKNOWN ) type = kp->scheme; + + // if ((ret = PKI_X509_new(PKI_DATATYPE_X509_KEYPAIR, driver)) == NULL) { + // PKI_ERROR(PKI_ERR_OBJECT_CREATE, "KeyPair"); + // return NULL; + // } + + // if((ret->value = (PKI_X509_KEYPAIR_VALUE *) EVP_PKEY_new()) == NULL ) { + // PKI_ERROR(PKI_ERR_OBJECT_CREATE, "KeyPair Value"); + // return NULL; + // } + + if( _pki_rand_seed() == 0 ) { + /* Probably low level of randomization available */ + PKI_log_debug("WARNING, low rand available!"); + } + + switch (type) { + +#ifdef ENABLE_ED448 + case PKI_SCHEME_ED448: { + int success = _evp_ctx_key_generation(PKI_ALGOR_ID_ED448, &value); + if (!success) { + PKI_DEBUG("Cannot generate the ED448 key"); + goto err; + } + } break; +#endif + +#ifdef ENABLE_X448 + case PKI_SCHEME_X448: { + int success = _evp_ctx_key_generation(PKI_ALGOR_ID_X448, &value); + if (!success) { + PKI_DEBUG("Cannot generate the X448 key"); + goto err; + } + } break; +#endif + +#ifdef ENABLE_ED25519 + case PKI_SCHEME_ED25519: { + int success = _evp_ctx_key_generation(PKI_ALGOR_ID_ED25519, &value); + if (!success) { + PKI_DEBUG("Cannot generate the ED448 key"); + goto err; + } + } break; +#endif + +#ifdef ENABLE_X25519 + case PKI_SCHEME_X25519: { + int success = _evp_ctx_key_generation(PKI_ALGOR_ID_X25519, &value); + if (!success) { + PKI_DEBUG("Cannot generate the ED448 key"); + goto err; + } + } break; +#endif + + case PKI_SCHEME_RSAPSS: + case PKI_SCHEME_RSA: { + // if ((rsa = _pki_rsakey_new( kp )) == NULL ) { + // PKI_DEBUG("Cannot generate the RSA key"); + // goto err; + // } + // if (!EVP_PKEY_assign_RSA((EVP_PKEY *) value, rsa)) { + // PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Can not assign RSA key"); + // if( rsa ) RSA_free( rsa ); + // goto err; + // } + int success = _evp_ctx_key_generation_rsa(kp, &value); + if (!success) { + PKI_DEBUG("Cannot generate the RSA key"); + goto err; + } + } break; + + case PKI_SCHEME_DSA: { + if ((dsa = _pki_dsakey_new( kp )) == NULL ) { + PKI_DEBUG("Cannot generate the DSA key"); + goto err; + } + if (!DSA_generate_key( dsa )) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, NULL); + goto err; + } + if ((value = (PKI_X509_KEYPAIR_VALUE *) EVP_PKEY_new()) == NULL ) { + PKI_ERROR(PKI_ERR_OBJECT_CREATE, "KeyPair Value"); + return NULL; + } + if (!EVP_PKEY_assign_DSA(value, dsa)) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Can not assign DSA key"); + if( dsa ) DSA_free ( dsa ); + goto err; + } + dsa=NULL; + } break; + +#ifdef ENABLE_ECDSA + + case PKI_SCHEME_ECDSA: { + if ((ec = _pki_ecdsakey_new( kp )) == NULL ) { + PKI_DEBUG("Cannot generate the ECDSA key"); + goto err; + } + if ((value = (PKI_X509_KEYPAIR_VALUE *) EVP_PKEY_new()) == NULL ) { + PKI_ERROR(PKI_ERR_OBJECT_CREATE, "KeyPair Value"); + return NULL; + } + if (!EVP_PKEY_assign_EC_KEY(value, ec)){ + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Can not assign ECDSA key"); + if( ec ) EC_KEY_free ( ec ); + goto err; + } + } break; + +#ifdef ENABLE_COMPOSITE + + // Generic Composite + case PKI_SCHEME_COMPOSITE: + // Explicit Composite + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_RSA: + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_P256: + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_BRAINPOOL256: + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_ED25519: + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_P384: + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_BRAINPOOL384: + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_ED448: + case PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_P256: + case PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_BRAINPOOL256: + case PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_ED25519: + case PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_RSA: + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_FALCON1024_P521: + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_FALCON1024_RSA: { + + if ((composite = _pki_composite_new(kp)) == NULL) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Can not initiate keypair generation"); + goto err; + } + if ((value = (PKI_X509_KEYPAIR_VALUE *) EVP_PKEY_new()) == NULL ) { + PKI_ERROR(PKI_ERR_OBJECT_CREATE, "KeyPair Value"); + return NULL; + } + if (!EVP_PKEY_assign_COMPOSITE(value, composite)) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Can not assign COMPOSITE key"); + if (composite) COMPOSITE_KEY_free(composite); + goto err; + } + } break; +#endif + +#ifdef ENABLE_COMBINED + case PKI_SCHEME_COMBINED: + if ((combined = _pki_combined_new(kp)) == NULL) { + if (ret) HSM_OPENSSL_X509_KEYPAIR_free(ret); + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Can not initiate keypair generation"); + return NULL; + }; + if ((value = (PKI_X509_KEYPAIR_VALUE *) EVP_PKEY_new()) == NULL ) { + PKI_ERROR(PKI_ERR_OBJECT_CREATE, "KeyPair Value"); + return NULL; + } + if (!EVP_PKEY_assign_COMBINED(value, combined)) { + if (ret) HSM_OPENSSL_X509_KEYPAIR_free(ret); + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Can not assign COMBINED key"); + if (combined) COMBINED_KEY_free(combined); + return NULL; + } + combined=NULL; + break; +#endif + +#endif // ENABLE_ECDSA + + default: + +#if defined(ENABLE_OQS) || defined(ENABLE_OQSPROV) + if ((ctx = _pki_get_evp_pkey_ctx(kp)) == NULL) { + PKI_DEBUG("Cannot generate the PQC key"); + goto err; + } + if (EVP_PKEY_keygen(ctx, &value) <= 0) { + if (ctx) EVP_PKEY_CTX_free(ctx); + goto err; + } + EVP_PKEY_CTX_free(ctx); + ctx = NULL; + +#else + /* No recognized scheme */ + PKI_ERROR(PKI_ERR_HSM_SCHEME_UNSUPPORTED, "%d", type ); + goto err; + +#endif // ENABLE_OQS || ENABLE_OQSPROV + + } + + // Checks that a Key was generated + if (!value) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Can not generate keypair"); + goto err; + } + + // Allocates the PKI_X509_KEYPAIR structure + if ((ret = PKI_X509_new(PKI_DATATYPE_X509_KEYPAIR, driver)) == NULL) { + PKI_ERROR(PKI_ERR_OBJECT_CREATE, "KeyPair"); + return NULL; + } + + /* Sets the value in the PKI_X509_KEYPAIR structure */ + if (PKI_ERR == PKI_X509_attach(ret, PKI_DATATYPE_X509_KEYPAIR, value, driver)) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Can not attach keypair"); + goto err; + } + + // Sets the requirement for the digest in the key + if (PKI_SCHEME_ID_requires_digest(type)) { + ret->signature_digest_required = 1; + } + + /* Let's return the PKEY infrastructure */ + return ret; + +err: + + // Memory Cleanup + if (value) EVP_PKEY_free(value); + if (ret) PKI_X509_KEYPAIR_free(ret); + +#if defined(ENABLE_OQS) || defined(ENABLE_OQSPROV) + if (ctx) EVP_PKEY_CTX_free(ctx); +#endif // ENABLE_OQS || ENABLE_OQSPROV + + // Error + return NULL; +} + +/* Key Free function */ +void HSM_OPENSSL_X509_KEYPAIR_free ( PKI_X509_KEYPAIR *pkey ) { + + if( !pkey) return; + + PKI_X509_free ( pkey ); + + return; +} + +// OpenSSL Fix +// When writing PEM formatted Keys the wrong version "0" is +// used by the default EVP_PKEY_ write functions for EC keys, +// we have to provide our own function until OpenSSL solve +// this issue + +int OPENSSL_HSM_write_bio_PrivateKey (BIO * bp, + EVP_PKEY * x, + const EVP_CIPHER * enc, + unsigned char * out_buffer, + int klen, + pem_password_cb * cb, + void * u) { + + int ret = PKI_ERR; + // Return value + + // Input Check + if (!x || !bp) return PKI_ERR; + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + // Let's get the scheme of the key + PKI_SCHEME_ID pkey_scheme = PKI_X509_KEYPAIR_VALUE_get_scheme(x); + if (!pkey_scheme) { + PKI_DEBUG("ERROR, can not get the scheme of key (key id: %d)", + PKI_X509_KEYPAIR_VALUE_get_id(x)); + return PKI_ERR; + } + // Let's get the type of the key + int pkey_type = PKI_ID_UNKNOWN; + switch (pkey_scheme) { + +#ifdef ENABLE_ECDSA + + // EC + case PKI_SCHEME_ED25519: { + pkey_type = EVP_PKEY_ED25519; + } break; + + case PKI_SCHEME_X25519: { + pkey_type = EVP_PKEY_X25519; + } break; + + case PKI_SCHEME_ED448: { + pkey_type = EVP_PKEY_ED448; + } break; + + case PKI_SCHEME_X448: { + pkey_type = EVP_PKEY_X448; + } break; + + case PKI_SCHEME_ECDSA: { + pkey_type = EVP_PKEY_EC; + } break; + +#endif // End of ENABLE_ECDSA + + default: { + // Nothing to do here + pkey_type = PKI_X509_KEYPAIR_VALUE_get_id(x); + } break; + } +#else // OpenSSL 1.1.1 + // Let's get the type of key + int pkey_type = EVP_PKEY_type(PKI_X509_KEYPAIR_VALUE_get_id(x)); +#endif // End of OPENSSL_VERSION_NUMBER >= 0x30000000L + + + // Different functions depending on the Key type + switch(pkey_type) + { + +#ifdef ENABLE_ECDSA + case EVP_PKEY_EC: { +# if OPENSSL_VERSION_NUMBER >= 0x30000000L + ret = PEM_write_bio_ECPrivateKey(bp, + EVP_PKEY_get0_EC_KEY(x), enc, (unsigned char *) out_buffer, klen, cb, u); +# elif OPENSSL_VERSION_NUMBER < 0x1010000fL + ret = PEM_write_bio_ECPrivateKey(bp, + x->pkey.ec, enc, (unsigned char *) out_buffer, klen, cb, u); +# else + ret = PEM_write_bio_ECPrivateKey(bp, + EVP_PKEY_get0_EC_KEY(x), enc, (unsigned char *) out_buffer, klen, cb, u); +# endif + if (!ret) { + PKI_DEBUG("Internal Error while encoding EC Key (PEM)."); + return PKI_ERR; + } + } break; +#endif + + default: { + if ((ret = PEM_write_bio_PKCS8PrivateKey(bp, x, enc, + (char *) out_buffer, klen, cb, u)) != 1) { + // Debug Info + PKI_DEBUG("Key Type NOT supported (%d)", pkey_type); + // Error Condition + return PKI_ERR; + } + } + } + + // All Done + return ret; +} + +// OpenSSL Fix +// +// Strangely enough OpenSSL does not provide an EVP_PKEY_dup() +// function, we supply it + +EVP_PKEY *OPENSSL_HSM_KEYPAIR_dup(EVP_PKEY *kVal) +{ + EVP_PKEY *ret = NULL; + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + + ret = EVP_PKEY_dup(kVal); + +#else + + int pkey_type = PKI_X509_KEYPAIR_VALUE_get_id(kVal); + if(!kVal) return NULL; + + if ((ret = EVP_PKEY_new()) == NULL) return NULL; + + if (!EVP_PKEY_copy_parameters(ret, kVal)) return NULL; + + switch (pkey_type) + { + + case EVP_PKEY_RSA: { + RSA *rsa = NULL; +// #if OPENSSL_VERSION_NUMBER >= 0x30000000L +// if (((rsa = EVP_PKEY_get1_RSA(kVal)) == NULL) || +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + if (((rsa = EVP_PKEY_get0_RSA(kVal)) == NULL) || +#else + if (((rsa = (RSA *)EVP_PKEY_get0(kVal)) == NULL) || +#endif + (!EVP_PKEY_set1_RSA(ret, rsa))) { + PKI_DEBUG("ERROR, can not duplicate the RSA key"); + return NULL; + } + } break; + + case EVP_PKEY_DH: { + DH *dh = NULL; +// #if OPENSSL_VERSION_NUMBER >= 0x30000000L +// if ( ((dh = EVP_PKEY_get1_DH(kVal)) == NULL) || +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + if ( ((dh = EVP_PKEY_get0_DH(kVal)) == NULL) || +#else + if ( ((dh = (DH *)EVP_PKEY_get0(kVal)) == NULL) || +#endif + (!EVP_PKEY_set1_DH(ret, dh))) { + PKI_DEBUG("ERROR, can not duplicate the DH key"); + return NULL; + } + } break; + +#ifdef ENABLE_ECDSA + case EVP_PKEY_EC: { + EC_KEY * ec = NULL; +// #if OPENSSL_VERSION_NUMBER >= 0x30000000L +// if (((ec = EVP_PKEY_get1_EC_KEY(kVal)) == NULL) || +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + if (((ec = EVP_PKEY_get0_EC_KEY(kVal)) == NULL) || +#else + if (((ec = (EC_KEY *)EVP_PKEY_get0(kVal)) == NULL) || +#endif + (!EVP_PKEY_set1_EC_KEY(ret, ec))) { + PKI_DEBUG("ERROR, can not duplicate the ECDSA key"); + return NULL; + } + } break; +#endif + +#ifdef ENABLE_DSA + case EVP_PKEY_DSA: { + DSA *dsa = NULL; +// #if OPENSSL_VERSION_NUMBER >= 0x30000000L +// if ( ((dsa = EVP_PKEY_get1_DSA(kVal)) == NULL) || +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + if ( ((dsa = EVP_PKEY_get0_DSA(kVal)) == NULL) || +#else + if ( ((dsa = (DSA *)EVP_PKEY_get0(kVal)) == NULL) || +#endif + (!EVP_PKEY_set1_DSA(ret, dsa))) { + PKI_DEBUG("ERROR, can not duplicate the DSA key"); + return NULL; + } + } break; +#endif + + default: { + PKI_MEM * mem = PKI_X509_KEYPAIR_VALUE_get_p8(kVal); + if (!mem) { + PKI_DEBUG("ERROR, can not serialize the key to PKCS8 format."); + return NULL; + } + + // Free the memory associated with the PKI_X509_KEYPAIR + if (ret) EVP_PKEY_free(ret); + + // Let's create a new PKI_X509_KEYPAIR from the PKCS8 data + ret = PKI_X509_KEYPAIR_VALUE_new_p8(mem); + if (!ret) { + PKI_DEBUG("ERROR, can not deserialize the key from PKCS8 format."); + return NULL; + } + + // Returns the newly allocated key + return ret; + + } break; + } + + // Update the reference for the PKEY + if (!EVP_PKEY_up_ref(kVal)) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Cannot update PKEY references"); + return NULL; + } +#endif + + + // All Done + return ret; +}; + diff --git a/src/crypto/pki_algor.c b/src/crypto/pki_algor.c new file mode 100644 index 00000000..2c7ddcab --- /dev/null +++ b/src/crypto/pki_algor.c @@ -0,0 +1,2228 @@ +/* openssl/pki_algor.c */ + +#include +#include + +#ifdef max +#undef max +#endif + +#ifndef max +#define max(a,b) \ + (((a) > (b)) ? (a) : (b)) +#endif + +/* List of supported digest algorithms grouped by scheme */ +const PKI_ALGOR_ID PKI_ALGOR_ID_LIST_RSA[] = { +// PKI_ALGOR_RSA_MD2, +#ifndef OPENSSL_FIPS + PKI_ALGOR_ID_RSA_MD4, + PKI_ALGOR_ID_RSA_MD5, +#endif + PKI_ALGOR_ID_RSA_SHA1, + PKI_ALGOR_ID_RSA_SHA224, + PKI_ALGOR_ID_RSA_SHA256, + PKI_ALGOR_ID_RSA_SHA384, + PKI_ALGOR_ID_RSA_SHA512, +#ifdef ENABLE_RSA_RIPEMD128 + PKI_ALGOR_ID_RSA_RIPEMD128, +#endif +#ifdef ENABLE_RSA_RIPEMD160 + PKI_ALGOR_ID_RSA_RIPEMD160, +#endif +#ifdef ENABLE_SHA3_256 + PKI_ALGOR_ID_RSA_SHA3_256, +#endif +#ifdef ENABLE_SHA3_384 + PKI_ALGOR_ID_RSA_SHA3_384, +#endif +#ifdef ENABLE_SHA3_512 + PKI_ALGOR_ID_RSA_SHA3_512, +#endif + PKI_ALGOR_ID_UNKNOWN +}; + +const PKI_ALGOR_ID PKI_ALGOR_ID_LIST_DSA[] = { +#ifdef PKI_ALGOR_ID_DSA_SHA1 + PKI_ALGOR_ID_DSA_SHA1, +#endif +#ifdef PKI_ALGOR_ID_DSA_SHA224 + PKI_ALGOR_ID_DSA_SHA224, +#endif +#ifdef PKI_ALGOR_ID_DSA_SHA256 + PKI_ALGOR_ID_DSA_SHA256, +#endif +#ifdef PKI_ALGOR_ID_DSA_SHA384 + PKI_ALGOR_ID_DSA_SHA384, +#endif +#ifdef PKI_ALGOR_ID_DSA_SHA512 + PKI_ALGOR_ID_DSA_SHA512, +#endif + PKI_ALGOR_ID_UNKNOWN +}; + +#ifdef ENABLE_ECDSA +PKI_ALGOR_ID PKI_ALGOR_ID_LIST_ECDSA[] = { +# ifdef PKI_ALGOR_ECDSA_SHA1 + PKI_ALGOR_ID_ECDSA_SHA1, +# endif +# ifdef PKI_ALGORID_ECDSA_SHA224 + PKI_ALGOR_ID_ECDSA_SHA224, +# endif +# ifdef PKI_ALGOR_ID_ECDSA_SHA256 + PKI_ALGOR_ID_ECDSA_SHA256, +# endif +# ifdef PKI_ALGOR_ID_ECDSA_SHA384 + PKI_ALGOR_ID_ECDSA_SHA384, +# endif +# ifdef PKI_ALGOR_ID_ECDSA_SHA512 + PKI_ALGOR_ID_ECDSA_SHA512, +# endif +# ifdef PKI_ALGOR_ID_ECDSA_SHA3_256 + PKI_ALGOR_ID_ECDSA_SHA3_256, +# endif +# ifdef PKI_ALGOR_ID_ECDSA_SHA3_384 + PKI_ALGOR_ID_ECDSA_SHA3_384, +# endif +# ifdef PKI_ALGOR_ID_ECDSA_SHA3_512 + PKI_ALGOR_ID_ECDSA_SHA3_512, +# endif + PKI_ALGOR_ID_UNKNOWN +}; +#else +PKI_ALGOR_ID PKI_ALGOR_ID_LIST_ECDSA[] = { + PKI_ALGOR_ID_UNKNOWN +}; +#endif + +#ifdef ENABLE_OQS + +PKI_ALGOR_ID PKI_ALGOR_ID_LIST_FALCON[] = { + PKI_ALGOR_ID_FALCON512, + PKI_ALGOR_ID_FALCON1024 +}; + +PKI_ALGOR_ID PKI_ALGOR_ID_LIST_DILITHIUM[] = { + PKI_ALGOR_ID_DILITHIUM2, + PKI_ALGOR_ID_DILITHIUM3, + PKI_ALGOR_ID_DILITHIUM5, +}; + +PKI_ALGOR_ID PKI_ALGOR_ID_LIST_SPHINCS[] = { +#ifdef NID_sphincssha2128fsimple + PKI_ALGOR_ID_SPHINCS_SHA2_128_F, +#endif +#ifdef NID_sphincssha2128ssimple + PKI_ALGOR_ID_SPHINCS_SHA2_128_S, +#endif +#ifdef NID_sphincssha2192fsimple + PKI_ALGOR_ID_SPHINCS_SHA2_192_F, +#endif +#ifdef NID_sphincssha2192ssimple + PKI_ALGOR_ID_SPHINCS_SHA2_192_S +#endif +}; + +PKI_ALGOR_ID PKI_ALGOR_ID_LIST_CLASSIC_MCELIECE[] = { + PKI_ALGOR_ID_CLASSIC_MCELIECE1, + PKI_ALGOR_ID_CLASSIC_MCELIECE2, + PKI_ALGOR_ID_CLASSIC_MCELIECE3, + PKI_ALGOR_ID_CLASSIC_MCELIECE4, + PKI_ALGOR_ID_CLASSIC_MCELIECE5 +}; + +PKI_ALGOR_ID PKI_ALGOR_ID_LIST_COMPOSITE_RSA_FALCON[] = { + PKI_ALGOR_ID_COMPOSITE_RSA_FALCON512 +}; + +PKI_ALGOR_ID PKI_ALGOR_ID_LIST_COMPOSITE_ECDSA_FALCON[] = { + PKI_ALGOR_ID_COMPOSITE_ECDSA_FALCON512, + PKI_ALGOR_ID_COMPOSITE_ECDSA_FALCON1024 +}; + +PKI_ALGOR_ID PKI_ALGOR_ID_LIST_COMPOSITE_RSA_DILITHIUM[] = { + PKI_ALGOR_ID_COMPOSITE_RSA_DILITHIUM2, + PKI_ALGOR_ID_COMPOSITE_RSA_DILITHIUM2_AES +}; + +PKI_ALGOR_ID PKI_ALGOR_ID_LIST_COMPOSITE_ECDSA_DILITHIUM[] = { + PKI_ALGOR_ID_COMPOSITE_ECDSA_DILITHIUM2, + PKI_ALGOR_ID_COMPOSITE_ECDSA_DILITHIUM3, + PKI_ALGOR_ID_COMPOSITE_ECDSA_DILITHIUM5, + PKI_ALGOR_ID_COMPOSITE_ECDSA_DILITHIUM2_AES, + PKI_ALGOR_ID_COMPOSITE_ECDSA_DILITHIUM3_AES, + PKI_ALGOR_ID_COMPOSITE_ECDSA_DILITHIUM5_AES +}; + +// PKI_ALGOR_ID PKI_ALGOR_ID_LIST_COMPOSITE[] = { +// PKI_ALGOR_ID_COMPOSITE, +// PKI_ALGOR_ID_COMPOSITE_OR +// }; + +#endif + +/* List of supported digest algorithms */ +PKI_ALGOR_ID PKI_DIGEST_ALG_ID_LIST[] = { +// PKI_ALGOR_MD2, +#ifndef OPENSSL_FIPS + PKI_ALGOR_ID_MD4, + PKI_ALGOR_ID_MD5, + PKI_ALGOR_ID_DSS1, +#endif + PKI_ALGOR_ID_SHA1, + PKI_ALGOR_ID_SHA224, + PKI_ALGOR_ID_SHA256, + PKI_ALGOR_ID_SHA384, + PKI_ALGOR_ID_SHA512, + PKI_ALGOR_ID_RIPEMD128, + PKI_ALGOR_ID_RIPEMD160, + PKI_ALGOR_ID_SHA3_256, + PKI_ALGOR_ID_SHA3_384, + PKI_ALGOR_ID_SHA3_512, + PKI_ALGOR_ID_SHAKE128, + PKI_ALGOR_ID_SHAKE256, + PKI_ALGOR_ID_UNKNOWN +}; + +PKI_X509_ALGOR_VALUE * PKI_X509_ALGOR_VALUE_new () { + + PKI_X509_ALGOR_VALUE *ret = NULL; + // Return value + + // Allocates a new X509_ALGOR + if ((ret = X509_ALGOR_new()) == NULL) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + } + + // Success + return ret; +} + + +void PKI_X509_ALGOR_VALUE_free(PKI_X509_ALGOR_VALUE *a) { + + // Input check + if ( !a ) return; + + // Free the memory + X509_ALGOR_free(a); + + // All Done + return; +} + +PKI_X509_ALGOR_VALUE * PKI_X509_ALGOR_VALUE_new_type ( int type ) { + + PKI_X509_ALGOR_VALUE *ret = NULL; + // Return Value + + // Input checks + if (type <= 0) { + PKI_ERROR(PKI_ERR_PARAM_RANGE, NULL); + return NULL; + } + + if (( ret = X509_ALGOR_new()) == NULL ) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return NULL; + } + + if (!X509_ALGOR_set0(ret, OBJ_nid2obj(type), V_ASN1_UNDEF, NULL)) { + PKI_ERROR(PKI_ERR_ALGOR_GET, NULL); + return NULL; + } + + // All Done + return ret; +} + +PKI_X509_ALGOR_VALUE * PKI_X509_ALGOR_VALUE_new_pkey(const PKI_X509_KEYPAIR_VALUE * pkey, + const PKI_ID digest_id) { + + PKI_X509_ALGOR_VALUE *ret = NULL; + // Return Value + + // Input Checks + if (!pkey) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return NULL; + } + + if (digest_id < 0) { + PKI_ERROR(PKI_ERR_PARAM_RANGE, NULL); + return NULL; + } + + // Checks we have a good digest_id + if (digest_id > 0 && EVP_get_digestbynid(digest_id) == NULL) { + PKI_DEBUG("Cannot get digest by NID (%d)", digest_id); + return NULL; + } + + // Gets the PKEY type + const int pkey_type = PKI_X509_KEYPAIR_VALUE_get_id(pkey); + if (!pkey_type) { + PKI_DEBUG("Cannot get PKEY identifier/type from the PKEY"); + return NULL; + } + + // Looks up the algorithm identifier + int algor_id; + if (!OBJ_find_sigid_by_algs(&algor_id, digest_id, pkey_type)) { + PKI_DEBUG("Cannot find the algorithm identifier for the PKEY (digest: %d, pkey: %d)", + digest_id, pkey_type); + return NULL; + } + + ret = PKI_X509_ALGOR_VALUE_new_type(algor_id); + if (!ret) { + PKI_DEBUG("Cannot create a new X509_ALGOR_VALUE from the algorithm identifier (%d)", algor_id); + return NULL; + } + + // All Done + return ret; +} + +// PKI_X509_ALGOR_VALUE * PKI_X509_ALGOR_VALUE_new_digest ( PKI_DIGEST_ALG *alg ) { + +// PKI_X509_ALGOR_VALUE *ret = NULL; +// // Pointer for returned item + +// PKI_ID id = PKI_ID_UNKNOWN; +// // Identifier for the algorithm + +// // Input checks +// if (!alg) return NULL; + +// // Checks for the MD identifier +// if ((id = EVP_MD_nid(alg)) == NID_undef) return NULL; + +// // Creates a new empty X509_ALGOR +// if ((ret = X509_ALGOR_new()) == NULL) { +// PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); +// return NULL; +// } + +// if (!X509_ALGOR_set0(ret, OBJ_nid2obj(id), V_ASN1_UNDEF, NULL)) { +// PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); +// goto err; +// } + +// // Success +// return ret; + +// err: +// // Freeing allocated memory +// if (ret) X509_ALGOR_free ( ret ); + +// // Error Condition +// return NULL; +// } + + +PKI_X509_ALGOR_VALUE * PKI_X509_ALGOR_VALUE_get_by_name ( const char *alg_s ) { + + char *pnt, *data, *tk; + char buf[1024]; + int i; + + PKI_ALGOR_ID alg_nid = PKI_ALGOR_ID_UNKNOWN; + + /* Check the argument */ + if (!alg_s) return (NULL); + + if ((data = strdup(alg_s)) == NULL) + { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return NULL; + } + + for (i = 0; i < strlen(data); i++) + { + data[i] = (char) toupper(data[i]); + } + + if (( tk = strtok_r ( data, "-", &pnt )) == NULL ) { + // No '-' found in the algoritm, an error! + PKI_Free ( data ); + return NULL; + } + + if( strncmp_nocase(tk, "ECDSA", 5 ) == 0 ) { + snprintf(buf, sizeof(buf), "ecdsa-with"); + } else { + snprintf(buf, sizeof(buf), "%s", tk ); + } + + for ( tk = strtok_r ( NULL, "-", &pnt ); tk; + tk = strtok_r ( NULL, "\r\n", &pnt )) { + + if ( tk == NULL ) break; + snprintf(buf+strlen(buf), sizeof(buf) - strlen(buf) - strlen(tk), + "-%s", tk ); + } + + // Check if the object is a valid OID + if ((alg_nid = OBJ_sn2nid( buf )) <= 0) { + + // Checks the long name database for the OID + if ((alg_nid = OBJ_ln2nid( buf )) <= 0) { + + // The text does not correspond to any known OID strings + // return a NULL pointer + return PKI_ALGOR_NULL; + } + } + + // Returns the pointer to the PKI_X509_ALGOR_VALUE structure + return PKI_X509_ALGOR_VALUE_get(alg_nid); +} + +char * PKI_ALGOR_ID_txt ( PKI_ALGOR_ID algor ) { + ASN1_OBJECT *a = NULL; + + if(( a = OBJ_nid2obj( algor )) == NULL ) { + return("Undefined"); + } + + ASN1_OBJECT_free( a ); + + return( (char *)OBJ_nid2sn( algor )); +} + +const char * PKI_X509_ALGOR_VALUE_get_parsed (const PKI_X509_ALGOR_VALUE * algor ) { + + int id; + + // Input Check + if (!algor || !algor->algorithm) { + // Error: We are Missing the Algorithm + return NULL; + } + + // Gets the NID from the object + if ((id = OBJ_obj2nid(algor->algorithm)) == PKI_ALGOR_ID_UNKNOWN) { + // Returns Nothing + return ( NULL ); + } + + // Returns the Text Representation of the OID for the Algorithm + return OBJ_nid2ln( id ); +} + +int PKI_SCHEME_ID_supports_multiple_components(PKI_SCHEME_ID id) { + + // Input checks + if (id <= 0) return PKI_ERR; + +#ifdef ENABLE_COMPOSITE + if (PKI_SCHEME_ID_is_composite(id) == PKI_OK) return PKI_OK; + if (PKI_SCHEME_ID_is_explicit_composite(id) == PKI_OK) return PKI_OK; +#endif + + // No multiple components supported + return PKI_ERR; +} + +int PKI_SCHEME_ID_is_composite(PKI_SCHEME_ID id) { + + // Input checks + if (id <= 0) return PKI_ERR; + +#ifdef ENABLE_COMPOSITE + // Generic or Explicit + if (id == PKI_SCHEME_COMPOSITE) { + return PKI_OK; + } +#endif + + // Neither + return PKI_ERR; +} + +int PKI_SCHEME_ID_is_explicit_composite(PKI_SCHEME_ID id) { + + // Input Checks + if (id <= 0) return PKI_ERR; + + // Checks for Explicit Composite OIDs + switch(id) { + +#ifdef ENABLE_COMPOSITE +# if defined(ENABLE_OQS) || defined(ENABLE_OQSPROV) + // Post Quantum Cryptography - Composite Crypto + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_RSA: + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_P256: + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_BRAINPOOL256: + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_ED25519: + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_P384: + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_BRAINPOOL384: + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_ED448: + case PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_P256: + case PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_BRAINPOOL256: + case PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_ED25519: + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_RSAPSS: + case PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_RSA: + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_FALCON1024_P521: + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_FALCON1024_RSA: { + // Explicit Composite Combinations, nothing to do + } break; +# endif +#endif + + default: { + // Non-Explicit Composite Scheme detected + return PKI_ERR; + } + } + + // All done + return PKI_OK; +} + +int PKI_SCHEME_ID_is_post_quantum(PKI_SCHEME_ID id) { + + // Input checks + if (id <= 0) return PKI_ERR; + + switch (id) { + +#if defined(ENABLE_OQS) || defined(ENABLE_OQSPROV) + + // Signature + case PKI_SCHEME_DILITHIUM: + case PKI_SCHEME_FALCON: + case PKI_SCHEME_SPHINCS: { + // Nothing to do + } break; + + // KEMs + case PKI_SCHEME_CLASSIC_MCELIECE: + case PKI_SCHEME_KYBER: { + // Nothing to do + } break; + + // Experimental + case PKI_SCHEME_BIKE: + case PKI_SCHEME_DILITHIUMX3: { + // Nothing to do + } break; + +#endif // End of ENABLE_OQS || ENABLE_OQSPROV + + default: + // Non-Post Quantum + return PKI_ERR; + } + + // All Done + return PKI_OK; +} + +int PKI_SCHEME_ID_requires_digest(PKI_SCHEME_ID id) { + + // Input checks + if (id <= 0) return PKI_ERR; + + // Composite, Combined, and Post-Quantum + if (!PKI_SCHEME_ID_is_post_quantum(id) && + !PKI_SCHEME_ID_supports_multiple_components(id)) { + + // Classical Territory + switch (id) { + + case PKI_SCHEME_RSAPSS: + case PKI_SCHEME_ED25519: + case PKI_SCHEME_ED448: { + // No digest required + } break; + + default: + // Digest is required for all remaining + // classical algorithm + return PKI_OK; + } + } + + // No Digest Required + return PKI_ERR; +} + +const char * PKI_SCHEME_ID_get_parsed ( PKI_SCHEME_ID id ) { + + const char *ret; + + switch ( id ) { + + // ======================== + // Classic or Modern Crypto + // ======================== + + case PKI_SCHEME_RSA: { + ret = "RSA"; + } break; + + case PKI_SCHEME_RSAPSS: { + ret = "RSA-PSS"; + } break; + +#ifdef ENABLE_ECDSA + case PKI_SCHEME_ECDSA: { + ret = "ECDSA"; + } break; +#endif + case PKI_SCHEME_ED25519: { + ret = "ED25519"; + } break; + + case PKI_SCHEME_X25519: { + ret = "X25519"; + } break; + + case PKI_SCHEME_ED448: { + ret = "ED448"; + } break; + + case PKI_SCHEME_X448: { + ret = "X448"; + } break; + + case PKI_SCHEME_DSA: { + ret = "DSA"; + } break; + + // =================== + // Post-Quantum Crypto + // =================== + +#if defined(ENABLE_OQS) || defined (ENABLE_OQSPROV) + + case PKI_SCHEME_FALCON: { + ret = "FALCON"; + } break; + + case PKI_SCHEME_DILITHIUM: { + ret = "DILITHIUM"; + } break; + + case PKI_SCHEME_SPHINCS: { + ret = "SPHINCS"; + } break; + + case PKI_SCHEME_CLASSIC_MCELIECE: { + ret = "MCELIECE"; + } break; + + // ========================= + // Post-Quantum Experimental + // ========================= + + case PKI_SCHEME_DILITHIUMX3: { + ret = "DILITHIUMX3"; + } break; + +#endif // End of ENABLE_OQS || ENABLE_OQSPROV + +#ifdef ENABLE_COMPOSITE + + // ===================== + // Composite (PQ) Crypto + // ===================== + + case PKI_SCHEME_COMPOSITE: { + ret = OPENCA_ALG_PKEY_EXP_COMP_NAME; + } break; + +# if defined(ENABLE_OQS) || defined(ENABLE_OQSPROV) + + // ========================= + // Composite: Generic and PQ + // ========================= + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_RSA: { + ret = OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_RSA_SHA256_NAME; + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_P256: { + ret = OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_P256_SHA256_NAME; + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_BRAINPOOL256: { + ret = OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_BRAINPOOL256_SHA256_NAME; + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_ED25519: { + ret = OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_ED25519_NAME; + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_P384: { + ret = OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_P384_SHA384_NAME; + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_BRAINPOOL384: { + ret = OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_BRAINPOOL384_SHA384_NAME; + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_ED448: { + ret = OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_ED448_NAME; + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_P256: { + ret = OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_FALCON512_P256_SHA256_NAME; + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_BRAINPOOL256: { + ret = OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_FALCON512_BRAINPOOL256_SHA256_NAME; + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_ED25519: { + ret = OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_FALCON512_ED25519_NAME; + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_RSAPSS: { + ret = OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_RSAPSS_SHA256_NAME; + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_RSA: { + ret = OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_FALCON512_RSA_SHA256_NAME; + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_FALCON1024_P521: { + ret = OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_FALCON1024_P521_SHA512_NAME; + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_FALCON1024_RSA: { + ret = OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_FALCON1024_RSA_SHA256_NAME; + } break; + +# endif + +# ifdef ENABLE_COMBINED + case PKI_SCHEME_COMPOSITE_OR: { + ret = "MULTIKEY"; + } break; +# endif + +#endif + + default: { + ret = "Unknown"; + } break; + }; + + return ret; +} + +int PKI_SCHEME_ID_get_bitsize(const PKI_SCHEME_ID scheme_id, const int sec_bits) { + + int ret = 0; + int scheme_sec_bits = 0; + // Return value + + // Input checks + if (scheme_id <= 0) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return -1; + } + + // Let's get the default security bits for + // the scheme. If we get a positive value, + // the scheme only support that size and we + // return that. + // + // Otherwise we will return the/ bits value + // from the combination of the input + // (scheme/sec_bits) + if (PKI_ERR == PKI_SCHEME_ID_security_bits(scheme_id, &scheme_sec_bits, NULL)) { + PKI_DEBUG("Can not get security bits for scheme %d", scheme_id); + return -1; + } + + // If the returned value is positive, it means the + // scheme only supports a single value for the size, + // we return that value. + if (scheme_sec_bits > 0) { + return scheme_sec_bits; + } + + // If the scheme supports more than one value (i.e., -1), + // it means that we need to look in the switch below. + switch (scheme_id) { + + case PKI_SCHEME_DSA: { + if (sec_bits < 112) { ret = 1024; } + else if (sec_bits < 128) { ret = 2048; } + else if (sec_bits == 128) { ret = 3072; } + else { + PKI_DEBUG("Security Bits value not supported (%d)", sec_bits); + return -1; + } + } break; + + case PKI_SCHEME_RSA: { + // Sec sec_bits Sizes + if (sec_bits < 50 ) { ret = 32; } + else if (sec_bits < 80 ) { ret = 512; } + else if (sec_bits < 96 ) { ret = 1024; } + else if (sec_bits < 112 ) { ret = 1536; } + // Acceptable bit sizes + else if (sec_bits < 128 ) { ret = 2048; } + else if (sec_bits < 140 ) { ret = 3072; } + else if (sec_bits < 192 ) { ret = 4096; } + // Over the top bit sizes + else if (sec_bits < 256 ) { ret = 7680; } + else if (sec_bits == 256 ) { ret = 15360; } + else { + PKI_DEBUG("Security Bits value not supported (%d)", sec_bits); + return -1; + } + } break; + + case PKI_SCHEME_ECDSA: { + if (sec_bits < 128) { ret = 224; } + else if (sec_bits < 192) { ret = 256; } + else if (sec_bits < 256) { ret = 384; } + else if (sec_bits == 256) { ret = 521; } + else { + PKI_DEBUG("Security Bits value not supported (%d)", sec_bits); + return -1; + } + } break; + + case PKI_SCHEME_ED448: + case PKI_SCHEME_X448: { + if (sec_bits <= 224) { ret = 448; } + else { + PKI_DEBUG("Security Bits value not supported (%d)", sec_bits); + return -1; + } + } + + case PKI_SCHEME_ED25519: + case PKI_SCHEME_X25519: { + if (sec_bits <= 128) { ret = 255; } + else { + PKI_DEBUG("Security Bits value not supported (%d)", sec_bits); + return -1; + } + } + +#ifdef ENABLE_COMPOSITE + + // ============================= + // Native Composite Cryptography + // ============================= + + case PKI_SCHEME_COMPOSITE: { + // No need to translate, same sec bits for + // the generation of all components, if they + // support it. + ret = -1; + } break; +#endif + +#ifdef ENABLE_COMBINED + case PKI_SCHEME_COMBINED: { + // No need to translate, output the input + ret = sec_bits; + } break; +#endif + +#if defined(ENABLE_OQS) || defined(ENABLE_OQSPROV) + + // ============================================= + // Post Quantum Cryptography: Digital Signatures + // ============================================= + + case PKI_SCHEME_FALCON: { + if (sec_bits <= 128) { ret = 897; } + else if (sec_bits <= 256) { ret = 1793; } + else { + PKI_DEBUG("Security Bits value not supported (%d)", sec_bits); + return -1; + } + } break; + + case PKI_SCHEME_DILITHIUM: { + if (sec_bits <= 128) { ret = 1312; } + else if (sec_bits <= 192) { ret = 1953; } + else if (sec_bits <= 256) { ret = 2593; } + else { + PKI_DEBUG("Security Bits value not supported (%d)", sec_bits); + return -1; + } + } break; + + // TODO: We need to change from the robust to the + // fast implementations as the robust is not + // going to be standardized + case PKI_SCHEME_SPHINCS: { + if (sec_bits <= 128) { ret = 32; } + else if (sec_bits <= 192) { ret = 32; } + else if (sec_bits <= 256) { ret = 32; } + else { + PKI_DEBUG("Security Bits value not supported (%d)", sec_bits); + return -1; + } + } break; + + case PKI_SCHEME_KYBER: { + if (sec_bits <= 128) { ret = 800; } + else if (sec_bits <= 192) { ret = 1184; } + else if (sec_bits <= 256) { ret = 1568; } + else { + PKI_DEBUG("Security Bits value not supported (%d)", sec_bits); + return -1; + } + } break; + +#ifdef ENABLE_COMPOSITE + + // =============================== + // Explicit Composite Combinations + // =============================== + + // Explicit Composite Crypto Schemes + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_RSA: { + // kp->oqs.algId = OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_RSA_SHA256_NAME); + ret = (1953 + 400) * 8; + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_RSAPSS: { + // kp->oqs.algId = OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_RSAPSS_SHA256_NAME); + ret = (1953 + 400); + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_P256: { + // kp->oqs.algId = OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_P256_SHA256_NAME); + ret = (1953 + 32) * 8; + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_BRAINPOOL256: { + // kp->oqs.algId = OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_BRAINPOOL256_SHA256_NAME); + ret = (1953 + 32) * 8; + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_ED25519: { + // kp->oqs.algId = OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_ED25519_NAME); + ret = (1953 + 32) * 8; + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_P384: { + // kp->oqs.algId = OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_P384_SHA384_NAME); + ret = (2593 + 48) * 8; + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_BRAINPOOL384: { + // kp->oqs.algId = OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_BRAINPOOL384_SHA384_NAME); + ret = (2593 + 48) * 8; + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_ED448: { + // kp->oqs.algId = OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_ED448_NAME); + ret = (2593 + 57) * 8; + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_P256: { + // kp->oqs.algId = OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_FALCON512_P256_SHA256_NAME); + ret = (897 + 32) * 8; + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_BRAINPOOL256: { + // kp->oqs.algId = OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_FALCON512_BRAINPOOL256_SHA256_NAME); + ret = (897 + 32) * 8; + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_ED25519: { + // kp->oqs.algId = OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_FALCON512_ED25519_NAME); + ret = (897 + 32) * 8; + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_RSA: { + // kp->oqs.algId = OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_FALCON512_RSA_SHA256_NAME); + ret = (897 + 32) * 8; + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_FALCON1024_P521: { + // kp->oqs.algId = OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_FALCON1024_P521_SHA512_NAME); + ret = (2593 + 64) * 8; + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_FALCON1024_RSA: { + // kp->oqs.algId = OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_FALCON1024_RSA_SHA256_NAME); + ret = (2593 + 64 + 400) * 8; + } break; + +#endif // End of ENABLE_COMPOSITE +#endif // End of ENABLE_OQS || ENABLE_OQSPROV + + default: { + // Sets the sec_bits + PKI_ERROR(PKI_ERR_ALGOR_UNKNOWN, "Scheme not supported (%d)", scheme_id); + return PKI_ERR; + } + } + + // All Done + return ret; +} + +int PKI_SCHEME_ID_security_bits(const PKI_SCHEME_ID scheme_id, + int * classic_sec_bits, + int * quantum_sec_bits) { + + // Input Checks + if (scheme_id <= 0) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return PKI_SCHEME_UNKNOWN; + } + + // if (classic_sec_bits) *classic_sec_bits = 0; + // if (quantum_sec_bits) *quantum_sec_bits = 0; + + // PKI_DEBUG("Getting Security Bits for Scheme %d", scheme_id); + + switch (scheme_id) { + + // Classic/Modern Cryptography + case PKI_SCHEME_UNKNOWN: { + if (classic_sec_bits) *classic_sec_bits = -1; + if (quantum_sec_bits) *quantum_sec_bits = -1; + } break; + + case PKI_SCHEME_RSA: { + if (classic_sec_bits) *classic_sec_bits = -1; + if (quantum_sec_bits) *quantum_sec_bits = -1; + } break; + + case PKI_SCHEME_RSAPSS: { + if (classic_sec_bits) *classic_sec_bits = -1; + if (quantum_sec_bits) *quantum_sec_bits = -1; + } break; + + case PKI_SCHEME_DSA: { + if (classic_sec_bits) *classic_sec_bits = -1; + if (quantum_sec_bits) *quantum_sec_bits = -1; + } break; + +#ifdef ENABLE_ECDSA + // ECDSA signature scheme + case PKI_SCHEME_ECDSA: { + if (classic_sec_bits) *classic_sec_bits = -1; + if (quantum_sec_bits) *quantum_sec_bits = -1; + } break; + +#endif + + // ED signature schemes + case PKI_SCHEME_ED448: { + if (classic_sec_bits) *classic_sec_bits = 224; + if (quantum_sec_bits) *quantum_sec_bits = 0; + } break; + + case PKI_SCHEME_ED25519: { + if (classic_sec_bits) *classic_sec_bits = 128; + if (quantum_sec_bits) *quantum_sec_bits = 0; + } break; + + // Key-Exchange based on Diffie-Hellman + case PKI_SCHEME_DH: { + if (classic_sec_bits) *classic_sec_bits = -1; + if (quantum_sec_bits) *quantum_sec_bits = -1; + } break; + + // Key-Exchange based on ED + case PKI_SCHEME_X448: { + if (classic_sec_bits) *classic_sec_bits = 224; + if (quantum_sec_bits) *quantum_sec_bits = 0; + } break; + + case PKI_SCHEME_X25519: { + if (classic_sec_bits) *classic_sec_bits = 128; + if (quantum_sec_bits) *quantum_sec_bits = 0; + } break; + +#if defined(ENABLE_OQS) || defined(ENABLE_OQSPROV) + + // Post Quantum Cryptography - KEMS + + case PKI_SCHEME_BIKE: { + if (classic_sec_bits) *classic_sec_bits = -1; + if (quantum_sec_bits) *quantum_sec_bits = -1; + } break; + + case PKI_SCHEME_FRODOKEM: { + if (classic_sec_bits) *classic_sec_bits = -1; + if (quantum_sec_bits) *quantum_sec_bits = -1; + } break; + + case PKI_SCHEME_CLASSIC_MCELIECE: { + if (classic_sec_bits) *classic_sec_bits = -1; + if (quantum_sec_bits) *quantum_sec_bits = -1; + } break; + + case PKI_SCHEME_KYBER: { + if (classic_sec_bits) *classic_sec_bits = -1; + if (quantum_sec_bits) *quantum_sec_bits = -1; + } break; + + // Post Quantum Cryptography - Digital Signatures + + case PKI_SCHEME_FALCON: { + if (classic_sec_bits) *classic_sec_bits = -1; + if (quantum_sec_bits) *quantum_sec_bits = -1; + } break; + + case PKI_SCHEME_SPHINCS: { + if (classic_sec_bits) *classic_sec_bits = -1; + if (quantum_sec_bits) *quantum_sec_bits = -1; + } break; + + case PKI_SCHEME_DILITHIUM: { + if (classic_sec_bits) *classic_sec_bits = -1; + if (quantum_sec_bits) *quantum_sec_bits = -1; + } break; + + // Experimental Only - To Be Removed (DilithiumX) + case PKI_SCHEME_DILITHIUMX3: { + if (classic_sec_bits) *classic_sec_bits = 192; + if (quantum_sec_bits) *quantum_sec_bits = 192; + } break; + +#endif // End of ENABLE_OQS || ENABLE_OQSPROV + +#ifdef ENABLE_COMPOSITE + // Composite Crypto Schemes + case PKI_SCHEME_COMPOSITE: { + if (classic_sec_bits) *classic_sec_bits = -1; + if (quantum_sec_bits) *quantum_sec_bits = -1; + } break; + +#if defined(ENABLE_OQS) || defined(ENABLE_OQSPROV) + + // Explicit Composite Crypto Schemes + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_RSA: { + if (classic_sec_bits) *classic_sec_bits = max(192, 128); + if (quantum_sec_bits) *quantum_sec_bits = max(192, 0); + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_P256: { + if (classic_sec_bits) *classic_sec_bits = max(192, 128); + if (quantum_sec_bits) *quantum_sec_bits = max(192, 0); + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_BRAINPOOL256: { + if (classic_sec_bits) *classic_sec_bits = max(192, 256); + if (quantum_sec_bits) *quantum_sec_bits = max(192, 0); + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_ED25519: { + if (classic_sec_bits) *classic_sec_bits = max(192, 128); + if (quantum_sec_bits) *quantum_sec_bits = max(192, 0); + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_P384: { + if (classic_sec_bits) *classic_sec_bits = max(256, 384); + if (quantum_sec_bits) *quantum_sec_bits = max(256, 0); + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_BRAINPOOL384: { + if (classic_sec_bits) *classic_sec_bits = max(256, 384); + if (quantum_sec_bits) *quantum_sec_bits = max(256, 0); + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_ED448: { + if (classic_sec_bits) *classic_sec_bits = max(256, 224); + if (quantum_sec_bits) *quantum_sec_bits = max(256, 0); + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_P256: { + if (classic_sec_bits) *classic_sec_bits = max(256, 256); + if (quantum_sec_bits) *quantum_sec_bits = max(256, 0); + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_BRAINPOOL256: { + if (classic_sec_bits) *classic_sec_bits = max(256, 256); + if (quantum_sec_bits) *quantum_sec_bits = max(256, 0); + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_ED25519: { + if (classic_sec_bits) *classic_sec_bits = max(256, 128); + if (quantum_sec_bits) *quantum_sec_bits = max(256, 0); + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_RSAPSS: { + if (classic_sec_bits) *classic_sec_bits = max(192, 128); + if (quantum_sec_bits) *quantum_sec_bits = max(192, 0); + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_RSA: { + if (classic_sec_bits) *classic_sec_bits = max(128, 128); + if (quantum_sec_bits) *quantum_sec_bits = max(128, 0); + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_FALCON1024_P521: { + if (classic_sec_bits) *classic_sec_bits = max(max(256, 256), max(256, 521)); + if (quantum_sec_bits) *quantum_sec_bits = max(max(256, 256), max(256, 0)); + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_FALCON1024_RSA: { + if (classic_sec_bits) *classic_sec_bits = max(max(256, 256), max(256, 128)); + if (quantum_sec_bits) *quantum_sec_bits = max(max(256, 256), max(256, 0)); + } break; + +#endif // End of ENABLE_OQS || ENABLE_OQSPROV +#endif // End of ENABLE_COMPOSITE + +#ifdef ENABLE_COMBINED + // Combined Crypto Schemes + case PKI_SCHEME_COMBINED: { + if (classic_sec_bits) *classic_sec_bits = -1; + if (quantum_sec_bits) *quantum_sec_bits = -1; + } break; + +#endif + + default: + PKI_DEBUG("ERROR, unknown scheme (%d)", scheme_id); + return PKI_ERR; + } + + // All Done + return PKI_OK; +} + +PKI_SCHEME_ID PKI_SCHEME_ID_get_by_name(const char * data, int *classic_sec_bits, int *quantum_sec_bits) { + + PKI_SCHEME_ID ret = PKI_SCHEME_UNKNOWN; + // Return value + + int default_sec_bits = 1; + // If set to 1, the function will return the default + // security bits for the given scheme + + // Input Checks + if (!data) { + if (classic_sec_bits) *classic_sec_bits = 0; + if (quantum_sec_bits) *quantum_sec_bits = 0; + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return PKI_SCHEME_UNKNOWN; + } + +#ifdef ENABLE_COMPOSITE + + // Generic Composite + if (ret == PKI_SCHEME_UNKNOWN) { + if (str_cmp_ex(data, "COMPOSITE", 0, 1) == 0) { + ret = PKI_SCHEME_COMPOSITE; + } + } + +#if defined(ENABLE_OQS) || defined (ENABLE_OQSPROV) + + // Explicit Composite + if (ret == PKI_SCHEME_UNKNOWN) { + // Explicit Composite - DILITHIUM3-P256 + if (str_cmp_ex(data, OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_P256_SHA256_OID, 0, 1) == 0 || + str_cmp_ex(data, OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_P256_SHA256_NAME, 0, 1) == 0 || + str_cmp_ex(data, "DILITHIUM3-ECDSA", 0, 1) == 0 || + str_cmp_ex(data, "DILITHIUM3-EC", 0, 1) == 0 || + str_cmp_ex(data, "DILITHIUM3-P256", 0, 1) == 0 || + str_cmp_ex(data, "D3-P256", 0, 1) == 0 || + str_cmp_ex(data, "DILITHIUM-P256", 0, 1) == 0) { + ret = PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_P256; + // Explicit Composite - DILITHIUM3-RSA + } else if (str_cmp_ex(data, OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_RSA_SHA256_OID, 0, 1) == 0 || + str_cmp_ex(data, OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_RSA_SHA256_NAME, 0, 1) == 0 || + str_cmp_ex(data, "DILITHIUM-RSA", 0, 1) == 0 || + str_cmp_ex(data, "D3-RSA", 0, 1) == 0 || + str_cmp_ex(data, "DILITHIUM3-RSA", 0, 1) == 0) { + ret = PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_RSA; + // Explicit Composite - DILITHIUM3-BRAINPOOL256 + } else if (str_cmp_ex(data, OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_BRAINPOOL256_SHA256_OID, 0, 1) == 0 || + str_cmp_ex(data, OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_BRAINPOOL256_SHA256_NAME, 0, 1) == 0 || + str_cmp_ex(data, "DILITHIUM-BRAINPOOL", 0, 1) == 0 || + str_cmp_ex(data, "DILITHIUM3-BRAINPOOL", 0, 1) == 0 || + str_cmp_ex(data, "D3-B256", 0, 1) == 0 || + str_cmp_ex(data, "DILITHIUM3-B256", 0, 1) == 0) { + ret = PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_BRAINPOOL256; + } else if (str_cmp_ex(data, OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_ED25519_OID, 0, 1) == 0 || + str_cmp_ex(data, OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_ED25519_NAME, 0, 1) == 0 || + str_cmp_ex(data, "DILITHIUM-ED25519", 0, 1) == 0 || + str_cmp_ex(data, "DILITHIUM-25519", 0, 1) == 0 || + str_cmp_ex(data, "DILITHIUM3-ED25519", 0, 1) == 0 || + str_cmp_ex(data, "DILITHIUM3-25519", 0, 1) == 0 || + str_cmp_ex(data, "D3-ED25519", 0, 1) == 0 || + str_cmp_ex(data, "D3-25519", 0, 1) == 0 || + str_cmp_ex(data, "DILITHIUM3-25519", 0, 1) == 0) { + ret = PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_ED25519; + } else if (str_cmp_ex(data, OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_P384_SHA384_OID, 0, 1) == 0 || + str_cmp_ex(data, OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_P384_SHA384_NAME, 0, 1) == 0 || + str_cmp_ex(data, "DILITHIUM5-ECDSA", 0, 1) == 0 || + str_cmp_ex(data, "DILITHIUM5-EC", 0, 1) == 0 || + str_cmp_ex(data, "DILITHIUM-P384", 0, 1) == 0 || + str_cmp_ex(data, "D5-P384", 0, 1) == 0 || + str_cmp_ex(data, "D5-ECDSA", 0, 1) == 0 || + str_cmp_ex(data, "DILITHIUM5-P384", 0, 1) == 0) { + ret = PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_P384; + } else if (str_cmp_ex(data, OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_BRAINPOOL384_SHA384_OID, 0, 1) == 0 || + str_cmp_ex(data, OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_BRAINPOOL384_SHA384_NAME, 0, 1) == 0 || + str_cmp_ex(data, "DILITHIUM5-BRAINPOOL", 0, 1) == 0 || + str_cmp_ex(data, "D5-B384", 0, 1) == 0 || + str_cmp_ex(data, "DILITHIUM5-B384", 0, 1) == 0) { + ret = PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_BRAINPOOL384; + } else if (str_cmp_ex(data, OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_ED448_OID, 0, 1) == 0 || + str_cmp_ex(data, OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_ED448_NAME, 0, 1) == 0 || + str_cmp_ex(data, "DILITHIUM5-448", 0, 1) == 0 || + str_cmp_ex(data, "DILITHIUM-ED448", 0, 1) == 0 || + str_cmp_ex(data, "D5-ED448", 0, 1) == 0 || + str_cmp_ex(data, "DILITHIUM-448", 0, 1) == 0) { + ret = PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_ED448; + } else if (str_cmp_ex(data, OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_FALCON512_P256_SHA256_OID, 0, 1) == 0 || + str_cmp_ex(data, OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_FALCON512_P256_SHA256_NAME, 0, 1) == 0 || + str_cmp_ex(data, "FALCON512-P256", 0, 1) == 0 || + str_cmp_ex(data, "FALCON-ECDSA", 0, 1) == 0 || + str_cmp_ex(data, "F512-ECDSA", 0, 1) == 0 || + str_cmp_ex(data, "F512-P256", 0, 1) == 0 || + str_cmp_ex(data, "FALCON-P256", 0, 1) == 0) { + ret = PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_P256; + } else if (str_cmp_ex(data, OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_FALCON512_BRAINPOOL256_SHA256_OID, 0, 1) == 0 || + str_cmp_ex(data, OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_FALCON512_BRAINPOOL256_SHA256_NAME, 0, 1) == 0 || + str_cmp_ex(data, "FALCON512-BRAINPOOL", 0, 1) == 0 || + str_cmp_ex(data, "FALCON-BRAINPOOL256", 0, 1) == 0 || + str_cmp_ex(data, "F512-B256", 0, 1) == 0 || + str_cmp_ex(data, "FALCON-BRAINPOOL", 0, 1) == 0) { + ret = PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_BRAINPOOL256; + } else if (str_cmp_ex(data, OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_FALCON512_ED25519_OID, 0, 1) == 0 || + str_cmp_ex(data, OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_FALCON512_ED25519_NAME, 0, 1) == 0 || + str_cmp_ex(data, "FALCON512-25519", 0, 1) == 0 || + str_cmp_ex(data, "FALCON-ED25519", 0, 1) == 0 || + str_cmp_ex(data, "F512-ED25519", 0, 1) == 0 || + str_cmp_ex(data, "FALCON-25519", 0, 1) == 0) { + return PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_ED25519; + // } else if (str_cmp_ex(data, OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_SPHINCS256_P256_SHA256_OID, 0, 1) == 0 || + // str_cmp_ex(data, OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_SPHINCS256_P256_SHA256_NAME, 0, 1) == 0 || + // str_cmp_ex(data, "SPHINCS256-ECDSA", 0, 1) == 0 || + // str_cmp_ex(data, "SPHINCS-ECDSA", 0, 1) == 0 || + // str_cmp_ex(data, "SPHINCS-P256", 0, 1) == 0) { + // return PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_ED25519; + } else if (str_cmp_ex(data, OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_RSAPSS_SHA256_OID, 0, 1) == 0 || + str_cmp_ex(data, OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_RSAPSS_SHA256_NAME, 0, 1) == 0 || + str_cmp_ex(data, "DILITHIUM3-RSAPSS", 0, 1) == 0 || + str_cmp_ex(data, "D3-RSAPSS", 0, 1) == 0 || + str_cmp_ex(data, "DILITHIUM-RSAPSS", 0, 1) == 0) { + ret = PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_RSAPSS; + } else if (str_cmp_ex(data, OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_FALCON512_RSA_SHA256_OID, 0, 1) == 0 || + str_cmp_ex(data, OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_FALCON512_RSA_SHA256_NAME, 0, 1) == 0 || + str_cmp_ex(data, "FALCON-RSA", 0, 1) == 0 || + str_cmp_ex(data, "F512-RSA", 0, 1) == 0 || + str_cmp_ex(data, "FALCON512-RSA", 0, 1) == 0) { + ret = PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_RSA; + // Explicit Composite - DILITHIUM5-FALCON1024-ECDSA-P521 + } else if (str_cmp_ex(data, OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_FALCON1024_P521_SHA512_OID, 0, 1) == 0 || + str_cmp_ex(data, OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_FALCON1024_P521_SHA512_NAME, 0, 1) == 0 || + str_cmp_ex(data, "DILITHIUM-FALCON-EC", 0, 1) == 0 || + str_cmp_ex(data, "D5-F1024-P521", 0, 1) == 0 || + str_cmp_ex(data, "DILITHIUM5-FALCON1024-P521", 0, 1) == 0 || + str_cmp_ex(data, "DILITHIUM-FALCON-P521", 0, 1) == 0) { + ret = PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_FALCON1024_P521; + // Explicit Composite - DILITHIUM5-FALCON1024-ECDSA-RSA + } else if (str_cmp_ex(data, OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_FALCON1024_RSA_SHA256_OID, 0, 1) == 0 || + str_cmp_ex(data, OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_FALCON1024_RSA_SHA256_NAME, 0, 1) == 0 || + str_cmp_ex(data, "DILITHIUM-FALCON-RSA", 0, 1) == 0 || + str_cmp_ex(data, "D5-F1024-RSA", 0, 1) == 0 || + str_cmp_ex(data, "DILITHIUM5-FALCON1024-RSA", 0, 1) == 0) { + ret = PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_FALCON1024_RSA; + } + } +#endif // End of ENABLE_OQS + +#endif // End of ENABLE_COMPOSITE + +#if defined(ENABLE_OQS) || defined(ENABLE_OQSPROV) + if (ret == PKI_SCHEME_UNKNOWN) { + if (str_cmp_ex(data, "DILITHIUMX3", 0, 1) == 0) { + ret = PKI_SCHEME_DILITHIUMX3; + } else if (str_cmp_ex(data, "DILITHIUM2", 0, 1) == 0) { + default_sec_bits = 0; + if (classic_sec_bits) *classic_sec_bits = 128; + if (quantum_sec_bits) *quantum_sec_bits = 128; + ret = PKI_SCHEME_DILITHIUM; + } else if (str_cmp_ex(data, "DILITHIUM3", 0, 1) == 0) { + default_sec_bits = 0; + if (classic_sec_bits) *classic_sec_bits = 192; + if (quantum_sec_bits) *quantum_sec_bits = 192; + ret = PKI_SCHEME_DILITHIUM; + } else if (str_cmp_ex(data, "DILITHIUM5", 0, 1) == 0) { + default_sec_bits = 0; + if (classic_sec_bits) *classic_sec_bits = 256; + if (quantum_sec_bits) *quantum_sec_bits = 256; + ret = PKI_SCHEME_DILITHIUM; + } else if (str_cmp_ex(data, "DILITHIUM", 0, 1) == 0) { + ret = PKI_SCHEME_DILITHIUM; + } else if (str_cmp_ex(data, "FALCON512", 0, 1) == 0) { + default_sec_bits = 0; + if (classic_sec_bits) *classic_sec_bits = 128; + if (quantum_sec_bits) *quantum_sec_bits = 128; + ret = PKI_SCHEME_FALCON; + } else if (str_cmp_ex(data, "FALCON1024", 0, 1) == 0) { + default_sec_bits = 0; + if (classic_sec_bits) *classic_sec_bits = 256; + if (quantum_sec_bits) *quantum_sec_bits = 256; + ret = PKI_SCHEME_FALCON; + } else if (str_cmp_ex(data, "FALCON", 0, 1) == 0) { + ret = PKI_SCHEME_FALCON; + } else if (str_cmp_ex(data, "KYBER", 0, 1) == 0) { + ret = PKI_SCHEME_KYBER; + } + } +#endif + + // Checks for Traditional Crypto + // ============================= + + if (ret == PKI_SCHEME_UNKNOWN) { + // RSA Option + if (str_cmp_ex(data, "RSA", 0, 1) == 0) { + ret = PKI_SCHEME_RSA; + // RSA-PSS Option + } else if (str_cmp_ex(data, "RSAPSS", 0, 1) == 0 || + str_cmp_ex(data, "RSA-PSS", 0, 1) == 0) { + ret = PKI_SCHEME_RSAPSS; + +#ifdef ENABLE_ECDSA + // ED 25519 Option + } else if (str_cmp_ex(data, "ED25519", 0, 1) == 0) { + ret = PKI_SCHEME_ED25519; + // X25519 Option + } else if (str_cmp_ex(data, "X25519", 0, 1) == 0) { + ret = PKI_SCHEME_X25519; + // ED 448 Option + } else if (str_cmp_ex(data, "ED448", 0, 1) == 0) { + ret = PKI_SCHEME_ED448; + // X448 Option + } else if (str_cmp_ex(data, "X448", 0, 1) == 0) { + ret = PKI_SCHEME_X448; + // EC Option + } else if (str_cmp_ex(data, "EC", 0, 1) == 0 || + str_cmp_ex(data, "ECDSA", 0, 1) == 0 || + str_cmp_ex(data, "B128", 0, 1) == 0 || + str_cmp_ex(data, "B192", 0, 1) == 0 || + str_cmp_ex(data, "B256", 0, 1) == 0 || + str_cmp_ex(data, "Brainpool", 9, 1) == 0 || + str_cmp_ex(data, "P256", 0, 1) == 0 || + str_cmp_ex(data, "P384", 0, 1) == 0 || + str_cmp_ex(data, "P512", 0, 1) == 0) { + ret = PKI_SCHEME_ECDSA; +#endif // End of ENABLE_ECDSA + + // DSA + } else if (str_cmp_ex(data, "DSA", 0, 1) == 0) { + ret = PKI_SCHEME_DSA; + } + } + + // Checks if we found the scheme + if (ret == PKI_SCHEME_UNKNOWN) { + // Some debugging + PKI_DEBUG("Cannot Convert [%s] into a recognized OID.", data); + } else { + // Checks if we need to retrieve the default security bits + if (default_sec_bits) { + // Returns the security bits for the scheme + if (PKI_ERR == PKI_SCHEME_ID_security_bits(ret, classic_sec_bits, quantum_sec_bits)) { + PKI_DEBUG("Cannot get security bits for scheme %d", ret); + return PKI_SCHEME_UNKNOWN; + } + } + } + + // Returns the scheme + return ret; +} + + +/*! + * \brief Build a PKI_ALGOR structure from its ID + */ + +PKI_X509_ALGOR_VALUE * PKI_X509_ALGOR_VALUE_get(PKI_ALGOR_ID algor) { + + // Input Checks + if (algor <= 0) { + PKI_ERROR(PKI_ERR_PARAM_NULL, "No Algorithm ID provided!"); + return NULL; + } + + // Let's return the PKIX X509 Algorithm Data structure + return PKI_X509_ALGOR_VALUE_new_type(algor); +} + +// /*! +// * \brief Build a PKI_ALGOR structure from its ID +// */ + +// PKI_X509_ALGOR_VALUE * PKI_X509_ALGOR_VALUE_get_ex(PKI_ALGOR_ID pubkey_id, PKI_ALGOR_ID digest_id) { + +// int alg_nid = PKI_ALGOR_ID_UNKNOWN; +// // Algorithm Identifier + +// // Input Checks +// if (pubkey_id <= 0) { +// PKI_ERROR(PKI_ERR_PARAM_NULL, "No Algorithm ID provided!"); +// return NULL; +// } +// if (!EVP_get_digestbynid(digest_id)) { +// PKI_ERROR(PKI_ERR_ALGOR_UNKNOWN, "ERROR, Digest Algorithm ID unknown (%d)", digest_id); +// return NULL; +// } + +// // Gets the combined algorithm ID +// if (!OBJ_find_sigid_by_algs(&alg_nid, digest_id, pubkey_id)) { +// PKI_DEBUG("Cannot find an algorithm for the pubkey (%d) and hash (%d) combination", +// pubkey_id, digest_id); +// return NULL; +// } + +// // Let's return the PKIX X509 Algorithm Data structure +// return PKI_X509_ALGOR_VALUE_new_type(alg_nid); +// } + +/* ! \brief Get a PKI_ALGOR from an PKI_ALGOR object */ + +PKI_ALGOR_ID PKI_X509_ALGOR_VALUE_get_id(const PKI_X509_ALGOR_VALUE *algor ) { + + // Input Checks + if (!algor || !algor->algorithm) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return PKI_ALGOR_ID_UNKNOWN; + } + + // Gets the Algorithm Id + return OBJ_obj2nid(algor->algorithm); +} + +/*! + * \brief Get the Digest Algorithm from the passed PKI_ALGOR + */ +const PKI_DIGEST_ALG *PKI_X509_ALGOR_VALUE_get_digest(const PKI_X509_ALGOR_VALUE *algor) { + + PKI_ALGOR_ID digest_id = PKI_ID_UNKNOWN; + // Digest Identifier + + // Input checks + if (!algor) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return NULL; + } + + // Retrieves the digest id + digest_id = PKI_X509_ALGOR_VALUE_get_digest_id(algor); + + // If nothing was found, let's return nothing + if (digest_id == NID_undef) return EVP_md_null(); + + // All Done + return EVP_get_digestbynid(digest_id); +} + +/*! + * \brief Returns the PKI_ALGOR_ID of the digest used in the PKI_ALGOR + */ +PKI_ALGOR_ID PKI_X509_ALGOR_VALUE_get_digest_id(const PKI_X509_ALGOR_VALUE *algor) { + + int alg_id = -1; + int pkey_id = -1; + int digest_id = -1; + // Algorithm Identifiers + + if ( !algor || !algor->algorithm ) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return PKI_ALGOR_ID_UNKNOWN; + } + + // Retrieves the Algorithm ID + if((alg_id = PKI_X509_ALGOR_VALUE_get_id(algor)) <= 0) { + PKI_ERROR(PKI_ERR_ALGOR_UNKNOWN, NULL); + return PKI_ALGOR_ID_UNKNOWN; + } + + // Gets the MD and PKEY components + if (!OBJ_find_sigid_algs(alg_id, &digest_id, &pkey_id)) { + PKI_DEBUG("Cannot break the signing algorithm (%d) into PKEY and MD (algor: %s).", + alg_id, PKI_X509_ALGOR_VALUE_get_parsed(algor)); + return PKI_ALGOR_ID_UNKNOWN; + } + + // All Done + return digest_id; +} + +/*! \brief Returns the PKI_SCHEME_ID (signature scheme ID) of the algorithm */ +PKI_SCHEME_ID PKI_X509_ALGOR_VALUE_get_scheme (const PKI_X509_ALGOR_VALUE *algor) { + + PKI_ALGOR_ID pkey_id = 0; + PKI_ALGOR_ID digest_id = 0; + // Algorithm Identifiers + + if (!algor) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return PKI_SCHEME_UNKNOWN; + } + + PKI_ALGOR_ID id = PKI_X509_ALGOR_VALUE_get_id(algor); + if (id == PKI_ALGOR_ID_UNKNOWN) { + PKI_DEBUG("Cannot get the algorithm ID from the PKI_ALGOR_VALUE (%s)", + PKI_X509_ALGOR_VALUE_get_parsed(algor)); + return PKI_SCHEME_UNKNOWN; + } + + // Gets the MD and PKEY components + // if (!OBJ_find_sigid_algs(id, &pkey_id, &digest_id)) { + if (!OBJ_find_sigid_algs(id, &digest_id, &pkey_id)) { + PKI_DEBUG("Cannot break the signing algorithm (%d) into PKEY and MD (algor: %s).", + id, PKI_X509_ALGOR_VALUE_get_parsed(algor)); + return PKI_SCHEME_UNKNOWN; + } + +#if OPENSSL_VERSION_NUMBER < 0x30000000L + // Gets the Type of PKEY + int pkey_type = EVP_PKEY_type(pkey_id); +#else + int pkey_type = pkey_id; +#endif // End of OPENSSL_VERSION_NUMBER + + PKI_DEBUG("******** OSSL3 UPGRADE: Check pkey_type (%d) vs. pkey_id (%d) ************", pkey_type, pkey_id); + + // Let's check the PKEY types + switch (pkey_type) { + + // RSA + case EVP_PKEY_RSA_PSS: + case EVP_PKEY_RSA: { + return PKI_SCHEME_RSA; + } break; + + // DH + case EVP_PKEY_DH: { + return PKI_SCHEME_DH; + } break; + + // ED25519 +#ifdef ENABLE_ED25519 + case EVP_PKEY_ED25519: { + return PKI_SCHEME_ED25519; + } break; +#endif + + // ED448 +#ifdef ENABLE_ED448 + case EVP_PKEY_ED448: { + return PKI_SCHEME_ED448; + } break; +#endif + +#ifdef ENABLE_DSA + // DSA + case EVP_PKEY_DSA: { + return PKI_SCHEME_DSA; + } break; +#endif + +#ifdef ENABLE_ECDSA + // EC + case EVP_PKEY_EC: { + return PKI_SCHEME_ECDSA; + } break; +#endif + +#ifdef ENABLE_DSA +#endif + + default: { + +#ifdef ENABLE_COMPOSITE + + // Check Generic Composite + if (PKI_ID_is_composite(pkey_type, NULL)) { + // COMPOSITE + return PKI_SCHEME_COMPOSITE; + } + + // Check Explicit Composite + PKI_SCHEME_ID explicit_scheme; + if (PKI_ID_is_explicit_composite(pkey_type, &explicit_scheme)) { + // Explicit Composite + return explicit_scheme; + } +#endif + +#if defined(ENABLE_OQS) || defined(ENABLE_OQSPROV) + + // Check PQC + PKI_SCHEME_ID pqc_scheme; + if (PKI_ID_is_pqc(pkey_type, &pqc_scheme)) { + // Explicit Composite + return pqc_scheme; + } + + // // Let's see if we can find the scheme via the + // // dynamic approach: + // if ( pkey_type == PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_FALCON512_NAME) + // || pkey_type == PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_FALCON1024_NAME)) { + // // FALCON + // return PKI_SCHEME_FALCON; + // } else if ( pkey_type == PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_DILITHIUM2_NAME) + // || pkey_type == PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_DILITHIUM3_NAME) + // || pkey_type == PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_DILITHIUM5_NAME)) { + // // DILITHIUM + // return PKI_SCHEME_DILITHIUM; + // } else if ( pkey_type == PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_SPHINCS128_F_SIMPLE_NAME) + // || pkey_type == PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_SPHINCS192_F_SIMPLE_NAME)) { + // // SPHINCS+ + // return PKI_SCHEME_SPHINCS; + // } else if ( pkey_type == PKI_ID_get_by_name("kyber512") + // || pkey_type == PKI_ID_get_by_name("kyber768") + // || pkey_type == PKI_ID_get_by_name("kyber1024")) { + // // KYBER + // return PKI_SCHEME_KYBER; + // } else if (pkey_type == PKI_ID_get_by_name("dilithiumX")) { + // // DILITHIUMX + // return PKI_SCHEME_DILITHIUMX3; + // } + +#endif // End of ENABLE_OQS || ENABLE_OQSPROV + } + + } + + // Let's check the pkey type + return PKI_SCHEME_UNKNOWN; + +// switch ( id ) { + +// case PKI_ALGOR_ID_DSA_SHA1: +// #ifdef ENABLE_DSA_SHA_2 +// case PKI_ALGOR_ID_DSA_SHA224: +// case PKI_ALGOR_ID_DSA_SHA256: +// #endif +// ret = PKI_SCHEME_DSA; +// break; +// // case PKI_ALGOR_RSA_MD2: +// case PKI_ALGOR_ID_RSA_MD4: +// case PKI_ALGOR_ID_RSA_MD5: +// case PKI_ALGOR_ID_RSA_SHA1: +// #ifdef ENABLE_SHA224 +// case PKI_ALGOR_ID_RSA_SHA224: +// #endif +// #ifdef ENABLE_SHA256 +// case PKI_ALGOR_ID_RSA_SHA256: +// #endif +// #ifdef ENABLE_SHA384 +// case PKI_ALGOR_ID_RSA_SHA384: +// #endif +// #ifdef ENABLE_SHA512 +// case PKI_ALGOR_ID_RSA_SHA512: +// ret = PKI_SCHEME_RSA; +// break; +// #endif +// #ifdef ENABLE_ECDSA +// case PKI_ALGOR_ID_ECDSA_SHA1: +// #endif +// #ifdef ENABLE_ECDSA_SHA_2 +// case PKI_ALGOR_ID_ECDSA_SHA224: +// case PKI_ALGOR_ID_ECDSA_SHA256: +// case PKI_ALGOR_ID_ECDSA_SHA384: +// case PKI_ALGOR_ID_ECDSA_SHA512: +// ret = PKI_SCHEME_ECDSA; +// break; +// #endif + +// #ifdef ENABLE_OQS + +// // ================== +// // Post-Quantum Algos +// // ================== + +// case PKI_ALGOR_ID_FALCON512: +// case PKI_ALGOR_ID_FALCON1024: +// ret = PKI_SCHEME_FALCON; +// break; + +// case PKI_ALGOR_ID_DILITHIUM3: +// case PKI_ALGOR_ID_DILITHIUM5: +// case PKI_ALGOR_ID_DILITHIUM3_AES: +// case PKI_ALGOR_ID_DILITHIUM5_AES: +// ret = PKI_SCHEME_DILITHIUM; +// break; + +// case PKI_ALGOR_ID_SPHINCS_SHA256_128_R: +// // case PKI_ALGOR_ID_SPHINCS_SHA256_192_R: +// // case PKI_ALGOR_ID_SPHINCS_SHA256_256_R: +// case PKI_ALGOR_ID_SPHINCS_SHAKE256_128_R: +// ret = PKI_SCHEME_SPHINCS; +// break; + +// // ================ +// // Composite Crypto +// // ================ + +// // NOTE: We cannot handle the composite/combined crypto +// // this way because we do not have the static value +// // for it, therefore we need to use a different approach +// // by checking it separately +// // #ifdef ENABLE_COMPOSITE +// // case NID_composite: +// // ret = PKI_SCHEME_COMPOSITE; +// // break; +// // #endif +// // +// // #ifdef ENABLE_COMBINED +// // case PKI_ALGOR_ID_COMPOSITE_OR: +// // ret = PKI_SCHEME_COMPOSITE_OR; +// // break; +// // #endif + +// // ==================== +// // OQS Composite Crypto +// // ==================== + +// case PKI_ALGOR_ID_COMPOSITE_RSA_FALCON512: +// ret = PKI_SCHEME_COMPOSITE_RSA_FALCON; +// break; + +// case PKI_ALGOR_ID_COMPOSITE_ECDSA_FALCON512: +// case PKI_ALGOR_ID_COMPOSITE_ECDSA_FALCON1024: +// ret = PKI_SCHEME_COMPOSITE_ECDSA_FALCON; +// break; + +// case PKI_ALGOR_ID_COMPOSITE_RSA_DILITHIUM2: +// ret = PKI_SCHEME_COMPOSITE_RSA_DILITHIUM; +// break; + +// case PKI_ALGOR_ID_COMPOSITE_ECDSA_DILITHIUM2: +// case PKI_ALGOR_ID_COMPOSITE_ECDSA_DILITHIUM3: +// case PKI_ALGOR_ID_COMPOSITE_ECDSA_DILITHIUM5: +// ret = PKI_SCHEME_COMPOSITE_ECDSA_DILITHIUM; +// break; + +// #endif +// default: +// ret = PKI_SCHEME_UNKNOWN; +// } + +// // Process the dynamic-provided schemes +// if (ret == PKI_SCHEME_UNKNOWN) { +// #ifdef ENABLE_COMPOSITE +// // Composite Crypto +// if (id == PKI_SCHEME_UNKNOWN && id == OBJ_txt2nid("composite")) { +// ret = PKI_SCHEME_COMPOSITE; +// } +// #endif + +// #ifdef ENABLE_COMBINED +// if (id == PKI_SCHEME_UNKNOWN && id == OBJ_txt2nid("combined")) { +// ret = PKI_SCHEME_COMBINED; +// } +// #endif +// } + +// return ( ret ); +} + +/*! \brief Returns the PKI_DIGEST_ALG * from its name. + * + * Returns the PKI_DIGEST_ALG * from its name (char *). An example + * of algorithm identifiers are "sha1", "sha224", "ripemd160". If the + * passed id is equal to 0, the default PKI_DIGEST_ALG is returned. + */ + +const PKI_DIGEST_ALG *PKI_DIGEST_ALG_get_by_name( const char *name ) { + + // Input Check + if (!name) { + /* For ease of use, let's fall back to the default one */ + return PKI_DIGEST_ALG_DEFAULT; + } + + // Returns the digest from the name + return EVP_get_digestbyname(name); +} + +/*! \brief Returns the string representation of a digest algorithm */ + +const char * PKI_DIGEST_ALG_get_parsed (const PKI_DIGEST_ALG * alg ) { + + if ( !alg ) return NULL; + + return EVP_MD_name ( alg ); +} + + +/*! \brief Returns the digest algorithm based on the key */ + +const PKI_DIGEST_ALG * PKI_DIGEST_ALG_get_by_key (const PKI_X509_KEYPAIR *pkey ) { + + EVP_PKEY *pp = NULL; + PKI_DIGEST_ALG * digest = NULL; + + int size = 0; + int p_type = 0; + + /* Let's set the digest for the right signature scheme */ + if( !pkey ) return NULL; + + size = PKI_X509_KEYPAIR_get_size ( pkey ); + if (size <= 0) + { + PKI_ERROR(PKI_ERR_GENERAL, "Key size is 0"); + return NULL; + } + + pp = (EVP_PKEY *) pkey->value; + +// #if OPENSSL_VERSION_NUMBER > 0x30000000L +// int p_id = 0; +// p_id = PKI_X509_KEYPAIR_get_id(pkey); +// p_type = EVP_PKEY_type(p_id); +// // TODO: Fix this trick +// if (p_type <= 0) p_type = p_id; +// #elif OPENSSL_VERSION_NUMBER < 0x1010000fL +// p_type = EVP_PKEY_type(pp->type); +// #else +// p_type = EVP_PKEY_type(EVP_PKEY_id(pp)); +// #endif + + p_type = PKI_X509_KEYPAIR_get_id(pkey); + + // TODO: Remove this debug + PKI_DEBUG("******* OSSL3 UPGRADE: Retrieved p_type (%d) from pkey (%d) ************", p_type, pkey->type); + + // Gets the default digest for the key + int default_nid = -1; + +#if OPENSSL_VERSION_NUMBER > 0x30000000L + char name_buf[50] = { 0x0 }; + int digestResult = EVP_PKEY_get_default_digest_name(pp, name_buf, sizeof(name_buf)); + default_nid = OBJ_txt2nid(name_buf); +#else + int digestResult = EVP_PKEY_get_default_digest_nid(pp, &default_nid); +#endif + + PKI_DEBUG("***** OSSL3 UPGRADE: EVP_PKEY_get_default_digest_nid (%d) seems to fail *****", digestResult); + + // Returns the default digest for the key if it is + // the only one supported + if (digestResult == 2 || default_nid != NID_undef) { + // The returned digest algorithm is required + return (const PKI_DIGEST_ALG *)EVP_get_digestbynid(default_nid); + } + + // if (default_nid != NID_undef) { + // // The returned digest algorithm is required + // return (const PKI_DIGEST_ALG *)EVP_get_digestbynid(default_nid); + // } + + switch (p_type) { + + case EVP_PKEY_RSA: + case EVP_PKEY_RSA_PSS: + digest=PKI_DIGEST_ALG_RSA_DEFAULT; + break; + + case EVP_PKEY_DSA: + digest=PKI_DIGEST_ALG_DSA_DEFAULT; + break; + + case EVP_PKEY_ED25519: + case EVP_PKEY_ED448: + digest=NULL; + break; + +#ifdef ENABLE_ECDSA + case EVP_PKEY_EC: + if ( size <= 160 ) { + digest = PKI_DIGEST_ALG_SHA1; + } else if ( size <= 224 ) { + digest = PKI_DIGEST_ALG_SHA224; + } else if ( size <= 256 ) { + digest = PKI_DIGEST_ALG_SHA256; + } else if ( size <= 384 ) { + digest = PKI_DIGEST_ALG_SHA384; + } else if ( size <= 521 ) { + digest = PKI_DIGEST_ALG_SHA512; + } else { + digest=PKI_DIGEST_ALG_ECDSA_DEFAULT; + }; + break; +#endif + +#ifdef ENABLE_OQS + case PKI_ALGOR_ID_FALCON1024: + case PKI_ALGOR_ID_FALCON512: { + // PQ Algorithms, Not Returning Hash + PKI_DEBUG("FALCON: Key Type [%d]; No Hash Returned", p_type); + digest = PKI_DIGEST_ALG_NULL; + } break; + + case PKI_ALGOR_ID_DILITHIUM5: + case PKI_ALGOR_ID_DILITHIUM3: + case PKI_ALGOR_ID_DILITHIUM2: { + PKI_DEBUG("DILITHIUM: Key Type [%d]; No Hash Returned", p_type); + digest = PKI_DIGEST_ALG_NULL; + } break; + + // case PKI_ALGOR_ID_SPHINCS_SHA256_256_R: + // case PKI_ALGOR_ID_SPHINCS_SHA256_192_R: +#ifdef NID_sphincssha2128fsimple + case PKI_ALGOR_ID_SPHINCS_SHA2_128_F: +#endif +#ifdef NID_sphincssha2128fsimple + case PKI_ALGOR_ID_SPHINCS_SHA2_128_S: +#endif +#ifdef NID_sphincssha2128fsimple + case PKI_ALGOR_ID_SPHINCS_SHA2_192_F: +#endif +#ifdef NID_sphincssha2128fsimple + case PKI_ALGOR_ID_SPHINCS_SHA2_192_S: +#endif + PKI_DEBUG("SPHINCS+: Key Type [%d]; No Hash Returned", p_type); + digest = PKI_DIGEST_ALG_NULL; + break; + +#endif + + default: + +#ifdef ENABLE_OQSPROV + // Dynamically checks for the support + // of different types of keys + if ( PKI_ID_get_by_name("dilithium2") == p_type + || PKI_ID_get_by_name("dilithium3") == p_type + || PKI_ID_get_by_name("dilithium5") == p_type + || PKI_ID_get_by_name("falcon512") == p_type + || PKI_ID_get_by_name("falcon1024") == p_type + || PKI_ID_get_by_name("sphincssha2128fsimple") == p_type + || PKI_ID_get_by_name("sphincssha2128ssimple") == p_type + || PKI_ID_get_by_name("sphincssha2192fsimple") == p_type + || PKI_ID_get_by_name("sphincsshake128fsimple") == p_type) { + // Use the NULL digest for these algorithms + digest = PKI_DIGEST_ALG_NULL; + } else { + // No digest for other types + digest = NULL; + } +#else + // No digest by default + digest = NULL; +#endif + } + + return (const PKI_DIGEST_ALG *)digest; +} + +/*! \brief Returns the PKI_DIGEST_ALG * associated with the alg id. + * + * Returns the PKI_DIGEST_ALG * associated with the alg id. If the + * passed id is equal to 0, the default PKI_DIGEST_ALG is returned. + */ + + +const PKI_DIGEST_ALG *PKI_DIGEST_ALG_get ( PKI_ALGOR_ID id ) { + + PKI_DIGEST_ALG * ret = NULL; + + switch ( id ) { +#ifdef ENABLE_MD4 + case PKI_ALGOR_MD4: + ret = PKI_DIGEST_ALG_MD4; + break; +#endif +#ifdef ENABLE_MD5 + case PKI_ALGOR_MD5: + ret = PKI_DIGEST_ALG_MD5; + break; +#endif +#ifdef ENABLE_SHA1 + case PKI_ALGOR_SHA1: + ret = PKI_DIGEST_ALG_SHA1; + break; +#endif +#ifdef PKI_ALGOR_DSS1 + case PKI_ALGOR_DSS1: + ret = PKI_DIGEST_ALG_DSS1; + break; +#endif +#ifdef ENABLE_SHA224 + case PKI_ALGOR_SHA224: + ret = PKI_DIGEST_ALG_SHA224; + break; +#endif +#ifdef ENABLE_SHA256 + case PKI_ALGOR_SHA256: + ret = PKI_DIGEST_ALG_SHA256; + break; +#endif +#ifdef ENABLE_SHA384 + case PKI_ALGOR_SHA384: + ret = PKI_DIGEST_ALG_SHA384; + break; +#endif +#ifdef ENABLE_SHA512 + case PKI_ALGOR_SHA512: + ret = PKI_DIGEST_ALG_SHA512; + break; +#endif +#ifdef ENABLE_RIPEMD160 + case PKI_ALGOR_RIPEMD160: + ret = PKI_DIGEST_ALG_RIPEMD160; + break; +#endif +#if OPENSSL_VERSION_NUMBER < 0x1000000fL +# ifdef ENABLE_ECDSA + case PKI_ALGOR_ECDSA_DSS1: + ret = PKI_DIGEST_ALG_ECDSA_SHA1; + break; +# endif +#endif + default: + ret = PKI_DIGEST_ALG_UNKNOWN; + } + + return (const PKI_DIGEST_ALG *) ret; +} + +const PKI_DIGEST_ALG * PKI_DIGEST_ALG_get_default(const PKI_X509_KEYPAIR * const x) { + + // Input Check + if (!x || !x->value) { + PKI_ERROR(PKI_ERR_PARAM_NULL, "Missing Key Value"); + return NULL; + } + + // Gets the value + PKI_X509_KEYPAIR_VALUE * pkey = PKI_X509_get_value(x); + + // Gets the default digest for the key + int def_nid = -1; + +#if OPENSSL_VERSION_NUMBER > 0x30000000L + char name_buf[50] = { 0x0 }; + int digestResult = EVP_PKEY_get_default_digest_name(pkey, name_buf, sizeof(name_buf)); + def_nid = OBJ_txt2nid(name_buf); +#else + int digestResult = EVP_PKEY_get_default_digest_nid(pkey, &def_nid); +#endif + PKI_DEBUG("***** OSSL3 UPGRADE: EVP_PKEY_get_default_digest_nid (%d) seems to fail *****", digestResult); + + // Checks for error + if (digestResult <= 0) { + PKI_DEBUG("Cannot get the default digest for signing (pkey type: %d)", PKI_X509_KEYPAIR_VALUE_get_id(pkey)); + return NULL; + +// #if OPENSSL_VERSION_NUMBER > 0x30000000L +// PKI_DEBUG("Returning the default digest (%s)", PKI_ID_get_txt(PKI_DIGEST_ALG_ID_DEFAULT)); +// return PKI_DIGEST_ALG_DEFAULT; +// #else +// // Error condition +// return NULL; +// #endif + + } + + // If the returned value is == 2, then the returned + // digest is mandatory and cannot be replaced + if (digestResult == 2) { + + // If no-hash is mandatory, we return the null MD + if (def_nid == NID_undef) return EVP_md_null(); + + // Let's return the mandatory one + return EVP_get_digestbynid(def_nid); + } + + // If we reach here, the PKEY does not have + // a mandatory hash, let's return our own default + return PKI_DIGEST_ALG_DEFAULT; +} + +const PKI_ALGOR_ID *PKI_ALGOR_ID_list ( PKI_SCHEME_ID scheme ) { + + const PKI_ALGOR_ID * ret; + + switch ( scheme ) { + case PKI_SCHEME_RSA: { + ret = PKI_ALGOR_ID_LIST_RSA; + } break; + + case PKI_SCHEME_DSA: { + ret = PKI_ALGOR_ID_LIST_DSA; + } break; + +#ifdef ENABLE_ECDSA + case PKI_SCHEME_ECDSA: { + ret = PKI_ALGOR_ID_LIST_ECDSA; + } break; +#endif + +#ifdef ENABLE_OQS + case PKI_SCHEME_FALCON: { + ret = PKI_ALGOR_ID_LIST_FALCON; + } break; + + case PKI_SCHEME_DILITHIUM: { + ret = PKI_ALGOR_ID_LIST_DILITHIUM; + } break; + + case PKI_SCHEME_SPHINCS: { + ret = PKI_ALGOR_ID_LIST_SPHINCS; + } break; + + case PKI_SCHEME_CLASSIC_MCELIECE: { + ret = PKI_ALGOR_ID_LIST_CLASSIC_MCELIECE; + } break; + + case PKI_SCHEME_DILITHIUMX3: { + ret = PKI_ALGOR_ID_LIST_DILITHIUM; + } break; + +#else + +#ifdef ENABLE_OQSPROV + case PKI_SCHEME_FALCON: + case PKI_SCHEME_DILITHIUM: + case PKI_SCHEME_SPHINCS: + case PKI_SCHEME_CLASSIC_MCELIECE: + case PKI_SCHEME_DILITHIUMX3: { + PKI_DEBUG("OQS Support not enabled in this build (only OQSPROV)!"); + ret = NULL; + } break; + +#endif + +#endif + default: + PKI_ERROR(PKI_ERR_ALGOR_UNKNOWN, NULL); + ret = NULL; + } + + return ret; +} + +const PKI_ALGOR_ID *PKI_DIGEST_ALG_ID_list( void ) { + + return PKI_DIGEST_ALG_ID_LIST; +} + +size_t PKI_ALGOR_ID_list_size( const PKI_ALGOR_ID * const list ) { + + size_t i = 0; + + if( !list ) return ( 0 ); + + while ( list[i] != PKI_ALGOR_ID_UNKNOWN ) i++; + + return( i ); +} + diff --git a/src/crypto/pki_digest.c b/src/crypto/pki_digest.c new file mode 100644 index 00000000..073684d1 --- /dev/null +++ b/src/crypto/pki_digest.c @@ -0,0 +1,315 @@ +/* openssl/pki_digest.c */ + +#include + +/*! \brief Free the memory associated with a CRYPTO_DIGEST data structure + */ + +void PKI_DIGEST_free ( CRYPTO_DIGEST *data ) +{ + if( !data ) return; + + if (data->digest) PKI_Free(data->digest); + data->digest = NULL; // Safety + data->algor = NULL; // Safety + + PKI_Free( data ); + + return; +} + +int PKI_DIGEST_new_value(unsigned char ** dst_buf, + const PKI_DIGEST_ALG * alg, + const unsigned char * data, + size_t size) { + + EVP_MD_CTX * md_ctx = NULL; + // Crypto Context for Digest Calculation + + int mem_alloc = 0; + // Tracks where the mem alloc happened + + int digest_size = 0; + // Return Value + + int success = 0; + // Tracks the success of the operation + + // Input Checks + if (!data || !alg || !dst_buf) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return 0; + } + + // Allocate a new CTX + if ((md_ctx = EVP_MD_CTX_new()) == NULL) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return 0; + } + + // Let's initialize the MD context + EVP_MD_CTX_init(md_ctx); + + // Allocates the buffer if not provided + if (*dst_buf == NULL) { + *dst_buf = PKI_Malloc(EVP_MAX_MD_SIZE); + mem_alloc = 1; + } + + // Makes sure we have a good buffer + if (*dst_buf == NULL) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return 0; + } + + // Initializes the Digest + success = EVP_DigestInit_ex(md_ctx, alg, NULL); + if (success == 1 ) { + + // Updates the digest value + EVP_DigestUpdate(md_ctx, data, size); + + // Finalize the digest + if ((EVP_DigestFinal_ex(md_ctx, *dst_buf, NULL)) == 1) { + + // All Ok + digest_size = EVP_MD_CTX_size(md_ctx); + } + + // // Let's clean everything up + EVP_MD_CTX_reset(md_ctx); + + // Free the CTX memory + EVP_MD_CTX_free(md_ctx); + md_ctx = NULL; // Safety + } + + // If we have an error, let's return '0' + if (digest_size <= 0) goto err; + + // Return the calculated value + return digest_size; + +err: + // Let's clean everything up + if (md_ctx) { + EVP_MD_CTX_reset(md_ctx); + EVP_MD_CTX_free(md_ctx); + } + + // Free the allocated memory only if we are not re-using + // the provided output buffer (dst_buf) + if (mem_alloc) { + PKI_Free(*dst_buf); + *dst_buf = NULL; // Safety + } + + // Nothing to return + return 0; + +} + +/*! \brief Calculate digest over data provided in a buffer + */ + +CRYPTO_DIGEST *PKI_DIGEST_new(const PKI_DIGEST_ALG *alg, + const unsigned char *data, + size_t size ) { + + // Return Object + CRYPTO_DIGEST *ret = NULL; + + // Input Checks + if (!data || !alg) return NULL; + + // Allocates the memory for the return CRYPTO_DIGEST + if ((ret = PKI_Malloc(sizeof(CRYPTO_DIGEST))) != NULL) { + + int dgst_size = 0; + + // Fills in the data and the size of the digest + if ((dgst_size = PKI_DIGEST_new_value(&ret->digest, + alg, data, size)) <= 0) { + goto err; + } + + ret->size = (size_t) dgst_size; + } + + // All done + return ret; + +err: + // Let's free any allocated memory + if (ret) PKI_DIGEST_free(ret); + + // No digest was calculated, return the error + return NULL; +} + +/*! \brief Calculates a digest over data buffer + */ + +CRYPTO_DIGEST *PKI_DIGEST_new_by_name(const char *alg_name, + const unsigned char *data, + size_t size ) { + + const PKI_DIGEST_ALG *alg; + + if ((alg = PKI_DIGEST_ALG_get_by_name( alg_name )) == NULL) { + /* Algorithm Error */ + return NULL; + } + + return PKI_DIGEST_new(alg, data, size); +} + +/*! \brief Calculates a digest over data contained in a PKI_MEM + */ + +CRYPTO_DIGEST *PKI_DIGEST_MEM_new(const PKI_DIGEST_ALG *alg, const PKI_MEM *data) { + return (PKI_DIGEST_new(alg, data->data, data->size )); +} + +CRYPTO_DIGEST *PKI_DIGEST_MEM_new_by_name(const char *alg_name, + const PKI_MEM *data ) { + + const PKI_DIGEST_ALG *alg; + + if ((alg = PKI_DIGEST_ALG_get_by_name(alg_name)) == NULL) { + /* Algorithm Error */ + return NULL; + } + + return ( PKI_DIGEST_new( alg, data->data, data->size )); +} + +/*! \brief Calculate the digest of data retrieved via a URL + */ + +CRYPTO_DIGEST *PKI_DIGEST_URL_new(const PKI_DIGEST_ALG *alg, const URL *url ) { + + PKI_MEM_STACK * stack = NULL; + PKI_MEM *data = NULL; + CRYPTO_DIGEST *ret = NULL; + + if(( stack = URL_get_data_url( url, 0, 0, NULL )) == NULL ) { + /* Error, Can not grab the data */ + return ( NULL ); + } + + if( (data = PKI_STACK_MEM_pop( stack )) == NULL ) { + /* Error, no objects returned! */ + PKI_STACK_free( stack ); + return ( NULL ); + } + + /* Calculate the Digest over the first object */ + ret = PKI_DIGEST_MEM_new( alg, data ); + + /* Let's free the data */ + PKI_MEM_free( data ); + + /* Let's free the stack data structure */ + PKI_STACK_free ( stack ); + + /* Return the diget data */ + return ( ret ); +} + +CRYPTO_DIGEST *PKI_DIGEST_URL_new_by_name(const char *alg_name, const URL *url) { + + const PKI_DIGEST_ALG *alg; + + if ((alg = PKI_DIGEST_ALG_get_by_name(alg_name)) == NULL) { + /* Algorithm Error */ + return NULL; + } + + return PKI_DIGEST_URL_new(alg, url); +} + +/*! \brief Returns the size of the output of the selected digest algorithm */ + +ssize_t PKI_DIGEST_get_size(const PKI_DIGEST_ALG *alg) +{ + int digest_size = 0; + ssize_t ret = -1; + + if (!alg) return ret; + + digest_size = EVP_MD_size(alg); + + ret = (ssize_t) digest_size; + + return ret; + +} + +/*! \brief Returns the size of the output of the provided algorithm */ + +int PKI_DIGEST_get_size_by_name(const char *alg_name) { + + const PKI_DIGEST_ALG *alg = NULL; + + if ((alg = PKI_DIGEST_ALG_get_by_name(alg_name)) == NULL) { + /* Algorithm Error */ + return -1; + } + + return EVP_MD_size(alg); +}; + +/*! \brief Returns the pointer to the calculated digest */ +const unsigned char * PKI_DIGEST_get_value(const CRYPTO_DIGEST *digest) { + + // Input Checks + if (!digest || !digest->digest || digest->size == 0) + return NULL; + + // Returns the pointer + return digest->digest; + +} + + +/*! \brief Returns the size of a calculated digest */ + +size_t PKI_DIGEST_get_value_size(const CRYPTO_DIGEST *dgst) +{ + if (!dgst || !dgst->digest || !dgst->size) return 0; + + return dgst->size; +} + +/*! \brief Returns the parsed (string) version of the digest content */ + +char * PKI_DIGEST_get_parsed(const CRYPTO_DIGEST *digest ) { + + char *ret = NULL; + int i = 0; + + if( !digest ) return ( NULL ); + + if ((digest->size <= 0) || (!digest->digest )) + return ( NULL ); + + ret = PKI_Malloc((digest->size * 3) + 1); + // ret = PKI_Malloc ( 1024 ); + ret[0] = '\x0'; + + for (i = 0; i < digest->size; i++) + { + unsigned char c; + char kk[4]; + + if( i > 0 ) strcat (ret, ":" ); + + c = digest->digest[i]; + sprintf(kk, "%2.2x%c", c,'\x0' ); + strcat(ret, kk); + } + + return ( ret ); +} + diff --git a/src/crypto/pki_hmac.c b/src/crypto/pki_hmac.c new file mode 100644 index 00000000..fbb80407 --- /dev/null +++ b/src/crypto/pki_hmac.c @@ -0,0 +1,300 @@ +/* HMAC utility */ + +#include +#include + +#if OPENSSL_VERSION_NUMBER < 0x1010000fL +static inline HMAC_CTX * HMAC_CTX_new() { + return (HMAC_CTX *) OPENSSL_malloc(sizeof(HMAC_CTX)); +} + +static inline void HMAC_CTX_free(HMAC_CTX * ctx) { + if (ctx) OPENSSL_free(ctx); +} +#endif + +/* + * \brief Allocates and return a new (empty) CRYPTO_HMAC + */ +CRYPTO_HMAC *PKI_HMAC_new_null(void) +{ + CRYPTO_HMAC *ret = NULL; + ret = PKI_Malloc(sizeof(CRYPTO_HMAC)); + + if (ret != NULL) { + + ret->key = NULL; + ret->value = NULL; + ret->digestAlg = NULL; + ret->initialized = 0; + + ret->ctx = HMAC_CTX_new(); + if (ret->ctx == NULL) { + PKI_Free(ret); + return NULL; + } + } + + return ret; +} + +/* + * \brief Allocates and initializes a new CRYPTO_HMAC + */ +CRYPTO_HMAC *PKI_HMAC_new(unsigned char *key, size_t key_size, PKI_DIGEST_ALG *digest, HSM *hsm) +{ + CRYPTO_HMAC *ret = PKI_HMAC_new_null(); + if (!ret) return ret; + + if (PKI_HMAC_init(ret, key, key_size, digest, hsm) != PKI_OK) + { + PKI_HMAC_free(ret); + return NULL; + } + + return ret; +} + +/* + * \brief Allocates and initializes a new CRYPTO_HMAC by using a PKI_MEM to hold the secret key + */ +CRYPTO_HMAC *PKI_HMAC_new_mem(PKI_MEM *key, PKI_DIGEST_ALG *digest, HSM *hsm) +{ + CRYPTO_HMAC *ret = NULL; + + if (!key || !key->data || key->size <= 0) + { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return NULL; + } + + ret = PKI_HMAC_new_null(); + if (!ret) + { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return NULL; + } + + if (PKI_HMAC_init(ret, key->data, key->size, digest, hsm) != PKI_OK) + { + PKI_HMAC_free(ret); + return NULL; + } + + return ret; +} + +/* + * \brief Frees the memory associated with a CRYPTO_HMAC + */ +void PKI_HMAC_free(CRYPTO_HMAC *hmac) +{ + if (!hmac) return; + + if (hmac->key) PKI_MEM_free (hmac->key); + if (hmac->value) PKI_MEM_free (hmac->value); + + hmac->digestAlg = NULL; + + HMAC_CTX_reset(hmac->ctx); + HMAC_CTX_free(hmac->ctx); +} + +/* + * \brief Initializes the passed hmac to use the passed key and digest algorithm + */ +int PKI_HMAC_init(CRYPTO_HMAC *hmac, unsigned char *key, size_t key_size, PKI_DIGEST_ALG *digest, HSM *hsm) +{ + if (!hmac) return PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + + // Free the memory if another key was used + if (hmac->key) PKI_MEM_free(hmac->key); + hmac->key = NULL; + + if (hmac->value) PKI_MEM_free(hmac->value); + hmac->value = NULL; + + // Generate the new PKI_MEM to hold the key data + hmac->key = PKI_MEM_new_data(key_size, key); + if (!hmac->key || !hmac->key->data || hmac->key->size <= 0) + { + hmac->initialized = 0; + return PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + } + + // Sets the algoritm + hmac->digestAlg = digest ? digest : PKI_DIGEST_ALG_SHA1; + + // Checks if HSM implementation was asked by the developer + if (hsm) + { + PKI_ERROR(PKI_ERR_GENERAL, "Code to support HMAC on HSMs not implemented, yet."); + hmac->initialized = 0; + return PKI_ERR; + } + + // Initializes the Context + HMAC_Init_ex(hmac->ctx, (const void *) key, (int) key_size, hmac->digestAlg, NULL); + + // Sets the initialization flag + hmac->initialized = 1; + + return PKI_OK; +} + +int PKI_HMAC_update(CRYPTO_HMAC *hmac, unsigned char *data, size_t data_size) +{ +#if OPENSSL_VERSION_NUMBER > 0x0090900fL + int rv = 0; +#endif + + if (!hmac || !hmac->initialized) + { + return PKI_ERROR(PKI_ERR_GENERAL, "CRYPTO_HMAC is not initialized"); + } + +#if OPENSSL_VERSION_NUMBER > 0x0090900fL + rv = HMAC_Update(hmac->ctx, (const unsigned char *) data, (unsigned int) data_size); + if (rv == 0) + { + return PKI_ERROR(PKI_ERR_GENERAL, "Error while updating the HMAC value"); + } +#else + HMAC_Update(hmac->ctx, (const unsigned char *) data, (unsigned int) data_size); +#endif + + return PKI_OK; +} + +int PKI_HMAC_update_mem(CRYPTO_HMAC *hmac, PKI_MEM *data) +{ + if (!hmac || !data || !data->data || data->size <= 0) + return PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + + return PKI_HMAC_update(hmac, data->data, data->size); +} + +int PKI_HMAC_finalize(CRYPTO_HMAC *hmac) +{ + int size = 0; + unsigned int verify_size = 0; + + if (!hmac || !hmac->initialized) + return PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + + // Let's prepare the return value + size = EVP_MD_size(hmac->digestAlg); + verify_size = (unsigned int) size; + + // Generate a new PKI_MEM container + hmac->value = PKI_MEM_new((size_t) size); + + // Let's finalize the HMAC +#if OPENSSL_VERSION_NUMBER > 0x0090900fL + int rv = HMAC_Final(hmac->ctx, hmac->value->data, &verify_size); + if (!rv) + { + PKI_log_err("can not finalize HMAC"); + PKI_MEM_free(hmac->value); + hmac->value = NULL; + + return PKI_ERR; + } +#else + // In OpenSSL < 0.9.9 the return value is actually void + HMAC_Final(hmac->ctx, hmac->value->data, &verify_size); +#endif + + // Checks the sizes + if (verify_size != size) + { + PKI_log_err("Error while finalizing HMAC, size (%d) should be (%d)", + verify_size, hmac->value->size); + + PKI_MEM_free(hmac->value); + hmac->value = NULL; + + return PKI_ERR; + } + + return PKI_OK; +} + +/* + * \brief Returns a PKI_MEM with the hmac raw value + */ +PKI_MEM * PKI_HMAC_get_value(CRYPTO_HMAC *hmac) +{ + if (!hmac) return NULL; + + return PKI_MEM_dup(hmac->value); +} + + +/* + * \brief Returns a B64 encoded PKI_MEM for the hmac value + */ +PKI_MEM *PKI_HMAC_get_value_b64(CRYPTO_HMAC *hmac) +{ + PKI_MEM *ret = NULL; + + // This returns a duplicate of the PKI_MEM value + ret = PKI_HMAC_get_value(hmac); + if (!ret) PKI_log_err("can not get the HMAC PKI_MEM value"); + + // If a valid PKI_MEM is returned, let's B64 it + if (ret && ret->data && ret->size > 0) + { + if (PKI_MEM_encode(ret, PKI_DATA_FORMAT_B64, 0) != PKI_OK) + { + PKI_log_err("can not B64 encoding HMAC PKI_MEM value"); + if (ret) PKI_MEM_free(ret); + + return NULL; + } + } + + return ret; +} + +PKI_MEM * PKI_HMAC_new_data(PKI_MEM *data, PKI_MEM *key, PKI_DIGEST_ALG *digest) +{ + unsigned char *hmac_value = NULL; + unsigned int hmac_size = 0; + + int key_size = 0; + size_t data_size = 0; + + PKI_MEM *ret = NULL; + + // Input parameters check + if (!data || data->size <= 0 || !key || key->size <= 0) + { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return NULL; + } + + // Let's use the correct types for the sizes (for the HMAC call) + key_size = (int) key->size; + data_size = (size_t) data->size; + + // Retrieve the data from the OpenSSL library + hmac_value = HMAC(digest ? digest : PKI_DIGEST_ALG_SHA1, + (unsigned char *) key->data, key_size, + (unsigned char *) data->data, data_size, + NULL, &hmac_size); + + // If no data is returned or size is wrong, let's return null + if (!hmac_value || hmac_size <= 0) + { + if (hmac_value) PKI_Free(hmac_value); + return NULL; + } + + // Create a new PKI_MEM object for returning the calculated value + ret = PKI_MEM_new_data(hmac_size, hmac_value); + + // Return the PKI_MEM object that contains the HMAC value + return ret; +} + diff --git a/src/crypto/pki_kdf.c b/src/crypto/pki_kdf.c new file mode 100644 index 00000000..240459a4 --- /dev/null +++ b/src/crypto/pki_kdf.c @@ -0,0 +1,22 @@ +/* KDF utility */ + +#include + +int PKI_KDF_derive(const EVP_MD * md, + unsigned char * label, + size_t labelen, + unsigned char * key, + size_t keylen, + unsigned char * data, + size_t datalen, + unsigned char ** out, + size_t * outlen) { + + EVP_KDF_CTX * CTX = NULL; + OSSL_PARAM params[7], *p = params; + + // Missing code + PKI_ERROR(PKI_ERR_NOT_IMPLEMENTED, NULL); + + return 0; +} \ No newline at end of file diff --git a/src/crypto/pki_keypair.c b/src/crypto/pki_keypair.c new file mode 100644 index 00000000..e6f4b500 --- /dev/null +++ b/src/crypto/pki_keypair.c @@ -0,0 +1,1664 @@ +/* openssl/pki_pkey.c */ + +#include +#include +#include "internal/ossl_lcl.h" + +PKI_X509_KEYPAIR *PKI_X509_KEYPAIR_new_null () { + return PKI_X509_new ( PKI_DATATYPE_X509_KEYPAIR, NULL ); +} + +void PKI_X509_KEYPAIR_free( PKI_X509_KEYPAIR *key ) { + + PKI_X509_free ( key ); + return; +} + +void PKI_X509_KEYPAIR_free_void ( void *key ) { + PKI_X509_free_void ( (PKI_X509_KEYPAIR *) key ); + return; +} + +/*! \brief Generate a new Keypair with the passed label (required for + * PKCS#11 HSMs ) as target + */ + +PKI_X509_KEYPAIR *PKI_X509_KEYPAIR_new(PKI_SCHEME_ID type, + int bits, + char * label, + PKI_CRED * cred, + HSM * hsm) { + + PKI_KEYPARAMS kp; + // Key Parameters to use for key generation + + // Initialize the Key Parameters + memset(&kp, 0, sizeof(PKI_KEYPARAMS)); + + // Common + kp.scheme = type; + kp.bits = bits; + + // RSA + kp.rsa.exponent = -1; + + // EC +#ifdef ENABLE_ECDSA + kp.ec.form = PKI_EC_KEY_FORM_UNKNOWN; + kp.ec.curve = -1; + kp.ec.asn1flags = -1; +#endif + + // Open Quantum Safe +#if defined(ENABLE_OQS) || defined (ENABLE_OQSPROV) + kp.oqs.algId = -1; +#endif + + switch (type) { + + case PKI_SCHEME_DSA: + case PKI_SCHEME_RSA: + case PKI_SCHEME_RSAPSS: { + if (!PKI_KEYPARAMS_set_key_size(&kp, bits)) { + PKI_DEBUG("ERROR, can not set the key size during keypair generation!"); + return NULL; + } + } break; + + default: + // Use the value as the security bits + if (!PKI_KEYPARAMS_set_security_bits(&kp, bits)) { + PKI_DEBUG("ERROR, can not set the security bits during keypair generation!"); + return NULL; + } + } + + // Generate the Key + return HSM_X509_KEYPAIR_new ( &kp, label, cred, hsm ); +} + +/*! \brief Generate a new Keypair with the passed URL (required for + * PKCS#11 HSMs ) as target + */ + +PKI_X509_KEYPAIR *PKI_X509_KEYPAIR_new_url( PKI_SCHEME_ID type, int bits, + URL *url, PKI_CRED *cred, HSM *hsm ) { + + PKI_KEYPARAMS kp; + + // Common + kp.scheme = type; + kp.bits = bits; + + // RSA + kp.rsa.exponent = -1; + + //DSA + + // EC +#ifdef ENABLE_ECDSA + kp.ec.form = PKI_EC_KEY_FORM_UNKNOWN; + kp.ec.curve = -1; + kp.ec.asn1flags = -1; +#endif + + // Open Quantum Safe +#if defined(ENABLE_OQS) || defined (ENABLE_OQSPROV) + kp.oqs.algId = -1; +#endif + + return HSM_X509_KEYPAIR_new_url ( &kp, url, cred, hsm ); +} + +/*! + * \brief Generate a new Keypair with the passed label (required for PKCS#11 HSMs ) as target + */ + +PKI_X509_KEYPAIR *PKI_X509_KEYPAIR_new_kp( PKI_KEYPARAMS *kp, + char *label, PKI_CRED *cred, HSM *hsm ) { + + return HSM_X509_KEYPAIR_new ( kp, label, cred, hsm ); +} + +/*! \brief Generate a new Keypair with the passed URL (required for + * PKCS#11 HSMs ) as target + */ + +PKI_X509_KEYPAIR *PKI_X509_KEYPAIR_new_url_kp( PKI_KEYPARAMS *kp, + URL *url, PKI_CRED *cred, HSM *hsm ) { + + return HSM_X509_KEYPAIR_new_url ( kp, url, cred, hsm ); +} + +/*! \brief Returns a char * with a string representation of the Keypair + */ + +char * PKI_X509_KEYPAIR_get_parsed (const PKI_X509_KEYPAIR *pkey ) { + + if( !pkey || !pkey->value ) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return ( NULL ); + }; + + PKI_ERROR(PKI_ERR_NOT_IMPLEMENTED, NULL); + + return NULL; +} + +/*! + * \brief Returns the signing scheme from a keypair + */ + +PKI_SCHEME_ID PKI_X509_KEYPAIR_get_scheme (const PKI_X509_KEYPAIR *k ) { + + PKI_X509_KEYPAIR_VALUE *pVal = NULL; + + if ( !k ) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return PKI_SCHEME_UNKNOWN; + }; + + pVal = k->value; + + return PKI_X509_KEYPAIR_VALUE_get_scheme ( pVal ); +}; + +/*! + * \brief Returns the signing scheme from a keypair value + */ + +PKI_SCHEME_ID PKI_X509_KEYPAIR_VALUE_get_scheme(const PKI_X509_KEYPAIR_VALUE *pVal) { + + PKI_SCHEME_ID ret = PKI_SCHEME_UNKNOWN; + // Return Value + + if ( !pVal ) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return ret; + } + +// // Let's get the type of the keypair +// #if OPENSSL_VERSION_NUMBER > 0x3000000fL +// int pkey_id = PKI_X509_KEYPAIR_VALUE_get_id(pVal); +// #else +// int pkey_id = EVP_PKEY_id(pVal); +// #endif // End of OPENSSL_VERSION_NUMBER > 0x3000000fL + +// int pkey_type = EVP_PKEY_type(pkey_id); +// if (pkey_type == PKI_ID_UNKNOWN) { +// #if OPENSSL_VERSION_NUMBER > 0x3000000fL +// pkey_type = pkey_id; +// #else +// PKI_DEBUG("ERROR, can not get the type of the keypair to get the scheme (ID: %d, TYPE: %d)!", pkey_id, pkey_type); +// return ret; +// #endif // End of OPENSSL_VERSION_NUMBER > 0x3000000fL +// } + + int pkey_type = PKI_X509_KEYPAIR_VALUE_get_id(pVal); + // Type of keypair + + if (!pkey_type) { + PKI_DEBUG("ERROR, can not get the type of the keypair (type: %d)!", pkey_type); + return ret; + } + + // Let's retrieve the scheme from the keypair type + // Check if the keypair is a composite one + if (PKI_ERR == PKI_ID_is_composite(pkey_type, &ret)) { + // Checks if the keypair is an explicit composite one + if (PKI_ERR == PKI_ID_is_explicit_composite(pkey_type, &ret)) { + // Checks if the keypair is a PQC one + if (PKI_ERR == PKI_ID_is_pqc(pkey_type, &ret)) { + // Checks if the keypair is a traditional one + if (PKI_ERR == PKI_ID_is_traditional(pkey_type, &ret)) { + // If we are here, the key ID is not recognized + PKI_DEBUG("Unrecognized keypair's type while retrieving the scheme (type: %d)", pkey_type); + return PKI_ERR; + } + } + } + } + + // All Done + return ret; + + +// // Maps the type of the keypair to the scheme +// switch(pkey_type) { + +// case PKI_ALGOR_DSA: +// ret = PKI_SCHEME_DSA; +// break; + +// case PKI_ALGOR_RSA: +// case PKI_ALGOR_RSAPSS: +// ret = PKI_SCHEME_RSA; +// break; + +// #ifdef ENABLE_ECDSA +// case PKI_ALGOR_ECDSA: +// ret = PKI_SCHEME_ECDSA; +// break; +// #endif + +// #ifdef ENABLE_OQS + +// case PKI_ALGOR_DILITHIUM2: +// case PKI_ALGOR_DILITHIUM3: +// case PKI_ALGOR_DILITHIUM5: { +// ret = PKI_SCHEME_DILITHIUM; +// } break; + +// case PKI_ALGOR_FALCON512: +// case PKI_ALGOR_FALCON1024: { +// ret = PKI_SCHEME_FALCON; +// } break; + +// case PKI_ALGOR_KYBER512: +// case PKI_ALGOR_KYBER768: +// case PKI_ALGOR_KYBER1024: { +// ret = PKI_SCHEME_KYBER; +// } break; + +// case PKI_ALGOR_SPHINCS_SHA256_128_R: +// case PKI_ALGOR_SPHINCS_SHAKE256_128_R: { +// ret = PKI_SCHEME_SPHINCS; +// } break; + +// #endif + +// default: { +// #ifdef ENABLE_COMPOSITE + +// PKI_DEBUG("Looking up the pkey_type (%d) in the composite list", pkey_type); + +// // Generic Composite +// if (PKI_ID_is_composite(pkey_type, &ret)) { +// PKI_DEBUG("Found a composite type (%d)", ret); +// } else if (PKI_ID_is_explicit_composite(pkey_type, &ret)) { +// // Scheme ID and PKEY types are the same +// // Nothing to do, ret was already retrieved +// PKI_DEBUG("Found an explicit composite type (%d)", ret); +// } else { +// ret = PKI_SCHEME_UNKNOWN; +// PKI_DEBUG("Cannot select the scheme for pkey_type = %d (%d)", pkey_type, ret); +// } + +// // if ( pkey_type == OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_OID)) { +// // return PKI_SCHEME_COMPOSITE; +// // // Explicit Composite +// // } else if ( pkey_type == OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_RSA_SHA256_OID) +// // || pkey_type == OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_RSAPSS_SHA256_OID) +// // || pkey_type == OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_P256_SHA256_OID) +// // || pkey_type == OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_BRAINPOOL256_SHA256_OID) +// // || pkey_type == OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_ED25519_OID) +// // || pkey_type == OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_P384_SHA384_OID) +// // || pkey_type == OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_BRAINPOOL384_SHA384_OID) +// // || pkey_type == OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_ED448_OID) +// // || pkey_type == OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_FALCON512_P256_SHA256_OID) +// // || pkey_type == OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_FALCON512_BRAINPOOL256_SHA256_OID) +// // || pkey_type == OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_FALCON512_ED25519_OID) +// // || pkey_type == OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_SPHINCS256_P256_SHA256_OID) +// // || pkey_type == OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_SPHINCS256_BRAINPOOL256_SHA256_OID) +// // || pkey_type == OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_SPHINCS256_ED25519_OID) +// // ) { +// // return (PKI_SCHEME_ID)pkey_type; +// // } +// #endif +// } // End of default + +// } // End of switch() + +// // All done. +// return ret; +}; + +/*! + * \brief Returns the default signing algorithm from a keypair + */ + +PKI_X509_ALGOR_VALUE * PKI_X509_KEYPAIR_get_algor (const PKI_X509_KEYPAIR * k, + const PKI_DIGEST_ALG * digest) { + + PKI_X509_ALGOR_VALUE *ret = NULL; + PKI_X509_KEYPAIR_VALUE *pVal = NULL; + + PKI_ID digest_id = PKI_DIGEST_ALG_ID_UNKNOWN; + // Digest ID + + if ( !k ) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return ret; + }; + + pVal = PKI_X509_get_value(k); + if (!pVal) { + PKI_ERROR(PKI_ERR_TOKEN_INIT, NULL); + return NULL; + } + + if (digest && digest != EVP_md_null()) { + digest_id = EVP_MD_nid(digest); + if (!digest_id) { + PKI_DEBUG("ERROR, can not get the digest ID from the digest (%s)", EVP_MD_name(digest)); + return NULL; + } + } + + return PKI_X509_KEYPAIR_VALUE_get_algor(pVal, digest_id); +} + + +int PKI_X509_KEYPAIR_get_id(const PKI_X509_KEYPAIR * key) { + + // Input check + if (!key || !key->value) return PKI_ID_UNKNOWN; + + // Forward + return PKI_X509_KEYPAIR_VALUE_get_id(key->value); +} + +int PKI_X509_KEYPAIR_VALUE_get_id(const PKI_X509_KEYPAIR_VALUE * pkey) { + + int pkey_id = PKI_ID_UNKNOWN; + + // Input Check + if (!pkey) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return PKI_ID_UNKNOWN; + } + +#if OPENSSL_VERSION_NUMBER > 0x3000000fL + + // Use the name of the keypair + const char * type_name = EVP_PKEY_get0_type_name(pkey); + if (!type_name) { + // if (EVP_PKEY_is_a(pkey, "COMPOSITE")) { + // PKI_DEBUG("OSSL3: Composite keypair detected"); + // pkey_id = PKI_ID_get_by_name("COMPOSITE"); + // } else { + PKI_DEBUG("OSSL3: Error, cannot get the type name from the keypair value"); + return PKI_ID_UNKNOWN; + // } + } + + // Special case because the string "EC" is not a valid type name + // therefore we need to check it explicitly. The name that should + // have been used is id-ecPublicKey (408) + + if (EVP_PKEY_is_a(pkey, "EC")) { + pkey_id = EVP_PKEY_EC; + } else if (EVP_PKEY_is_a(pkey, "RSAPSS")) { + pkey_id = EVP_PKEY_RSA_PSS; + } else if (EVP_PKEY_is_a(pkey, "RSA")) { + pkey_id = EVP_PKEY_RSA; +#ifdef ENABLE_DSA + } else if (EVP_PKEY_is_a(pkey, "DSA")) { + pkey_id = EVP_PKEY_DSA; +#endif + } else if (EVP_PKEY_is_a(pkey, "DH")) { + pkey_id = EVP_PKEY_DH; + } else { + pkey_id = PKI_ID_get_by_name(type_name); + } +#elif OPENSSL_VERSION_NUMBER < 0x1010000fL + pkey_id = pVal->type; +#else + pkey_id = EVP_PKEY_type(EVP_PKEY_id(pkey)); +#endif + + // Retrieves the PKEY type + int pkey_type = EVP_PKEY_type(pkey_id); + if (!pkey_type) { + // For explicit composite, pkey_id and pkey_type are the same + if (PKI_ID_is_explicit_composite(pkey_id, NULL) + || PKI_ID_is_composite(pkey_id, NULL) + || PKI_ID_is_pqc(pkey_id, NULL)) { + // Type and ID are the same (no aliases) + pkey_type = pkey_id; + } else { + PKI_DEBUG("Error while getting the PKEY type from the keypair value (%s)", PKI_ID_get_txt(pkey_id)); + return PKI_ERR; + } + } + + // Returns the PKEY ID + return pkey_type; +} + +// int PKI_X509_KEYPAIR_get_ossl_type(const PKI_X509_KEYPAIR * key) { + +// // Input check +// if (!key || !key->value) return PKI_ID_UNKNOWN; + +// // Forward +// return PKI_X509_KEYPAIR_VALUE_get_ossl_type(key->value); +// } + +// int PKI_X509_KEYPAIR_VALUE_get_ossl_type(const PKI_X509_KEYPAIR_VALUE * pkey) { + +// int pkey_type = PKI_ID_UNKNOWN; +// // Return Value + +// // Input Check +// if (!pkey) { +// PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); +// return PKI_ID_UNKNOWN; +// } + +// int pkey_id = PKI_X509_KEYPAIR_VALUE_get_id(pkey); +// if (pkey_id <= 0) { +// PKI_DEBUG("Cannot retrieve the PKEY ID from the keypair value"); +// return PKI_ID_UNKNOWN; +// } + +// // Retrieves the PKEY type +// pkey_type = EVP_PKEY_type(pkey_id); +// if (!pkey_type) { +// // For explicit composite, pkey_id and pkey_type are the same +// if (PKI_ID_is_explicit_composite(pkey_id, NULL) +// || PKI_ID_is_composite(pkey_id, NULL) +// || PKI_ID_is_pqc(pkey_id, NULL)) { +// // Type and ID are the same (no aliases) +// pkey_type = pkey_id; +// } else { +// PKI_DEBUG("Error while getting the PKEY type from the keypair value (%s)", PKI_ID_get_txt(pkey_id)); +// return PKI_ERR; +// } +// } + +// // All Done +// return pkey_type; + +// } + +int PKI_X509_KEYPAIR_get_default_digest(const PKI_X509_KEYPAIR * key) { + return PKI_X509_KEYPAIR_VALUE_get_default_digest(key ? key->value : NULL); +} + +int PKI_X509_KEYPAIR_VALUE_get_default_digest(const PKI_X509_KEYPAIR_VALUE * pkey) { + + int def_nid = PKI_ID_UNKNOWN; + // Return Value + + // Input Check + if (!pkey) return PKI_ID_UNKNOWN; + + // Retrieves the default digest for the PKEY +#if OPENSSL_VERSION_NUMBER > 0x30000000L + char name_buf[50] = { 0x0 }; + int digestResult = EVP_PKEY_get_default_digest_name((PKI_X509_KEYPAIR_VALUE *)pkey, name_buf, sizeof(name_buf)); + def_nid = OBJ_txt2nid(name_buf); +#else + int digestResult = EVP_PKEY_get_default_digest_nid((PKI_X509_KEYPAIR_VALUE *)pkey, &def_nid); +#endif + +// #if OPENSSL_VERSION_NUMBER > 0x3000000fL +// char buff[50] = { 0 }; +// size_t buff_size = 50; +// digestResult = EVP_PKEY_get_default_digest_name((EVP_PKEY *)pkey, buff, buff_size); +// def_nid = PKI_ID_get_by_name(buff); +// PKI_DEBUG("***** OSSL3 UPGRADE: EVP_PKEY_get_default_digest_name (%d) does work.... ???? (nid: %d - %s) *****", digestResult, def_nid, buff); +// #endif + + // Check for error condition + if (digestResult == -2) { + PKI_DEBUG("Digest is not supported for keypair of type %s", PKI_ID_get_txt(PKI_X509_KEYPAIR_VALUE_get_id(pkey))); + def_nid = -1; + } else if (digestResult <= 0) { + int pkey_id = PKI_X509_KEYPAIR_VALUE_get_id(pkey); +#ifdef ENABLE_COMPOSITE + if (PKI_ID_is_explicit_composite(pkey_id, NULL) + || PKI_ID_is_composite(pkey_id, NULL)) { + // For explicit, no default digest is available + def_nid = PKI_DIGEST_ALG_ID_NULL; +#else + if (0) { + // Empty placeholder for when composite is not enabled +#endif +#if defined(ENABLE_OQS) || defined(ENABLE_OQSPROV) + } else if (PKI_ID_is_pqc(pkey_id, NULL)) { + // For explicit, no default digest is available + def_nid = PKI_DIGEST_ALG_ID_NULL; +#endif + } else { + PKI_DEBUG("ERROR, can not get the default digest for the keypair value (pkey: %s, result: %d)", + PKI_ID_get_txt(pkey_id), digestResult); + def_nid = -1; + } + } + + // All Done + return def_nid; +} + +int PKI_X509_KEYPAIR_requires_digest(const PKI_X509_KEYPAIR * k) { + + // Input Check + if (!k || !k->value) return PKI_ERR; + + // Let's use the new X509 value for keys + if (k->signature_digest_required > -1) { + return k->signature_digest_required; + } + + // Use the old approach (less efficient) + return PKI_X509_KEYPAIR_VALUE_requires_digest(k->value); +} + +int PKI_X509_KEYPAIR_VALUE_requires_digest(const PKI_X509_KEYPAIR_VALUE * pkey) { + + // PKI_SCHEME_ID scheme_id = PKI_SCHEME_UNKNOWN; + // // Scheme identifier + + // int def_nid = PKI_ID_UNKNOWN; + // // Combined algorithms ID + + PKI_ID pkey_type = PKI_ID_UNKNOWN; + PKI_ID pkey_id = PKI_ID_UNKNOWN; + // PKEY ID + + // Input Check + if (!pkey) return PKI_ERR; + + // Retrieves the PKEY ID + pkey_id = PKI_X509_KEYPAIR_VALUE_get_id(pkey); + pkey_type = EVP_PKEY_type(pkey_id); + if (pkey_type <= 0) { +#if OPENSSL_VERSION_NUMBER > 0x3000000fL + // TODO: Remove this trick + pkey_type = pkey_id; +#else + PKI_ERROR(PKI_ERR_ALGOR_UNKNOWN, NULL); + return PKI_ERR; +#endif // End of OPENSSL_VERSION_NUMBER > 0x3000000fL + } + + // Checks if the PKEY requires a digest + return PKI_ID_requires_digest(pkey_type); + + // // Retrieves the default digest for the PKEY + // int digestResult = EVP_PKEY_get_default_digest_nid((PKI_X509_KEYPAIR_VALUE *)pkey, &def_nid); + + // // Check for error condition + // if (digestResult <= 0) { + // PKI_ERROR(PKI_ERR_ALGOR_UNKNOWN, NULL); + // return PKI_ID_UNKNOWN; + // } + + // // Checks if the returned default is the mandatory one + // if (digestResult == 2) return PKI_OK; + + // scheme_id = PKI_X509_KEYPAIR_VALUE_get_scheme(pkey); + // if (scheme_id <= 0) { + // PKI_ERROR(PKI_ERR_ALGOR_UNKNOWN, NULL); + // return PKI_ERR; + // } + + // // Let's return the result of the check on the scheme + // return PKI_SCHEME_ID_requires_digest(scheme_id); +} + +int PKI_X509_KEYPAIR_is_digest_supported(const PKI_X509_KEYPAIR * k, const PKI_DIGEST_ALG * digest) { + + // Input Check + if (!k || !k->value) return PKI_ERR; + + return PKI_X509_KEYPAIR_VALUE_is_digest_supported(k->value, digest); +} + +int PKI_X509_KEYPAIR_VALUE_is_digest_supported(const PKI_X509_KEYPAIR_VALUE * pkey, const PKI_DIGEST_ALG * digest) { + + int def_nid = PKI_ID_UNKNOWN; + // Default digest ID + + int algor_nid = PKI_ID_UNKNOWN; + // Combined algorithms ID + + // Input Check + if (!pkey) return PKI_ERR; + + // Retrieves the default digest for the PKEY +#if OPENSSL_VERSION_NUMBER > 0x30000000L + char name_buf[50] = { 0x0 }; + int digestResult = EVP_PKEY_get_default_digest_name((PKI_X509_KEYPAIR_VALUE *)pkey, name_buf, sizeof(name_buf)); + def_nid = OBJ_txt2nid(name_buf); +#else + int digestResult = EVP_PKEY_get_default_digest_nid((PKI_X509_KEYPAIR_VALUE *)pkey, &def_nid); +#endif + PKI_DEBUG("***** OSSL3 UPGRADE: EVP_PKEY_get_default_digest_nid (%d) seems to fail *****", digestResult); + + // Check for error condition + if (digestResult <= 0) { + PKI_ERROR(PKI_ERR_ALGOR_UNKNOWN, NULL); + return PKI_ID_UNKNOWN; + } + + // Checks if the returned default is the mandatory one + if (digestResult == 2 && EVP_MD_nid(digest) != def_nid) { + return PKI_ERR; + } + + // Checks the combined OID existence + int pkey_type = PKI_X509_KEYPAIR_VALUE_get_id(pkey); + // int pkey_type = EVP_PKEY_type(pkey_id); + if (pkey_type <= 0) { +// #if OPENSSL_VERSION_NUMBER > 0x3000000fL +// // TODO: Remove this trick +// pkey_type = pkey_id; +// #else + PKI_ERROR(PKI_ERR_ALGOR_UNKNOWN, NULL); + return PKI_ERR; + +// #endif // End of OPENSSL_VERSION_NUMBER > 0x3000000fL + } + + if (!OBJ_find_sigid_by_algs(&algor_nid, EVP_MD_nid(digest), pkey_type)) { + // Combined Algorithm is not found + return PKI_ERR; + } + + // All Done + return PKI_OK; +} + +/*! + * \brief Returns the default signing algorithm from a keypair value + */ +PKI_X509_ALGOR_VALUE * PKI_X509_KEYPAIR_VALUE_get_algor(const PKI_X509_KEYPAIR_VALUE * pVal, + const PKI_ID digest_id) { + + PKI_X509_ALGOR_VALUE *ret = NULL; + // Return Value + + int algId = NID_undef; + // Algorithm ID for the return value + + int def_nid = -1; + // OpenSSL return code + + PKI_SCHEME_ID scheme = PKI_X509_KEYPAIR_VALUE_get_scheme(pVal); + if (scheme <= 0) { + PKI_DEBUG("Retrieved SCHEME for keypair value is not valid (%d)", scheme); + return NULL; + } + + // Retrieves the PKEY ID + int pkey_type = PKI_X509_KEYPAIR_VALUE_get_id(pVal); + if (!pkey_type) { + PKI_DEBUG("Retrieved PKEY ID for keypair value is not valid (type: %d)", pkey_type); + return NULL; + } + + if (PKI_SCHEME_ID_is_explicit_composite(scheme)) { + + // Explicit does not use any global hash algorithm + // we can safely use the same ID as the PKEY for the + // signature algorithm + if (digest_id > 0) { + // Digest is not supported + PKI_DEBUG("Digest is not supported for explicit composite keypair values"); + return NULL; + } + ret = PKI_X509_ALGOR_VALUE_new_type(pkey_type); + + } else if (PKI_SCHEME_ID_is_post_quantum(scheme) == PKI_OK) { + + // Also in this case, the default use is not to do + // hash-n-sign, but to use the PKEY directly on the + // data to sign + // ret = PKI_X509_ALGOR_VALUE_new_type(pkey_type); + ret = PKI_X509_ALGOR_VALUE_new_pkey(pVal, digest_id); + + } else { + + // Retrieves the default digest + // def_ret = EVP_PKEY_get_default_digest_nid((EVP_PKEY *)pVal, &def_nid); + // PKI_DEBUG("***** OSSL3 UPGRADE: EVP_PKEY_get_default_digest_nid (ret: %d, nid: %d) seems to fail *****", def_ret, def_nid); + + def_nid = (digest_id > 0 ? digest_id : PKI_X509_KEYPAIR_VALUE_get_default_digest(pVal)); + if (def_nid <= 0) { + // Digest Not supported or NID_undef as default + def_nid = PKI_DIGEST_ALG_ID_NULL; + } + + // Digest supported, let's use it + if (!OBJ_find_sigid_by_algs(&algId, def_nid, pkey_type)) { + // No default algorithm found, let's return the PKEY id + if (def_nid == NID_undef) { + // No default digest found, let's return the PKEY id + ret = PKI_X509_ALGOR_VALUE_new_type(pkey_type); + if (!ret) { + PKI_DEBUG("Cannot find a signing algorithm for pkey (%d) and no hash", pkey_type); + return NULL; + } + } else { + // The selected digest is not supported + PKI_DEBUG("Cannot find a signing algorithm for pkey (%d) and hash (%d)", pkey_type, def_nid); + return NULL; + } + } else { + PKI_DEBUG("Got the default signing algorithm ID from the KEY value (%d)", algId); + // Algorithm found, let's return it + ret = PKI_X509_ALGOR_VALUE_new_type(algId); + if (!ret) { + PKI_DEBUG("Cannot find a signing algorithm for pkey (%d) and hash (%d)", pkey_type, def_nid); + return NULL; + } + } + + // if (def_nid == NID_undef) { + // // Error or No digest is supported + // PKI_DEBUG("No default digest for algorithm (%d), using the PKEY as the Algorithm ID"); + // algId = EVP_PKEY_id(pVal); + // ret = PKI_X509_ALGOR_VALUE_new_type(algId); + + // } else { + // // Digest supported, let's use it + // if (!OBJ_find_sigid_by_algs(&algId, def_nid, EVP_PKEY_id(pVal))) { + // // No default algorithm found, let's return the PKEY id + // ret = PKI_X509_ALGOR_VALUE_new_type(EVP_PKEY_type(EVP_PKEY_id(pVal))); + // } + // PKI_DEBUG("Got the default signing algorithm ID from the KEY value"); + // // Gets the algorithm + // ret = PKI_X509_ALGOR_VALUE_new_type(algId); + // } + } + + if (!ret) { + PKI_DEBUG("Cannot find a signing algorithm for pkey (%d)", pkey_type); + return NULL; + } + + // // Debugging + // PKI_DEBUG("------> algId: %d, ret: %p", algId, ret); + + // All Done + return ret; +} + +/*! + * \brief Returns the size (in bits) of a pubkey + */ + +int PKI_X509_KEYPAIR_get_size (const PKI_X509_KEYPAIR *k ) { + + PKI_X509_KEYPAIR_VALUE *pKey = NULL; + + if (!k) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return -1; + }; + + pKey = k->value; + + return PKI_X509_KEYPAIR_VALUE_get_size ( pKey ); +} + +/*! + * \brief Returns the size (in bits) of a pubkey value + */ + +int PKI_X509_KEYPAIR_VALUE_get_size (const PKI_X509_KEYPAIR_VALUE *pKey ) { + + int ret = -1; + + if (!pKey) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return ret; + }; + + return EVP_PKEY_bits((PKI_X509_KEYPAIR_VALUE *)pKey); +} + +/*! \brief Returns the (unsigned char *) digest of a pubkey value */ + +CRYPTO_DIGEST *PKI_X509_KEYPAIR_VALUE_pub_digest (const PKI_X509_KEYPAIR_VALUE * pkey, + const PKI_DIGEST_ALG * md) { + + X509_PUBKEY *xpk = NULL; + CRYPTO_DIGEST * ret = NULL; + + unsigned char * buf = NULL; + int buf_size = 0; + + // Input Check + if (!pkey) return NULL; + + // Check for MD (if not, let's use the default) + if(!md) md = PKI_DIGEST_ALG_DEFAULT; + + // Sets the Public Key + if(!X509_PUBKEY_set(&xpk, (EVP_PKEY *)pkey)) { + PKI_DEBUG("Error building X509 PUBKEY data"); + return NULL; + } + + // Checks the results of the set operation + if (!xpk) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return NULL; + } + +#if OPENSSL_VERSION_NUMBER < 0x1010000fL + + buf = xpk->public_key->data; + buf_size = xpk->public_key->length; + +#else + + if (1 != X509_PUBKEY_get0_param(NULL, + (const unsigned char **)&buf, &buf_size, NULL, xpk)) { + PKI_log_err("Can not get the PublicKeyInfo from the KeyPair."); + X509_PUBKEY_free(xpk); + return NULL; + } + +#endif + + // Calculates the digest over the DER representation of the pubkey + if (buf != NULL && buf_size > 0) { + + // Gets the Digest Value + if ((ret = PKI_DIGEST_new(md, buf, (size_t) buf_size)) == NULL) { + PKI_DEBUG("Crypto Error: %s", ERR_error_string( ERR_get_error(), NULL )); + X509_PUBKEY_free(xpk); + return NULL; + } + } + + // Free the X509_KEYPAIR memory + X509_PUBKEY_free(xpk); + + // Success + return ret; +} + +/*! \brief Returns the (unsigned char *) digest of the pubkey */ + +CRYPTO_DIGEST *PKI_X509_KEYPAIR_pub_digest (const PKI_X509_KEYPAIR *k, + const PKI_DIGEST_ALG *md) { + + if( !k || !k->value ) return ( NULL ); + + return PKI_X509_KEYPAIR_VALUE_pub_digest ( k->value, md ); + +} + +/*! \brief Returns the passed PKI_X509_KEYPAIR_VALUE in PKCS#8 format */ + +PKI_MEM *PKI_X509_KEYPAIR_VALUE_get_p8 (const PKI_X509_KEYPAIR_VALUE * pkey ) { + + BIO *mem = NULL; + PKI_MEM *ret = NULL; + + // Input checks + if (!pkey) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return NULL; + } + + // Creates a new memory BIO + if((mem = BIO_new(BIO_s_mem())) == NULL ) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return NULL; + } + + // Writes the PKCS8 Private Key + if (i2d_PKCS8PrivateKeyInfo_bio(mem, (EVP_PKEY *) pkey) > 0 ) { + if( BIO_flush ( mem ) <= 0 ) { + PKI_log_debug("ERROR flushing mem"); + } + // Creates the PKI_MEM to be returned + ret = PKI_MEM_new_bio(mem, NULL); + } + + // Frees the BIO + BIO_free ( mem ); + + // All done + return ret; +} + +/*! \brief Returns the passed PKI_X509_KEYPAIR in PKCS#8 format */ + +PKI_MEM *PKI_X509_KEYPAIR_get_p8 (const PKI_X509_KEYPAIR *k ) { + + if (!k || !k->value ) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return NULL; + } + + // pkey = k->value; + + // if((mem = BIO_new(BIO_s_mem())) == NULL ) { + // return NULL; + // } + + // if(i2d_PKCS8PrivateKeyInfo_bio(mem, (EVP_PKEY *) pkey) > 0 ) { + // if( BIO_flush ( mem ) <= 0 ) { + // PKI_log_debug("ERROR flushing mem"); + // } + // ret = PKI_MEM_new_bio ( mem, NULL ); + // } + + // BIO_free ( mem ); + + return PKI_X509_KEYPAIR_VALUE_get_p8(k->value); +} + +/*! \brief Reads a PKI_X509_KEYPAIR from a PKCS#8 format */ + +PKI_X509_KEYPAIR_VALUE *PKI_X509_KEYPAIR_VALUE_new_p8 (const PKI_MEM *buf ) { + + BIO * bio = NULL; + // Memory BIO for reading the buffer + + PKI_X509_KEYPAIR_VALUE * pkey_val = NULL; + // Internal PKI_X509_KEYPAIR_VALUE + + // Input checks + if (!buf || !buf->data || !buf->size) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return NULL; + } + + // Creates a new memory BIO + if ((bio = BIO_new(BIO_s_mem())) == NULL ) { + PKI_DEBUG("Memory Error"); + return NULL; + } + + // Writes the data to the bio + BIO_write(bio, buf->data, (int) buf->size); + + // Reads the PKCS8 Private Key + pkey_val = d2i_PKCS8PrivateKey_bio(bio, (EVP_PKEY **) &pkey_val, NULL, NULL); + if (!pkey_val) { + PKI_DEBUG("Can not read the PKCS8 Private Key"); + BIO_free(bio); + return NULL; + } + + // Frees the BIO + BIO_free(bio); + bio = NULL; + + // All Done + return pkey_val; +} + +/*! \brief Reads a PKI_X509_KEYPAIR from a PKCS#8 format */ + +PKI_X509_KEYPAIR *PKI_X509_KEYPAIR_new_p8 (const PKI_MEM *buf ) { + + PKI_X509_KEYPAIR_VALUE * pkey_val = NULL; + // Internal PKI_X509_KEYPAIR_VALUE + + // Input checks + if (!buf || !buf->data || !buf->size) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return NULL; + } + + // // Creates a new memory BIO + // if ((bio = BIO_new(BIO_s_mem())) == NULL ) { + // PKI_DEBUG("Memory Error"); + // return NULL; + // } + + // // Writes the data to the bio + // BIO_write(bio, buf->data, (int) buf->size); + + // // Reads the PKCS8 Private Key + // pkey_val = d2i_PKCS8PrivateKey_bio(bio, (EVP_PKEY **) &pkey_val, NULL, NULL); + // if (!pkey_val) { + // PKI_DEBUG("Can not read the PKCS8 Private Key"); + // BIO_free(bio); + // return NULL; + // } + + // // Frees the BIO + // BIO_free(bio); + // bio = NULL; + + // Creates the PKI_X509_KEYPAIR_VALUE + pkey_val = PKI_X509_KEYPAIR_VALUE_new_p8(buf); + if (!pkey_val) { + PKI_DEBUG("Can not read the PKCS8 Private Key"); + return NULL; + } + + // Creates the PKI_X509_KEYPAIR + PKI_X509_KEYPAIR * pkey = PKI_X509_new_value(PKI_DATATYPE_X509_KEYPAIR, pkey_val, NULL); + if (!pkey) { + PKI_DEBUG("Can not create the PKI_X509_KEYPAIR"); + return NULL; + } + + // All Done + return pkey; +} + +/*! + * \brief Returns a DER encoded Public Key + */ + +PKI_MEM * PKI_X509_KEYPAIR_get_pubkey(const PKI_X509_KEYPAIR *kp) +{ + PKI_X509_KEYPAIR_VALUE *kVal = NULL; + PKI_MEM *ret = NULL; + + if(!kp || !kp->value) + { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return NULL; + }; + + kVal = kp->value; + + if((ret = PKI_MEM_new_null())==NULL) + { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return NULL; + }; + + ret->size = (size_t) i2d_PUBKEY(kVal, &(ret->data)); + + return ret; +} + +/*! + * \brief Returns a Private Key in PKCS#8 format + */ + +PKI_MEM *PKI_X509_KEYPAIR_get_privkey(const PKI_X509_KEYPAIR *kp) +{ + return PKI_X509_KEYPAIR_get_p8(kp); + + /* + PKI_X509_KEYPAIR_VALUE *kVal = NULL; + PKI_X509_MEM *ret = NULL; + + if(!kp || !kp->value) reutrn PKI_ERR(PKI_ERROR_NULL_PARAM, NULL); + + kVal = kp->value; + + if((ret = PKI_X509_MEM_new_null())==NULL) + { + PKI_ERR(PKI_ERROR_NULL_PARAM, NULL); + return NULL; + }; + + ret->size = i2d_PRIVKEY(kVal, &(ret->data)); + + return ret; + */ + +}; + +int PKI_X509_KEYPAIR_get_curve(const PKI_X509_KEYPAIR *kp) { + + // Input Checks + if (!kp || !kp->value) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return PKI_ERR; + } + +#ifdef ENABLE_ECDSA + + // Checks if the key is an EC Key + if (PKI_X509_KEYPAIR_get_id(kp) != NID_X9_62_id_ecPublicKey) { + PKI_ERROR(PKI_ERR_ALGOR_COMPOSITE_EXPLICIT_WRONG_COMPONENT, NULL); + return PKI_ERR; + } + + // Retrieves the EC key + EC_KEY * ec = (EC_KEY *)EVP_PKEY_get0_EC_KEY((EVP_PKEY *)kp->value); + if (!ec) { + PKI_ERROR(PKI_ERR_POINTER_NULL, NULL); + return PKI_ERR; + } + + // Retrieves the EC Group + const EC_GROUP * pkey_group = EC_KEY_get0_group(ec); + if (!pkey_group) { + PKI_ERROR(PKI_ERR_POINTER_NULL, NULL); + return PKI_ERR; + } + + // Returns the curve name + return EC_GROUP_get_curve_name(pkey_group); + +#else + return PKI_ID_UNKNOWN; +#endif + +} + +// int PKI_X509_KEYPAIR_get_curve (const PKI_X509_KEYPAIR *kp ) { + +// #ifdef ENABLE_ECDSA +// PKI_X509_KEYPAIR_VALUE *pVal = NULL; +// const EC_GROUP *gr; +// EC_GROUP *gr2; +// EC_KEY *ec = NULL; +// EC_POINT *point = NULL; +// BN_CTX *ctx = NULL; +// int ret = PKI_ID_UNKNOWN; + +// EC_builtin_curve *curves = NULL; +// size_t num_curves = 0; +// int i; + +// BIGNUM *order = NULL; + +// unsigned long long keyBits = 0; +// unsigned long long curveBits = 0; + +// pVal = kp->value; +// if (!pVal ) return PKI_ID_UNKNOWN; + +// ctx = BN_CTX_new(); + +// switch (EVP_PKEY_type(EVP_PKEY_id(pVal))) +// { +// case EVP_PKEY_EC: { +// // ec = pVal->pkey.ec; +// if ((ec = EVP_PKEY_get1_EC_KEY(pVal)) == NULL) goto err; +// } break; + +// default: { +// goto err; +// } break; +// } + +// if ((gr = EC_KEY_get0_group(ec)) == NULL) return PKI_ID_UNKNOWN; + +// order = BN_new(); +// if (EC_GROUP_get_order(gr, order, NULL)) { +// keyBits = (unsigned long long) BN_num_bits(order); +// } +// BN_free( order ); +// order = NULL; + +// if((point = EC_POINT_new( gr )) == NULL ) { +// PKI_log_err("Can not generate a new point in Key's Group"); +// goto err; +// }; + +// /* Get the number of availabe ECDSA curves in OpenSSL */ +// if ((num_curves = EC_get_builtin_curves(NULL, 0)) < 1 ) { +// /* No curves available! */ +// goto err; +// } + +// /* Alloc the needed memory */ +// #if OPENSSL_VERSION_NUMBER < 0x1010000fL +// curves = OPENSSL_malloc((int)(sizeof(EC_builtin_curve) * num_curves)); +// #else +// curves = OPENSSL_malloc(sizeof(EC_builtin_curve) * num_curves); +// #endif +// if (curves == NULL) goto err; + +// /* Get the builtin curves */ +// if (!EC_get_builtin_curves(curves, num_curves)) goto err; + +// // Allocates the BN +// order = BN_new(); + +// /* Cycle through the curves and display the names */ +// for( i = 0; i < num_curves; i++ ) { +// int nid; + +// nid = curves[i].nid; + +// if(( gr2 = EC_GROUP_new_by_curve_name( nid )) == NULL) { +// PKI_log_err("Can not get default curve [%d]", i); +// break; +// }; + +// if (EC_GROUP_get_order(gr2, order, NULL)) { +// curveBits = (unsigned long long) BN_num_bits(order); +// }; + +// if ( curveBits == keyBits ) { +// if( EC_POINT_is_on_curve( gr2, point, ctx ) ) { +// ret = nid; +// break; +// }; +// }; + +// if( gr2 ) EC_GROUP_free ( gr2 ); +// }; + +// // Free Memory +// if (order) BN_free(order); +// if (curves) free(curves); +// if (ctx) BN_CTX_free(ctx); +// if (ec) EC_KEY_free(ec); + +// // Return Result +// return ret; + +// err: + +// // Free Memory +// if (order) BN_free (order); +// if (curves) free(curves); +// if (ctx) BN_CTX_free(ctx); +// if (ec) EC_KEY_free(ec); + +// // Return Error +// return PKI_ID_UNKNOWN; + +// #else +// return PKI_ID_UNKNOWN; +// #endif +// } +// + +PKI_MEM * PKI_X509_KEYPAIR_VALUE_encrypt(const PKI_X509_KEYPAIR_VALUE * pVal, + const unsigned char * const data, + size_t const data_len, + int const flags) { + + EVP_PKEY * pkey = (EVP_PKEY *)pVal; + // Pointer to the keypair value + + EVP_PKEY_CTX * pkey_ctx = NULL; + // Pointer to the EVP context + + PKI_MEM * out_mem = NULL; + // Output buffer + + int padding = -1; + // Padding + + size_t enc_size = 0; + // Encrypted data max size + + // Input Checks + if (!pVal || !data || data_len == 0) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return NULL; + } + + // Checks the padding + if (flags <= 0) { + // No padding specified, let's check the keypair type + int pkey_id = PKI_X509_KEYPAIR_VALUE_get_id(pVal); + int pkey_type = EVP_PKEY_type(pkey_id); + if (pkey_type <= 0) { +#if OPENSSL_VERSION_NUMBER > 0x3000000fL + pkey_type = pkey_id; +#else + PKI_ERROR(PKI_ERR_ALGOR_UNKNOWN, NULL); + return NULL; +#endif // End of OPENSSL_VERSION_NUMBER > 0x3000000fL + } + PKI_DEBUG("***** OSSL3 UPGRADE: Got PKEY ID %d (checking against RSA - %d, RSA2 - %d, and RSAPSS - %d)", + pkey_type, EVP_PKEY_RSA, EVP_PKEY_RSA2, EVP_PKEY_RSA_PSS); + + // Let's set the padding for RSA keys + if (EVP_PKEY_RSA == pkey_type || + EVP_PKEY_RSA2 == pkey_type || + EVP_PKEY_RSA_PSS == pkey_type) { + // RSA supports encryption and different + // padding options, let's set the default + padding = RSA_PKCS1_OAEP_PADDING; + } + } else { + padding = flags; + } + + // Creates a new PKEY context + if ((pkey_ctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return NULL; + } + + // Initializes the Encryption Process (will fail for key pairs + // that do not support encryption) + if (EVP_PKEY_encrypt_init(pkey_ctx) <= 0) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_ENCRYPT_INIT, NULL); + goto err; + } + + // Sets the padding, if one is set + if (padding > 0) { + +// int pkey_id = PKI_X509_KEYPAIR_VALUE_get_id(pkey); +// int pkey_type = EVP_PKEY_type(pkey_id); +// if (pkey_type <= 0) { +// #if OPENSSL_VERSION_NUMBER > 0x3000000fL +// pkey_type = pkey_id; +// #else +// PKI_ERROR(PKI_ERR_ALGOR_UNKNOWN, NULL); +// return NULL; +// #endif // End of OPENSSL_VERSION_NUMBER > 0x3000000fL +// } +// PKI_DEBUG("**** OSSL3 UPGRADE: Got PKEY ID %d vs. EVP_PKEY_id() -> %d", pkey_id, EVP_PKEY_id(pkey)); + + int pkey_type = PKI_X509_KEYPAIR_VALUE_get_id(pkey); + if (!pkey_type) { + PKI_DEBUG("Cannot retrieve the PKEY type from the EVP_PKEY object"); + goto err; + } + + // Sets the padding via the CTRL interface + switch (pkey_type) { + + // RSA Algorithm(s) + case EVP_PKEY_RSA: + case EVP_PKEY_RSA2: + case EVP_PKEY_RSA_PSS: { + if (EVP_PKEY_CTX_ctrl(pkey_ctx, pkey_type, EVP_PKEY_OP_ENCRYPT, EVP_PKEY_CTRL_RSA_PADDING, padding, NULL) <= 0) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_ENCRYPT_INIT, NULL); + goto err; + } + } break; + + // Default Algorithms + default: + PKI_DEBUG("Public Key Type %d does not support encryption"); + goto err; + } + } + + //Let's encrypt the data + if (EVP_PKEY_encrypt(pkey_ctx, NULL, &enc_size, data, data_len) <= 0) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_ENCRYPT, NULL); + goto err; + } + + // Let's allocate the output buffer + if ((out_mem = PKI_MEM_new(enc_size)) == NULL) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + goto err; + } + + //Let's encrypt the data + if (EVP_PKEY_encrypt(pkey_ctx, out_mem->data, &out_mem->size, data, data_len) <= 0) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_ENCRYPT, NULL); + goto err; + } + + // Free allocated CTX + if (pkey_ctx) EVP_PKEY_CTX_free(pkey_ctx); + pkey_ctx = NULL; // Safety + + // All Done. + return out_mem; + +err: + + // Free allocated memory + if (out_mem) PKI_MEM_free(out_mem); + out_mem = NULL; // Safety + + // Free the CTX from OpenSSL + if (pkey_ctx) EVP_PKEY_CTX_free(pkey_ctx); + pkey_ctx = NULL; // Safety + + // Error condition + return NULL; +} + +PKI_MEM * PKI_X509_KEYPAIR_encrypt(const PKI_X509_KEYPAIR * keypair, + const unsigned char * const data, + size_t const data_len, + int const flags) { + + // Wrapper for the call to the lower crypto layer + return PKI_X509_KEYPAIR_VALUE_encrypt(PKI_X509_get_value(keypair), data, data_len, flags); +} + +PKI_MEM * PKI_X509_KEYPAIR_VALUE_decrypt(const PKI_X509_KEYPAIR_VALUE * pVal, + const unsigned char * const data, + size_t const data_len, + int const flags) { + + EVP_PKEY * pkey = (EVP_PKEY *)pVal; + // Pointer to the keypair value + + EVP_PKEY_CTX * pkey_ctx = NULL; + // Pointer to the EVP context + + PKI_MEM * out_mem = NULL; + // Output buffer + + int padding = -1; + // Padding + + size_t dec_size = 0; + // Size of decrypted data + + // Input Checks + if (!pVal || !data || data_len == 0) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return NULL; + } + + // Checks the padding + if (flags <= 0) { +// int pkey_id = PKI_X509_KEYPAIR_VALUE_get_id(pVal); +// int pkey_type = EVP_PKEY_type(pkey_id); +// if (pkey_type <= 0) { +// #if OPENSSL_VERSION_NUMBER > 0x3000000fL +// pkey_type = pkey_id; +// #else +// PKI_ERROR(PKI_ERR_ALGOR_UNKNOWN, NULL); +// return NULL; +// #endif // End of OPENSSL_VERSION_NUMBER > 0x3000000fL +// } +// PKI_DEBUG("***** OSSL3 UPGRADE: Got PKEY ID %d vs. EVP_PKEY_id() -> %d", pkey_id, EVP_PKEY_id(pkey)); + + int pkey_type = PKI_X509_KEYPAIR_VALUE_get_id(pVal); + if (!pkey_type) { + PKI_DEBUG("Cannot retrieve the PKEY type from the EVP_PKEY object"); + return NULL; + } + + if (EVP_PKEY_RSA == pkey_type || + EVP_PKEY_RSA2 == pkey_type || + EVP_PKEY_RSA_PSS == pkey_type) { + // RSA supports encryption and different + // padding options, let's set the default + padding = RSA_PKCS1_OAEP_PADDING; + } + } else { + padding = flags; + } + + // Creates a new PKEY context + if ((pkey_ctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return NULL; + } + + // Initializes the Encryption Process (will fail for key pairs + // that do not support encryption) + if (!EVP_PKEY_decrypt_init(pkey_ctx)) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_ENCRYPT_INIT, NULL); + return NULL; + } + + // Sets the padding, if one is set + if (padding > 0) { + +// int pkey_id = PKI_X509_KEYPAIR_VALUE_get_id(pkey); +// int pkey_type = EVP_PKEY_type(pkey_id); +// if (pkey_type <= 0) { +// #if OPENSSL_VERSION_NUMBER > 0x3000000fL +// pkey_type = pkey_id; +// #else +// PKI_ERROR(PKI_ERR_ALGOR_UNKNOWN, NULL); +// return NULL; +// #endif // End of OPENSSL_VERSION_NUMBER > 0x3000000fL +// } +// PKI_DEBUG("***** OSSL3 UPGRADE: Got PKEY ID %d vs. EVP_PKEY_id() -> %d", pkey_type, EVP_PKEY_type(pkey_id)); + int pkey_type = PKI_X509_KEYPAIR_VALUE_get_id(pkey); + if (!pkey_type) { + PKI_DEBUG("Cannot retrieve the PKEY type for PKEY decrypt."); + return NULL; + } + + // Sets the padding via the CTRL interface + switch (pkey_type) { + + // RSA Algorithm(s) + case EVP_PKEY_RSA: + case EVP_PKEY_RSA2: + case EVP_PKEY_RSA_PSS: { + if (EVP_PKEY_CTX_ctrl(pkey_ctx, pkey_type, EVP_PKEY_OP_DECRYPT, EVP_PKEY_CTRL_RSA_PADDING, padding, NULL) <= 0) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_ENCRYPT_INIT, NULL); + goto err; + } + } break; + + // Default Algorithms + default: + PKI_DEBUG("Public Key Type %d does not support encryption"); + goto err; + } + } + + // Let's get the output buffer size + if (!EVP_PKEY_decrypt(pkey_ctx, NULL, &dec_size, data, data_len)) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_ENCRYPT, NULL); + return NULL; + } + + // Let's allocate the output buffer + if ((out_mem = PKI_MEM_new(dec_size)) == NULL) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return NULL; + } + + // Let's decrypt the data + if (!EVP_PKEY_decrypt(pkey_ctx, out_mem->data, &out_mem->size, data, data_len)) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_ENCRYPT, NULL); + return NULL; + } + + // Free allocated CTX + if (pkey_ctx) EVP_PKEY_CTX_free(pkey_ctx); + pkey_ctx = NULL; // Safety + + // All Done. + return out_mem; + +err: + + // Free allocated memory + if (out_mem) PKI_MEM_free(out_mem); + out_mem = NULL; // Safety + + // Free the CTX from OpenSSL + if (pkey_ctx) EVP_PKEY_CTX_free(pkey_ctx); + pkey_ctx = NULL; // Safety + + // Error condition + return NULL; +} + +PKI_MEM * PKI_X509_KEYPAIR_decrypt(const PKI_X509_KEYPAIR * keypair, + const unsigned char * const data, + size_t const data_len, + int const flags) { + + // Wrapper for lower-layer crypto call + return PKI_X509_KEYPAIR_VALUE_decrypt(PKI_X509_get_value(keypair), data, data_len, flags); +} + +/*! \brief Puts a X509_KEYPAIR to a PKI_MEM */ + +PKI_MEM *PKI_X509_KEYPAIR_get_public_bitstring(const PKI_X509_KEYPAIR * key, + PKI_MEM ** pki_mem) { + + PKI_X509_KEYPAIR_VALUE * k_val = NULL; + // Pointer to the underlying crypto-layer + + // Input checks + if (!key) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return NULL; + } + + // Gets the value and calls the lower-level function + k_val = PKI_X509_get_value(key); + + // All done + return PKI_X509_KEYPAIR_VALUE_get_public_bitstring(k_val, pki_mem); +} + +/*! \brief Puts a X509_KEYPAIR_VALUE's raw key value into a PKI_MEM */ + +PKI_MEM *PKI_X509_KEYPAIR_VALUE_get_public_bitstring(const PKI_X509_KEYPAIR_VALUE * const k_val, + PKI_MEM ** pki_mem) { + + const unsigned char * buff; + int len = 0; + // Output buffer for the raw key + + X509_PUBKEY * xpk = NULL; + // Data structures to extract the raw data + + PKI_MEM * ret = NULL; + // Return data structure + + // Input checks + if (!k_val) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return NULL; + } + + // Sets the Public Key + if(!X509_PUBKEY_set(&xpk, (EVP_PKEY *)k_val)) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_ENCODE, NULL); + return NULL; + } + + // Checks we have a good pointer + if (!xpk) { + PKI_ERROR(PKI_ERR_POINTER_NULL, NULL); + return NULL; + } + + // Extracts the Public Key + if (!X509_PUBKEY_get0_param(NULL, (const unsigned char **)&buff, &len, NULL, xpk)) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_ENCODE, NULL); + X509_PUBKEY_free(xpk); + return NULL; + } + + // Checks if to re-use the passed structure or create a new one + if (pki_mem && *pki_mem) { + // Uses the passed PKI_MEM structure + ret = *pki_mem; + // Frees the data, if any is present + if (ret->data) PKI_Free(ret->data); + ret->data = NULL; + // Allocates the new buffer and copies the data + if (PKI_OK != PKI_MEM_add(ret, buff, (size_t)len)) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return NULL; + } + } else if (pki_mem) { + // Let's generate the return object + if ((ret = PKI_MEM_new_data((size_t)len, buff)) == NULL) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return NULL; + } + // Let's update the output parameter + if (pki_mem) *pki_mem = ret; + } + + // Free heap memory + if (xpk) X509_PUBKEY_free(xpk); + xpk = NULL; + + // All Done + return ret; +} \ No newline at end of file diff --git a/src/crypto/pki_keyparams.c b/src/crypto/pki_keyparams.c new file mode 100644 index 00000000..45cdf33e --- /dev/null +++ b/src/crypto/pki_keyparams.c @@ -0,0 +1,1149 @@ +/* openssl/pki_keyparams.c */ + +#include + +#ifndef _LIBPKI_OID_DEFS_H +#include +#endif + +#ifndef _LIBPKI_PKI_DATATYPES_H +#include +#endif + +/*! + * \brief Allocates memory for a new PKI_KEYPARAMS (for key of type 'scheme') + */ + +PKI_KEYPARAMS *PKI_KEYPARAMS_new(PKI_SCHEME_ID scheme_id, + const PKI_X509_PROFILE * prof) { + + PKI_KEYPARAMS *kp = NULL; + // Pointer to the data structure + + // Allocates the memory + if ((kp = (PKI_KEYPARAMS *)PKI_Malloc(sizeof(PKI_KEYPARAMS))) == NULL) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return NULL; + } + + // Zeroize the Memory + memset(kp, 0, sizeof(PKI_KEYPARAMS)); + + // Sets the security bits + kp->sec_bits = -1; + kp->pq_sec_bits = -1; + + // Checks and Fixes the Scheme + if (scheme_id <= 0) { scheme_id = PKI_SCHEME_DEFAULT; } + + // Sets the scheme + if (PKI_ERR == PKI_KEYPARAMS_set_scheme(kp, scheme_id, PKI_DEFAULT_CLASSIC_SEC_BITS)) { + PKI_DEBUG("ERROR, can not set the scheme (%d)", scheme_id); + PKI_Free(kp); + return NULL; + } + + +#ifdef ENABLE_COMPOSITE + + // Allocates the memory for the stack of keys (composite keys) + if ((kp->comp.k_stack = PKI_STACK_X509_KEYPAIR_new()) == NULL) { + OPENSSL_free(kp); + return NULL; + } + + kp->comp.k_of_n = NULL; + +#endif + + if (prof) { + + // PKI_X509_ALGOR_VALUE *alg = NULL; + char *tmp_s = NULL; + + // Scheme + if (scheme_id <= 0 ) { + if(( tmp_s = PKI_CONFIG_get_value(prof, + "/profile/keyParams/algorithm" )) != NULL ) { + // if((alg = PKI_X509_ALGOR_VALUE_get_by_name(tmp_s)) != NULL ) { + PKI_SCHEME_ID scheme_id = PKI_SCHEME_ID_get_by_name(tmp_s, NULL, NULL); + if (!scheme_id) { + PKI_DEBUG("ERROR, can not get the scheme id for %s", tmp_s); + PKI_Free(tmp_s); + PKI_KEYPARAMS_free(kp); + return NULL; + } + if (PKI_ERR == PKI_KEYPARAMS_set_scheme(kp, scheme_id, -1)) { + PKI_DEBUG("ERROR, can not set the scheme (%d)", scheme_id); + PKI_Free(tmp_s); + PKI_KEYPARAMS_free(kp); + return NULL; + } + // kp->scheme = PKI_X509_ALGOR_VALUE_get_scheme ( alg ); + // } + + // TODO: Remove this debug statement + PKI_DEBUG("Selected ALGOR is %s\n", tmp_s ); + + PKI_Free ( tmp_s ); + }; + } else { + kp->scheme = scheme_id; + } + + // // Get the Profile value of Bits + // if ((tmp_s = PKI_CONFIG_get_value(prof, + // "/profile/keyParams/bits" )) != NULL ) { + // if (PKI_ERR == PKI_KEYPARAMS_set_security_bits(kp, atoi(tmp_s))) { + // PKI_DEBUG("ERROR, can not set the security bits from the profile (%s)!", tmp_s); + // PKI_KEYPARAMS_free(kp); + // PKI_Free(tmp_s); + // return NULL; + // } + // PKI_Free ( tmp_s ); + // } else { + // kp->bits = -1; + // }; + + if( kp->scheme == PKI_SCHEME_UNKNOWN ) kp->scheme = PKI_SCHEME_DEFAULT; + + // Looks for the security bits + if ((tmp_s = PKI_CONFIG_get_value(prof, + "/profile/keyParams/secBits" )) != NULL ) { + // Sets the configured security bits + if (PKI_ERR == PKI_KEYPARAMS_set_security_bits(kp, atoi(tmp_s))) { + PKI_DEBUG("ERROR, can not set the security bits from the profile (%s)!", tmp_s); + PKI_KEYPARAMS_free(kp); + PKI_Free(tmp_s); + return NULL; + } + PKI_Free(tmp_s); + } else { + // Use the default + if (PKI_ERR == PKI_KEYPARAMS_set_scheme(kp, kp->scheme, PKI_DEFAULT_CLASSIC_SEC_BITS)) { + PKI_DEBUG("ERROR, can not set the security bits from the profile (%d)!", PKI_DEFAULT_CLASSIC_SEC_BITS); + PKI_KEYPARAMS_free(kp); + return NULL; + } + } + + // Get the Profile Params + switch (kp->scheme) { + +#if defined(ENABLE_OQS) || defined(ENABLE_OQSPROV) + + case PKI_SCHEME_DILITHIUM: { + if ((tmp_s = PKI_CONFIG_get_value(prof, + "/profile/keyParams/mode" )) != NULL ) { + + if (strncmp_nocase("AES", tmp_s, 3) == 0) { + // Sets the correct algorithm + PKI_KEYPARAMS_set_oqs_key_params(kp, PKI_ALGOR_OQS_PARAM_DILITHIUM_AES); + } + + PKI_Free (tmp_s); + }; + } break; + +#endif + +#ifdef ENABLE_ECDSA + case PKI_SCHEME_ECDSA: { + + // Sets the standard defaults + kp->ec.asn1flags = PKI_EC_KEY_ASN1_DEFAULT; + kp->ec.form = PKI_EC_KEY_FORM_DEFAULT; + + if ((tmp_s = PKI_CONFIG_get_value(prof, + "/profile/keyParams/curveName" )) != NULL) { + PKI_OID *oid = NULL; + + if((oid = PKI_OID_get( tmp_s )) != NULL) { + if((kp->ec.curve = PKI_OID_get_id( oid )) == PKI_ID_UNKNOWN) {; + kp->ec.curve = -1; + }; + PKI_OID_free ( oid ); + } + PKI_Free( tmp_s ); + }; + + if(( tmp_s = PKI_CONFIG_get_value( prof, + "/profile/keyParams/pointType" )) != NULL ) { + if(strncmp_nocase( tmp_s, "uncompressed", 12) == 0 ) { + kp->ec.form = PKI_EC_KEY_FORM_UNCOMPRESSED; + } else if ( strncmp_nocase( tmp_s, "compressed", 10) == 0 ) { + kp->ec.form = PKI_EC_KEY_FORM_COMPRESSED; + } else if ( strncmp_nocase( tmp_s, "hybrid", 6) == 0 ) { + kp->ec.form = PKI_EC_KEY_FORM_HYBRID; + } else { + kp->ec.form = PKI_EC_KEY_FORM_UNKNOWN; + }; + PKI_Free ( tmp_s ); + }; + + if(( tmp_s = PKI_CONFIG_get_value(prof, + "/profile/keyParams/ecParams" )) != NULL ) { + if(strncmp_nocase(tmp_s, "namedCurve", 10) == 0) { + kp->ec.asn1flags = 1; + } else if (strncmp_nocase(tmp_s,"implicitCurve",13) == 0){ + kp->ec.asn1flags = 2; + } else if (strncmp_nocase(tmp_s,"specifiedCurve",14) == 0){ + kp->ec.asn1flags = 0; + } else { + // Defaults to namedCurve + kp->ec.asn1flags = 1; + }; + PKI_Free ( tmp_s ); + } else { + kp->ec.asn1flags = -1; + }; + } break; + +#endif // End of ENABLE_ECDSA + + case PKI_SCHEME_RSA: + case PKI_SCHEME_RSAPSS: { + if ((tmp_s = PKI_CONFIG_get_value(prof, + "/profile/keyParams/bits" )) != NULL ) { + // Sets the configured security bits + if (PKI_ERR == PKI_KEYPARAMS_set_security_bits(kp, atoi(tmp_s))) { + PKI_DEBUG("ERROR, can not set the security bits from the profile (%s)!", tmp_s); + PKI_KEYPARAMS_free(kp); + PKI_Free(tmp_s); + return NULL; + } + PKI_Free(tmp_s); + } + } break; + + default: + PKI_DEBUG("No supported special parameter processing for selected algorithm (%d).", kp->scheme); + } + } + + // All Done + return kp; +}; + +/*! + * \brief Frees the memory associated with a PKI_KEYPARAMS structure + */ + +void PKI_KEYPARAMS_free ( PKI_KEYPARAMS *kp ) { + + if (!kp) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return; + }; + +#ifdef ENABLE_COMPOSITE + + if (kp->comp.k_stack) PKI_STACK_X509_KEYPAIR_free_all(kp->comp.k_stack); + kp->comp.k_stack = NULL; + +#endif + PKI_Free ( kp ); + + return; +}; + +/*! + * \brief Returns the type (PKI_SCHEME_ID) of the PKI_KEYPARAMS + */ + +PKI_SCHEME_ID PKI_KEYPARAMS_get_type(const PKI_KEYPARAMS *kp) { + + if (!kp) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return PKI_SCHEME_UNKNOWN; + } + + return (PKI_SCHEME_ID)kp->scheme; +}; + +/* !\brief Sets the scheme for the key generation. Returns PKI_OK or PKI_ERR. */ + +int PKI_KEYPARAMS_set_scheme(PKI_KEYPARAMS * kp, PKI_SCHEME_ID scheme_id, int sec_bits) { + + int scheme_sec_bits = 0; + int scheme_pq_sec_bits = 0; + // Security bits for the scheme + + // Input checks + if (kp == NULL || scheme_id <= 0) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return PKI_ERR; + } + + // Let's use the default, if nothing was passed + if (sec_bits <= 0) sec_bits = PKI_DEFAULT_CLASSIC_SEC_BITS; + + // Let's check if the scheme supports the sec_bits + if (PKI_ERR == PKI_SCHEME_ID_security_bits(scheme_id, &scheme_sec_bits, &scheme_pq_sec_bits)) { + PKI_DEBUG("Can not get security bits for scheme %d", scheme_id); + return PKI_ERR; + } + + // If the returned value is positive, it means the scheme only supports + // a single value for the size. + if (scheme_sec_bits > 0) { + // Returns an error if the sec_bits were actually set + if (scheme_sec_bits < sec_bits) { + PKI_DEBUG("Scheme %d only supports %d bits", scheme_id, scheme_sec_bits); + return PKI_ERR; + } + } + + // Sets the security bits + kp->sec_bits = sec_bits; + + // Sets the PQ security bits + kp->pq_sec_bits = scheme_pq_sec_bits; + + // If the scheme supports more than one value (i.e., -1), + // it means that we need to look in the switch below. + switch (scheme_id) { + + case PKI_SCHEME_DSA: { + kp->scheme = PKI_SCHEME_DSA; + kp->pkey_type = EVP_PKEY_DSA; + if (sec_bits <= 112) { kp->dsa.bits = 1024 ; kp->sec_bits = 112; } + else if (sec_bits <= 128) { kp->dsa.bits = 3072; kp->sec_bits = 128; } + else { + PKI_DEBUG("Security Bits value not supported (%d) (max: 128)", sec_bits); + return PKI_ERR; + } + kp->bits = kp->dsa.bits; + } break; + + case PKI_SCHEME_RSAPSS: + case PKI_SCHEME_RSA: { + if (scheme_id == PKI_SCHEME_RSAPSS) { + kp->pkey_type = EVP_PKEY_RSA_PSS; + kp->scheme = PKI_SCHEME_RSAPSS; + } else { + kp->pkey_type = EVP_PKEY_RSA; + kp->scheme = PKI_SCHEME_RSA; + } + // Sec sec_bits Sizes + if (sec_bits <= 112 ) { kp->rsa.bits = 2048; kp->sec_bits = 112; } + else if (sec_bits <= 128 ) { kp->rsa.bits = 3072; kp->sec_bits = 128; } + else if (sec_bits <= 192 ) { kp->rsa.bits = 4096; kp->sec_bits = 192; } + else if (sec_bits <= 256 ) { kp->rsa.bits = 8192; kp->sec_bits = 256; } + else if (sec_bits <= 384 ) { kp->rsa.bits = 16384; kp->sec_bits = 384; } + else { + PKI_DEBUG("Security Bits value not supported (%d)", sec_bits); + return -1; + } + kp->bits = kp->rsa.bits; + } break; + + case PKI_SCHEME_ECDSA: { + kp->scheme = PKI_SCHEME_ECDSA; + kp->pkey_type = EVP_PKEY_EC; + if (sec_bits <= 112) { kp->ec.curve = NID_secp224r1 ; kp->sec_bits = 112; } + else if (sec_bits <= 128) { kp->ec.curve = NID_X9_62_prime256v1; kp->sec_bits = 128; } + else if (sec_bits <= 192) { kp->ec.curve = NID_secp384r1; kp->sec_bits = 192; } + else if (sec_bits <= 256) { kp->ec.curve = NID_secp521r1; kp->sec_bits = 256; } + else { + PKI_DEBUG("Security Bits value not supported (%d)", sec_bits); + return -1; + } + kp->ec.asn1flags = -1; + kp->ec.form = PKI_EC_KEY_FORM_UNKNOWN; + } break; + + case PKI_SCHEME_ED448: + case PKI_SCHEME_X448: { + if (scheme_id == PKI_SCHEME_ED448) { + kp->scheme = PKI_SCHEME_ED448; + kp->pkey_type = EVP_PKEY_ED448; + } else { + kp->scheme = PKI_SCHEME_X448; + kp->pkey_type = EVP_PKEY_X448; + } + if (sec_bits > 224) { + PKI_DEBUG("Security Bits value not supported (%d)", sec_bits); + return -1; + } + kp->sec_bits = 224; + } break; + + case PKI_SCHEME_ED25519: + case PKI_SCHEME_X25519: { + if (scheme_id == PKI_SCHEME_ED25519) { + kp->scheme = PKI_SCHEME_ED25519; + kp->pkey_type = EVP_PKEY_ED25519; + } else { + kp->scheme = PKI_SCHEME_X25519; + kp->pkey_type = EVP_PKEY_X25519; + } + if (sec_bits > 128) { + PKI_DEBUG("Security Bits value not supported (%d)", sec_bits); + return -1; + } + kp->sec_bits = 128; + } break; + +#if defined(ENABLE_OQS) || defined(ENABLE_OQSPROV) + + // ============================================= + // Post Quantum Cryptography: Digital Signatures + // ============================================= + + case PKI_SCHEME_FALCON: { + kp->scheme = PKI_SCHEME_FALCON; + if (sec_bits <= 128) { kp->oqs.algId = PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_FALCON512_NAME); kp->sec_bits = 128; } + else if (sec_bits <= 256) { kp->oqs.algId = PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_FALCON1024_NAME); kp->sec_bits = 256; } + else { + PKI_DEBUG("Security Bits value not supported (%d)", sec_bits); + return -1; + } + kp->pkey_type = kp->oqs.algId; + } break; + + case PKI_SCHEME_DILITHIUM: { + kp->scheme = PKI_SCHEME_DILITHIUM; + if (sec_bits <= 128) { kp->oqs.algId = PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_DILITHIUM2_NAME); kp->sec_bits = 128; } + else if (sec_bits <= 192) { kp->oqs.algId = PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_DILITHIUM3_NAME); kp->sec_bits = 192; } + else if (sec_bits <= 256) { kp->oqs.algId = PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_DILITHIUM5_NAME); kp->sec_bits = 256; } + else { + PKI_DEBUG("Security Bits value not supported (%d)", sec_bits); + return -1; + } + kp->pkey_type = kp->oqs.algId; + } break; + + // TODO: We need to change from the robust to the + // fast implementations as the robust is not + // going to be standardized + case PKI_SCHEME_SPHINCS: { + kp->scheme = PKI_SCHEME_SPHINCS; + if (sec_bits <= 128) { kp->oqs.algId = PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_SPHINCS128_F_SIMPLE_NAME); kp->sec_bits = 128; } + else if (sec_bits <= 192) { kp->oqs.algId = PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_SPHINCS192_F_SIMPLE_NAME); kp->sec_bits = 128; } + else { + PKI_DEBUG("Security Bits value not supported (%d)", sec_bits); + return -1; + } + kp->pkey_type = kp->oqs.algId; + } break; + + case PKI_SCHEME_KYBER: { + kp->scheme = PKI_SCHEME_KYBER; + if (sec_bits <= 128) { kp->oqs.algId = PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_KYBER512_NAME); kp->sec_bits = 128; } + else if (sec_bits <= 192) { kp->oqs.algId = PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_KYBER512_NAME); kp->sec_bits = 192; } + else if (sec_bits <= 256) { kp->oqs.algId = PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_KYBER512_NAME); kp->sec_bits = 256; } + else { + PKI_DEBUG("Security Bits value not supported (%d)", sec_bits); + return -1; + } + kp->pkey_type = kp->oqs.algId; + } break; + +#endif // End of ENABLE_OQS || ENABLE_OQSPROV + +#ifdef ENABLE_COMBINED + case PKI_SCHEME_COMBINED: { + // No need to translate, output the input + ret = sec_bits; + } break; +#endif + +#ifdef ENABLE_COMPOSITE + + // ============================= + // Native Composite Cryptography + // ============================= + + case PKI_SCHEME_COMPOSITE: { + kp->scheme = PKI_SCHEME_COMPOSITE; + kp->pkey_type = PKI_ID_get_by_name(OPENCA_ALG_PKEY_EXP_COMP_NAME); + kp->sec_bits = sec_bits; + } break; + +#if defined(ENABLE_OQS) || defined (ENABLE_OQSPROV) + // =============================== + // Explicit Composite Combinations + // =============================== + + // Explicit Composite Crypto Schemes + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_RSA: { + kp->scheme = PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_RSA; + kp->oqs.algId = OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_RSA_SHA256_NAME); + kp->pkey_type = kp->oqs.algId; + kp->sec_bits = 192; + kp->pq_sec_bits = 192; + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_RSAPSS: { + kp->scheme = PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_RSAPSS; + kp->oqs.algId = OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_RSAPSS_SHA256_NAME); + kp->pkey_type = kp->oqs.algId; + kp->sec_bits = 192; + kp->pq_sec_bits = 192; + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_P256: { + kp->scheme = PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_P256; + kp->oqs.algId = OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_P256_SHA256_NAME); + kp->pkey_type = kp->oqs.algId; + kp->sec_bits = 192; + kp->pq_sec_bits = 192; + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_BRAINPOOL256: { + kp->scheme = PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_BRAINPOOL256; + kp->oqs.algId = OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_BRAINPOOL256_SHA256_NAME); + kp->pkey_type = kp->oqs.algId; + kp->sec_bits = 192; + kp->pq_sec_bits = 192; + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_ED25519: { + kp->scheme = PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_ED25519; + kp->oqs.algId = OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM3_ED25519_NAME); + kp->pkey_type = kp->oqs.algId; + kp->sec_bits = 192; + kp->pq_sec_bits = 192; + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_P384: { + kp->scheme = PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_P384; + kp->oqs.algId = OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_P384_SHA384_NAME); + kp->pkey_type = kp->oqs.algId; + kp->sec_bits = 256; + kp->pq_sec_bits = 256; + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_BRAINPOOL384: { + kp->scheme = PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_BRAINPOOL384; + kp->oqs.algId = OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_BRAINPOOL384_SHA384_NAME); + kp->pkey_type = kp->oqs.algId; + kp->sec_bits = 256; + kp->pq_sec_bits = 256; + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_ED448: { + kp->scheme = PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_ED448; + kp->oqs.algId = OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_ED448_NAME); + kp->pkey_type = kp->oqs.algId; + kp->sec_bits = 256; + kp->pq_sec_bits = 256; + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_P256: { + kp->scheme = PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_P256; + kp->oqs.algId = OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_FALCON512_P256_SHA256_NAME); + kp->pkey_type = kp->oqs.algId; + kp->sec_bits = 128; + kp->pq_sec_bits = 128; + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_BRAINPOOL256: { + kp->scheme = PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_BRAINPOOL256; + kp->oqs.algId = OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_FALCON512_BRAINPOOL256_SHA256_NAME); + kp->pkey_type = kp->oqs.algId; + kp->sec_bits = 128; + kp->pq_sec_bits = 128; + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_ED25519: { + kp->scheme = PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_ED25519; + kp->oqs.algId = OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_FALCON512_ED25519_NAME); + kp->pkey_type = kp->oqs.algId; + kp->sec_bits = 128; + kp->pq_sec_bits = 128; + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_RSA: { + kp->scheme = PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_RSA; + kp->oqs.algId = OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_FALCON512_RSA_SHA256_NAME); + kp->pkey_type = kp->oqs.algId; + kp->sec_bits = 128; + kp->pq_sec_bits = 128; + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_FALCON1024_P521: { + kp->scheme = PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_FALCON1024_P521; + kp->oqs.algId = OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_FALCON1024_P521_SHA512_NAME); + kp->pkey_type = kp->oqs.algId; + kp->sec_bits = 256; + kp->pq_sec_bits = 256; + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_FALCON1024_RSA: { + kp->scheme = PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_FALCON1024_RSA; + kp->oqs.algId = OBJ_sn2nid(OPENCA_ALG_PKEY_EXP_COMP_EXPLICIT_DILITHIUM5_FALCON1024_RSA_SHA256_NAME); + kp->pkey_type = kp->oqs.algId; + kp->sec_bits = 256; + kp->pq_sec_bits = 256; + } break; + +#endif // End of ENABLE_OQS || ENABLE_OQSPROV + +#endif // End of ENABLE_COMPOSITE + + default: { + // Sets the sec_bits + PKI_ERROR(PKI_ERR_ALGOR_UNKNOWN, "Scheme not supported (%d)", scheme_id); + return PKI_ERR; + } + } + + // All Done + return PKI_OK; +}; + +/* !\brief Sets the curve for key generation (and resets the scheme to EC) */ +int PKI_KEYPARAMS_set_curve(PKI_KEYPARAMS * kp, + const char * curveName, + PKI_EC_KEY_FORM curveForm, + PKI_EC_KEY_ASN1 asn1flags) { + +#ifdef ENABLE_ECDSA + + int curveId = 0; + + // Input Checks + if (!kp || !curveName) return PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + + // Let's get the curve Identifier + if ((curveId = PKI_OID_get_id(PKI_OID_get(curveName))) == PKI_ID_UNKNOWN) + return PKI_ERR; + + // Let's now set the curve name and the scheme (to be sure) + kp->scheme = PKI_SCHEME_ECDSA; + kp->ec.curve = curveId; + + // Sets the Form for the curve (if specified) + if (curveForm > 0) kp->ec.form = curveForm; + + // Sets the flags + if (asn1flags > -1) kp->ec.asn1flags = asn1flags; + + // All Done + return PKI_OK; + +#else + return PKI_ERR; +#endif +}; + + +int PKI_KEYPARAMS_set_security_bits(PKI_KEYPARAMS * kp, int sec_bits) { + + // Input Checks + if (!kp) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return PKI_ERR; + } + + if (kp->scheme == PKI_SCHEME_UNKNOWN) { + PKI_ERROR(PKI_ERR_GENERAL, "Unknown scheme when setting the bits size"); + return PKI_ERR; + } + + // Assigns the Bits + // if (kp->bits <= 0 && sec_bits > 0) kp->bits = sec_bits; + + if (PKI_ERR == PKI_KEYPARAMS_set_scheme(kp, kp->scheme, sec_bits)) { + PKI_DEBUG("Can not set the KEY_PARAMS scheme (%s at %d bits)", + PKI_SCHEME_ID_get_parsed(kp->scheme), sec_bits); + return PKI_ERR; + } + + // // Retrieves the default bits size for the scheme (sec level) + // if (!PKI_SCHEME_ID_security_bits(kp->scheme, &sec_bits, NULL)) { + // PKI_ERROR(PKI_ERR_GENERAL, "Can not retrieve the default sec bits for scheme %d", kp->scheme); + // return PKI_ERR; + // } + + // Let's update the key params, if we got good values + // (i.e., the scheme is not just a generic one) + if (kp->sec_bits > 0) { + + // Sets the bits size from the security bits + kp->bits = PKI_SCHEME_ID_get_bitsize(kp->scheme, kp->sec_bits); + + // Returns the bits size + return PKI_OK; + } + + // All Done + return PKI_OK; +}; + +/*! \brief Sets the bits size for key generation */ +int PKI_KEYPARAMS_set_key_size(PKI_KEYPARAMS * kp, int bits) { + + int sec_bits = -1; + + // Input Checks + if (!kp) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return PKI_ERR; + } + + switch (kp->scheme) { + case PKI_SCHEME_RSA: + case PKI_SCHEME_RSAPSS: { + // Assigns the bits + kp->rsa.bits = bits; + } break; + + case PKI_SCHEME_DSA: { + // Assigns the bits + kp->dsa.bits = bits; + } break; + + default: { + PKI_ERROR(PKI_ERR_GENERAL, "Scheme not supported when setting the bits size (scheme id: %d)", kp->scheme); + return PKI_ERR; + } + } + + // Updates the secBits + if (bits <= 50 ) { bits = 50; sec_bits = 32; } + else if (bits <= 512 ) { bits = 512; sec_bits = 80; } + else if (bits <= 1024 ) { bits = 1024; sec_bits = 96; } + else if (bits <= 1536 ) { bits = 1536; sec_bits = 110; } + // Acceptable bit sizes + else if (bits <= 2048 ) { bits = 2048; sec_bits = 112; } + else if (bits <= 3072 ) { bits = 3072; sec_bits = 128; } + else if (bits <= 4096 ) { bits = 4096; sec_bits = 192; } + // Over the top bit sizes + else if (bits <= 7680 ) { bits = 7680; sec_bits = 256; } + else { + PKI_DEBUG("Bits value not supported (%d)", bits); + return -1; + } + + // Sets the security bits + kp->sec_bits = PKI_KEYPARAMS_set_security_bits(kp, sec_bits); + + // All Done + return PKI_OK; +}; + +#if defined(ENABLE_OQS) || defined (ENABLE_OQSPROV) + +/*! \brief Sets the bits size for key generation */ +int PKI_KEYPARAMS_set_oqs_key_params(PKI_KEYPARAMS * kp, PKI_ALGOR_OQS_PARAM algParam) { + + // Input Checks + if (!kp || kp->bits <= 0) return + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + + if (kp->scheme == PKI_SCHEME_UNKNOWN) + return PKI_ERROR(PKI_ERR_GENERAL, "Unknown scheme when setting the bits size"); + + switch (kp->scheme) { + + // ============================================= + // Post Quantum Cryptography: Digital Signatures + // ============================================= + + + case PKI_SCHEME_DILITHIUM: { + if (algParam != PKI_ALGOR_OQS_PARAM_DILITHIUM_AES) { + return PKI_ERROR(PKI_ERR_GENERAL, + "Dilithium only supports the AES parameter"); + }; + if (kp->bits <= 128) { + kp->oqs.algId = PKI_ALGOR_ID_DILITHIUM2; + } else if (kp->bits <= 192) { + kp->oqs.algId = PKI_ALGOR_ID_DILITHIUM3; + } else { + kp->oqs.algId = PKI_ALGOR_ID_DILITHIUM5; + } + } break; + + case PKI_SCHEME_FALCON: { + if (kp->bits <= 128) { + kp->oqs.algId = PKI_ALGOR_ID_FALCON512; + } else { + kp->oqs.algId = PKI_ALGOR_ID_FALCON1024; + } + } break; + + case PKI_SCHEME_SPHINCS: { + if (algParam != PKI_ALGOR_OQS_PARAM_SPHINCS_SHAKE) { + return PKI_ERROR(PKI_ERR_GENERAL, + "SPHINCS+ only supports the SHAKE parameter"); + }; + if (kp->bits <= 128) { + kp->oqs.algId = PKI_ALGOR_ID_SPHINCS_SHA2_128_F; + } else if (kp->bits <= 192) { + kp->oqs.algId = PKI_ALGOR_ID_SPHINCS_SHA2_192_F; + } else { + PKI_DEBUG("SPHINCS+ WITH SHAKE only supports 128 bits of security."); + return PKI_ERR; + } + } break; + + default: { + PKI_DEBUG("Trying to set OQS param [%d] on a non-OQS algorithm [%d]", algParam, kp->scheme); + return PKI_ERR; + } + } + + // All Done + return PKI_OK; +} + +#endif + +#ifdef ENABLE_COMPOSITE + +/*! \brief Sets the bits size for key generation */ +int PKI_KEYPARAMS_add_key(PKI_KEYPARAMS * kp, PKI_X509_KEYPAIR * key) { + +#ifdef ENABLE_COMPOSITE + + int add_key_id = -1; + int last_key_id = -1; + int next_required_id = -1; + // Adding, Last, and Next Key Types + + int key_sk_elements = 0; + // Number of components for the key + + PKI_X509_KEYPAIR_STACK * key_sk = NULL; + // Pointer to the stack of components for the key + + // Input Checks + if (!kp || !kp->comp.k_stack) { + return PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + } + + // Let's set the key stack + key_sk = kp->comp.k_stack; + + // Let's get the ID for the that is being added + // add_key_id = EVP_PKEY_id((EVP_PKEY *)key->value); + add_key_id = PKI_X509_KEYPAIR_get_id(key); + // PKI_DEBUG("***** OSSL3 UPGRADE: GOT KEY ID %d vs. EVP_PKEY_id() -> %d", add_key_id, EVP_PKEY_id((EVP_PKEY *)key->value)); + if (add_key_id <= NID_undef) { + PKI_DEBUG("Cannot retrieve the type of key being added."); + return PKI_ERR; + } + + // Let's check if we have any key in the stack already + if ((key_sk_elements = PKI_STACK_X509_KEYPAIR_elements(key_sk)) > 0) { + + const PKI_X509_KEYPAIR_VALUE * evp_pkey; + // Pointer to the OSSL key pointer + + // Let's get the ID from the latest key on the stack + evp_pkey = PKI_X509_get_value(PKI_STACK_X509_KEYPAIR_get_num(key_sk, key_sk_elements - 1)); + if (!evp_pkey) { + PKI_DEBUG("Cannot verify the type of key component #%d", key_sk_elements); + return PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, NULL); + } + +// // Gets the Last Key's ID +// int last_key = PKI_X509_KEYPAIR_VALUE_get_id(evp_pkey); +// last_key_id = EVP_PKEY_type(last_key); +// if (last_key_id <= 0) { +// #if OPENSSL_VERSION_NUMBER > 0x3000000fL +// last_key_id = last_key; +// #else +// PKI_ERROR(PKI_ERR_ALGOR_UNKNOWN, NULL); +// return PKI_ERR; +// #endif // End of OPENSSL_VERSION_NUMBER > 0x3000000fL + + last_key_id = PKI_X509_KEYPAIR_VALUE_get_id(evp_pkey); + if (!last_key_id) { + PKI_DEBUG("Cannot get the type of key to be added to the component #%d", key_sk_elements); + return PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, NULL); + } + // PKI_DEBUG("***** OSSL3 UPGRADE: GOT KEY ID %d vs. EVP_PKEY_id() -> %d", add_key_id, EVP_PKEY_id((EVP_PKEY *)key->value)); + } + + // Checks ID requirements (explicit composite only) + switch (kp->scheme) { + + case PKI_SCHEME_COMPOSITE: { + next_required_id = 0; // No Required ID (any can work) + } break; + +#if defined(ENABLE_OQS) || defined(ENABLE_OQSPROV) + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_RSA: { + + // NID_dilithium3 + if (last_key_id <= 0) { + next_required_id = PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_DILITHIUM3_NAME); + // NID_rsaEncryption + } else if (last_key_id == PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_DILITHIUM3_NAME)) { + next_required_id = NID_rsaEncryption; + } else { + PKI_ERROR(PKI_ERR_ALGOR_COMPOSITE_EXPLICIT_WRONG_COMPONENT, NULL); + return PKI_ERR; + } + + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_RSAPSS: { + + // NID_dilithium3 + if (last_key_id <= 0) { + next_required_id = PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_DILITHIUM3_NAME); + // NID_rsaEncryption + } else if (last_key_id == PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_DILITHIUM3_NAME)) { + next_required_id = NID_rsassaPss; + } else { + PKI_ERROR(PKI_ERR_ALGOR_COMPOSITE_EXPLICIT_WRONG_COMPONENT, NULL); + return PKI_ERR; + } + + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_BRAINPOOL256: { + // NID_dilithium3 + if (last_key_id <= 0) { + next_required_id = PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_DILITHIUM3_NAME); + // NID_brainpoolP256r1 + } else if (last_key_id == PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_DILITHIUM3_NAME)) { + // Requires an EC key + next_required_id = NID_X9_62_id_ecPublicKey; + // Requires the Brainpool P256 curve + if (NID_brainpoolP256r1 != PKI_X509_KEYPAIR_get_curve(key)) { + PKI_ERROR(PKI_ERR_ALGOR_COMPOSITE_EXPLICIT_WRONG_COMPONENT, NULL); + return PKI_ERR; + } + } else { + PKI_ERROR(PKI_ERR_ALGOR_COMPOSITE_EXPLICIT_WRONG_COMPONENT, NULL); + return PKI_ERR; + } + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM3_ED25519: { + // NID_dilithium3 + if (last_key_id <= 0) { + next_required_id = PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_DILITHIUM3_NAME); + // NID_secp256v1 + } else if (last_key_id == PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_DILITHIUM3_NAME)) { + next_required_id = NID_ED25519; + } else { + PKI_ERROR(PKI_ERR_ALGOR_COMPOSITE_EXPLICIT_WRONG_COMPONENT, NULL); + return PKI_ERR; + } + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_P384: { + // NID_dilithium5 + if (last_key_id <= 0) { + next_required_id = PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_DILITHIUM5_NAME); + // NID_secp384r1 + } else if (last_key_id == PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_DILITHIUM5_NAME)) { + // Requires an EC key + next_required_id = NID_X9_62_id_ecPublicKey; + // Requires the secp384r1 curve + if (NID_secp384r1 != PKI_X509_KEYPAIR_get_curve(key)) { + PKI_ERROR(PKI_ERR_ALGOR_COMPOSITE_EXPLICIT_WRONG_COMPONENT, NULL); + return PKI_ERR; + } + // EC_KEY * ec = EVP_PKEY_get0_EC_KEY((EVP_PKEY *)key->value); + // if (!ec) { + // PKI_ERROR(PKI_ERR_POINTER_NULL, NULL); + // return PKI_ERR; + // } + // const EC_GROUP * pkey_group = EC_KEY_get0_group(ec); + // if (NID_secp384r1 != EC_GROUP_get_curve_name(pkey_group)) { + // PKI_ERROR(PKI_ERR_ALGOR_COMPOSITE_EXPLICIT_WRONG_COMPONENT, NULL); + // return PKI_ERR; + // } + } else { + PKI_ERROR(PKI_ERR_ALGOR_COMPOSITE_EXPLICIT_WRONG_COMPONENT, NULL); + return PKI_ERR; + } + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_BRAINPOOL384: { + // NID_dilithium5 + if (last_key_id <= 0) { + next_required_id = PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_DILITHIUM5_NAME); + // NID_brainpoolP384r1 + } else if (last_key_id == PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_DILITHIUM5_NAME)) { + // Requires an EC key + next_required_id = NID_X9_62_id_ecPublicKey; + // Requires the Brainpool P384 curve + if (NID_brainpoolP384r1 != PKI_X509_KEYPAIR_get_curve(key)) { + PKI_ERROR(PKI_ERR_ALGOR_COMPOSITE_EXPLICIT_WRONG_COMPONENT, NULL); + return PKI_ERR; + } + } else { + PKI_ERROR(PKI_ERR_ALGOR_COMPOSITE_EXPLICIT_WRONG_COMPONENT, NULL); + return PKI_ERR; + } + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_ED448: { + // NID_dilithium5 + if (last_key_id <= 0) { + next_required_id = PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_DILITHIUM5_NAME); + // NID_ED448 + } else if (last_key_id == PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_DILITHIUM5_NAME)) { + next_required_id = NID_ED448; + } else { + PKI_ERROR(PKI_ERR_ALGOR_COMPOSITE_EXPLICIT_WRONG_COMPONENT, NULL); + return PKI_ERR; + } + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_P256: { + // NID_falcon512 + if (last_key_id <= 0) { + next_required_id = PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_FALCON512_NAME); + // NID_X9_62_prime256v1 + } else if (last_key_id == PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_FALCON512_NAME)) { + // Requires an EC key + next_required_id = NID_X9_62_id_ecPublicKey; + // Requires the prime256v1 curve + if (NID_X9_62_prime256v1 != PKI_X509_KEYPAIR_get_curve(key)) { + PKI_ERROR(PKI_ERR_ALGOR_COMPOSITE_EXPLICIT_WRONG_COMPONENT, NULL); + return PKI_ERR; + } + } else { + PKI_ERROR(PKI_ERR_ALGOR_COMPOSITE_EXPLICIT_WRONG_COMPONENT, NULL); + return PKI_ERR; + } + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_BRAINPOOL256: { + // NID_falcon512 + if (last_key_id <= 0) { + next_required_id = PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_FALCON512_NAME); + // NID_brainpoolP256r1 + } else if (last_key_id == PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_FALCON512_NAME)) { + // Requires an EC key + next_required_id = NID_X9_62_id_ecPublicKey; + // Requires the Brainpool P256 curve + if (NID_brainpoolP256r1 != PKI_X509_KEYPAIR_get_curve(key)) { + PKI_ERROR(PKI_ERR_ALGOR_COMPOSITE_EXPLICIT_WRONG_COMPONENT, NULL); + return PKI_ERR; + } + } else { + PKI_ERROR(PKI_ERR_ALGOR_COMPOSITE_EXPLICIT_WRONG_COMPONENT, NULL); + return PKI_ERR; + } + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_ED25519: { + // NID_falcon512 + if (last_key_id <= 0) { + next_required_id = PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_FALCON512_NAME); + // NID_ED25519 + } else if (last_key_id == PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_FALCON512_NAME)) { + next_required_id = NID_ED25519; + } else { + PKI_ERROR(PKI_ERR_ALGOR_COMPOSITE_EXPLICIT_WRONG_COMPONENT, NULL); + return PKI_ERR; + } + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_FALCON512_RSA: { + // NID_falcon512 + if (last_key_id <= 0) { + next_required_id = PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_FALCON512_NAME); + // NID_rsaEncryption + } else if (last_key_id == PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_FALCON512_NAME)) { + next_required_id = NID_rsaEncryption; + } else { + PKI_ERROR(PKI_ERR_ALGOR_COMPOSITE_EXPLICIT_WRONG_COMPONENT, NULL); + return PKI_ERR; + } + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_FALCON1024_P521: { + // NID_dilithium5 + if (last_key_id <= 0) { + next_required_id = PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_DILITHIUM5_NAME); + // NID_falcon1024 + } else if (last_key_id == PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_DILITHIUM5_NAME)) { + next_required_id = PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_FALCON1024_NAME); + // NID_secp521r1 + } else if (last_key_id == PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_FALCON1024_NAME)) { + // Requires an EC key + next_required_id = NID_X9_62_id_ecPublicKey; + // Requires the Brainpool P256 curve + if (NID_secp521r1 != PKI_X509_KEYPAIR_get_curve(key)) { + PKI_ERROR(PKI_ERR_ALGOR_COMPOSITE_EXPLICIT_WRONG_COMPONENT, NULL); + return PKI_ERR; + } + } else { + PKI_ERROR(PKI_ERR_ALGOR_COMPOSITE_EXPLICIT_WRONG_COMPONENT, NULL); + return PKI_ERR; + } + } break; + + case PKI_SCHEME_COMPOSITE_EXPLICIT_DILITHIUM5_FALCON1024_RSA: { + // NID_dilithium5 + if (last_key_id <= 0) { + next_required_id = PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_DILITHIUM5_NAME); + // NID_falcon1024 + } else if (last_key_id == PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_DILITHIUM5_NAME)) { + next_required_id = PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_FALCON1024_NAME); + // NID_rsaEncryption + } else if (last_key_id == PKI_ID_get_by_name(OPENCA_ALG_PKEY_PQC_FALCON1024_NAME)) { + next_required_id = NID_rsaEncryption; + } else { + PKI_ERROR(PKI_ERR_ALGOR_COMPOSITE_EXPLICIT_WRONG_COMPONENT, NULL); + return PKI_ERR; + } + } break; + +#endif // End of ENABLE_OQS || ENABLE_OQSPROV + + default: { + // Not Handled + next_required_id = -1; + } + + } + + if (next_required_id > 0 && next_required_id != add_key_id) { + PKI_DEBUG("Key type (%d) is not the right one (expected: %d)", + add_key_id, next_required_id); + PKI_ERROR(PKI_ERR_ALGOR_COMPOSITE_EXPLICIT_WRONG_COMPONENT, NULL); + return PKI_ERR; + } + + // Checks we have a good stack + if (PKI_STACK_X509_KEYPAIR_push(kp->comp.k_stack, key) <= 0) { + PKI_DEBUG("Cannot add a component key to the composite one"); + PKI_ERROR(PKI_ERR_ALGOR_ADD, NULL); + return PKI_ERR; + } + + // All Done + return PKI_OK; + +#else + + // No Composite Support + return PKI_ERR; + +#endif // End of ENABLE_COMPOSITE + +} + +/*! \brief Sets the k_of_n parameter for Composite keys */ +int PKI_KEYPARAMS_set_kofn(PKI_KEYPARAMS * kp, int kofn) { + + if (!kp) return PKI_ERR; + + kp->comp.k_of_n = ASN1_INTEGER_new(); + if (!kp->comp.k_of_n) return PKI_ERR; + + if (kofn > 0) { + ASN1_INTEGER_set(kp->comp.k_of_n, kofn); + } else { + ASN1_INTEGER_set(kp->comp.k_of_n, 1); + } + + return PKI_OK; +} + +#endif // ENABLE_COMPOSITE \ No newline at end of file diff --git a/src/crypto/pki_oid.c b/src/crypto/pki_oid.c new file mode 100644 index 00000000..ae620771 --- /dev/null +++ b/src/crypto/pki_oid.c @@ -0,0 +1,209 @@ +/* OID management for libpki */ + +#include + +const PKI_CONFIG * PKI_OID_load (const char *uri ) { + const PKI_CONFIG *oidConf = NULL; + + if(( oidConf = PKI_CONFIG_load(uri)) == NULL ) { + return NULL; + } + + return oidConf; +} + + +/*! + * \brief Create a new OID object + * + * Create a new OID by using its name. It returns a PKI_OID + * pointer if successful, otherwise it returns NULL + */ + +PKI_OID *PKI_OID_new(const char *oid, const char *name, const char *descr ) { + PKI_OID *ret = NULL; + int nid = NID_undef; + + if( !oid && !name && !descr ) return NULL; + + /* Check if the object already exists */ + if( ((nid = OBJ_sn2nid(name)) != NID_undef) || + ((nid = OBJ_ln2nid(name)) != NID_undef) ) + ret = OBJ_nid2obj(nid); + + if(!ret) { + /* If it does not exists, then create it */ + (void) OBJ_create( oid, name, descr ); + + if( ((nid = OBJ_sn2nid(name)) != NID_undef) || + ((nid = OBJ_ln2nid(name)) != NID_undef) ) + ret = OBJ_nid2obj(nid); + } + + /* If successful it returns the new Object, otherwise it + return NULL */ + return ( ret ); +} + +/*! \brief Returns the OID associated with a PKI_ID */ + +PKI_OID *PKI_OID_new_id ( PKI_ID id ) { + PKI_OID *oid = NULL; + + oid = OBJ_nid2obj(id); + + return ( oid ); +} + +/*! + * \brief Free memory associated with a PKI_OID structure + * + * This function frees the memory associated with the provided + * pointer to a PKI_OID structure. + */ + +void PKI_OID_free ( PKI_OID *oid ) { + + if( !oid ) return; + + ASN1_OBJECT_free ( oid ); + + return; +} + +void PKI_OID_free_void ( void *buf ) { + if( !buf ) return; + PKI_OID_free( (PKI_OID *) buf); +} + +/*! \brief See PKI_OID_new_text. */ + +PKI_OID *PKI_OID_get( const char *name ) { + return PKI_OID_new_text ( name ); +} + +/*! + * \brief Retrieve a pointer to an OID + * + * This function retrieves an OID pointer from the passed name. + * Check also the configuration options. + */ + +PKI_OID *PKI_OID_new_text ( const char *name ) { + + PKI_OID *ret = NULL; + // return value + + // Check the input + if (!name) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return NULL; + } + + // Try to get the OID from the OpenSSL internal DB + ret = OBJ_txt2obj ( name, 0 ); + if (ret == NID_undef) { + // If not found, try to get it from the short name + ret = OBJ_nid2obj(OBJ_sn2nid(name)); + if (ret == NID_undef) { + // If not found, try to get it from the long name + ret = OBJ_nid2obj(OBJ_ln2nid(name)); + } + } + + // All Done + return ret ; +} + +/*! + * \brief Returns a duplicate of the passed PKI_OID structure + */ + +PKI_OID *PKI_OID_dup( const PKI_OID *a ) { + PKI_OID *ret = NULL; + + if( !a ) return ( NULL ); + + ret = OBJ_dup( a ); + return ( ret ); +} + +/*! + * \brief Compares two PKI_OID and returns 0 if they match + */ + +int PKI_OID_cmp( const PKI_OID *a, const PKI_OID *b ) { + + if ( !a || !b ) { + return(-1); + } + + return ( OBJ_cmp ( a, b )); +} + +/*! \brief Returns the PKI_ID of the object if recognized */ + +PKI_ID PKI_OID_get_id ( const PKI_OID *a ) { + + PKI_ID ret = PKI_ID_UNKNOWN; + + if ( !a ) return ( ret ); + + ret = OBJ_obj2nid ( a ); + + if( ret == NID_undef ) { + return PKI_ID_UNKNOWN; + } + + return ret; +} + +/*! \brief Return the description associated with a PKI_OID object */ + +const char * PKI_OID_get_descr ( const PKI_OID *a ) { + + int nid; + + if( !a ) return ("Unknown"); + + nid = PKI_OID_get_id( a ); + + if( nid != NID_undef ) { + return ( OBJ_nid2ln( nid ) ); + } + + return ("Unknown"); +} + +/*! \brief Returns a new allocated string representation of an OID */ + +char * PKI_OID_get_str ( const PKI_OID *a ) { + + char *ret = NULL; + BUF_MEM *buf_mem = NULL; + BIO *mem = NULL; + + /* Check the Input */ + if( !a ) return NULL; + + if((mem = BIO_new(BIO_s_mem())) == NULL ) { + return ( NULL ); + } + + i2a_ASN1_OBJECT(mem, (ASN1_OBJECT *)a); + + /* Copy the data from the BIO to the PKI_MEM structure */ + BIO_get_mem_ptr(mem, &buf_mem); + + if( ( ret = PKI_Malloc ( (size_t) (buf_mem->length + 1))) == NULL ) { + BIO_free_all( mem ); + return ( NULL ); + } + + memcpy(ret, buf_mem->data, (size_t) buf_mem->length ); + ret[buf_mem->length] = '\x0'; + + BIO_free_all ( mem ); + + return ( ret ); +} diff --git a/src/crypto/pki_rand.c b/src/crypto/pki_rand.c new file mode 100644 index 00000000..33b5c1e8 --- /dev/null +++ b/src/crypto/pki_rand.c @@ -0,0 +1,34 @@ +/* OpenCA libpki package +* (c) 2000-2007 by Massimiliano Pala and OpenCA Group +* All Rights Reserved +* +* =================================================================== +* Released under OpenCA LICENSE +*/ + +#include + +int PKI_RAND_get( unsigned char **buf, size_t num) { + + int ret = 0; + // OSSL return code + + // Input Checks + if (!buf || num <= 0) return PKI_ERR; + + // Allocates the buffer if not already allocated + if ((*buf == NULL) && ((*buf = malloc( num )) == NULL)) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return PKI_ERR; + } + + // Gets the random data + ret = RAND_bytes(*buf, (int)num); + if (ret != 1) { + PKI_DEBUG("Failed to retrieve (%d) random bytes (code: %d)", num, ret); + return PKI_ERR; + } + + // All Done + return ret; +} \ No newline at end of file diff --git a/src/pkix/cmc/Makefile.am b/src/pkix/cmc/Makefile.am new file mode 100644 index 00000000..0b5942ef --- /dev/null +++ b/src/pkix/cmc/Makefile.am @@ -0,0 +1,25 @@ +## OpenCA Makefile - by Massimiliano Pala +## (c) 1999-2014 by Massimiliano Pala and OpenCA Project +## All Rights Reserved + +TOP = .. +include $(TOP)/global-vars + +BASE_DEFS = + +DEFS = $(OPENCA_DEFS) + +AM_CPPFLAGS = -I$(TOP) \ + $(openssl_cflags) \ + $(libxml2_cflags) \ + $(COND_INCLUDES) + +SRCS = \ + asn1.c \ + cmc_cert_req.c \ + cmc_simple.c + +noinst_LTLIBRARIES = libpki-cmc.la +libpki_cmc_la_SOURCES = $(SRCS) +libpki_cmc_la_CFLAGS = $(BUILD_LIBPKI_CFLAGS) + diff --git a/src/pkix/cmc/Makefile.in b/src/pkix/cmc/Makefile.in new file mode 100644 index 00000000..7b5db108 --- /dev/null +++ b/src/pkix/cmc/Makefile.in @@ -0,0 +1,779 @@ +# Makefile.in generated by automake 1.16.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = src/cmc +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(SHELL) $(top_srcdir)/build/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/src/libpki/config.h \ + $(top_builddir)/src/libpki/libpki_enables.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +libpki_cmc_la_LIBADD = +am__objects_1 = libpki_cmc_la-asn1.lo libpki_cmc_la-cmc_cert_req.lo \ + libpki_cmc_la-cmc_simple.lo +am_libpki_cmc_la_OBJECTS = $(am__objects_1) +libpki_cmc_la_OBJECTS = $(am_libpki_cmc_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libpki_cmc_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libpki_cmc_la_CFLAGS) \ + $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src/libpki +depcomp = $(SHELL) $(top_srcdir)/build/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/libpki_cmc_la-asn1.Plo \ + ./$(DEPDIR)/libpki_cmc_la-cmc_cert_req.Plo \ + ./$(DEPDIR)/libpki_cmc_la-cmc_simple.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libpki_cmc_la_SOURCES) +DIST_SOURCES = $(libpki_cmc_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/build/depcomp \ + $(top_srcdir)/build/mkinstalldirs +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_DATE = @BUILD_DATE@ +BUILD_DATE_FULL = @BUILD_DATE_FULL@ +BUILD_DATE_PRETTY = @BUILD_DATE_PRETTY@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CHMOD = @CHMOD@ +CHOWN = @CHOWN@ +CP = @CP@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CPU = @CPU@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CXX = @CXX@ +CYGPATH_W = @CYGPATH_W@ +DATE = @DATE@ +DEFS = $(OPENCA_DEFS) +DEPDIR = @DEPDIR@ +DESTDIR = @DESTDIR@ +DIST_NAME = @DIST_NAME@ +DIST_VERSION = @DIST_VERSION@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +GZIP = @GZIP@ +HAS_PKGCONF = @HAS_PKGCONF@ +INSTALL = @INSTALL@ +INSTALL_BUILDER = @INSTALL_BUILDER@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKE = @MAKE@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR = @MKDIR@ +MKDIR_P = @MKDIR_P@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PDFLATEX = @PDFLATEX@ +PERL = @PERL@ +PG_CONFIG = @PG_CONFIG@ +PG_CPPFLAGS = @PG_CPPFLAGS@ +PKGMK = @PKGMK@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POD2MAN = @POD2MAN@ +PWD = @PWD@ +RANLIB = @RANLIB@ +RC = @RC@ +RPM = @RPM@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TAR = @TAR@ +TODAY = @TODAY@ +VERSION = @VERSION@ +ZIP = @ZIP@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_aux_dir = @ac_aux_dir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +arch_target = @arch_target@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +composite_cflags = @composite_cflags@ +composite_ldadd = @composite_ldadd@ +composite_ldflags = @composite_ldflags@ +conf_dir = @conf_dir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +day = @day@ +dist_group = @dist_group@ +dist_user = @dist_user@ +docdir = @docdir@ +dvidir = @dvidir@ +enable_debug = @enable_debug@ +etc_dir = @etc_dir@ +exec_prefix = @exec_prefix@ +extra_checks = @extra_checks@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +hr = @hr@ +htmldir = @htmldir@ +iface_age = @iface_age@ +iface_current = @iface_current@ +iface_revision = @iface_revision@ +iface_version = @iface_version@ +include_dir = @include_dir@ +include_prefix = @include_prefix@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +kmf_cflags = @kmf_cflags@ +kmf_ldadd = @kmf_ldadd@ +kmf_libflags = @kmf_libflags@ +kmf_prefix = @kmf_prefix@ +ldap_cflags = @ldap_cflags@ +ldap_ldadd = @ldap_ldadd@ +ldap_ldflags = @ldap_ldflags@ +ldap_prefix = @ldap_prefix@ +ldap_vendor = @ldap_vendor@ +lib_major = @lib_major@ +lib_micro = @lib_micro@ +lib_minor = @lib_minor@ +lib_prefix = @lib_prefix@ +lib_revision = @lib_revision@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libpki_cflags = @libpki_cflags@ +libpki_ldadd = @libpki_ldadd@ +libpki_ldflags = @libpki_ldflags@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +min = @min@ +mkdir_p = @mkdir_p@ +mon = @mon@ +my_cflags = @my_cflags@ +my_ldadd = @my_ldadd@ +my_ldflags = @my_ldflags@ +myarch = @myarch@ +mybits = @mybits@ +mybits_install = @mybits_install@ +mysql_cflags = @mysql_cflags@ +mysql_config = @mysql_config@ +mysql_ldadd = @mysql_ldadd@ +mysql_ldflags = @mysql_ldflags@ +mysql_prefix = @mysql_prefix@ +oldincludedir = @oldincludedir@ +openssl_cflags = @openssl_cflags@ +openssl_include = @openssl_include@ +openssl_ldadd = @openssl_ldadd@ +openssl_ldflags = @openssl_ldflags@ +openssl_prefix = @openssl_prefix@ +openssl_static_libs = @openssl_static_libs@ +oqs_cflags = @oqs_cflags@ +oqs_ldadd = @oqs_ldadd@ +oqs_ldflags = @oqs_ldflags@ +oqsprov_cflags = @oqsprov_cflags@ +oqsprov_ldadd = @oqsprov_ldadd@ +oqsprov_ldflags = @oqsprov_ldflags@ +package_build = @package_build@ +package_prefix = @package_prefix@ +pdfdir = @pdfdir@ +pg_cflags = @pg_cflags@ +pg_config = @pg_config@ +pg_ldadd = @pg_ldadd@ +pg_ldflags = @pg_ldflags@ +pg_prefix = @pg_prefix@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pthread_opts = @pthread_opts@ +resolv_ldadd = @resolv_ldadd@ +rpath = @rpath@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sdkver = @sdkver@ +sec = @sec@ +sharedstatedir = @sharedstatedir@ +shlext = @shlext@ +shlib_history = @shlib_history@ +shlib_version = @shlib_version@ +srcdir = @srcdir@ +sys_cflags = @sys_cflags@ +sys_ldadd = @sys_ldadd@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +test_libs = @test_libs@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +txt_revision = @txt_revision@ +xml2_cflags = @xml2_cflags@ +xml2_config = @xml2_config@ +xml2_include = @xml2_include@ +xml2_ldadd = @xml2_ldadd@ +xml2_ldflags = @xml2_ldflags@ +xml2_prefix = @xml2_prefix@ +yr = @yr@ +TOP = .. +BASE_DEFS = +AM_CPPFLAGS = -I$(TOP) \ + $(openssl_cflags) \ + $(libxml2_cflags) \ + $(COND_INCLUDES) + +SRCS = \ + asn1.c \ + cmc_cert_req.c \ + cmc_simple.c + +noinst_LTLIBRARIES = libpki-cmc.la +libpki_cmc_la_SOURCES = $(SRCS) +libpki_cmc_la_CFLAGS = $(BUILD_LIBPKI_CFLAGS) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/cmc/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/cmc/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libpki-cmc.la: $(libpki_cmc_la_OBJECTS) $(libpki_cmc_la_DEPENDENCIES) $(EXTRA_libpki_cmc_la_DEPENDENCIES) + $(AM_V_CCLD)$(libpki_cmc_la_LINK) $(libpki_cmc_la_OBJECTS) $(libpki_cmc_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_cmc_la-asn1.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_cmc_la-cmc_cert_req.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_cmc_la-cmc_simple.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +libpki_cmc_la-asn1.lo: asn1.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_cmc_la_CFLAGS) $(CFLAGS) -MT libpki_cmc_la-asn1.lo -MD -MP -MF $(DEPDIR)/libpki_cmc_la-asn1.Tpo -c -o libpki_cmc_la-asn1.lo `test -f 'asn1.c' || echo '$(srcdir)/'`asn1.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_cmc_la-asn1.Tpo $(DEPDIR)/libpki_cmc_la-asn1.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='asn1.c' object='libpki_cmc_la-asn1.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_cmc_la_CFLAGS) $(CFLAGS) -c -o libpki_cmc_la-asn1.lo `test -f 'asn1.c' || echo '$(srcdir)/'`asn1.c + +libpki_cmc_la-cmc_cert_req.lo: cmc_cert_req.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_cmc_la_CFLAGS) $(CFLAGS) -MT libpki_cmc_la-cmc_cert_req.lo -MD -MP -MF $(DEPDIR)/libpki_cmc_la-cmc_cert_req.Tpo -c -o libpki_cmc_la-cmc_cert_req.lo `test -f 'cmc_cert_req.c' || echo '$(srcdir)/'`cmc_cert_req.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_cmc_la-cmc_cert_req.Tpo $(DEPDIR)/libpki_cmc_la-cmc_cert_req.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cmc_cert_req.c' object='libpki_cmc_la-cmc_cert_req.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_cmc_la_CFLAGS) $(CFLAGS) -c -o libpki_cmc_la-cmc_cert_req.lo `test -f 'cmc_cert_req.c' || echo '$(srcdir)/'`cmc_cert_req.c + +libpki_cmc_la-cmc_simple.lo: cmc_simple.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_cmc_la_CFLAGS) $(CFLAGS) -MT libpki_cmc_la-cmc_simple.lo -MD -MP -MF $(DEPDIR)/libpki_cmc_la-cmc_simple.Tpo -c -o libpki_cmc_la-cmc_simple.lo `test -f 'cmc_simple.c' || echo '$(srcdir)/'`cmc_simple.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_cmc_la-cmc_simple.Tpo $(DEPDIR)/libpki_cmc_la-cmc_simple.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cmc_simple.c' object='libpki_cmc_la-cmc_simple.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_cmc_la_CFLAGS) $(CFLAGS) -c -o libpki_cmc_la-cmc_simple.lo `test -f 'cmc_simple.c' || echo '$(srcdir)/'`cmc_simple.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/libpki_cmc_la-asn1.Plo + -rm -f ./$(DEPDIR)/libpki_cmc_la-cmc_cert_req.Plo + -rm -f ./$(DEPDIR)/libpki_cmc_la-cmc_simple.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/libpki_cmc_la-asn1.Plo + -rm -f ./$(DEPDIR)/libpki_cmc_la-cmc_cert_req.Plo + -rm -f ./$(DEPDIR)/libpki_cmc_la-cmc_simple.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-noinstLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + +include $(TOP)/global-vars + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/pkix/cmc/asn1.c b/src/pkix/cmc/asn1.c new file mode 100644 index 00000000..3a0e2893 --- /dev/null +++ b/src/pkix/cmc/asn1.c @@ -0,0 +1,407 @@ +/* LibPKI CMS Data Structure and ASN1 code + * (c) 2004-2007 by Massimiliano Pala and OpenCA Group + * All Rights Reserved + * + * This software is released under the LICENSE included + * in the archive. You can not remove this copyright notice. + */ + + +#include +#include + +#include + +/* + PEND_INFO ::= SEQUENCE { + pendToken OCTET STRING, + pendTime GeneralizedTime + } +*/ + +ASN1_SEQUENCE(PEND_INFO) = { + ASN1_SIMPLE(PEND_INFO, pendInfo, ASN1_OCTET_STRING), + ASN1_SIMPLE(PEND_INFO, pendTime, ASN1_GENERALIZEDTIME) +} ASN1_SEQUENCE_END(PEND_INFO) + +IMPLEMENT_ASN1_FUNCTIONS(PEND_INFO) + +/* + BODY_PART_REFERENCE ::= SEQUENCE { + bodyPartID BodyPartID, + bodyPartPath SEQUENCE SIZE(1..MAX) OF BodyPartID + } +*/ + +ASN1_SEQUENCE(BODY_PART_REFERENCE) = { + ASN1_SIMPLE( BODY_PART_REFERENCE, bodyPartID, ASN1_INTEGER), + ASN1_SEQUENCE_OF( BODY_PART_REFERENCE, bodyPartPath, ASN1_INTEGER ) +} ASN1_SEQUENCE_END(BODY_PART_REFERENCE) + +IMPLEMENT_ASN1_FUNCTIONS(BODY_PART_REFERENCE) + +/* + CMC_STATUS_INFO ::= SEQUENCE { + cMCStatus CMCStatus, + bodyList SEQUENCE SIZE (1..MAX) OF BODY_PART_REFERENCE, + statusString UTF8String OPTIONAL, + otherInfo CHOICE { + failInfo CMCFailInfo, + pendInfo PEND_INFO, + extendedFailInfo SEQUENCE { + failInfoOID OBJECT_IDENTIFIER, + failInfoValue AttributeValue } + } OPTIONAL + } +*/ + +/* Watch out because the ASN1_ANY value could swallow everything else... */ + +ASN1_SEQUENCE(EXTENDED_FAIL_INFO) = { + ASN1_SIMPLE(EXTENDED_FAIL_INFO, failInfoOID, ASN1_OBJECT ), + ASN1_SIMPLE(EXTENDED_FAIL_INFO, failInfoValue, ASN1_ANY ) +} ASN1_SEQUENCE_END(EXTENDED_FAIL_INFO) + +IMPLEMENT_ASN1_FUNCTIONS(EXTENDED_FAIL_INFO) + +ASN1_CHOICE(OTHER_INFO_EX) = { + ASN1_SIMPLE(OTHER_INFO_EX, value.failInfo, ASN1_INTEGER), + ASN1_SIMPLE(OTHER_INFO_EX, value.pendInfo, PEND_INFO), + ASN1_SIMPLE(OTHER_INFO_EX, value.extendedFailInfo, EXTENDED_FAIL_INFO ) +} ASN1_CHOICE_END(OTHER_INFO_EX) + +IMPLEMENT_ASN1_FUNCTIONS(OTHER_INFO_EX) + +ASN1_SEQUENCE(CMC_STATUS_INFO_EX) = { + ASN1_SIMPLE(CMC_STATUS_INFO_EX, cMCStatus, ASN1_INTEGER), + ASN1_SEQUENCE_OF(CMC_STATUS_INFO_EX, bodyList, BODY_PART_REFERENCE), + ASN1_OPT(CMC_STATUS_INFO_EX, statusString, ASN1_UTF8STRING), + ASN1_SIMPLE(CMC_STATUS_INFO_EX, otherInfo, OTHER_INFO_EX) +} ASN1_SEQUENCE_END(CMC_STATUS_INFO_EX) + +IMPLEMENT_ASN1_FUNCTIONS(CMC_STATUS_INFO_EX) + +/* + CMCStatusInfo ::= SEQUENCE { + cMCStatusInfo CMCStatus, + bodyList SEQUENCE SIZE (1..MAX) OF BodyPartID, + statusString UTF8String OPTIONAL, + otherInfo CHOICE { + failInfo CMCFailInfo, + pendInfo PendInfo + } OPTIONAL + } +*/ + +ASN1_CHOICE(OTHER_INFO) = { + ASN1_SIMPLE(OTHER_INFO, value.failInfo, ASN1_INTEGER), + ASN1_SIMPLE(OTHER_INFO, value.pendInfo, PEND_INFO), +} ASN1_CHOICE_END(OTHER_INFO) + +IMPLEMENT_ASN1_FUNCTIONS(OTHER_INFO) + +ASN1_SEQUENCE(CMC_STATUS_INFO) = { + ASN1_SIMPLE(CMC_STATUS_INFO, cMCStatusInfo, ASN1_INTEGER), + ASN1_SEQUENCE_OF(CMC_STATUS_INFO, bodyList, ASN1_INTEGER), + ASN1_OPT(CMC_STATUS_INFO_EX, statusString, ASN1_UTF8STRING), + ASN1_SIMPLE(CMC_STATUS_INFO_EX, otherInfo, OTHER_INFO) +} ASN1_SEQUENCE_END(CMC_STATUS_INFO) + +IMPLEMENT_ASN1_FUNCTIONS(CMC_STATUS_INFO) + +/* + TAGGED_ATTRIBUTE ::= SEQUENCE { + bodyPartID BodyPartID, + attrType OBJECT IDENTIFIER, + attrValues SET OF AttributeValue + } +*/ + +ASN1_SEQUENCE(TAGGED_ATTRIBUTE) = { + ASN1_SIMPLE( TAGGED_ATTRIBUTE, bodyPartID, ASN1_INTEGER ), + ASN1_SIMPLE( TAGGED_ATTRIBUTE, attrType, ASN1_OBJECT), + ASN1_SET_OF( TAGGED_ATTRIBUTE, attrValues, ASN1_ANY ) +} ASN1_SEQUENCE_END( TAGGED_ATTRIBUTE ) + +IMPLEMENT_ASN1_FUNCTIONS(TAGGED_ATTRIBUTE) + +/* + OTHER_MSG ::= SEQUENECE { + bodyPartID BodyPartID, + otherMsgType OBJECT IDENTIFIER, + otherMsgValue ANY DEFINED BY otherMsgType + } +*/ + +ASN1_SEQUENCE(OTHER_MSG) = { + ASN1_SIMPLE ( OTHER_MSG, bodyPartID, ASN1_INTEGER ), + ASN1_SIMPLE ( OTHER_MSG, otherMsgType, ASN1_OBJECT ), + ASN1_SIMPLE ( OTHER_MSG, otherMsgValue, ASN1_ANY ) +} ASN1_SEQUENCE_END(OTHER_MSG) + +IMPLEMENT_ASN1_FUNCTIONS( OTHER_MSG ) + +/* + CMC_UNSIGNED_DATA ::= SEQUENCE { + bodyPartPath SEQUENCE SIZE (1..MAX) OF BodyPartID, + identifier OBJECT IDENTIFIER, + content ANY DEFINED BY identifier +*/ + +ASN1_SEQUENCE(CMC_UNSIGNED_DATA) = { + ASN1_SEQUENCE_OF( CMC_UNSIGNED_DATA, bodyPartPath, ASN1_INTEGER ), + ASN1_SIMPLE ( CMC_UNSIGNED_DATA, identifier, ASN1_OBJECT ), + ASN1_SIMPLE ( CMC_UNSIGNED_DATA, content, ASN1_ANY ) +} ASN1_SEQUENCE_END(CMC_UNSIGNED_DATA) + +IMPLEMENT_ASN1_FUNCTIONS(CMC_UNSIGNED_DATA) + +/* + ContentInfo ::= SEQUENCE { + bodyPartID BodyPartID, + contentInfo ContentInfo + } +*/ + +ASN1_SEQUENCE(CONTENT_INFO) = { + ASN1_SIMPLE(CONTENT_INFO, contentType, ASN1_OBJECT), + ASN1_EXP_OPT(CONTENT_INFO, content, ASN1_ANY, 0 ) +} ASN1_SEQUENCE_END(CONTENT_INFO) + +IMPLEMENT_ASN1_FUNCTIONS(CONTENT_INFO) + +/* + TaggedContentInfo ::= SEQUENCE { + bodyPartID BodyPartID, + contentInfo ContentInfo + } +*/ + +ASN1_SEQUENCE(TAGGED_CONTENT_INFO) = { + ASN1_SIMPLE( TAGGED_CONTENT_INFO, bodyPartID, ASN1_INTEGER), + ASN1_SIMPLE( TAGGED_CONTENT_INFO, contentInfo, CONTENT_INFO) +} ASN1_SEQUENCE_END(TAGGED_CONTENT_INFO) + +IMPLEMENT_ASN1_FUNCTIONS(TAGGED_CONTENT_INFO) + +/* + TaggedCertificationRequest ::= SEQUENCE { + bodyPartID BodyPartID, + certificationRequest CertificationRequest + } +*/ + +ASN1_SEQUENCE(TAGGED_CERTIFICATION_REQUEST) = { + ASN1_SIMPLE(TAGGED_CERTIFICATION_REQUEST, bodyPartID, ASN1_INTEGER), + ASN1_SIMPLE(TAGGED_CERTIFICATION_REQUEST, certificationRequest, X509_REQ), +} ASN1_SEQUENCE_END(TAGGED_CERTIFICATION_REQUEST) + +IMPLEMENT_ASN1_FUNCTIONS(TAGGED_CERTIFICATION_REQUEST) + +/* + PKMACValue ::= SEQUENCE { + algId AlgorithmIdentifier, + -- the algorithm value shall be PasswordBasedMac + -- {1 2 840 113533 7 66 13} + -- the parameter value is PBMParameter + value BIT STRING } +*/ + +ASN1_SEQUENCE(PKMAC_VALUE) = { + ASN1_SIMPLE(PKMAC_VALUE, algID, X509_ALGOR), + ASN1_SIMPLE(PKMAC_VALUE, value, ASN1_BIT_STRING) +} ASN1_SEQUENCE_END(PKMAC_VALUE) + +IMPLEMENT_ASN1_FUNCTIONS(PKMAC_VALUE) + +/* + POPOSigningKeyInput ::= SEQUENCE { + authInfo CHOICE { + sender [0] GeneralName, + -- used only if an authenticated identity has been + -- established for the sender (e.g., a DN from a + -- previously-issued and currently-valid certificate) + publicKeyMAC PKMACValue }, + -- used if no authenticated GeneralName currently exists for + -- the sender; publicKeyMAC contains a password-based MAC + -- on the DER-encoded value of publicKey + publicKey SubjectPublicKeyInfo } -- from CertTemplate +*/ + +ASN1_CHOICE(AUTH_INFO) = { + ASN1_EXP(AUTH_INFO, value.sender, X509_NAME, 0), + ASN1_EXP(AUTH_INFO, value.publicKeyMAC, PKMAC_VALUE, 1) +} ASN1_CHOICE_END(AUTH_INFO) + +IMPLEMENT_ASN1_FUNCTIONS(AUTH_INFO) + +ASN1_SEQUENCE(PUBKEY_INFO) = { + ASN1_SIMPLE(PUBKEY_INFO, algorithm, X509_ALGOR), + ASN1_SIMPLE(PUBKEY_INFO, subjectPublicKey, ASN1_BIT_STRING) +} ASN1_SEQUENCE_END(PUBKEY_INFO) + +IMPLEMENT_ASN1_FUNCTIONS(PUBKEY_INFO) + +ASN1_SEQUENCE(POP_O_SIGNING_KEY_INPUT) = { + ASN1_SIMPLE(POP_O_SIGNING_KEY_INPUT, authInfo, AUTH_INFO), + ASN1_SIMPLE(POP_O_SIGNING_KEY_INPUT, publicKey, PUBKEY_INFO) +} ASN1_SEQUENCE_END(POP_O_SIGNING_KEY_INPUT) + +IMPLEMENT_ASN1_FUNCTIONS(POP_O_SIGNING_KEY_INPUT) + +/* + POPOSigningKey ::= SEQUENCE { + poposkInput [0] POPOSigningKeyInput OPTIONAL, + algorithmIdentifier AlgorithmIdentifier, + signature BIT STRING } + -- The signature (using "algorithmIdentifier") is on the + -- DER-encoded value of poposkInput. NOTE: If the CertReqMsg + -- certReq CertTemplate contains the subject and publicKey values, + -- then poposkInput MUST be omitted and the signature MUST be + -- computed on the DER-encoded value of CertReqMsg certReq. If + -- the CertReqMsg certReq CertTemplate does not contain the public + -- key and subject values, then poposkInput MUST be present and + -- MUST be signed. This strategy ensures that the public key is + -- not present in both the poposkInput and CertReqMsg certReq + -- CertTemplate fields. +*/ + +ASN1_SEQUENCE(POP_O_SIGNING_KEY) = { + ASN1_EXP_OPT(POP_O_SIGNING_KEY, poposkInput, POP_O_SIGNING_KEY_INPUT, 0), + ASN1_SIMPLE(POP_O_SIGNING_KEY, algorithmIdentifier, X509_ALGOR), + ASN1_SIMPLE(POP_O_SIGNING_KEY, signature, ASN1_BIT_STRING) +} ASN1_SEQUENCE_END(POP_O_SIGNING_KEY) + +IMPLEMENT_ASN1_FUNCTIONS(POP_O_SIGNING_KEY) + +/* + SubsequentMessage ::= INTEGER { + encrCert (0), + -- requests that resulting certificate be encrypted for the + -- end entity (following which, POP will be proven in a + -- confirmation message) + challengeResp (1) } + -- requests that CA/RA engage in challenge-response exchange with + -- end entity in order to prove private key possession + + POPOPrivKey ::= CHOICE { + thisMessage [0] BIT STRING, + -- posession is proven in this message (which contains the private + -- key itself (encrypted for the CA)) + subsequentMessage [1] SubsequentMessage, + -- possession will be proven in a subsequent message + dhMAC [2] BIT STRING } + -- for keyAgreement (only), possession is proven in this message + -- (which contains a MAC (over the DER-encoded value of the + -- certReq parameter in CertReqMsg, which must include both subject + -- and publicKey) based on a key derived from the end entity's + -- private DH key and the CA's public DH key); + -- the dhMAC value MUST be calculated as per the directions given + -- in Appendix A. +*/ + +ASN1_CHOICE(POP_O_PRIVKEY) = { + ASN1_EXP(POP_O_PRIVKEY, value.thisMessage, ASN1_BIT_STRING, 0), + ASN1_EXP(POP_O_PRIVKEY, value.subsequentMessage, ASN1_INTEGER, 1), + ASN1_EXP(POP_O_PRIVKEY, value.dhMAC, ASN1_BIT_STRING, 2) +} ASN1_CHOICE_END(POP_O_PRIVKEY) + +IMPLEMENT_ASN1_FUNCTIONS(POP_O_PRIVKEY) + +/* + ProofOfPossession ::= CHOICE { + raVerified [0] NULL, + -- used if the RA has already verified that the requester is in + -- possession of the private key + signature [1] POPOSigningKey, + keyEncipherment [2] POPOPrivKey, + keyAgreement [3] POPOPrivKey } +*/ + +ASN1_CHOICE(X509_POP) = { + ASN1_EXP(X509_POP, value.raVerified, ASN1_INTEGER, 0), + ASN1_EXP(X509_POP, value.signature, POP_O_SIGNING_KEY, 1), + ASN1_EXP(X509_POP, value.keyEncipherment, POP_O_PRIVKEY, 2), + ASN1_EXP(X509_POP, value.keyAgreement, POP_O_PRIVKEY, 3) +} ASN1_CHOICE_END(X509_POP) + +IMPLEMENT_ASN1_FUNCTIONS(X509_POP) + +/* + CertReqMsg ::= SEQUENCE { + certReq CertificateRequest, + pop ProofOfPossession OPTIONAL, + regInfo SEQUENCE SIZE (1..MAX) OF AttributeTypeAndValue OPTIONAL + } +*/ + +ASN1_SEQUENCE(CERT_REQ_MSG) = { + ASN1_SIMPLE(CERT_REQ_MSG, certReq, X509_REQ ), + ASN1_OPT(CERT_REQ_MSG, pop, X509_POP ), + ASN1_SEQUENCE_OF_OPT(CERT_REQ_MSG, certReq, X509_REQ ) +} ASN1_SEQUENCE_END(CERT_REQ_MSG) + +IMPLEMENT_ASN1_FUNCTIONS(CERT_REQ_MSG) + +/* + TaggedRequest ::= CHOICE { + tcr [0] TaggedCertificationRequest, + crm [1] CertReqMsg, + orm [2] SEQUENCE { + bodyPartID BodyPartID, + requestMessageType OBJECT IDENTIFIER, + requestMessageValue ANY DEFINED BY requestMessageType + } + } +*/ + +ASN1_SEQUENCE(OTHER_REQ_MSG) = { + ASN1_SIMPLE(OTHER_REQ_MSG, bodyPartID, ASN1_INTEGER), + ASN1_SIMPLE(OTHER_REQ_MSG, requestMessageType, ASN1_OBJECT), + ASN1_SIMPLE(OTHER_REQ_MSG, requestMessageValue, ASN1_ANY), +} ASN1_SEQUENCE_END(OTHER_REQ_MSG) + +IMPLEMENT_ASN1_FUNCTIONS(OTHER_REQ_MSG) + +ASN1_CHOICE(TAGGED_REQUEST) = { + ASN1_EXP(TAGGED_REQUEST, value.tcr, TAGGED_CERTIFICATION_REQUEST, 0), + ASN1_EXP(TAGGED_REQUEST, value.crm, CERT_REQ_MSG, 1), + ASN1_EXP(TAGGED_REQUEST, value.orm, OTHER_REQ_MSG, 2) +} ASN1_CHOICE_END(TAGGED_REQUEST) + +IMPLEMENT_ASN1_FUNCTIONS(TAGGED_REQUEST) + +/* + PKI_DATA ::= SEQUENCE { + controlSequence SEQUENCE SIZE(0..MAX) OF TAGGED_ATTRIBUTE, + reqSequence SEQUENCE SIZE(0..MAX) OF TaggedRequest, + cmsSequence SEQUENCE SIZE(0..MAX) OF TaggedContentInfo, + otherMsgSequence SEQUENCE SIZE(0..MAX) OF OTHER_MSG + } +*/ + +ASN1_SEQUENCE(PKI_DATA) = { + ASN1_EXP_SEQUENCE_OF_OPT(PKI_DATA, controlSequence, TAGGED_ATTRIBUTE, 0), + ASN1_EXP_SEQUENCE_OF_OPT(PKI_DATA, reqSequence, TAGGED_REQUEST, 1), + ASN1_EXP_SEQUENCE_OF_OPT(PKI_DATA, cmsSequence, TAGGED_CONTENT_INFO, 2), + ASN1_EXP_SEQUENCE_OF_OPT(PKI_DATA, otherMsgSequence, OTHER_MSG, 3) +} ASN1_SEQUENCE_END(PKI_DATA) + +IMPLEMENT_ASN1_FUNCTIONS(PKI_DATA) + +/* + RESPONSE_BODY ::= SEQUENCE { + controlSequence SEQUENCE SIZE(0..MAX) OF TAGGED_ATTRIBUTE, + cmsSequence SEQUENCE SIZE(0..MAX) OF TaggedContentInfo, + otherMsgSequence SEQUENCE SIZE(0..MAX) OF OTHER_MSG + } +*/ + +ASN1_SEQUENCE(RESPONSE_BODY) = { + ASN1_EXP_SEQUENCE_OF_OPT(RESPONSE_BODY, controlSequence, TAGGED_ATTRIBUTE, 0), + ASN1_EXP_SEQUENCE_OF_OPT(RESPONSE_BODY, cmsSequence, TAGGED_CONTENT_INFO, 1), + ASN1_EXP_SEQUENCE_OF_OPT(RESPONSE_BODY, otherMsgSequence, OTHER_MSG, 2) +} ASN1_SEQUENCE_END(RESPONSE_BODY) + +IMPLEMENT_ASN1_FUNCTIONS(RESPONSE_BODY) + diff --git a/src/pkix/cmc/cmc_cert_req.c b/src/pkix/cmc/cmc_cert_req.c new file mode 100644 index 00000000..15d37a28 --- /dev/null +++ b/src/pkix/cmc/cmc_cert_req.c @@ -0,0 +1,297 @@ +/* CMS Support for LibPKI + * (c) 2008 by Massimiliano Pala and OpenCA Group + * All Rights Reserved + * + * This software is released under the GPL2 License included + * in the archive. You can not remove this copyright notice. + */ + +#include + +/* DER <-> INTERNAL Macros */ +CERT_REQ_MSG *d2i_CERT_REQ_MSG_bio ( BIO *bp, CERT_REQ_MSG *p ) { +#if OPENSSL_VERSION_NUMBER < 0x0090800fL + return (CERT_REQ_MSG *) ASN1_d2i_bio( + (char *(*)(void))CERT_REQ_MSG_new, + (char *(*)(void **, const unsigned char **, long))d2i_CERT_REQ_MSG, + bp, (unsigned char **) &p); +#else + return (CERT_REQ_MSG *) ASN1_d2i_bio( + (void *(*)(void))CERT_REQ_MSG_new, + (void *(*)(void **, const unsigned char **, long))d2i_CERT_REQ_MSG, + bp, (void **) &p); +#endif +} + +int i2d_CERT_REQ_MSG_bio(BIO *bp, CERT_REQ_MSG *o ) { +#if OPENSSL_VERSION_NUMBER < 0x0090800fL + return ASN1_i2d_bio( (int (*)(CERT_REQ_MSG *, unsigned char **)) i2d_CERT_REQ_MSG, bp, (unsigned char *) o); +#else + return ASN1_i2d_bio( (i2d_of_void *) i2d_CERT_REQ_MSG, bp, (unsigned char *) o); +#endif +} + + +/* PEM <-> INTERNAL Macros */ +CERT_REQ_MSG *PEM_read_bio_CERT_REQ_MSG( BIO *bp ) { +#if OPENSSL_VERSION_NUMBER < 0x0090800fL + return (CERT_REQ_MSG *) PEM_ASN1_read_bio( (char *(*)()) d2i_CERT_REQ_MSG, + PEM_STRING_CERT_REQ_MSG, bp, NULL, NULL, NULL); +#else + return (CERT_REQ_MSG *) PEM_ASN1_read_bio( (void *(*)()) d2i_CERT_REQ_MSG, + PEM_STRING_CERT_REQ_MSG, bp, NULL, NULL, NULL); +#endif +} + + +int PEM_write_bio_CERT_REQ_MSG( BIO *bp, CERT_REQ_MSG *o ) { + return PEM_ASN1_write_bio ( (int (*)())i2d_CERT_REQ_MSG, + PEM_STRING_CERT_REQ_MSG, bp, (char *) o, NULL, + NULL, 0, NULL, NULL ); +} + +/* ======================== REQ get API ========================== */ + +/*! + * \brief Retrieves a CERT_REQ_MSG request from the resource specified in the + * provided URI string +*/ + +CERT_REQ_MSG *CERT_REQ_MSG_get( char *url_s ) { + + URL *url = NULL; + + if( !url_s ) return ( NULL ); + + if((url = URL_new( url_s )) == NULL ) { + return (NULL); + } + + return ( CERT_REQ_MSG_get_url( url )); +} + +/*! + * \brief Retrieves a CERT_REQ_MSG request from the resource specified in the + * provided URL structure +*/ + +CERT_REQ_MSG *CERT_REQ_MSG_get_url( URL *url ) { + + CERT_REQ_MSG *ret = NULL; + PKI_MEM_STACK *mem_sk = NULL; + PKI_MEM *in = NULL; + + if(!url) return NULL; + + if((mem_sk = URL_get_data_url ( url, 60, 0, NULL )) == NULL ) { + return(NULL); + } + + if((in = PKI_STACK_MEM_pop( mem_sk )) != NULL ) { + ret = CERT_REQ_MSG_get_mem( in ); + } + + if( mem_sk ) PKI_STACK_MEM_free_all ( mem_sk ); + + return ( ret ); +} + +/*! + * \brief Retrieves a CERT_REQ_MSG request from the specified file descriptor +*/ + +CERT_REQ_MSG *CERT_REQ_MSG_get_fd( int fd ) { + + PKI_MEM *mem = NULL; + CERT_REQ_MSG *ret = NULL; + + unsigned char buf[4096]; + ssize_t n = 0; + + if((mem = PKI_MEM_new_null()) == NULL ) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return NULL; + } + + while( (n = _Read( fd, buf, sizeof( buf ))) > 0 ) { + PKI_MEM_add( mem, buf, (size_t) n ); + } + + ret = CERT_REQ_MSG_get_mem( mem ); + + PKI_MEM_free ( mem ); + + return ( ret ); +} + +/*! + * \brief Retrieves a CERT_REQ_MSG request from the passed PKI_MEM +*/ + +CERT_REQ_MSG *CERT_REQ_MSG_get_mem( PKI_MEM *mem ) { + + BIO *bp = NULL; + BUF_MEM *p = NULL; + CERT_REQ_MSG *ret = NULL; + + size_t curr = 0; + + if ((bp = BIO_new_mem_buf( mem->data, (int) mem->size )) == NULL) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return NULL; + } + + // p = (BUF_MEM *) bp->ptr; + BIO_get_mem_ptr(bp, &p); + curr = (size_t) p->length; + + if((ret = PEM_read_bio_CERT_REQ_MSG(bp)) == NULL){ + + /* Resetting the BIO to previous pointer */ +#if ( OPENSSL_VERSION_NUMBER >= 0x10000000L ) + p->length = (size_t) curr; +#else + p->length = (int) curr; +#endif + p->data -= curr; + + /* Is it DER encoded (???) */ + if((ret = d2i_CERT_REQ_MSG_bio(bp,NULL)) == NULL ) { + /* Format is not recognized! */ + PKI_log_debug("ERROR, can not load CERT_REQ_MSG!"); + } + } + + return ( ret ); +} + +/* =========================== CERT_REQ_MSG REQ put API ========================= */ + +/*! + * \brief Sends/Writes a CERT_REQ_MSG request in the resource specified in the + * provided URI string +*/ + +int CERT_REQ_MSG_put( CERT_REQ_MSG *req, char *url_s, + int format, PKI_MEM_STACK **ret_sk ) { + + URL *url = NULL; + + if( !url_s ) return ( PKI_ERR ); + + if((url = URL_new( url_s )) == NULL ) { + return ( PKI_ERR ); + } + + return CERT_REQ_MSG_put_url( req, url, format, ret_sk ); +} + +/*! + * \brief Sends/Writes a CERT_REQ_MSG request in the resource specified in the + * provided URL structure +*/ + +int CERT_REQ_MSG_put_url( CERT_REQ_MSG *req, URL *url, + int format, PKI_MEM_STACK **ret_sk ) { + + PKI_MEM *mem = NULL; + int ret = 0; + + if( !url ) return ( PKI_ERR ); + + if((mem = PKI_MEM_new_null()) == NULL ) { + return ( PKI_ERR ); + } + + if(CERT_REQ_MSG_put_mem( req, mem, format ) == PKI_ERR ) { + if( mem ) PKI_MEM_free ( mem ); + return (PKI_ERR); + } + + ret = URL_put_data_url(url, mem, PKI_CONTENT_TYPE_CERT_REQ_MSG, + ret_sk, 60, 0, NULL ); + + if( mem ) PKI_MEM_free ( mem ); + + return ( ret ); +} + +/*! + * \brief Writes a CERT_REQ_MSG request in the provided file descriptior +*/ + +int CERT_REQ_MSG_put_fp( CERT_REQ_MSG *req, FILE * file, int format ) { + + int ret = 0; + ssize_t n = 0; + int fd = 0; + PKI_MEM *mem = NULL; + + if((mem = PKI_MEM_new_null()) == NULL ) { + PKI_log_debug("Memory Allocation error (%s:%d)!", + __FILE__, __LINE__ ); + + return ( PKI_ERR ); + }; + + if( CERT_REQ_MSG_put_mem( req, mem, format ) == PKI_ERR ) { + if( mem ) PKI_MEM_free ( mem ); + return ( PKI_ERR ); + } + + fd = fileno( file ); + + if((n = _Write( fd, mem->data, mem->size )) < 0 ) { + ret = PKI_ERR; + } else { + ret = PKI_OK; + } + + return ( ret ); +} + +/*! + * \brief Sends/Store a CERT_REQ_MSG request in a PKI_MEM structure +*/ + +int CERT_REQ_MSG_put_mem( CERT_REQ_MSG *req, PKI_MEM *mem, int format ) { + + BIO *mem_bio = NULL; + BUF_MEM *buf = NULL; + + int rv = 0; + + if( !req || !mem ) return ( PKI_ERR ); + + if((mem_bio = BIO_new(BIO_s_mem())) == NULL ) { + return ( PKI_ERR ); + } + + switch ( format ) { + case PKI_DATA_FORMAT_PEM: + rv = PEM_write_bio_CERT_REQ_MSG( mem_bio, req ); + break; + case PKI_DATA_FORMAT_ASN1: + rv = i2d_CERT_REQ_MSG_bio( mem_bio, req ); + break; + default: + /* Format not supported! */ + goto err; + } + + if ( rv == 0 ) goto err; + + BIO_get_mem_ptr( mem_bio, &buf ); + rv = PKI_MEM_add( mem, (const unsigned char *)buf->data, (size_t) buf->length ); + + if( mem_bio ) BIO_free ( mem_bio ); + + return ( rv ); +err: + + if( mem_bio ) BIO_free (mem_bio); + + return ( PKI_ERR ); +} + + diff --git a/src/pkix/cmc/cmc_simple.c b/src/pkix/cmc/cmc_simple.c new file mode 100644 index 00000000..0886f8a6 --- /dev/null +++ b/src/pkix/cmc/cmc_simple.c @@ -0,0 +1,48 @@ +/* CMS Simple - PKIX Message Management */ + +#include + +typedef void PKI_CMS_RESP; +typedef void PKI_CMS_REQ; + +PKI_CMS_RESP *PKI_MSG_CMS_write ( PKI_CMS_REQ *req, URL *url ) { + + int rv = 0; + PKI_MEM_STACK *data = NULL; + PKI_MEM *req_data = NULL; + + // PKI_CMS_RESP *cms_resp = NULL; + + if( !req || !url ) return (PKI_ERR); + + /* Here we have to process the request in order to find out: + 1-the type of the request + 2-convert to a memory data chunk + 3-save the content to a PKI_MEM data structure (req_data) + */ + + rv = URL_put_data_url ( url, req_data, CMS_REQ_SIMPLE_DATATYPE, + &data, 0, 0, NULL ); + + /* + if( url->proto == URI_PROTO_HTTP ) { + data = URL_post_data_http(url, req_data->data, req_data->size, + CMS_REQ_SIMPLE_DATATYPE ); + } else if( url->proto == URI_PROTO_FILE ) { + // data = URL_write( url, req_data ); + } else if( url->proto == URI_PROTO_LDAP ) { + // data = URL_LDAP_post_data( url, req_data); + }; + */ + + if( (rv == PKI_ERR ) || ( data == NULL )) { + return ( PKI_ERR ); + } + + /* Else process the CMS data */ + // cms = PKI_CMS_new_mem( data ); + + // if( req_data ) PKI_MEM_free (req_data); + + return( NULL ); +} diff --git a/src/pkix/est/Makefile.am b/src/pkix/est/Makefile.am new file mode 100644 index 00000000..b64c22de --- /dev/null +++ b/src/pkix/est/Makefile.am @@ -0,0 +1,26 @@ +## OpenCA Makefile - by Massimiliano Pala +## (c) 1999-2007 by Massimiliano Pala and OpenCA Project +## All Rights Reserved + +TOP = .. +include $(TOP)/global-vars + +BASE_DEFS = + +DEFS = $(OPENCA_DEFS) + +MYEST = \ + pki_x509_est_attr.c \ + pki_x509_est_data.c \ + pki_x509_est_asn1.c \ + pki_x509_est_msg.c + +AM_CPPFLAGS = -I$(TOP) \ + $(openssl_cflags) \ + $(libxml2_cflags) \ + $(COND_INCLUDES) + +noinst_LTLIBRARIES = libpki-est.la +libpki_est_la_SOURCES = $(MYEST) +libpki_est_la_CFLAGS = $(BUILD_LIBPKI_CFLAGS) + diff --git a/src/pkix/est/Makefile.in b/src/pkix/est/Makefile.in new file mode 100644 index 00000000..8bf8d385 --- /dev/null +++ b/src/pkix/est/Makefile.in @@ -0,0 +1,793 @@ +# Makefile.in generated by automake 1.16.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = src/est +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(SHELL) $(top_srcdir)/build/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/src/libpki/config.h \ + $(top_builddir)/src/libpki/libpki_enables.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +libpki_est_la_LIBADD = +am__objects_1 = libpki_est_la-pki_x509_est_attr.lo \ + libpki_est_la-pki_x509_est_data.lo \ + libpki_est_la-pki_x509_est_asn1.lo \ + libpki_est_la-pki_x509_est_msg.lo +am_libpki_est_la_OBJECTS = $(am__objects_1) +libpki_est_la_OBJECTS = $(am_libpki_est_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libpki_est_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libpki_est_la_CFLAGS) \ + $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src/libpki +depcomp = $(SHELL) $(top_srcdir)/build/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/libpki_est_la-pki_x509_est_asn1.Plo \ + ./$(DEPDIR)/libpki_est_la-pki_x509_est_attr.Plo \ + ./$(DEPDIR)/libpki_est_la-pki_x509_est_data.Plo \ + ./$(DEPDIR)/libpki_est_la-pki_x509_est_msg.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libpki_est_la_SOURCES) +DIST_SOURCES = $(libpki_est_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/build/depcomp \ + $(top_srcdir)/build/mkinstalldirs +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_DATE = @BUILD_DATE@ +BUILD_DATE_FULL = @BUILD_DATE_FULL@ +BUILD_DATE_PRETTY = @BUILD_DATE_PRETTY@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CHMOD = @CHMOD@ +CHOWN = @CHOWN@ +CP = @CP@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CPU = @CPU@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CXX = @CXX@ +CYGPATH_W = @CYGPATH_W@ +DATE = @DATE@ +DEFS = $(OPENCA_DEFS) +DEPDIR = @DEPDIR@ +DESTDIR = @DESTDIR@ +DIST_NAME = @DIST_NAME@ +DIST_VERSION = @DIST_VERSION@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +GZIP = @GZIP@ +HAS_PKGCONF = @HAS_PKGCONF@ +INSTALL = @INSTALL@ +INSTALL_BUILDER = @INSTALL_BUILDER@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKE = @MAKE@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR = @MKDIR@ +MKDIR_P = @MKDIR_P@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PDFLATEX = @PDFLATEX@ +PERL = @PERL@ +PG_CONFIG = @PG_CONFIG@ +PG_CPPFLAGS = @PG_CPPFLAGS@ +PKGMK = @PKGMK@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POD2MAN = @POD2MAN@ +PWD = @PWD@ +RANLIB = @RANLIB@ +RC = @RC@ +RPM = @RPM@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TAR = @TAR@ +TODAY = @TODAY@ +VERSION = @VERSION@ +ZIP = @ZIP@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_aux_dir = @ac_aux_dir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +arch_target = @arch_target@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +composite_cflags = @composite_cflags@ +composite_ldadd = @composite_ldadd@ +composite_ldflags = @composite_ldflags@ +conf_dir = @conf_dir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +day = @day@ +dist_group = @dist_group@ +dist_user = @dist_user@ +docdir = @docdir@ +dvidir = @dvidir@ +enable_debug = @enable_debug@ +etc_dir = @etc_dir@ +exec_prefix = @exec_prefix@ +extra_checks = @extra_checks@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +hr = @hr@ +htmldir = @htmldir@ +iface_age = @iface_age@ +iface_current = @iface_current@ +iface_revision = @iface_revision@ +iface_version = @iface_version@ +include_dir = @include_dir@ +include_prefix = @include_prefix@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +kmf_cflags = @kmf_cflags@ +kmf_ldadd = @kmf_ldadd@ +kmf_libflags = @kmf_libflags@ +kmf_prefix = @kmf_prefix@ +ldap_cflags = @ldap_cflags@ +ldap_ldadd = @ldap_ldadd@ +ldap_ldflags = @ldap_ldflags@ +ldap_prefix = @ldap_prefix@ +ldap_vendor = @ldap_vendor@ +lib_major = @lib_major@ +lib_micro = @lib_micro@ +lib_minor = @lib_minor@ +lib_prefix = @lib_prefix@ +lib_revision = @lib_revision@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libpki_cflags = @libpki_cflags@ +libpki_ldadd = @libpki_ldadd@ +libpki_ldflags = @libpki_ldflags@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +min = @min@ +mkdir_p = @mkdir_p@ +mon = @mon@ +my_cflags = @my_cflags@ +my_ldadd = @my_ldadd@ +my_ldflags = @my_ldflags@ +myarch = @myarch@ +mybits = @mybits@ +mybits_install = @mybits_install@ +mysql_cflags = @mysql_cflags@ +mysql_config = @mysql_config@ +mysql_ldadd = @mysql_ldadd@ +mysql_ldflags = @mysql_ldflags@ +mysql_prefix = @mysql_prefix@ +oldincludedir = @oldincludedir@ +openssl_cflags = @openssl_cflags@ +openssl_include = @openssl_include@ +openssl_ldadd = @openssl_ldadd@ +openssl_ldflags = @openssl_ldflags@ +openssl_prefix = @openssl_prefix@ +openssl_static_libs = @openssl_static_libs@ +oqs_cflags = @oqs_cflags@ +oqs_ldadd = @oqs_ldadd@ +oqs_ldflags = @oqs_ldflags@ +oqsprov_cflags = @oqsprov_cflags@ +oqsprov_ldadd = @oqsprov_ldadd@ +oqsprov_ldflags = @oqsprov_ldflags@ +package_build = @package_build@ +package_prefix = @package_prefix@ +pdfdir = @pdfdir@ +pg_cflags = @pg_cflags@ +pg_config = @pg_config@ +pg_ldadd = @pg_ldadd@ +pg_ldflags = @pg_ldflags@ +pg_prefix = @pg_prefix@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pthread_opts = @pthread_opts@ +resolv_ldadd = @resolv_ldadd@ +rpath = @rpath@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sdkver = @sdkver@ +sec = @sec@ +sharedstatedir = @sharedstatedir@ +shlext = @shlext@ +shlib_history = @shlib_history@ +shlib_version = @shlib_version@ +srcdir = @srcdir@ +sys_cflags = @sys_cflags@ +sys_ldadd = @sys_ldadd@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +test_libs = @test_libs@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +txt_revision = @txt_revision@ +xml2_cflags = @xml2_cflags@ +xml2_config = @xml2_config@ +xml2_include = @xml2_include@ +xml2_ldadd = @xml2_ldadd@ +xml2_ldflags = @xml2_ldflags@ +xml2_prefix = @xml2_prefix@ +yr = @yr@ +TOP = .. +BASE_DEFS = +MYEST = \ + pki_x509_est_attr.c \ + pki_x509_est_data.c \ + pki_x509_est_asn1.c \ + pki_x509_est_msg.c + +AM_CPPFLAGS = -I$(TOP) \ + $(openssl_cflags) \ + $(libxml2_cflags) \ + $(COND_INCLUDES) + +noinst_LTLIBRARIES = libpki-est.la +libpki_est_la_SOURCES = $(MYEST) +libpki_est_la_CFLAGS = $(BUILD_LIBPKI_CFLAGS) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/est/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/est/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libpki-est.la: $(libpki_est_la_OBJECTS) $(libpki_est_la_DEPENDENCIES) $(EXTRA_libpki_est_la_DEPENDENCIES) + $(AM_V_CCLD)$(libpki_est_la_LINK) $(libpki_est_la_OBJECTS) $(libpki_est_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_est_la-pki_x509_est_asn1.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_est_la-pki_x509_est_attr.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_est_la-pki_x509_est_data.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_est_la-pki_x509_est_msg.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +libpki_est_la-pki_x509_est_attr.lo: pki_x509_est_attr.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_est_la_CFLAGS) $(CFLAGS) -MT libpki_est_la-pki_x509_est_attr.lo -MD -MP -MF $(DEPDIR)/libpki_est_la-pki_x509_est_attr.Tpo -c -o libpki_est_la-pki_x509_est_attr.lo `test -f 'pki_x509_est_attr.c' || echo '$(srcdir)/'`pki_x509_est_attr.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_est_la-pki_x509_est_attr.Tpo $(DEPDIR)/libpki_est_la-pki_x509_est_attr.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pki_x509_est_attr.c' object='libpki_est_la-pki_x509_est_attr.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_est_la_CFLAGS) $(CFLAGS) -c -o libpki_est_la-pki_x509_est_attr.lo `test -f 'pki_x509_est_attr.c' || echo '$(srcdir)/'`pki_x509_est_attr.c + +libpki_est_la-pki_x509_est_data.lo: pki_x509_est_data.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_est_la_CFLAGS) $(CFLAGS) -MT libpki_est_la-pki_x509_est_data.lo -MD -MP -MF $(DEPDIR)/libpki_est_la-pki_x509_est_data.Tpo -c -o libpki_est_la-pki_x509_est_data.lo `test -f 'pki_x509_est_data.c' || echo '$(srcdir)/'`pki_x509_est_data.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_est_la-pki_x509_est_data.Tpo $(DEPDIR)/libpki_est_la-pki_x509_est_data.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pki_x509_est_data.c' object='libpki_est_la-pki_x509_est_data.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_est_la_CFLAGS) $(CFLAGS) -c -o libpki_est_la-pki_x509_est_data.lo `test -f 'pki_x509_est_data.c' || echo '$(srcdir)/'`pki_x509_est_data.c + +libpki_est_la-pki_x509_est_asn1.lo: pki_x509_est_asn1.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_est_la_CFLAGS) $(CFLAGS) -MT libpki_est_la-pki_x509_est_asn1.lo -MD -MP -MF $(DEPDIR)/libpki_est_la-pki_x509_est_asn1.Tpo -c -o libpki_est_la-pki_x509_est_asn1.lo `test -f 'pki_x509_est_asn1.c' || echo '$(srcdir)/'`pki_x509_est_asn1.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_est_la-pki_x509_est_asn1.Tpo $(DEPDIR)/libpki_est_la-pki_x509_est_asn1.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pki_x509_est_asn1.c' object='libpki_est_la-pki_x509_est_asn1.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_est_la_CFLAGS) $(CFLAGS) -c -o libpki_est_la-pki_x509_est_asn1.lo `test -f 'pki_x509_est_asn1.c' || echo '$(srcdir)/'`pki_x509_est_asn1.c + +libpki_est_la-pki_x509_est_msg.lo: pki_x509_est_msg.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_est_la_CFLAGS) $(CFLAGS) -MT libpki_est_la-pki_x509_est_msg.lo -MD -MP -MF $(DEPDIR)/libpki_est_la-pki_x509_est_msg.Tpo -c -o libpki_est_la-pki_x509_est_msg.lo `test -f 'pki_x509_est_msg.c' || echo '$(srcdir)/'`pki_x509_est_msg.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_est_la-pki_x509_est_msg.Tpo $(DEPDIR)/libpki_est_la-pki_x509_est_msg.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pki_x509_est_msg.c' object='libpki_est_la-pki_x509_est_msg.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_est_la_CFLAGS) $(CFLAGS) -c -o libpki_est_la-pki_x509_est_msg.lo `test -f 'pki_x509_est_msg.c' || echo '$(srcdir)/'`pki_x509_est_msg.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/libpki_est_la-pki_x509_est_asn1.Plo + -rm -f ./$(DEPDIR)/libpki_est_la-pki_x509_est_attr.Plo + -rm -f ./$(DEPDIR)/libpki_est_la-pki_x509_est_data.Plo + -rm -f ./$(DEPDIR)/libpki_est_la-pki_x509_est_msg.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/libpki_est_la-pki_x509_est_asn1.Plo + -rm -f ./$(DEPDIR)/libpki_est_la-pki_x509_est_attr.Plo + -rm -f ./$(DEPDIR)/libpki_est_la-pki_x509_est_data.Plo + -rm -f ./$(DEPDIR)/libpki_est_la-pki_x509_est_msg.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-noinstLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + +include $(TOP)/global-vars + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/pkix/est/pki_x509_est_asn1.c b/src/pkix/est/pki_x509_est_asn1.c new file mode 100644 index 00000000..01c9d6fa --- /dev/null +++ b/src/pkix/est/pki_x509_est_asn1.c @@ -0,0 +1,17 @@ +/* EST ASN.1 implementation + * (c) 2003-2019 by Massimiliano Pala and OpenCA Group + * All Rights Reserved + * + * This software is released under the OpenCA License included + * in the archive. You can not remove this copyright notice. + */ + +#include + +ASN1_SEQUENCE(EST_ISSUER_AND_SUBJECT) = { + ASN1_SIMPLE(EST_ISSUER_AND_SUBJECT, issuer, X509_NAME), + ASN1_SIMPLE(EST_ISSUER_AND_SUBJECT, subject, X509_NAME) +} ASN1_SEQUENCE_END(EST_ISSUER_AND_SUBJECT) + +IMPLEMENT_ASN1_FUNCTIONS(EST_ISSUER_AND_SUBJECT) + diff --git a/src/pkix/est/pki_x509_est_attr.c b/src/pkix/est/pki_x509_est_attr.c new file mode 100644 index 00000000..4c6c13fe --- /dev/null +++ b/src/pkix/est/pki_x509_est_attr.c @@ -0,0 +1,563 @@ +/* + * OpenCA EST -- signed attributes handling routines + * (c) 2009 by Massimiliano Pala and OpenCA Group + * + */ + +#include + +#define EST_CONF_LIST_SIZE 8 + +EST_CONF_ATTRIBUTE EST_ATTRIBUTE_list [EST_CONF_LIST_SIZE] = { + { EST_ATTRIBUTE_MESSAGE_TYPE, "2.16.840.1.113733.1.9.2", + "estMessageType", "EST Message Type", -1 }, + { EST_ATTRIBUTE_PKI_STATUS, "2.16.840.1.113733.1.9.3", + "pkiStatus", "Status", -1 }, + { EST_ATTRIBUTE_FAIL_INFO, "2.16.840.1.113733.1.9.4", + "failInfo", "Failure Info", -1 }, + { EST_ATTRIBUTE_SENDER_NONCE, "2.16.840.1.113733.1.9.5", + "senderNonce", "Sender Nonce", -1 }, + { EST_ATTRIBUTE_RECIPIENT_NONCE, "2.16.840.1.113733.1.9.6", + "recipientNonce", "Recipient Nonce", -1 }, + { EST_ATTRIBUTE_TRANS_ID, "2.16.840.1.113733.1.9.7", + "transId", "Transaction Identifier", -1 }, + { EST_ATTRIBUTE_EXTENSION_REQ, "2.16.840.1.113733.1.9.8", + "extensionReq", "Extension Request", -1 }, + { EST_ATTRIBUTE_PROXY_AUTH, "1.3.6.1.4.1.4263.5.5", + "proxyAuth", "Proxy Authenticator", -1 }, +}; + +void PKI_X509_EST_init ( void ) { + int i = 0; + int nid = NID_undef; + + EST_CONF_ATTRIBUTE *curr_oid = NULL; + + i = 0; + while( i < EST_CONF_LIST_SIZE ) { + curr_oid = &EST_ATTRIBUTE_list[i]; + if(( nid = OBJ_create(curr_oid->oid_s, curr_oid->descr, + curr_oid->long_descr)) == NID_undef) { + return; + } + + curr_oid->nid = nid; + i++; + } + + return; +} + +/*! \brief Returns the EST_ATTRIBUTE_TYPE from the attribute name */ + +EST_ATTRIBUTE_TYPE PKI_X509_EST_ATTRIBUTE_get_txt(const char * txt) { + + EST_CONF_ATTRIBUTE *curr = NULL; + int i = 0; + + while( i < EST_CONF_LIST_SIZE ) { + + // Gets the i-th attribute + curr = &EST_ATTRIBUTE_list[i]; + + // Check if the attribute matches + if (strcmp_nocase(curr->descr, txt) == 0) break; + + i++; + } + + // Returns the type value + if (curr) return (EST_ATTRIBUTE_TYPE)curr->attr_type; + + // Not found + return EST_ATTRIBUTE_TYPE_UNKNOWN; +} + +/*! \brief Returns the PKI_ID of the specified EST_ATTRIBUTE_TYPE */ + +PKI_ID PKI_X509_EST_ATTRIBUTE_get_nid ( EST_ATTRIBUTE_TYPE num ) { + + EST_CONF_ATTRIBUTE *curr = NULL; + int i = 0; + + i = 0; + while( i < EST_CONF_LIST_SIZE ) { + curr = &EST_ATTRIBUTE_list[i]; + if ( curr->attr_type == num ) + break; + i++; + } + + if ( curr ) return curr->nid; + + return NID_undef; +} + +/*! \brief Returns the PKI_OID for the specified EST attribute */ + +PKI_OID *PKI_X509_EST_MSG_get_oid ( EST_ATTRIBUTE_TYPE est_attribute ) { + + EST_CONF_ATTRIBUTE *curr = NULL; + + int i = 0; + + i = 0; + while( i < EST_CONF_LIST_SIZE ) { + curr = &EST_ATTRIBUTE_list[i]; + if ( curr->attr_type == est_attribute ) + break; + i++; + } + + if ( curr ) return PKI_OID_get ( curr->descr ); + + return NULL; +} + +/*! \brief Sets the message type attribute in a EST message (signed P7) */ +int PKI_X509_EST_MSG_set_attribute(PKI_X509_EST_MSG * msg, + EST_ATTRIBUTE_TYPE type, + const unsigned char * const data, + size_t size) { + + PKI_X509_ATTRIBUTE *a = NULL; + PKI_ID id = 0; + + if (!msg || !data) return PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + + // Gets the Type of the attribute + if ((id = PKI_X509_EST_ATTRIBUTE_get_nid ( type )) == NID_undef ) { + return PKI_ERROR(PKI_ERR_EST_ATTRIBUTE_UNKNOWN, NULL); + } + + // Creates the Attribute based on the type + switch (type) { + + // PRINTABLESTRING Attributes + case EST_ATTRIBUTE_MESSAGE_TYPE: + case EST_ATTRIBUTE_PKI_STATUS: + case EST_ATTRIBUTE_FAIL_INFO: + case EST_ATTRIBUTE_TRANS_ID: + case EST_ATTRIBUTE_EXTENSION_REQ: + case EST_ATTRIBUTE_PROXY_AUTH: { + a = PKI_X509_ATTRIBUTE_new(id, + V_ASN1_PRINTABLESTRING, + data, + size ); + } break; + + // OCTET_STRING Attributes + case EST_ATTRIBUTE_SENDER_NONCE: + case EST_ATTRIBUTE_RECIPIENT_NONCE: { + a = PKI_X509_ATTRIBUTE_new(id, + V_ASN1_OCTET_STRING, + data, + size); + } break; + + default: + return PKI_ERROR(PKI_ERR_EST_ATTRIBUTE_UNKNOWN, NULL); + } + + // Checks we have a valid object + if (!a) return PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + + // Removes the attribute (if already present) + PKI_X509_PKCS7_delete_signed_attribute(msg, id); + + // Returns the result of adding the signed attribute + return PKI_X509_PKCS7_add_signed_attribute( msg, a); +} + +/*! \brief Adds an attribute (identified by its name) to a EST message */ + +int PKI_X509_EST_MSG_set_attribute_by_name(PKI_X509_EST_MSG * msg, + const char * const name, + const unsigned char * const data, + size_t size) { + + PKI_ID type = 0; + + // Input Check + if (!msg || !data || !name) + return PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + + // Gets the Attribute Type + if ((type = PKI_X509_EST_ATTRIBUTE_get_txt(name)) == -1) + return PKI_ERROR(PKI_ERR_EST_ATTRIBUTE_UNKNOWN, NULL); + + // Sets the Attribute in the Message + return PKI_X509_EST_MSG_set_attribute(msg, type, data, size); + +} + +/*! \brief Adds the specified attribute (int) as a string */ + +int PKI_X509_EST_MSG_set_attribute_int(PKI_X509_EST_MSG * msg, + PKI_ID id, + int val) { + + char buf[BUFF_MAX_SIZE]; + + if (!msg ) return PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + + snprintf(buf, sizeof(buf), "%d%c", val, '\x0'); + + return PKI_X509_EST_MSG_set_attribute(msg, id, + (const unsigned char*) buf, strlen(buf)); +} + +/*! \brief Returns the value of the specified attribute in a PKI_MEM */ + +PKI_MEM * PKI_X509_EST_MSG_get_attr_value(const PKI_X509_EST_MSG * const msg, + EST_ATTRIBUTE_TYPE type) { + + const PKI_X509_ATTRIBUTE *attr = NULL; + PKI_MEM *ret = NULL; + + const PKI_STRING *st = NULL; + int nid = NID_undef; + + // Input Check + if (!msg || msg->value) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return NULL; + } + + // Attribute Type Check + if ((nid = PKI_X509_EST_ATTRIBUTE_get_nid(type)) == NID_undef) { + PKI_ERROR(PKI_ERR_EST_ATTRIBUTE_UNKNOWN, NULL); + return NULL; + } + + // Retrieves the Signed Attribute from the message + if ((attr = PKI_X509_PKCS7_get_signed_attribute(msg, nid)) == NULL) { + + // Attribute not present + return NULL; + } + + // If we have a value, let's return it in a PKI_MEM container + if ((st = PKI_X509_ATTRIBUTE_get_value(attr)) != NULL) { + + // Build the container + ret = PKI_MEM_new_null (); + ret->data = PKI_Malloc((size_t) st->length); + ret->size = (size_t) st->length; + + // Copy the data from the attribute to the container + memcpy(ret->data, st->data, (size_t)st->length); + } + + // Returns the container + return ret; +} + +int PKI_X509_EST_MSG_get_attr_value_int(const PKI_X509_EST_MSG * const msg, + EST_ATTRIBUTE_TYPE type) { + + + PKI_MEM *mem = NULL; + int ret = -1; + + // Input Checks + if (!msg || !msg->value) return -1; + + // Gets the Value from the message + if ((mem = PKI_X509_EST_MSG_get_attr_value(msg, type)) == NULL) { + + // Attribute not found, let's return -1 as the error value + return -1; + } + + // If we have a good value, let's convert it to an integer + if ( mem && mem->data && mem->size > 0 ) { + + // Gets the integer + ret = atoi((const char *) mem->data); + } + + // Free the allocated memory + PKI_MEM_free(mem); + + // Returns the Attribute value as an integer + return ret; +} + + +/* ------------------------ Specific Attributes ------------------------ */ + +/*! \brief Generates a new PKI_MEM suitable for the transId of a EST message */ + +PKI_MEM *PKI_X509_EST_MSG_new_trans_id(const PKI_X509_KEYPAIR * key) { + + CRYPTO_DIGEST *dgst = NULL; + PKI_MEM *mem = NULL; + + if (!key || !key->value ) return NULL; + + if((dgst = PKI_X509_KEYPAIR_pub_digest(key, PKI_DIGEST_ALG_DEFAULT )) + == NULL ) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, + "Can not retrieve digest of public key (%d)", + PKI_DIGEST_ALG_DEFAULT); + + return NULL; + } + + // Allocates a new PKI_MEM container + if(( mem = PKI_MEM_new_null()) == NULL ) { + + // Memory Allocation Error + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + PKI_DIGEST_free ( dgst ); + return NULL; + } + + // Retrieves the parsed digest value + if ((mem->data = (unsigned char *) PKI_DIGEST_get_parsed(dgst)) + == NULL ) { + // Error while getting the parsed digest + PKI_ERROR(PKI_ERR_DIGEST_VALUE_NULL, NULL); + + // Free Allocated Memory + PKI_MEM_free(mem); + PKI_DIGEST_free(dgst); + + // Nothing to return + return NULL; + } + + // Sets the Size of the data + mem->size = strlen((const char *) mem->data); + + // Free the DIGEST structure + if (dgst) PKI_DIGEST_free(dgst); + + // All Done + return mem; +} + +/*! \brief Sets the transactionId attribute in a EST message */ + +int PKI_X509_EST_MSG_set_trans_id(PKI_X509_EST_MSG * msg, + const PKI_MEM * const mem) { + + int ret = PKI_OK; + + // Input Checks + if (!msg || !mem) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return ( PKI_ERR ); + } + + // Sets the Attribute + ret = PKI_X509_EST_MSG_set_attribute(msg, + EST_ATTRIBUTE_TRANS_ID, + mem->data, + mem->size ); + + // Returns the return code from setting the attribute + return ret; +} + +char * PKI_X509_EST_MSG_get_trans_id(const PKI_X509_EST_MSG * const msg) { + + PKI_MEM * mem = NULL; + char * ret = NULL; + + if((mem = PKI_X509_EST_MSG_get_attr_value(msg, + EST_ATTRIBUTE_TRANS_ID)) == NULL) { + return NULL; + } + + // Checks the returned MEM structure for data + if (!mem->data || mem->size <= 0) { + PKI_MEM_free(mem); + return NULL; + } + + // Get a reference + ret = (char *) mem->data; + mem->data = NULL; + mem->size = 0; + + // Releases the PKI_MEM structure + PKI_MEM_free(mem); + + // Returns the duplicated value + return ret; +} + +/*! \brief Sets the senderNonce attribute in a EST message */ + +int PKI_X509_EST_MSG_set_sender_nonce(PKI_X509_EST_MSG * msg, + const PKI_MEM * const mem) { + + int ret = PKI_OK; + + // Input Check + if (!msg) return PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + + if (mem != NULL) { + ret = PKI_X509_EST_MSG_set_attribute(msg, + EST_ATTRIBUTE_SENDER_NONCE, + mem->data, + mem->size); + } else { + + PKI_MEM * aMem = NULL; + // Locally allocated entry + + // Allocates the local mem structure + if ((aMem = PKI_MEM_new(NONCE_SIZE)) == NULL) + return PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + + // Use random bytes to fill in the data + RAND_bytes(aMem->data, NONCE_SIZE); + + // Sets the Attribute + ret = PKI_X509_EST_MSG_set_attribute(msg, + EST_ATTRIBUTE_SENDER_NONCE, + aMem->data, + aMem->size); + + // Free locally allocated memory + if (aMem) PKI_MEM_free(aMem); + + } + + return ret; +} + + +/*! \brief Sets the recipientNonce attribute from a EST message */ + +int PKI_X509_EST_MSG_set_recipient_nonce(PKI_X509_EST_MSG * msg, + const PKI_MEM * const mem) { + + int ret = PKI_OK; + + // Input Check + if (!msg || !msg->value) return PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + + if( mem != NULL ) { + ret = PKI_X509_EST_MSG_set_attribute(msg, + EST_ATTRIBUTE_RECIPIENT_NONCE, + mem->data, + mem->size ); + } else { + + PKI_MEM * aMem = NULL; + // Locally allocated structure + + // Allocate the structure + if ((aMem = PKI_MEM_new(NONCE_SIZE)) == NULL) + return PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + + // Fill in with random bytes + RAND_bytes(aMem->data, NONCE_SIZE); + + // Sets the attribute + ret = PKI_X509_EST_MSG_set_attribute(msg, + EST_ATTRIBUTE_RECIPIENT_NONCE, + aMem->data, + aMem->size); + + // Free locally allocated memory + PKI_MEM_free(aMem); + } + + // All Done + return ret; +} + +/*! \brief Sets the messageType attribute in a EST message */ + +int PKI_X509_EST_MSG_set_type(PKI_X509_EST_MSG * msg, + EST_MESSAGE_TYPE type) { + + return PKI_X509_EST_MSG_set_attribute_int(msg, + EST_ATTRIBUTE_MESSAGE_TYPE, + type); +} + +/*! \brief Returns the messageType attribute from a EST message */ + +EST_MESSAGE_TYPE PKI_X509_EST_MSG_get_type(const PKI_X509_EST_MSG * const msg) { + + return PKI_X509_EST_MSG_get_attr_value_int(msg, + EST_ATTRIBUTE_MESSAGE_TYPE); +} + +/*! \brief Sets the pkiStatus attribute in a EST message */ + +int PKI_X509_EST_MSG_set_status(PKI_X509_EST_MSG * msg, + EST_STATUS status) { + + return PKI_X509_EST_MSG_set_attribute_int(msg, + EST_ATTRIBUTE_PKI_STATUS, + (int) status); +} + + +/*! \brief Returns the pkiStatus attribute from a EST message */ + +EST_STATUS PKI_X509_EST_MSG_get_status(const PKI_X509_EST_MSG * const msg) { + + return (EST_STATUS) PKI_X509_EST_MSG_get_attr_value_int(msg, + EST_ATTRIBUTE_PKI_STATUS); +} + +/*! \brief Sets the failInfo attribute in a EST message */ + +int PKI_X509_EST_MSG_set_failinfo(PKI_X509_EST_MSG * msg, + int fail) { + + return PKI_X509_EST_MSG_set_attribute_int(msg, + EST_ATTRIBUTE_FAIL_INFO, + fail); +} + +/*! \brief Returns the failInfo attribute from a EST message */ + +EST_FAILURE PKI_X509_EST_MSG_get_failinfo(const PKI_X509_EST_MSG * const msg) { + + return (EST_FAILURE) PKI_X509_EST_MSG_get_attr_value_int(msg, + EST_ATTRIBUTE_FAIL_INFO); +} + + +/*! \brief Returns the senderNonce attribute from a EST message */ + +PKI_MEM *PKI_X509_EST_MSG_get_sender_nonce(const PKI_X509_EST_MSG * const msg) { + + return PKI_X509_EST_MSG_get_attr_value(msg, + EST_ATTRIBUTE_SENDER_NONCE); +} + +/*! \brief Returns the recipientNonce attribute from a EST message */ + +PKI_MEM *PKI_X509_EST_MSG_get_recipient_nonce(PKI_X509_EST_MSG * const msg) { + + return PKI_X509_EST_MSG_get_attr_value ( msg, + EST_ATTRIBUTE_RECIPIENT_NONCE ); +} + +/*! \brief Sets the proxyAuthenticator attribute from a EST message */ + +int PKI_X509_EST_MSG_set_proxy(PKI_X509_EST_MSG * msg, + int auth) { + + return PKI_X509_EST_MSG_set_attribute_int(msg, + EST_ATTRIBUTE_PROXY_AUTH, + auth ); +} + +int PKI_X509_EST_MSG_get_proxy(const PKI_X509_EST_MSG * const msg) { + + return PKI_X509_EST_MSG_get_attr_value_int(msg, + EST_ATTRIBUTE_PROXY_AUTH ); + +} + diff --git a/src/pkix/est/pki_x509_est_data.c b/src/pkix/est/pki_x509_est_data.c new file mode 100644 index 00000000..5f4b0cc4 --- /dev/null +++ b/src/pkix/est/pki_x509_est_data.c @@ -0,0 +1,91 @@ +/* EST msg handling + * (c) 2009-2019 by Massimiliano Pala and OpenCA Labs + * All Rights Reserved + */ + +#include + +/*! \brief Generates a new EST_DATA */ + +PKI_X509_EST_DATA * PKI_X509_EST_DATA_new ( void ) { + + return PKI_X509_PKCS7_new ( PKI_X509_PKCS7_TYPE_ENCRYPTED ); +} + +/*! \brief Frees the memory associated with a PKI_X509_EST_DATA */ + +void PKI_X509_EST_DATA_free ( PKI_X509_EST_DATA *data ) { + + PKI_X509_PKCS7_free ( data ); + + return; +} + + +/*! \brief Adds a recipient to a EST_DATA */ + +int PKI_X509_EST_DATA_add_recipient ( PKI_X509_EST_DATA *data, + PKI_X509_CERT *recipient ) { + return PKI_X509_PKCS7_add_recipient ( data, recipient ); +} + +/*! \brief Adds a stack of recipients for a EST_DATA */ + +int PKI_X509_EST_DATA_set_recipients ( PKI_X509_EST_DATA *data, + PKI_X509_CERT_STACK *sk ) { + return PKI_X509_PKCS7_set_recipients ( data, sk ); +} + +/*! \brief Sets the content of the EST_DATA via a PKI_X509 object */ + +int PKI_X509_EST_DATA_set_x509_obj ( PKI_X509_EST_DATA *data, PKI_X509 *obj ) +{ + PKI_MEM *mem = NULL; + int ret = PKI_ERR; + + if ( !data || !data->value || !obj || !obj->value ) + return PKI_ERR; + + if (( mem = PKI_X509_put_mem ( obj, PKI_DATA_FORMAT_ASN1, NULL, NULL )) == NULL ) + return PKI_ERROR(PKI_ERR_GENERAL, NULL); + + ret = PKI_X509_EST_DATA_set_raw_data ( data, mem->data, (ssize_t) mem->size ); + + PKI_MEM_free ( mem ); + + return ret; +} + +/*! \brief Sets the content of the EST_DATA via a EST_ISSUER_AND_SUBJECT */ + +int PKI_X509_EST_DATA_set_ias ( PKI_X509_EST_DATA *est_data, EST_ISSUER_AND_SUBJECT *ias ) +{ + unsigned char *data = NULL; + ssize_t size = 0; + + if ( !est_data || !est_data->value || !ias ) return PKI_ERR; + + if( (size = i2d_EST_ISSUER_AND_SUBJECT(ias, NULL)) <= 0 ) return PKI_ERR; + + if ((data = ( unsigned char * ) PKI_Malloc ( (size_t) size )) == NULL ) return PKI_ERR; + + if (i2d_EST_ISSUER_AND_SUBJECT( ias, &data ) <= 0 ) + { + PKI_Free ( data ); + return PKI_ERR; + } + + return PKI_X509_EST_DATA_set_raw_data ( est_data, data, size ); +} + +/*! \brief Sets the content of the EST_DATA (raw data) */ + +int PKI_X509_EST_DATA_set_raw_data ( PKI_X509_EST_DATA *data, + unsigned char *raw_val, ssize_t size ) { + + if ( !data || !data->value || !raw_val || size <= 0 ) + return PKI_ERR; + + return PKI_X509_PKCS7_encode ( data, raw_val, (size_t) size ); +} + diff --git a/src/pkix/est/pki_x509_est_msg.c b/src/pkix/est/pki_x509_est_msg.c new file mode 100644 index 00000000..d61fc7a7 --- /dev/null +++ b/src/pkix/est/pki_x509_est_msg.c @@ -0,0 +1,216 @@ +/* EST msg handling + * (c) 2009-2019 by Massimiliano Pala and OpenCA Labs + * All Rights Reserved + */ + +#include + +/*! \brief Generates a new PKI_X509_EST message */ + +PKI_X509_EST_MSG *PKI_X509_EST_MSG_new ( EST_MESSAGE_TYPE type ) { + + PKI_X509_EST_MSG * ret = NULL; + + if ((ret = PKI_X509_PKCS7_new (PKI_X509_PKCS7_TYPE_SIGNED)) == NULL){ + return NULL; + } + + return ret; +} + +/*! \brief Frees the memory associated with a PKI_X509_EST_MSG */ + +void PKI_X509_EST_MSG_free ( PKI_X509_EST_MSG *msg ) { + + PKI_X509_PKCS7_free ( msg ); + + return; +} + +/*! \brief Encodes a EST_MSG to a PKCS7 structure */ + +int PKI_X509_EST_MSG_encode ( PKI_X509_EST_MSG *msg, + PKI_X509_EST_DATA *data ) { + + PKI_MEM *mem = NULL; + int ret = PKI_OK; + + if ((mem = PKI_X509_PKCS7_put_mem ( data, PKI_DATA_FORMAT_ASN1, + NULL, NULL, NULL )) == NULL ) { + return PKI_ERR; + } + + ret = PKI_X509_PKCS7_encode ( msg, mem->data, mem->size ); + PKI_MEM_free ( mem ); + + return ret; +} + +/*! \brief Retrieves the decoded data (raw) from a EST_MSG */ + +PKI_MEM *PKI_X509_EST_MSG_decode ( PKI_X509_EST_MSG *msg, + PKI_X509_KEYPAIR * key, PKI_X509_CERT *x ) { + + return PKI_X509_PKCS7_decode ( msg, key, x ); +} + +/*! + * \brief Retrieves the X509 object from the EST_MSG + */ + +PKI_X509 *PKI_X509_EST_MSG_get_x509_obj ( PKI_X509_EST_MSG *msg, + PKI_DATATYPE type, PKI_DATA_FORMAT format, + PKI_X509_KEYPAIR *key, PKI_X509_CERT *x ) { + + PKI_MEM *mem = NULL; + PKI_X509 *ret = NULL; + + if((mem = PKI_X509_PKCS7_decode ( msg, key, x )) == NULL ) { + PKI_log_debug("Can not decode EST message"); + return NULL; + }; + + if((ret = PKI_X509_get_mem( mem, type, format, NULL, NULL )) == NULL ) { + PKI_log_debug("Can not get X509 object (%d) from raw data.", type); + }; + + if(mem) PKI_MEM_free ( mem ); + + return ret; +} + +/*! \brief Add a signer to a EST_MSG */ + +int PKI_X509_EST_MSG_add_signer ( PKI_X509_EST_MSG *msg, + PKI_X509_CERT *signer, PKI_X509_KEYPAIR *key, + PKI_DIGEST_ALG *md ) { + + return PKI_X509_PKCS7_add_signer (msg, signer, key, md); +} + +/*! \brief Add a signer to a EST_MSG by using the passed toke data */ + +int PKI_X509_EST_MSG_add_signer_tk ( PKI_X509_EST_MSG *msg, + PKI_TOKEN *tk, PKI_DIGEST_ALG *md ) { + + return PKI_X509_PKCS7_add_signer_tk ( msg, tk, md ); +} + +/*! \brief Generates a PKCSReq message from a keypair and a subject */ + +PKI_X509_EST_MSG * PKI_X509_EST_MSG_new_certreq ( PKI_X509_KEYPAIR *key, + PKI_X509_REQ *req, PKI_X509_CERT *signer, + PKI_X509_CERT_STACK *recipients, PKI_DIGEST_ALG *md ) { + + PKI_X509_EST_MSG *ret = NULL; + PKI_X509_EST_DATA *est_data = NULL; + + PKI_X509_REQ *my_request = NULL; + PKI_X509_CERT *my_signer = NULL; + + if ( !key || !key->value ) { + PKI_log_err ( "Signing Key is required!"); + return NULL; + } + + if ( ( !req || !req->value ) && (!signer || !signer->value ) ) { + PKI_log_err ( "ERROR, a request or singer is required!"); + return NULL; + } + + if ( !recipients ) { + PKI_log_err ("Recipients are required to encrypt EST messge!"); + return NULL; + } + + if ( req && req->value ) { + my_request = req; + } else { + char *subject = NULL; + + subject = PKI_X509_CERT_get_parsed( signer, + PKI_X509_DATA_SUBJECT ); + + if ( !subject ) return NULL; + + /* We need the request for the inner P7 (encrypted) */ + if((my_request = PKI_X509_REQ_new( key, subject, NULL, + NULL, NULL, NULL )) == NULL ) { + PKI_log_err( "EST_MSG_new_certreq()::Can not generate " + "a new PKCS#10 request"); + PKI_Free ( subject ); + goto err; + }; + + PKI_Free ( subject ); + } + + if ( signer && signer->value ) { + my_signer = signer; + } else { + // char * subject = NULL; + + // if (( subject = PKI_X509_REQ_get_parsed ( my_request, + // PKI_X509_DATA_SUBJECT )) == NULL ) { + // return NULL; + // } + + if ((my_signer = PKI_X509_CERT_new ( NULL, key, + my_request, NULL, NULL, PKI_VALIDITY_ONE_MONTH, NULL, + NULL, NULL, NULL )) == NULL ) { + + PKI_log_err ( "Can not generate a self-sign cert for " + "EST message"); + goto err; + } + // PKI_Free ( subject ); + } + + if ( (est_data = PKI_X509_EST_DATA_new ()) == NULL ) { + PKI_log_err ( "Memory Failure"); + goto err; + } + + if ( PKI_X509_EST_DATA_set_recipients ( est_data, + recipients ) == PKI_ERR ) { + PKI_log_err ( "Can not set recipients in EST message!"); + goto err; + } + + if ( PKI_X509_EST_DATA_set_x509_obj( est_data, + my_request ) == PKI_ERR ) { + goto err; + } + + // Now we have the encrypted content, let's generate the outer + // message and set the content + + if(( ret = PKI_X509_EST_MSG_new(PKI_X509_EST_MSG_PKCSREQ)) == NULL ) { + PKI_log_err ( "Memory Failure"); + goto err; + } + + if( PKI_X509_EST_MSG_add_signer ( ret, my_signer, key, md ) + == PKI_ERR ) { + PKI_log_err ( "Can not set the EST message signer"); + goto err; + } + + PKI_X509_EST_MSG_set_sender_nonce ( ret, NULL ); + PKI_X509_EST_MSG_set_type ( ret, PKI_X509_EST_MSG_PKCSREQ ); + + if (PKI_X509_EST_MSG_encode ( ret, est_data ) == PKI_ERR ) { + PKI_log_err ( "Can not encode EST message!"); + goto err; + } + + return ret; + +err: + if ( my_request && !req ) PKI_X509_REQ_free (my_request); + if ( my_signer && !signer ) PKI_X509_CERT_free (my_signer); + if ( est_data ) PKI_X509_EST_DATA_free ( est_data ); + if ( ret ) PKI_X509_EST_MSG_free ( ret ); + + return NULL; +} diff --git a/src/pkix/pki_x509_p12.c b/src/pkix/pki_x509_p12.c new file mode 100644 index 00000000..ca119a5a --- /dev/null +++ b/src/pkix/pki_x509_p12.c @@ -0,0 +1,1020 @@ +/* PKI_TOKEN write/load object management */ + +#include + +/* ----------------------- Internal PKCS12 functions ----------------------- */ + +enum bag_datatype_st { + BAG_DATATYPE_ALL = 0, + BAG_DATATYPE_KEYPAIR, + BAG_DATATYPE_CERT, + BAG_DATATYPE_CACERT, + BAG_DATATYPE_OTHERCERTS, + BAG_DATATYPE_UNKNOWN +}; + +/* Prototypes */ + +static STACK_OF(PKCS12_SAFEBAG) * _get_bags( + const PKI_X509_PKCS12 * const p12, + const char * const pwd); + +static void * _get_bags_data( + const STACK_OF(PKCS12_SAFEBAG) * bags, + int dataType, + const char * const pwd ); + +static void * _get_bag_value(PKCS12_SAFEBAG * bag, + int dataType, + const char * const pwd ); + +static PKI_X509_CERT * _get_cacert( + const PKI_X509_PKCS12 * const p12, + const PKI_X509_CERT * const x, + const char *pwd); + +static PKI_X509_CERT_STACK * _get_othercerts_stack( + const PKI_X509_PKCS12 * const p12, + const PKI_X509_CERT * const x, + const char * const pwd); + +static PKI_X509_KEYPAIR_STACK * _get_keypair_stack( + const PKI_X509_PKCS12 * const p12, + const char * const pwd); + +/* Internal Functions */ + +static STACK_OF(PKCS12_SAFEBAG) * _get_bags( + const PKI_X509_PKCS12 * const p12, + const char * const pwd) { + + STACK_OF(PKCS7) *asafes = NULL; + STACK_OF(PKCS12_SAFEBAG) *bags = NULL; + STACK_OF(PKCS12_SAFEBAG) *ret = NULL; + + int i, bagnid; + PKCS7 *p7 = NULL; + + if ( !p12 || !p12->value ) return NULL; + + if (!( asafes = PKCS12_unpack_authsafes(p12->value))) + return (NULL); + + if((ret = sk_PKCS12_SAFEBAG_new_null()) == NULL ) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return NULL; + } + + for (i = 0; i < sk_PKCS7_num (asafes); i++) { + PKCS12_SAFEBAG *oneBag = NULL; + + p7 = sk_PKCS7_value (asafes, i); + bagnid = OBJ_obj2nid (p7->type); + if (bagnid == NID_pkcs7_data) { + bags = PKCS12_unpack_p7data(p7); + } else if (bagnid == NID_pkcs7_encrypted) { + if( pwd) { + bags=PKCS12_unpack_p7encdata(p7,pwd,(int)strlen(pwd)); + } else { + bags = PKCS12_unpack_p7encdata(p7, NULL, 0); + } + } else { + continue; + } + + if (!bags) { + PKI_DEBUG("No Bags got from PKCS7 # %d", i); + continue; + } + + while ((oneBag = sk_PKCS12_SAFEBAG_pop ( bags )) != NULL ){ + sk_PKCS12_SAFEBAG_push( ret, oneBag ); + } + + sk_PKCS12_SAFEBAG_free ( bags ); + bags = NULL; + } + + if( sk_PKCS12_SAFEBAG_num( ret ) < 1 ) { + PKI_log_debug("%s:%d::No SAFEBAGS found in P12!", + __FILE__, __LINE__ ); + sk_PKCS12_SAFEBAG_free ( ret ); + return ( NULL ); + } + + return ( ret ); +} + +static void * _get_bags_data ( + const STACK_OF(PKCS12_SAFEBAG) * bags, + int dataType, + const char * const pwd ) { + + int i; + + void *ret = NULL; + PKCS12_SAFEBAG *bag = NULL; + + if( !bags ) { + PKI_log_debug("_get_bags_data()::ERROR, no bags passed!"); + return ( NULL ); + } + + switch ( dataType ) { + case BAG_DATATYPE_KEYPAIR: + ret = PKI_STACK_X509_KEYPAIR_new(); + break; + case BAG_DATATYPE_CERT: + case BAG_DATATYPE_CACERT: + case BAG_DATATYPE_OTHERCERTS: + ret = PKI_STACK_X509_CERT_new(); + break; + default: + return ( NULL ); + } + + if( !ret ) { + PKI_log_debug("%s:%d::Memory Error", __FILE__, __LINE__ ); + return ( NULL ); + } + + for ( i=0 ; i < sk_PKCS12_SAFEBAG_num ( bags ); i++ ) { + PKI_STACK *bag_sk = NULL; + void *el = NULL; + + if((bag = sk_PKCS12_SAFEBAG_value ( bags, i )) == NULL ) { + PKI_log_debug("_get_bags_data()::No BaG got from " + "bags # %d", i ); + continue; + }; + + if((bag_sk = _get_bag_value ( bag, dataType, pwd )) == NULL ) { + // PKI_log_debug("_get_bags_data()::No BaG_SK got from " + // "bags # %d", i ); + continue; + } + + // PKI_log_debug("_get_bags_data()::Got %d data items (i=%d)", + // PKI_STACK_elements( bag_sk ), i); + + while ((el = PKI_STACK_pop ( bag_sk )) != NULL) { + PKI_STACK_push( ret, el ); + } + + if (bag_sk) PKI_STACK_free(bag_sk); + bag_sk = NULL; + } + + return ( ret ); +} + + +static void * _get_bag_value( + PKCS12_SAFEBAG *bag, + int dataType, + const char * const pwd ) { + + int type; + + PKI_X509_KEYPAIR_VALUE *pkey = NULL; + PKI_X509_KEYPAIR *k = NULL; + PKI_X509_CERT *cert = NULL; + PKI_X509_CERT_VALUE *cert_val = NULL; + + const PKCS8_PRIV_KEY_INFO *p8 = NULL; + + void *ret = NULL; + PKI_STACK *sk = NULL; + + type = M_PKCS12_bag_type ( bag ); + + switch ( type ) { + + case NID_keyBag: { + if( dataType != BAG_DATATYPE_KEYPAIR ) { + return ( NULL ); + }; +#if OPENSSL_VERSION_NUMBER > 0x1010000fL + p8 = PKCS12_SAFEBAG_get0_p8inf(bag); + if ((pkey = EVP_PKCS82PKEY(p8)) == NULL) return NULL; +#else + p8 = bag->value.keybag; + if ((pkey = EVP_PKCS82PKEY((PKCS8_PRIV_KEY_INFO *)p8)) == NULL) return (NULL); +#endif + + // print_attribs (out, p8->attributes, "Key Attributes"); + // PEM_write_bio_PrivateKey (out, pkey, enc, NULL, 0, NULL, pempass); + // ret = EVP_PKEY_new(); + // EVP_PKEY_copy_parameters(ret, pkey); + if (( k = PKI_X509_KEYPAIR_new_null()) == NULL ) { + return NULL; + } + k->value = pkey; + ret = k; + } break; + + case NID_pkcs8ShroudedKeyBag: { + if( dataType != BAG_DATATYPE_KEYPAIR ) { + return ( NULL ); + }; + if (!(p8 = PKCS12_decrypt_skey(bag, pwd, (int) strlen(pwd)))) { + return ( NULL ); + } + +#if OPENSSL_VERSION_NUMBER > 0x1010000fL + if ((pkey = EVP_PKCS82PKEY(p8)) == NULL) return (NULL); +#else + if ((pkey = EVP_PKCS82PKEY((PKCS8_PRIV_KEY_INFO *)p8)) == NULL) return (NULL); +#endif + + if (( k = PKI_X509_KEYPAIR_new_null()) == NULL ) { + return NULL; + } + k->value = pkey; + ret = k; + } break; + + case NID_certBag: { + if( (dataType != BAG_DATATYPE_CERT ) && + ( dataType != BAG_DATATYPE_CACERT ) && + (dataType != BAG_DATATYPE_OTHERCERTS)) { + return ( NULL ); + } + + // Checks it is not a key bag +#if OPENSSL_VERSION_NUMBER > 0x1010000fL + if (PKCS12_SAFEBAG_get0_attr(bag, NID_localKeyID)) { + if (dataType != BAG_DATATYPE_CERT) return NULL; + } +#else + if (PKCS12_get_attr(bag, NID_localKeyID)) { + if (dataType != BAG_DATATYPE_CERT) return NULL; + } +#endif + + // print_attribs (out, bag->attrib, "Bag Attributes"); + if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate ) { + return ( NULL ); + } + if (!(cert_val = PKCS12_certbag2x509(bag))) { + return ( NULL ); + } + if(( cert = PKI_X509_CERT_new_null ()) == NULL ) { + X509_free ( cert_val ); + return NULL; + } + + cert->value = cert_val; + ret = cert; + } break; + + case NID_safeContentsBag: { + // PKI_log_debug("Found Bag => TYPE is NID_safeContentsBag"); + const STACK_OF(PKCS12_SAFEBAG) * safes = NULL; + + // Get the SafeBags +#if OPENSSL_VERSION_NUMBER > 0x1010000fL + safes = PKCS12_SAFEBAG_get0_safes(bag); +#else + safes = bag->value.safes; +#endif + + // If no safe bags, let's return NULL + if (!safes) return NULL; + + // Returns the SafeBags Data + return _get_bags_data(safes, dataType, pwd); + + } break; + + default: { + PKI_log_debug("ERROR::P12 BAG type not supported (%d)", + type ); + return (NULL); + } + } + + switch ( dataType ) { + case BAG_DATATYPE_KEYPAIR: + sk = PKI_STACK_X509_KEYPAIR_new(); + PKI_STACK_X509_KEYPAIR_push ( + (PKI_X509_KEYPAIR_STACK *) sk, + (PKI_X509_KEYPAIR *) ret ); + break; + case BAG_DATATYPE_CERT: + case BAG_DATATYPE_CACERT: + case BAG_DATATYPE_OTHERCERTS: + sk = PKI_STACK_X509_CERT_new(); + PKI_STACK_X509_CERT_push ( (PKI_X509_CERT_STACK *) sk, + (PKI_X509_CERT *) ret ); + break; + } + + return ( sk ); +} + +static PKI_X509_CERT_STACK * _get_cert_stack( + const PKI_X509_PKCS12 * const p12, + const char * const pwd) { + + STACK_OF(PKCS12_SAFEBAG) *sk_bags = NULL; + PKI_X509_CERT_STACK *ret = NULL; + + // PKI_log_debug("_get_cert_stack()::Start()!"); + + if((sk_bags = _get_bags ( p12, pwd )) == NULL ) { + PKI_log_debug("_get_cert_stack()::No Bags found!"); + return ( NULL ); + } + + // PKI_log_debug("_get_cert_stack()::Got %d Bags found!", + // sk_PKCS12_SAFEBAG_num( sk_bags) ); + ret = _get_bags_data ( sk_bags, BAG_DATATYPE_CERT, pwd ); + // PKI_log_debug("_get_cert_stack()::Got %d Certs back", + // PKI_STACK_X509_CERT_elements( ret )); + + // PKI_log_debug("_get_cert_stack()::END()!"); + return ( ret ); +} + + +static PKI_X509_CERT * _get_cacert ( + const PKI_X509_PKCS12 * const p12, + const PKI_X509_CERT * const client, + const char * const pwd) { + + STACK_OF(PKCS12_SAFEBAG) *sk_bags = NULL; + PKI_X509_CERT_STACK *ca_sk = NULL; + + PKI_X509_CERT *cacert = NULL; + PKI_X509_CERT *ret = NULL; + + const PKI_X509_CERT *x = NULL; + + PKI_CRED cred; + PKI_CRED *cred_pnt = NULL; + + int i = 0; + + if (!p12 || !p12->value) return NULL; + + if ((sk_bags = _get_bags(p12, pwd)) == NULL) return NULL; + + x = client; + + if( pwd ) { + cred.password = pwd; + cred_pnt = &cred; + } + + if (x == NULL) { + if ((x = PKI_X509_PKCS12_get_cert( p12, cred_pnt )) == NULL ) { + PKI_DEBUG("Can not find user cert in P12"); + return NULL; + } + } + + if ((ca_sk = _get_bags_data(sk_bags, BAG_DATATYPE_CACERT, pwd)) == NULL) { + // No Bags DATA found + return NULL; + } + + for (i = 0; i < PKI_STACK_X509_CERT_elements(ca_sk); i++ ) { + + if ((cacert = PKI_STACK_X509_CERT_get_num(ca_sk, i)) == NULL) continue; + + if ((X509_check_issued(cacert->value, x->value)) == X509_V_OK) { + // Found CA Cert - Exit Cycle + break; + } + + // Resets the pointer + cacert = NULL; + } + + // Duplicate the CA certificate + if (cacert) ret = PKI_X509_CERT_dup(cacert); + + // Free allocated memory + if (!client && x) PKI_X509_CERT_free((PKI_X509_CERT *)x); + if (ca_sk) PKI_STACK_X509_CERT_free(ca_sk); + + return ret; +} + +static PKI_X509_CERT_STACK * _get_othercerts_stack( + const PKI_X509_PKCS12 * const p12, + const PKI_X509_CERT * const cacert, + const char * const pwd){ + + STACK_OF(PKCS12_SAFEBAG) *sk_bags = NULL; + PKI_X509_CERT_STACK *x_sk = NULL; + const PKI_X509_CERT *ca_cert = NULL; + PKI_X509_CERT *user_cert = NULL; + PKI_X509_CERT_VALUE *ca_cert_val = NULL; + PKI_X509_CERT_VALUE *user_cert_val = NULL; + PKI_CRED cred; + + int i=0; + + memset ( &cred, 0L, sizeof( cred )); + + if (!p12 || !p12->value) return NULL; + + if ((sk_bags = _get_bags(p12, pwd)) == NULL) return NULL; + + if ((x_sk = _get_bags_data(sk_bags, BAG_DATATYPE_OTHERCERTS, pwd)) == NULL) { + return ( x_sk ); + } + + if (pwd) cred.password = pwd; + + if (!cacert) ca_cert = _get_cacert( p12, NULL, pwd); + else ca_cert = cacert; + + if (ca_cert) ca_cert_val = ca_cert->value; + + user_cert = PKI_X509_PKCS12_get_cert(p12, &cred); + if (user_cert) user_cert_val = user_cert->value; + + if (!ca_cert_val && !user_cert_val) return x_sk; + + for (i = 0; i < PKI_STACK_X509_CERT_elements(x_sk); i++) { + + PKI_X509_CERT *x = NULL; + + x = PKI_STACK_X509_CERT_get_num ( x_sk, i ); + if( (ca_cert) && (X509_cmp( x->value, ca_cert_val) == 0) ) { + x = PKI_STACK_X509_CERT_del_num ( x_sk, i ); + PKI_X509_CERT_free ( x ); + continue; + } + + if (user_cert_val && X509_cmp (x->value, user_cert_val ) == 0) { + x = PKI_STACK_X509_CERT_del_num ( x_sk, i ); + PKI_X509_CERT_free ( x ); + continue; + } + } + + if (!cacert && ca_cert) PKI_X509_CERT_free((PKI_X509_CERT *)ca_cert); + if (user_cert) PKI_X509_CERT_free (user_cert); + + return ( x_sk ); +} + +static PKI_X509_KEYPAIR_STACK * _get_keypair_stack( + const PKI_X509_PKCS12 * const p12, + const char * const pwd) { + + STACK_OF(PKCS12_SAFEBAG) *sk_bags = NULL; + PKI_X509_KEYPAIR_STACK *ret = NULL; + + if ((sk_bags = _get_bags ( p12, pwd )) == NULL) { + PKI_DEBUG("No Keypair found"); + return NULL; + } + + ret = _get_bags_data(sk_bags, BAG_DATATYPE_KEYPAIR, pwd); + return ( ret ); +} + +static int _pki_p12_copy_bag_attr(PKCS12_SAFEBAG * bag, + const PKI_X509_KEYPAIR * const k, + int nid) { + + int idx; + X509_ATTRIBUTE *attr; + STACK_OF(X509_ATTRIBUTE) * attr_sk = NULL; + + if( !k || !k->value || !bag ) return PKI_ERR; + + idx = EVP_PKEY_get_attr_by_NID(k->value, nid, -1); + + if (idx < 0) return (PKI_OK); + + attr = EVP_PKEY_get_attr(k->value, idx); +#if OPENSSL_VERSION_NUMBER > 0x1010000fL + attr_sk = (STACK_OF(X509_ATTRIBUTE) *)PKCS12_SAFEBAG_get0_attrs(bag); +#else + attr_sk = bag->attrib; +#endif + + if (!X509at_add1_attr(&attr_sk, attr)) return PKI_ERR; + + return (PKI_OK); +} +/* ----------------------- Exported PKCS12 functions ----------------------- */ + +/*! \brief Allocates memory for a new PKI_X509_PKCS12 object */ + +PKI_X509_PKCS12 *PKI_X509_PKCS12_new_null ( void ) { + + PKI_X509_PKCS12 *p12 = NULL; + + if((p12 = PKI_X509_new( PKI_DATATYPE_X509_PKCS12, NULL )) == NULL ) { + return NULL; + } + + /* Returns the result */ + return ( p12 ); +} + +/*! \brief Releases the memory associated with a PKI_X509_PKCS12 object */ + +void PKI_X509_PKCS12_free ( PKI_X509_PKCS12 *p12 ) { + + if ( p12 ) PKI_X509_free ( p12 ); + + return; +} + +void PKI_X509_PKCS12_free_void ( void *p12 ) { + + if( p12 ) PKI_X509_free ( (PKI_X509_PKCS12 *) p12 ); + + return; +} + +/*! \brief Verifies the MAC against the passed credentials */ + +int PKI_X509_PKCS12_verify_cred(const PKI_X509_PKCS12 * const p12, + const PKI_CRED * const cred ) { + + int macVerified = PKI_ERR; + + if( !cred || !cred->password ) { + if( PKCS12_verify_mac( p12->value, NULL, 0) ) { + macVerified = PKI_OK; + } + } else if (PKCS12_verify_mac ( p12->value, cred->password, -1)) { + macVerified = PKI_OK; + } + + return macVerified; +} + +/*! \brief Returns the keypair present in a PKI_X509_PKCS12 object */ + +PKI_X509_KEYPAIR *PKI_X509_PKCS12_get_keypair( + const PKI_X509_PKCS12 * const p12, + const PKI_CRED * const cred ) { + + PKI_X509_KEYPAIR_STACK *sk = NULL; + PKI_X509_KEYPAIR *ret = NULL; + char *pwd = NULL; + + if( cred ) pwd = (char *) cred->password; + + if((sk = _get_keypair_stack( p12, pwd)) == NULL ) { + PKI_log_debug("PKI_X509_PKCS12_get_keypair()::Returned stack is " + "empty!"); + return ( NULL ); + } + + ret = PKI_STACK_X509_KEYPAIR_pop( sk ); + + PKI_STACK_X509_KEYPAIR_free ( sk ); + + return ( ret ); +} + +/*! \brief Returns a copy of the client (user) cert present + * in a PKI_X509_PKCS12 object */ + +PKI_X509_CERT *PKI_X509_PKCS12_get_cert( + const PKI_X509_PKCS12 * const p12, + const PKI_CRED * const cred ) { + + PKI_X509_CERT_STACK *sk = NULL; + PKI_X509_CERT *ret = NULL; + PKI_X509_CERT *x = NULL; + PKI_X509_KEYPAIR *key = NULL; + + int i = 0; + + char *pwd = NULL; + + if( !p12 || !p12->value ) return NULL; + + if( cred ) pwd = (char *) cred->password; + + if((key = PKI_X509_PKCS12_get_keypair ( p12, cred )) == NULL ) { + PKI_log_debug("ERROR::PKCS#12 without private key!"); + } + + if((sk = _get_cert_stack( p12, pwd)) == NULL ) { + return ( NULL ); + } + + for( i=0; i < PKI_STACK_X509_CERT_elements( sk ); i++ ) { + if((x = PKI_STACK_X509_CERT_get_num( sk, i )) == NULL ) { + continue; + } + if(key && X509_check_private_key(x->value, key->value)) { + // char *subj; + + // subj = PKI_X509_CERT_get_parsed(x, + // PKI_X509_DATA_SUBJECT ); + /* Cert and Key match, we found our cert! */ + ret = PKI_X509_dup( x ); + // PKI_log_debug("Cert Matching private Key: %s", subj ); + } else { + // char *subj; + + // subj = PKI_X509_CERT_get_parsed(x, + // PKI_X509_DATA_SUBJECT ); + // PKI_log_debug("Cert not matching key: %s", subj ); + // PKI_Free ( subj ); + } + } + + PKI_STACK_X509_CERT_free_all ( sk ); + + return ( ret ); +} + +/*! \brief Returns the CA cert present (if) in a PKI_X509_PKCS12 object */ + +PKI_X509_CERT *PKI_X509_PKCS12_get_cacert( + const PKI_X509_PKCS12 * const p12, + const PKI_CRED * const cred ) { + + PKI_X509_CERT *ret = NULL; + char *pwd = NULL; + + if (!p12 || !p12->value) return NULL; + + if (cred) pwd = (char *) cred->password; + + if ((ret = _get_cacert( p12, NULL, pwd)) == NULL) return NULL; + + return ( ret ); +} + +/*! \brief Returns all the certs besides the CA and the user cert present (if) + * in a PKI_X509_PKCS12 object */ + +PKI_X509_CERT_STACK *PKI_X509_PKCS12_get_otherCerts( + const PKI_X509_PKCS12 * const p12, + const PKI_CRED * const cred) { + + PKI_X509_CERT_STACK *sk = NULL; + PKI_X509_CERT *cacert = NULL; + char *pwd = NULL; + + if (!p12 || !p12->value) return NULL; + + if (cred) pwd = (char *) cred->password; + + if ((cacert = _get_cacert(p12, NULL, pwd)) != NULL) + sk = _get_othercerts_stack( p12, cacert, pwd); + + return sk; +} + +int PKI_X509_PKCS12_TOKEN_export( + const PKI_TOKEN * const tk, + const URL * const url, + int format, + HSM *hsm ) { + + if (!tk || !url) return PKI_ERR; + + /* + p12 = PKCS12_create(cpass, name, key, ucert, certs, + key_pbe, cert_pbe, iter, -1, keytype); + + if (!p12) + { + ERR_print_errors (bio_err); + goto export_end; + } + + if (maciter != -1) + PKCS12_set_mac(p12, mpass, -1, NULL, 0, maciter, NULL); + + i2d_PKCS12_bio(out, p12); + */ + + return (PKI_ERR); +} + +/*! \brief Generates a new PKI_X509_PKCS12 object from a PKI_X509_PKCS12_DATA obj */ + +PKI_X509_PKCS12 * PKI_X509_PKCS12_new( + const PKI_X509_PKCS12_DATA * const p12_data, + const PKI_CRED * const cred) { + + PKI_X509_PKCS12 *ret = NULL; + char *pass = NULL; + int mac_iter = -1; + + if( !p12_data ) return ( NULL ); + + if(( ret = PKI_X509_PKCS12_new_null()) == NULL ) { + return NULL; + } + + /* let's add the safes */ + if((ret->value = PKCS12_add_safes((PKI_X509_PKCS12_DATA *)p12_data, + 0)) == NULL ) { + PKI_X509_PKCS12_free ( ret ); + return NULL; + } + + ret->cred = PKI_CRED_dup ( cred ); + + if( cred && cred->password ) { + pass = (char *) cred->password; + mac_iter = 1; + } + + if ((mac_iter != -1) && + !PKCS12_set_mac(ret->value, pass, -1, NULL, 0, mac_iter, NULL)){ + PKI_log_debug("ERROR, can not set mac iter!"); + PKI_X509_PKCS12_free (ret); + return ( NULL ); + } + + return ( ret ); +} + +/*! \brief Generates an empty PKI_X509_PKCS12_DATA object to be populated before + * using it to create a PKCS12 */ + +PKI_X509_PKCS12_DATA *PKI_X509_PKCS12_DATA_new ( void ) { + PKI_X509_PKCS12_DATA *ret = NULL; + + if((ret = sk_PKCS7_new_null()) == NULL ) { + PKI_log_debug("Memory Error!"); + return ( NULL ); + } + + return ( ret ); +} + +void PKI_X509_PKCS12_DATA_free ( PKI_X509_PKCS12_DATA *p12_data ) { + + if( !p12_data ) return; + + sk_PKCS7_pop_free(p12_data, PKCS7_free); + + return; +} + +/*! \brief Adds a Keypair (LocalKey) to the PKCS12 */ + +int PKI_X509_PKCS12_DATA_add_keypair( + PKI_X509_PKCS12_DATA *data, + const PKI_X509_KEYPAIR * const keypair, + const PKI_CRED * const cred ) { + + STACK_OF(PKCS12_SAFEBAG) *bags = NULL; + PKCS12_SAFEBAG *bag = NULL; + char *pass = NULL; + + CRYPTO_DIGEST *keyid; + int keytype = 0; + + /* Check Parameters */ + if( !data || !keypair ) return (PKI_ERR); + + if( cred && cred->password ) { + pass = (char *) cred->password; + } + + /* Get the Digest of the Public key */ + keyid = PKI_X509_KEYPAIR_pub_digest ( keypair, PKI_DIGEST_ALG_SHA1 ); + + /* Builds the bag for the PKCS12 */ + bag = PKCS12_add_key(&bags, keypair->value, keytype, + PKCS12_DEFAULT_ITER, NID_pbe_WithSHA1And3_Key_TripleDES_CBC, + pass); + + if (!bag) { + PKI_log_debug("ERROR::Can not add bag to P12 (%s)", + ERR_error_string(ERR_get_error(), NULL )); + goto err; + } + + if ((_pki_p12_copy_bag_attr(bag, keypair, NID_ms_csp_name)) == PKI_ERR ) { + PKI_log_debug("ERROR::Can not copy bag attributes(%s)!", + ERR_error_string(ERR_get_error(),NULL)); + goto err; + } + if ((_pki_p12_copy_bag_attr(bag, keypair, + NID_localKeyID)) == PKI_ERR ) { + PKI_log_debug("ERROR::Can not copy bag attributes (%s)!", + ERR_error_string(ERR_get_error(), NULL)); + goto err; + } + + if( keyid ) { + if(!PKCS12_add_localkeyid( bag, keyid->digest, + (int) keyid->size )) { + PKI_log_debug("ERROR::Can not add p12 localkeyid (%s)!", + ERR_error_string(ERR_get_error(), NULL)); + goto err; + } + } + + if (bags && !PKCS12_add_safe(&data, bags, -1, 0, NULL)) { + PKI_log_debug("ERROR::Can not add bags to p12 (%s)!", + ERR_error_string(ERR_get_error(), NULL)); + goto err; + } + + sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); + PKI_DIGEST_free ( keyid ); + + return (PKI_OK); + +err: + + if (keyid) PKI_DIGEST_free ( keyid ); + if (bags) sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); + + return ( PKI_ERR ); +} + +/*! \brief Adds user certificate, cacertificate and trusted certs to P12 */ + +int PKI_X509_PKCS12_DATA_add_certs ( + PKI_X509_PKCS12_DATA *data, + const PKI_X509_CERT * const cert, + const PKI_X509_CERT * const cacert, + const PKI_X509_CERT_STACK * const trusted, + const PKI_CRED * const cred ) { + + STACK_OF(PKCS12_SAFEBAG) *bags = NULL; + PKCS12_SAFEBAG *bag = NULL; + PKI_X509_KEYPAIR *keypair = NULL; + CRYPTO_DIGEST *keyid = NULL; + + const PKI_X509_KEYPAIR_VALUE *pubKey = NULL; + + char *name = NULL; + char *pass = NULL; + + int nid_cert = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; + int iter = PKCS12_DEFAULT_ITER; + + if (!cert || !cert->value) return PKI_ERR; + + if (cred && cred->password) pass = (char *) cred->password; + + /* Get the Digest of the Public key */ + if ((pubKey = PKI_X509_CERT_get_data(cert, + PKI_X509_DATA_KEYPAIR_VALUE)) == NULL) { + PKI_ERROR(PKI_ERR_GENERAL, "Can not retrieve pubKey from the certificate"); + return ( PKI_ERR ); + } + + if ((keypair = PKI_X509_new(PKI_DATATYPE_X509_KEYPAIR, NULL)) == NULL) { + PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, NULL); + return PKI_ERR; + } + + keypair->value = (PKI_X509_KEYPAIR *)pubKey; + + if ((keyid = PKI_X509_KEYPAIR_pub_digest(keypair, + PKI_DIGEST_ALG_SHA1)) == NULL) { + PKI_ERROR(PKI_ERR_GENERAL, "Can not get keypair digest"); + return ( PKI_ERR ); + } + + keypair->value = NULL; + PKI_X509_KEYPAIR_free ( keypair ); + + if ((bag = PKCS12_add_cert(&bags, cert->value )) == NULL) + { + PKI_ERROR(PKI_ERR_GENERAL, "Can not add cert bag to the list of bags"); + return ( PKI_ERR ); + } + + name = PKI_X509_CERT_get_parsed( cert, PKI_X509_DATA_SUBJECT); + if (name && !PKCS12_add_friendlyname(bag, name, -1)) + { + PKI_ERROR(PKI_ERR_GENERAL, "can not add friendly name"); + PKI_DIGEST_free ( keyid ); + return ( PKI_ERR ); + } + PKI_Free(name); + name = NULL; // Safety + + if (keyid->size && !PKCS12_add_localkeyid(bag, keyid->digest, (int) keyid->size)) + { + PKI_ERROR(PKI_ERR_GENERAL, "can not add localkeyid"); + PKI_DIGEST_free ( keyid ); + return ( PKI_ERR ); + }; + + /* Let's free some memory */ + PKI_DIGEST_free ( keyid ); + + /* Adds the CA certificate */ + if (cacert && cacert->value) + { + if (!PKCS12_add_cert(&bags, cacert->value )) + { + PKI_ERROR(PKI_ERR_GENERAL, "can not add CA cert to P12"); + return PKI_ERR; + } + } + + /* Adds all the other certs */ + if (trusted) + { + int i = 0; + + for (i = 0; i < PKI_STACK_X509_CERT_elements (trusted); i++) + { + PKI_X509_CERT *x = NULL; + + x = PKI_STACK_X509_CERT_get_num(trusted, i); + if (x->value) + { + if (!PKCS12_add_cert(&bags, x->value)) + PKI_ERROR(PKI_ERR_GENERAL, "can not add certificate in bag"); + } + } + } + + if (bags && !PKCS12_add_safe(&data, bags, nid_cert, iter, pass)) + { + PKI_ERROR(PKI_ERR_GENERAL, "can not add data to PKCS12_DATA object"); + return PKI_ERR; + } + + /* Free more memory */ + sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); + + return PKI_OK; +} + +/*! \brief Adds a 'generic' list of certs to P12 */ + +int PKI_X509_PKCS12_DATA_add_other_certs( + PKI_X509_PKCS12_DATA *data, + const PKI_X509_CERT_STACK * const sk, + const PKI_CRED * const cred ) { + + STACK_OF(PKCS12_SAFEBAG) *bags = NULL; + char *pass = NULL; + + int nid_cert = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; + int iter = PKCS12_DEFAULT_ITER; + int i = 0; + + if( !data || !sk ) return ( PKI_ERR ); + + if( cred && cred->password ) { + pass = (char *) cred->password; + } + + for(i = 0; i < PKI_STACK_X509_CERT_elements (sk); i++) { + PKI_X509_CERT *x = NULL; + + x = PKI_STACK_X509_CERT_get_num ( sk, i); + if( x->value ) { + if (!PKCS12_add_cert(&bags, x->value)) { + PKI_log_debug("ERROR, can not add cert in bag"); + } + } + } + + if (bags && !PKCS12_add_safe(&data, bags, nid_cert, iter, pass)) { + PKI_log_err("ERROR, can not add data to PKCS12_DATA obj!"); + sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); + return ( PKI_ERR ); + } + + sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); + + return ( PKI_OK ); + +} + +/* ------------------------ PEM <-> INTERNAL Macros ------------------- */ + +PKI_X509_PKCS12_VALUE *PEM_read_bio_PKCS12( PKI_IO *bp ) { +#if OPENSSL_VERSION_NUMBER < 0x0090800fL + return (PKI_X509_PKCS12_VALUE *) + PEM_ASN1_read_bio( (char *(*)()) d2i_PKCS12, + PKI_X509_PKCS12_PEM_ARMOUR, bp, NULL, NULL, NULL); +#else + return (PKI_X509_PKCS12_VALUE *) + PEM_ASN1_read_bio( (void *(*)()) d2i_PKCS12, + PKI_X509_PKCS12_PEM_ARMOUR, bp, NULL, NULL, NULL); +#endif +} + +int PEM_write_bio_PKCS12( PKI_IO *bp, + const PKI_X509_PKCS12_VALUE * o ) { + + return PEM_ASN1_write_bio ( (int (*)())i2d_PKCS12, + PKI_X509_PKCS12_PEM_ARMOUR, bp, (char *) o, NULL, + NULL, 0, NULL, NULL ); +} + diff --git a/src/pkix/pki_x509_pkcs7.c b/src/pkix/pki_x509_pkcs7.c new file mode 100644 index 00000000..d4cb6870 --- /dev/null +++ b/src/pkix/pki_x509_pkcs7.c @@ -0,0 +1,1489 @@ +/* openssl/pki_x509_pkcs7.c */ + +#include + +#include "internal/x509_data_st.h" + +/* ------------------------------ internal (static ) ------------------------- */ + +static STACK_OF(X509) * __get_chain (const PKI_X509_PKCS7 * const p7) { + + STACK_OF(X509) *x_sk = NULL; + PKI_X509_PKCS7_TYPE type = 0; + + PKI_X509_PKCS7_VALUE *value = NULL; + + if( !p7 || !p7->value ) return ( PKI_ERR ); + + type = PKI_X509_PKCS7_get_type ( p7 ); + + value = p7->value; + + switch ( type ) { + case PKI_X509_PKCS7_TYPE_SIGNED: + x_sk = value->d.sign->cert; + break; + case PKI_X509_PKCS7_TYPE_SIGNEDANDENCRYPTED: + x_sk = value->d.signed_and_enveloped->cert; + break; + default: + return NULL; + } + + return x_sk; +} + +static const STACK_OF(X509_CRL) *__get_crl (const PKI_X509_PKCS7 * const p7 ) { + + STACK_OF(X509_CRL) *x_sk = NULL; + PKI_X509_PKCS7_TYPE type = 0; + + PKI_X509_PKCS7_VALUE *value = NULL; + + if( !p7 || !p7->value ) return ( PKI_ERR ); + + type = PKI_X509_PKCS7_get_type ( p7 ); + + value = p7->value; + + switch ( type ) { + case PKI_X509_PKCS7_TYPE_SIGNED: + x_sk = value->d.sign->crl; + break; + case PKI_X509_PKCS7_TYPE_SIGNEDANDENCRYPTED: + x_sk = value->d.signed_and_enveloped->crl; + break; + default: + return NULL; + } + + return x_sk; +} + + + +/*! \brief Returns the number of recipients */ + +int PKI_X509_PKCS7_get_recipients_num(const PKI_X509_PKCS7 * const p7 ) { + + STACK_OF(PKCS7_RECIP_INFO) *r_sk = NULL; + PKI_X509_PKCS7_VALUE *p7val = NULL; + + PKI_X509_PKCS7_TYPE type = 0; + int ret = 0; + + if ( !p7 || !p7->value ) return -1; + + if ( PKI_X509_PKCS7_has_recipients ( p7 ) == PKI_ERR ) { + return 0; + } + + p7val = p7->value; + + type = PKI_X509_PKCS7_get_type ( p7 ); + switch ( type ) { + case PKI_X509_PKCS7_TYPE_ENCRYPTED: + r_sk = p7val->d.enveloped->recipientinfo; + break; + case PKI_X509_PKCS7_TYPE_SIGNEDANDENCRYPTED: + r_sk = p7val->d.signed_and_enveloped->recipientinfo; + break; + default: + r_sk = NULL; + } + + if ( r_sk ) { + ret = sk_PKCS7_RECIP_INFO_num ( r_sk ); + } + + return ret; +} + +/*! \brief Returns the number of signers */ + +int PKI_X509_PKCS7_get_signers_num(const PKI_X509_PKCS7 * const p7) { + + int ret = -1; + PKI_X509_PKCS7_TYPE type = PKI_X509_PKCS7_TYPE_UNKNOWN; + + PKI_X509_PKCS7_VALUE *p7val = NULL; + STACK_OF(PKCS7_SIGNER_INFO) *s_sk = NULL; + + if ( PKI_X509_PKCS7_has_signers ( p7 ) == PKI_ERR ) { + return 0; + } + + p7val = p7->value; + + type = PKI_X509_PKCS7_get_type ( p7 ); + + switch ( type ) { + case PKI_X509_PKCS7_TYPE_SIGNED: + s_sk = p7val->d.sign->signer_info; + break; + case PKI_X509_PKCS7_TYPE_SIGNEDANDENCRYPTED: + s_sk = p7val->d.signed_and_enveloped->signer_info; + break; + default: + s_sk = NULL; + } + + if ( s_sk ) { + ret = sk_PKCS7_SIGNER_INFO_num ( s_sk ); + } + + return ret; +} + +const PKCS7_RECIP_INFO * PKI_X509_PKCS7_get_recipient_info( + const PKI_X509_PKCS7 * const p7, + int idx ) { + + PKI_X509_PKCS7_TYPE type = 0; + int recipients_num = 0; + PKCS7_RECIP_INFO *ret = NULL; + STACK_OF(PKCS7_RECIP_INFO) *r_sk = NULL; + PKI_X509_PKCS7_VALUE *p7val = NULL; + + if ( !p7 || !p7->value ) return NULL; + + p7val = p7->value; + + if((recipients_num = PKI_X509_PKCS7_get_recipients_num ( p7 )) <= 0 ) { + return NULL; + } + + if ( recipients_num < idx ) return NULL; + + type = PKI_X509_PKCS7_get_type ( p7 ); + switch ( type ) { + case PKI_X509_PKCS7_TYPE_ENCRYPTED: + r_sk = p7val->d.enveloped->recipientinfo; + break; + case PKI_X509_PKCS7_TYPE_SIGNEDANDENCRYPTED: + r_sk = p7val->d.signed_and_enveloped->recipientinfo; + break; + default: + r_sk = NULL; + } + + if ( r_sk ) { + ret = sk_PKCS7_RECIP_INFO_value ( r_sk, idx ); + } + + return ret; + +} + +/*! \brief Returns a copy of the n-th recipient certificate */ + +const PKI_X509_CERT * PKI_X509_PKCS7_get_recipient_cert( + const PKI_X509_PKCS7 * const p7, + int idx ) { + + const PKCS7_RECIP_INFO *r_info = NULL; + + if ((r_info = PKI_X509_PKCS7_get_recipient_info ( p7, idx )) == NULL) + return NULL; + + return (const PKI_X509_CERT *)r_info->cert; +} + +/*! \brief Returns the encryption algorithm */ + +const PKI_X509_ALGOR_VALUE * PKI_X509_PKCS7_get_encode_alg( + const PKI_X509_PKCS7 * const p7) { + + PKI_X509_ALGOR_VALUE *ret = NULL; + PKI_X509_PKCS7_VALUE *val = NULL; + + if( !p7 || !p7->value ) return NULL; + + val = p7->value; + + switch ( PKI_X509_PKCS7_get_type ( p7 ) ) { + case PKI_X509_PKCS7_TYPE_ENCRYPTED: + ret = val->d.enveloped->enc_data->algorithm; + break; + case PKI_X509_PKCS7_TYPE_SIGNEDANDENCRYPTED: + ret = val->d.signed_and_enveloped->enc_data->algorithm; + break; + default: + ret = NULL; + } + + return ret; +} + +const PKCS7_SIGNER_INFO * PKI_X509_PKCS7_get_signer_info( + const PKI_X509_PKCS7 * const p7, + int idx ) { + + PKI_X509_PKCS7_TYPE type = 0; + int cnt = 0; + const STACK_OF(PKCS7_SIGNER_INFO) *sk = NULL; + const PKCS7_SIGNER_INFO *ret = NULL; + + PKI_X509_PKCS7_VALUE *value = NULL; + + if ( !p7 || !p7->value ) return ( NULL ); + + type = PKI_X509_PKCS7_get_type ( p7 ); + + value = p7->value; + + switch (type) { + + case PKI_X509_PKCS7_TYPE_SIGNED: { + if (value && value->d.sign) { + sk = value->d.sign->signer_info; + } + } break; + + case PKI_X509_PKCS7_TYPE_SIGNEDANDENCRYPTED: { + if (value && value->d.signed_and_enveloped) { + sk = value->d.signed_and_enveloped->signer_info; + } + } break; + + default: { + PKI_ERROR(PKI_ERR_X509_PKCS7_TYPE_UNKNOWN, NULL); + return NULL; + } + } + + // Retrieves the Signer Info structure + if((cnt = sk_PKCS7_SIGNER_INFO_num ( sk )) <= 0 ) { + PKI_ERROR(PKI_ERR_X509_PKCS7_SIGNER_INFO_NULL, NULL); + return ( NULL ); + } + + // If the requested is out of scope, nothing to return + if (idx > cnt ) return NULL; + + // Retrieves the value + if( idx >= 0 ) { + ret = sk_PKCS7_SIGNER_INFO_value( sk, idx ); + } else { + ret = sk_PKCS7_SIGNER_INFO_value( sk, cnt-1 ); + } + + // All Done + return ret; +} + +/* ----------------------- Exported Functions -------------------------*/ + +void PKI_X509_PKCS7_free_void ( void *p7 ) { + + PKI_X509_free ( (PKI_X509_PKCS7 *) p7 ); + return; +} + +void PKI_X509_PKCS7_free ( PKI_X509_PKCS7 *p7 ) { + + if( p7 == NULL ) return; + + PKI_X509_free( p7 ); + + return; +} + +PKI_X509_PKCS7 *PKI_X509_PKCS7_new(PKI_X509_PKCS7_TYPE type) { + + PKI_X509_PKCS7 * p7 = NULL; + PKI_X509_PKCS7_VALUE * value = NULL; + + if((value = p7->cb->create()) == NULL ) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return NULL; + } + + if(!PKCS7_set_type(value, (int)type)) { + PKCS7_free(value); + PKI_ERROR(PKI_ERR_X509_PKCS7_TYPE_UNKNOWN, NULL); + return ( NULL ); + } + + switch(type) { + + // If encrypted, we need to set the cipher + case PKI_X509_PKCS7_TYPE_ENCRYPTED: + case PKI_X509_PKCS7_TYPE_SIGNEDANDENCRYPTED: { + if (!PKI_X509_PKCS7_set_cipher(p7, + (EVP_CIPHER *) PKI_CIPHER_AES(256,cbc))) { + // Reports the error + PKI_ERROR(PKI_ERR_X509_PKCS7_CIPHER, NULL); + + // Free the allocated memory + PKCS7_free(value); + + // Nothing else to do + return NULL; + } + } break; + + // If signed, just prepare the content + case PKI_X509_PKCS7_TYPE_SIGNED: { + // Sets the content in the PKCS7 structure + PKCS7_content_new(value, NID_pkcs7_data); + } break; + + default: { + PKI_ERROR(PKI_ERR_X509_PKCS7_TYPE_UNKNOWN, NULL); + PKCS7_free(value); + + return NULL; + } break; + } + + // Allocates the new structure with the generated value + if ((p7 = PKI_X509_new_value(PKI_DATATYPE_X509_PKCS7, value, NULL)) == NULL) { + + // Reports the error + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + PKCS7_free(value); + + // Nothing to return + return NULL; + } + + return p7; +} + +/*! + * \brief Returns the type of the PKI_X509_PKCS7 data (see PKI_X509_PKCS7_TYPE) + */ + +PKI_X509_PKCS7_TYPE PKI_X509_PKCS7_get_type(const PKI_X509_PKCS7 * const p7 ) { + + PKI_ID type = PKI_ID_UNKNOWN; + PKI_X509_PKCS7_VALUE *value = NULL; + + if(!p7 || !p7->value ) { + PKI_log_debug ( "PKI_X509_PKCS7_get_type()::No Message!"); + return PKI_X509_PKCS7_TYPE_UNKNOWN; + } + + value = p7->value; + + if(!value->type ) { + PKI_log_debug ( "PKI_X509_PKCS7_get_type()::No Message Type!"); + return PKI_X509_PKCS7_TYPE_UNKNOWN; + } + + type = PKI_OID_get_id( value->type ); + + switch ( type ) { + case NID_pkcs7_enveloped: + return PKI_X509_PKCS7_TYPE_ENCRYPTED; + break; + case NID_pkcs7_signed: + return PKI_X509_PKCS7_TYPE_SIGNED; + break; + case NID_pkcs7_signedAndEnveloped: + return PKI_X509_PKCS7_TYPE_SIGNEDANDENCRYPTED; + break; + case NID_pkcs7_data: + return PKI_X509_PKCS7_TYPE_DATA; + break; + default: + return PKI_X509_PKCS7_TYPE_UNKNOWN; + } +} + + +int PKI_X509_PKCS7_add_crl(PKI_X509_PKCS7 * p7, + const PKI_X509_CRL * const crl ) { + + // Input Check + if (!p7 || !p7->value || !crl || !crl->value) + return PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + + // Adds the CRL to the PKCS7 value structure + PKCS7_add_crl(p7->value, crl->value); + + // All Done + return PKI_OK; +} + +int PKI_X509_PKCS7_add_crl_stack(PKI_X509_PKCS7 * p7, + const PKI_X509_CRL_STACK * const crl_sk ) { + int i; + + if( !p7 || !p7->value || !crl_sk ) { + return PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + } + + for( i=0; i < PKI_STACK_X509_CRL_elements( crl_sk ); i++ ) { + PKI_X509_CRL *crl = NULL; + + if ((crl = PKI_STACK_X509_CRL_get_num(crl_sk, i)) == NULL) + continue; + + PKCS7_add_crl( p7->value, crl->value); + } + + return PKI_OK; +} + + +/*! \brief Returns the number of CRLs present in the signature */ + +int PKI_X509_PKCS7_get_crls_num(const PKI_X509_PKCS7 * const p7 ) { + + const STACK_OF(X509_CRL) *x_sk = NULL; + + if ((x_sk = __get_crl(p7)) == NULL) return -1; + + return sk_X509_CRL_num((STACK_OF(X509_CRL) *) x_sk); +} + + +/*! \brief Returns a copy of the n-th CRL from the signature */ + +PKI_X509_CRL *PKI_X509_PKCS7_get_crl(const PKI_X509_PKCS7 * const p7, + int idx) { + + PKI_X509_CRL_VALUE *x = NULL; + const STACK_OF(X509_CRL) *x_sk = NULL; + + if (!p7 || !p7->value) return ( NULL ); + + if ((x_sk = __get_crl(p7)) == NULL) return NULL; + + if ( idx < 0 ) idx = 0; + + if ((x = sk_X509_CRL_value(x_sk, idx)) == NULL) return NULL; + + return PKI_X509_new_dup_value(PKI_DATATYPE_X509_CRL, x, NULL); + +} + +/*! \brief Adds a certificate to the signature's certificate chain */ + +int PKI_X509_PKCS7_add_cert(const PKI_X509_PKCS7 * p7, + const PKI_X509_CERT * const x) { + + if (!p7 || !p7->value || !x || !x->value) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return PKI_ERR; + } + + PKCS7_add_certificate( p7->value, x->value ); + + return( PKI_OK ); +} + +/*! \brief Adds a stack of certificates to the signature's certificate chain */ + +int PKI_X509_PKCS7_add_cert_stack(const PKI_X509_PKCS7 * p7, + const PKI_X509_CERT_STACK * const x_sk) { + int i; + + if( !p7 || !p7->value || !x_sk ) { + PKI_log_err( "PKI_X509_PKCS7_add_crl_stack()::Missing param!"); + return PKI_ERR; + } + + for( i=0; i < PKI_STACK_X509_CERT_elements( x_sk ); i++ ) { + PKI_X509_CERT *x = NULL; + + if(( x = PKI_STACK_X509_CERT_get_num( x_sk, i )) == NULL) { + continue; + } + + PKCS7_add_certificate( p7->value, x->value ); + } + + return ( PKI_OK ); +} + +/*! \brief Returns the number of certificates present in the signature chain */ + +int PKI_X509_PKCS7_get_certs_num(const PKI_X509_PKCS7 * const p7 ) { + + const STACK_OF(X509) *x_sk = NULL; + + if ((x_sk = __get_chain(p7)) == NULL) return -1; + + return sk_X509_num((STACK_OF(X509) *)x_sk); +} + + +/*! \brief Returns a copy of the n-th cert from a singed/signed&enc PKCS7 */ + +PKI_X509_CERT *PKI_X509_PKCS7_get_cert(const PKI_X509_PKCS7 * const p7, + int idx) { + + PKI_X509_CERT_VALUE *x = NULL; + const STACK_OF(X509) *x_sk = NULL; + + if (!p7 || !p7->value) return NULL; + + if ((x_sk = __get_chain(p7)) == NULL) return NULL; + + if ( idx < 0 ) idx = 0; + + if ((x = sk_X509_value(x_sk, idx)) == NULL) return NULL; + + return PKI_X509_new_dup_value ( PKI_DATATYPE_X509_CERT, x, NULL ); + +} + + +/*! \brief Clears the chain of certificate for the signer */ + +int PKI_X509_PKCS7_clear_certs(const PKI_X509_PKCS7 * p7) { + + STACK_OF(X509) *x_sk = NULL; + // Pointer to the stack of certificates + + // Gets the pointer to the stack structure + if ((x_sk = __get_chain(p7)) == NULL) + return PKI_ERR; + + // Frees the certificates stack + sk_X509_free(x_sk); + + // All Done + return PKI_OK; +} + +/*! + * \brief Returns a signed version of the PKI_X509_PKCS7 by using the passed token + */ + +int PKI_X509_PKCS7_add_signer_tk(PKI_X509_PKCS7 * p7, + const PKI_TOKEN * const tk, + const PKI_DIGEST_ALG * md){ + + if (!p7 || !p7->value) return PKI_ERR; + + return PKI_X509_PKCS7_add_signer(p7, + tk->cert, + tk->keypair, + md); +} + +/*! + * \brief Signs a PKI_X509_PKCS7 (must be of SIGNED type) + */ + +int PKI_X509_PKCS7_add_signer(const PKI_X509_PKCS7 * p7, + const PKI_X509_CERT * const signer, + const PKI_X509_KEYPAIR * const k, + const PKI_DIGEST_ALG * md ) { + + PKCS7_SIGNER_INFO *signerInfo = NULL; + + if ( !p7 || !signer || !k ) { + if ( !p7 ) PKI_log_debug ( "!p7"); + if ( !signer ) PKI_log_debug ( "!signer"); + if ( !k ) PKI_log_debug ( "!key"); + return PKI_ERR; + } + + if ( !p7->value || !signer->value || !k->value ) { + if ( !p7->value ) PKI_log_debug ( "!p7->value"); + if ( !signer->value ) PKI_log_debug ( "!signer->value"); + if ( !k->value ) PKI_log_debug ( "!key->value"); + return PKI_ERR; + } + + if( !md ) md = PKI_DIGEST_ALG_DEFAULT; + + if((signerInfo = PKCS7_add_signature( p7->value, + signer->value, k->value, md)) == NULL) { + return ( PKI_ERR ); + } + PKCS7_add_certificate ( p7->value, signer->value ); + + return ( PKI_OK ); + +} + +/*! \brief Returns PKI_OK if the p7 has signers already set, PKI_ERR + * otherwise + */ + +int PKI_X509_PKCS7_has_signers(const PKI_X509_PKCS7 * const p7 ) { + + PKI_X509_PKCS7_TYPE type = 0; + + if ( !p7 || !p7->value ) return ( PKI_ERR ); + + type = PKI_X509_PKCS7_get_type ( p7 ); + + switch ( type ) { + case PKI_X509_PKCS7_TYPE_SIGNED: + case PKI_X509_PKCS7_TYPE_SIGNEDANDENCRYPTED: + if(PKI_X509_PKCS7_get_signer_info(p7, -1)) + return (PKI_OK); + break; + default: + return PKI_ERR; + } + + return PKI_ERR; + +} + +/*! \brief Returns PKI_OK if the p7 has recipients already set, PKI_ERR + * otherwise + */ + +int PKI_X509_PKCS7_has_recipients(const PKI_X509_PKCS7 * const p7) { + + PKI_X509_PKCS7_TYPE type = 0; + PKI_X509_PKCS7_VALUE *value = NULL; + + if( !p7 || !p7->value ) return ( PKI_ERR ); + + type = PKI_X509_PKCS7_get_type ( p7 ); + + value = p7->value; + + switch ( type ) { + case PKI_X509_PKCS7_TYPE_ENCRYPTED: + if( value->d.enveloped && + value->d.enveloped->recipientinfo) + return PKI_OK; + break; + case PKI_X509_PKCS7_TYPE_SIGNEDANDENCRYPTED: + if( value->d.signed_and_enveloped && + value->d.signed_and_enveloped->recipientinfo) + return PKI_OK; + break; + default: + return PKI_ERR; + } + + return PKI_ERR; +} + +/*! + * \brief Encode a PKI_X509_PKCS7 by performing sign/encrypt operation + */ + +int PKI_X509_PKCS7_encode(const PKI_X509_PKCS7 * const p7, + unsigned char *data, + size_t size ) { + + PKI_X509_PKCS7_TYPE type = PKI_X509_PKCS7_TYPE_SIGNED; + const PKCS7_SIGNER_INFO * signerInfo = NULL; + BIO *bio = NULL; + + if( !p7 || !p7->value ) return ( PKI_ERR ); + + type = PKI_X509_PKCS7_get_type ( p7 ); + + if (( type == PKI_X509_PKCS7_TYPE_ENCRYPTED ) + || (type == PKI_X509_PKCS7_TYPE_SIGNEDANDENCRYPTED)) { + + if ( PKI_X509_PKCS7_has_recipients ( p7 ) == PKI_ERR ) { + PKI_log_debug ( "PKI_X509_PKCS7_encode()::Missing " + "Recipients!"); + return PKI_ERR; + } + } + + if ( (type == PKI_X509_PKCS7_TYPE_SIGNED) || + (type == PKI_X509_PKCS7_TYPE_SIGNEDANDENCRYPTED )) { + + if(( signerInfo = PKI_X509_PKCS7_get_signer_info( p7, + -1 )) == NULL ) { + return ( PKI_ERR ); + } + + PKCS7_add_signed_attribute((PKCS7_SIGNER_INFO *)signerInfo, + NID_pkcs9_contentType, + V_ASN1_OBJECT, + OBJ_nid2obj(NID_pkcs7_data)); + } + + if((bio = PKCS7_dataInit(p7->value, NULL)) == NULL ) { + PKI_log_err("PKI_X509_PKCS7_sign()::Error dataInit [%s]", + ERR_error_string(ERR_get_error(),NULL)); + return ( PKI_ERR ); + } + + if( BIO_write( bio, data, (int) size ) <= 0 ) { + PKI_log_err("PKI_X509_PKCS7_sign()::Error dataSign [%s]", + ERR_error_string(ERR_get_error(),NULL)); + return ( PKI_ERR ); + } + + (void)BIO_flush(bio); + + if(!PKCS7_dataFinal( p7->value, bio )) { + PKI_log_err("PKI_X509_PKCS7_sign()::Error End dataSign [%s]", + ERR_error_string(ERR_get_error(),NULL)); + return ( PKI_ERR ); + }; + + if( bio ) BIO_free_all ( bio ); + + return ( PKI_OK ); + +} + +/*! + * \brief Returns the raw data contained in a PKI_X509_PKCS7 (any type) + */ + +PKI_MEM *PKI_X509_PKCS7_get_raw_data(const PKI_X509_PKCS7 * const p7 ) { + + unsigned char *data = NULL; + ssize_t len = -1; + PKI_X509_PKCS7_TYPE type = PKI_X509_PKCS7_TYPE_UNKNOWN; + + PKI_X509_PKCS7_VALUE *p7val = NULL; + PKI_MEM *ret = NULL; + + if( !p7 || !p7->value ) return ( NULL ); + + p7val = p7->value; + type = PKI_X509_PKCS7_get_type ( p7 ); + + switch (type) + { + case PKI_X509_PKCS7_TYPE_DATA: + data = p7val->d.data->data; + len = p7val->d.data->length; + break; + + case PKI_X509_PKCS7_TYPE_SIGNED: + if (p7val->d.sign && p7val->d.sign->contents && + p7val->d.sign->contents->d.data) + { + data = p7val->d.sign->contents->d.data->data; + len = p7val->d.sign->contents->d.data->length; + } + break; + + case PKI_X509_PKCS7_TYPE_ENCRYPTED: + if (p7val->d.enveloped && p7val->d.enveloped->enc_data && + p7val->d.enveloped->enc_data->enc_data) + { + data = p7val->d.enveloped->enc_data->enc_data->data; + len = p7val->d.enveloped->enc_data->enc_data->length; + } + break; + + case PKI_X509_PKCS7_TYPE_SIGNEDANDENCRYPTED: + if (p7val->d.signed_and_enveloped && + p7val->d.signed_and_enveloped->enc_data && + p7val->d.signed_and_enveloped->enc_data->enc_data ) + { + data = p7val->d.signed_and_enveloped->enc_data->enc_data->data; + len = p7val->d.signed_and_enveloped->enc_data->enc_data->length; + } + break; + + default: + PKI_log_debug ("Unknown PKCS7 type"); + return NULL; + } + + if ((ret = PKI_MEM_new_null()) == NULL) + { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return NULL; + } + + if (PKI_MEM_add(ret, data, (size_t) len) == PKI_ERR) + { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Memory Failure (ret=%p, data=%p, len=%d)", + ret, data, len ); + PKI_MEM_free ( ret ); + return NULL; + } + + /* + if((p7bio = PKCS7_dataInit(p7->value ,NULL)) != NULL ) { + (void)BIO_flush(p7bio); + ret = PKI_MEM_new_bio( p7bio, NULL ); + BIO_free_all ( p7bio ); + } else { + PKI_log_debug("PKCS7::get_raw_data()::Can not get data [%s]", + ERR_error_string(ERR_get_error(), NULL )); + } + */ + + return ( ret ); + +} + +/*! + * \brief Decrypts (if needed) and returns the idata from a PKI_X509_PKCS7 by using + * keypair and, if present, cert of the PKI_TOKEN argument. + */ + +PKI_MEM *PKI_X509_PKCS7_get_data_tk(const PKI_X509_PKCS7 * const p7, + const PKI_TOKEN * const tk ) { + + if (!p7 || !tk ) return NULL; + + return PKI_X509_PKCS7_get_data(p7, tk->keypair, tk->cert); +} + +/*! + * \brief Decrypts (if needed) and returns the data from a PKI_X509_PKCS7 + */ + +PKI_MEM *PKI_X509_PKCS7_get_data(const PKI_X509_PKCS7 * const p7, + const PKI_X509_KEYPAIR * const k, + const PKI_X509_CERT * const x ) { + + PKI_X509_PKCS7_TYPE type = PKI_X509_PKCS7_TYPE_UNKNOWN; + + if( !p7 || !p7->value ) return ( NULL ); + + type = PKI_X509_PKCS7_get_type ( p7 ); + + switch ( type ) { + case PKI_X509_PKCS7_TYPE_ENCRYPTED: + case PKI_X509_PKCS7_TYPE_SIGNEDANDENCRYPTED: + PKI_log_debug("PKI_X509_PKCS7_get_data()::P7 is encrypted!"); + return PKI_X509_PKCS7_decode ( p7, k, x ); + break; + default: + PKI_log_debug("PKI_X509_PKCS7_get_data()::P7 not encrypted"); + return PKI_X509_PKCS7_get_raw_data ( p7 ); + } +} + +/*! + * \brief Decrypts the data from a (must) encrypted PKI_X509_PKCS7 + */ + + +PKI_MEM *PKI_X509_PKCS7_decode(const PKI_X509_PKCS7 * const p7, + const PKI_X509_KEYPAIR * const k, + const PKI_X509_CERT * const x ) { + + BIO *bio = NULL; + PKI_MEM *mem = NULL; + PKI_X509_PKCS7_TYPE type = PKI_X509_PKCS7_TYPE_UNKNOWN; + PKI_X509_CERT_VALUE *x_val = NULL; + PKI_X509_KEYPAIR_VALUE *pkey = NULL; + + if ( !p7 || !p7->value || !k || !k->value ) { + PKI_log_debug("PKI_X509_PKCS7_decode()::Missing p7 or pkey!"); + return ( NULL ); + }; + + pkey = k->value; + + type = PKI_X509_PKCS7_get_type ( p7 ); + + switch ( type ) { + case PKI_X509_PKCS7_TYPE_ENCRYPTED: + case PKI_X509_PKCS7_TYPE_SIGNEDANDENCRYPTED: + break; + default: + PKI_log_debug("PKI_X509_PKCS7_decode()::Wrong MSG type!"); + return PKI_ERR; + } + + if ( x ) x_val = x->value; + + if((bio = PKCS7_dataDecode(p7->value, pkey, NULL, x_val)) == NULL) { + PKI_log_debug ( "PKI_X509_PKCS7_decode()::Decrypt error [%s]", + ERR_error_string(ERR_get_error(), NULL )); + return ( NULL ); + } + + if((mem = PKI_MEM_new_bio( (PKI_IO *) bio, NULL )) == NULL ) { + PKI_log_debug("PKI_X509_PKCS7_decode()::Memory Error!"); + if( bio ) BIO_free_all ( bio ); + return ( NULL ); + } + + if (bio ) BIO_free_all ( bio ); + + return ( mem ); +} + +/*! \brief Set the cipher in a encrypted (or signed and encrypted) PKCS7 */ + +int PKI_X509_PKCS7_set_cipher(const PKI_X509_PKCS7 * p7, + const PKI_CIPHER * const cipher) { + + PKI_X509_PKCS7_TYPE type; + + if( !p7 || !p7->value || !cipher ) return ( PKI_ERR ); + + type = PKI_X509_PKCS7_get_type ( p7 ); + switch ( type ) { + case PKI_X509_PKCS7_TYPE_ENCRYPTED: + case PKI_X509_PKCS7_TYPE_SIGNEDANDENCRYPTED: + break; + default: + return PKI_ERR; + } + + if(!PKCS7_set_cipher(p7->value, cipher)) { + PKI_log_debug("PKI_X509_PKCS7_set_cipher()::Error setting Cipher " + "[%s]", ERR_error_string(ERR_get_error(), NULL)); + return ( PKI_ERR ); + } + + return PKI_OK; +} + + +/*! \brief Sets the recipients for a PKI_X509_PKCS7 */ + +int PKI_X509_PKCS7_set_recipients(const PKI_X509_PKCS7 *p7, + const PKI_X509_CERT_STACK * const x_sk ) { + + int i = 0; + PKI_X509_PKCS7_TYPE type; + + if( !p7 || !p7->value || !x_sk ) return ( PKI_ERR ); + + type = PKI_X509_PKCS7_get_type ( p7 ); + switch ( type ) { + case PKI_X509_PKCS7_TYPE_ENCRYPTED: + case PKI_X509_PKCS7_TYPE_SIGNEDANDENCRYPTED: + break; + default: + return PKI_ERR; + } + + for( i = 0; i < PKI_STACK_X509_CERT_elements ( x_sk ); i++ ) { + PKI_X509_CERT *x = NULL; + x = PKI_STACK_X509_CERT_get_num( x_sk, i ); + PKCS7_add_recipient( p7->value, x->value ); + PKI_X509_PKCS7_add_cert ( p7, x ); + } + + return ( PKI_OK ); +} + +/*! \brief Adds a new recipient for the PKI_X509_PKCS7 */ +int PKI_X509_PKCS7_add_recipient(const PKI_X509_PKCS7 * p7, + const PKI_X509_CERT * x ) { + + if (!p7 || !p7->value || !x || !x->value) return PKI_ERR; + + PKCS7_add_recipient( p7->value, x->value ); + PKI_X509_PKCS7_add_cert(p7, x); + + return PKI_OK; +} + +/* -------------------------------- Add Attributes ---------------------- */ + +int PKI_X509_PKCS7_add_signed_attribute(const PKI_X509_PKCS7 * p7, + PKI_X509_ATTRIBUTE * a) { + + PKCS7_SIGNER_INFO *signerInfo = NULL; + + if (!p7 || !p7->value || !a) return PKI_ERR; + + if ((signerInfo = (PKCS7_SIGNER_INFO *) + PKI_X509_PKCS7_get_signer_info (p7, -1)) == NULL ) { + PKI_ERROR(PKI_ERR_GENERAL, "signerInfo not present in PKCS7"); + return PKI_ERR; + } + + if (signerInfo->auth_attr == NULL) { + signerInfo->auth_attr = PKI_STACK_X509_ATTRIBUTE_new_null(); + } + + return PKI_STACK_X509_ATTRIBUTE_add(signerInfo->auth_attr, a); + +} + +int PKI_X509_PKCS7_add_attribute(const PKI_X509_PKCS7 * p7, + PKI_X509_ATTRIBUTE * a) { + + PKCS7_SIGNER_INFO *signerInfo = NULL; + + if( !p7 || !p7->value || !a ) return ( PKI_ERR ); + + if ((signerInfo = (PKCS7_SIGNER_INFO *) + PKI_X509_PKCS7_get_signer_info ( p7, -1 )) == NULL ) { + PKI_DEBUG("signerInfo not present in PKCS#7"); + return PKI_ERR; + } + + if (signerInfo->unauth_attr == NULL) { + signerInfo->unauth_attr = PKI_STACK_X509_ATTRIBUTE_new_null(); + } + + return PKI_STACK_X509_ATTRIBUTE_add( signerInfo->unauth_attr, a); + +} + +/* -------------------------------- Get Attributes ---------------------- */ + +const PKI_X509_ATTRIBUTE *PKI_X509_PKCS7_get_signed_attribute( + const PKI_X509_PKCS7 * const p7, + PKI_ID id) { + + const PKCS7_SIGNER_INFO *signerInfo = NULL; + + if (!p7 || !p7->value) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return NULL; + } + + if ((signerInfo = PKI_X509_PKCS7_get_signer_info(p7, -1)) == NULL) + return NULL; + + if (signerInfo->auth_attr == NULL) return NULL; + + return PKI_STACK_X509_ATTRIBUTE_get(signerInfo->auth_attr, id); +} + +const PKI_X509_ATTRIBUTE *PKI_X509_PKCS7_get_attribute( + const PKI_X509_PKCS7 * const p7, + PKI_ID id ) { + + const PKCS7_SIGNER_INFO *signerInfo = NULL; + + if (!p7 || !p7->value) return NULL; + + if ((signerInfo = PKI_X509_PKCS7_get_signer_info(p7, -1)) == NULL) { + PKI_DEBUG("signerInfo missing in PKCS7"); + return NULL; + } + + if (signerInfo->unauth_attr == NULL) return NULL; + + return PKI_STACK_X509_ATTRIBUTE_get(signerInfo->auth_attr, id); +} + +const PKI_X509_ATTRIBUTE *PKI_X509_PKCS7_get_signed_attribute_by_name( + const PKI_X509_PKCS7 * const p7, + const char *name ) { + + const PKCS7_SIGNER_INFO *signerInfo = NULL; + + if (!p7 || !p7->value) return NULL; + + if ((signerInfo = PKI_X509_PKCS7_get_signer_info(p7, -1)) == NULL) { + PKI_DEBUG("signerInfo not present in PKCS7"); + return NULL; + } + + if (signerInfo->auth_attr == NULL) return NULL; + + return PKI_STACK_X509_ATTRIBUTE_get_by_name(signerInfo->auth_attr, + name); +} + +const PKI_X509_ATTRIBUTE *PKI_X509_PKCS7_get_attribute_by_name( + const PKI_X509_PKCS7 * const p7, + const char *name) { + + const PKCS7_SIGNER_INFO *signerInfo = NULL; + + if (!p7 || !p7->value) return NULL; + + if ((signerInfo = PKI_X509_PKCS7_get_signer_info(p7, -1)) == NULL) { + PKI_DEBUG("signerInfo not present in PKCS7"); + return NULL; + } + + if (signerInfo->unauth_attr == NULL) return ( NULL ); + + return PKI_STACK_X509_ATTRIBUTE_get_by_name(signerInfo->auth_attr, + name); +} + +/* ------------------------------- Delete Attributes ---------------------- */ + +/*! \brief Deletes a signed attribute (id) from a PKI_X509_PKCS7 */ + +int PKI_X509_PKCS7_delete_signed_attribute(const PKI_X509_PKCS7 *p7, + PKI_ID id) { + + const PKCS7_SIGNER_INFO *signerInfo = NULL; + + if (!p7 || !p7->value) return PKI_ERR; + + if ((signerInfo = PKI_X509_PKCS7_get_signer_info(p7, -1)) == NULL) { + PKI_DEBUG("signerInfo not present in PKCS7"); + return PKI_ERR; + } + + if (signerInfo->auth_attr == NULL) return PKI_OK; + + return PKI_STACK_X509_ATTRIBUTE_delete(signerInfo->auth_attr, id); + +} + +/*! \brief Deletes an attribute (id) from a PKI_X509_PKCS7 */ + +int PKI_X509_PKCS7_delete_attribute(const PKI_X509_PKCS7 *p7, PKI_ID id ) { + + const PKCS7_SIGNER_INFO *signerInfo = NULL; + + if (!p7 || !p7->value) return PKI_ERR; + + if ((signerInfo = PKI_X509_PKCS7_get_signer_info(p7, -1)) == NULL ) { + PKI_DEBUG("signerInfo not present in PKCS7"); + return ( PKI_ERR ); + } + + if (signerInfo->unauth_attr == NULL) return PKI_OK; + + return PKI_STACK_X509_ATTRIBUTE_delete(signerInfo->unauth_attr, id); + +} + +/* ---------------------------- TEXT Format ---------------------------- */ + +int PKI_X509_PKCS7_VALUE_print_bio ( PKI_IO *bio, + const PKI_X509_PKCS7_VALUE *p7val ) { + + PKI_X509_PKCS7_TYPE type; + int i,j; + + int cert_num = -1; + int crl_num = -1; + int signers_num = -1; + char *tmp_str = NULL; + + PKI_X509_PKCS7 *msg = NULL; + PKI_X509_CERT *cert = NULL; + CRYPTO_DIGEST *digest = NULL; + PKI_MEM *mem = NULL; + + const PKCS7_SIGNER_INFO *si = NULL; + + if (!bio || !p7val ) return PKI_ERR; + + if (( msg = PKI_X509_new_dup_value ( PKI_DATATYPE_X509_PKCS7, + p7val, NULL )) == NULL ) { + return PKI_ERR; + } + + type = PKI_X509_PKCS7_get_type ( msg ); + + BIO_printf( bio, "PKCS#7 Message:\r\n" ); + BIO_printf( bio, " Message Type:\r\n " ); + + switch ( type ) { + case PKI_X509_PKCS7_TYPE_ENCRYPTED: + BIO_printf( bio, "Encrypted\r\n" ); + break; + case PKI_X509_PKCS7_TYPE_SIGNED: + BIO_printf( bio, "Signed\r\n" ); + break; + case PKI_X509_PKCS7_TYPE_SIGNEDANDENCRYPTED: + BIO_printf( bio, "Signed and Encrypted\r\n" ); + break; + default: + BIO_printf( bio, "Unknown (%d)\r\n", type ); + break; + } + + BIO_printf( bio, " Message Data:\r\n"); + if (( mem = PKI_X509_PKCS7_get_raw_data ( msg )) == NULL ) { + BIO_printf( bio, " None.\r\n"); + } else { + PKI_X509_PKCS7_TYPE msg_type = 0; + + BIO_printf( bio, " Size=%u bytes\r\n", + (unsigned int) mem->size ); + + msg_type = PKI_X509_PKCS7_get_type ( msg ); + if ( msg_type == PKI_X509_PKCS7_TYPE_ENCRYPTED || + msg_type == + PKI_X509_PKCS7_TYPE_SIGNEDANDENCRYPTED){ + BIO_printf( bio, " Encrypted=yes\r\n"); + BIO_printf( bio, " Algorithm=%s\r\n", + PKI_X509_ALGOR_VALUE_get_parsed ( + PKI_X509_PKCS7_get_encode_alg ( msg ))); + } else { + BIO_printf( bio, " Encrypted=no\r\n"); + } + PKI_MEM_free ( mem ); + } + + i = 0; + if (( si = PKI_X509_PKCS7_get_signer_info ( msg, i )) == NULL ) { + BIO_printf(bio, " Signature Info:\r\n" ); + BIO_printf(bio, " No Signature found.\r\n" ); + } + + // Print the Signer Info + BIO_printf( bio, " Signer Info:\r\n"); + signers_num = PKI_X509_PKCS7_get_signers_num ( msg ); + for ( i = 0; i < signers_num; i++ ) { + PKCS7_ISSUER_AND_SERIAL *ias = NULL; + + BIO_printf ( bio, " [%d of %d] Signer Details:\r\n", + i+1, signers_num ); + + if (( si = PKI_X509_PKCS7_get_signer_info ( msg, i )) == NULL ) + break; + + if((ias = si->issuer_and_serial) == NULL ) { + BIO_printf ( bio, " " + "ERROR::Missing Info!\r\n"); + } else { + tmp_str = PKI_INTEGER_get_parsed ( ias->serial ); + BIO_printf ( bio, " Serial=%s\r\n", tmp_str ); + PKI_Free ( tmp_str ); + + tmp_str = PKI_X509_NAME_get_parsed ( ias->issuer ); + BIO_printf ( bio, " Issuer=%s\r\n", tmp_str ); + PKI_Free ( tmp_str ); + } + + if ( si->digest_enc_alg ) { + BIO_printf( bio, " " + "Encryption Algoritm=%s\r\n", + PKI_X509_ALGOR_VALUE_get_parsed ( si->digest_enc_alg )); + } + + if ( si->digest_alg ) { + BIO_printf( bio, " Digest Algorithm=%s\r\n", + PKI_X509_ALGOR_VALUE_get_parsed ( si->digest_alg )); + } + + BIO_printf( bio, " Signed Attributes:\r\n"); + if ( si->auth_attr ) { +#if OPENSSL_VERSION_NUMBER > 0x1010000fL + LIBPKI_X509_ATTRIBUTE_FULL *a = NULL; +#else + X509_ATTRIBUTE *a = NULL; +#endif + int attr_num = 0; + char * tmp_str = NULL; + + for ( attr_num = 0; attr_num < + PKI_STACK_X509_ATTRIBUTE_elements ( + si->auth_attr ); attr_num++ ) { + + a = PKI_STACK_X509_ATTRIBUTE_get_num ( + si->auth_attr, attr_num ); + + if ( PKI_OID_get_id ( a->object ) == + NID_pkcs9_messageDigest ) { + tmp_str = PKI_X509_ATTRIBUTE_get_parsed + ( a ); + + BIO_printf( bio, " " + "Message Digest:"); + for ( j=0; j < strlen(tmp_str); j++ ) { + if ( ( j % 60 ) == 0 ) { + BIO_printf (bio, + "\r\n "); + } + BIO_printf(bio,"%c",tmp_str[j]); + } BIO_printf( bio, "\r\n"); + // PKI_Free ( tmp_str ); + + } else { + BIO_printf( bio, " %s=", + PKI_X509_ATTRIBUTE_get_descr ( + a ) ); + tmp_str= + PKI_X509_ATTRIBUTE_get_parsed(a); + BIO_printf( bio, "%s\r\n", tmp_str ); + PKI_Free ( tmp_str ); + } + + } + } else { + BIO_printf( bio, " None.\r\n"); + } + + BIO_printf( bio," Non Signed Attributes:\r\n"); + if ( si->unauth_attr ) { + PKI_X509_ATTRIBUTE *a = NULL; + int attr_num = 0; + char * tmp_str = NULL; + + for ( attr_num = 0; attr_num < + PKI_STACK_X509_ATTRIBUTE_elements ( + si->auth_attr ); attr_num++ ) { + + a = PKI_STACK_X509_ATTRIBUTE_get_num ( + si->auth_attr, attr_num ); + + BIO_printf( bio, " %s=", + PKI_X509_ATTRIBUTE_get_descr ( a ) ); + + tmp_str = PKI_X509_ATTRIBUTE_get_parsed ( a ); + BIO_printf( bio, "%s\r\n", tmp_str ); + PKI_Free ( tmp_str ); + } + BIO_printf( bio, "\r\n"); + } else { + BIO_printf( bio, " None.\r\n"); + } + } + + BIO_printf( bio, "\r\n Recipients Info:\r\n"); + if( PKI_X509_PKCS7_has_recipients ( msg ) == PKI_ERR ) { + BIO_printf( bio, " No Recipients\r\n"); + } else { + int rec_num = 0; + const PKI_X509_CERT *rec = NULL; + + rec_num = PKI_X509_PKCS7_get_recipients_num ( msg ); + for ( i=0; i < rec_num; i++ ) { + rec = PKI_X509_PKCS7_get_recipient_cert ( msg, i ); + if ( !rec ) { + const PKCS7_RECIP_INFO *ri = NULL; + PKCS7_ISSUER_AND_SERIAL *ias = NULL; + + BIO_printf( bio, " " + "[%d of %d] Recipient Details:\r\n", + i+1, rec_num ); + + ri = PKI_X509_PKCS7_get_recipient_info(msg,i); + if (!ri) { + BIO_printf(bio," "); + continue; + } + + if((ias = ri->issuer_and_serial) != NULL ) { + + tmp_str = PKI_INTEGER_get_parsed ( + ias->serial ); + BIO_printf( bio, " " + "Serial=%s\r\n", tmp_str ); + PKI_Free ( tmp_str ); + + tmp_str = PKI_X509_NAME_get_parsed ( + ias->issuer ); + BIO_printf( bio, " " + "Issuer=%s\r\n", tmp_str ); + PKI_Free ( tmp_str ); + + BIO_printf( bio, " " + "Key Encoding Algorithm=%s\r\n", + PKI_X509_ALGOR_VALUE_get_parsed ( + ri->key_enc_algor )); + } + + } else { + + BIO_printf( bio, " " + "[%d] Recipient Certificate:\r\n", i ); + + tmp_str = PKI_X509_CERT_get_parsed( cert, + PKI_X509_DATA_SUBJECT ); + + BIO_printf( bio, " " + "Subject=%s\r\n", tmp_str); + PKI_Free ( tmp_str ); + } + } + } + + /* Now Let's Check the CRLs */ + + BIO_printf(bio, "\r\n Certificates:\r\n"); + if ((cert_num = PKI_X509_PKCS7_get_certs_num ( msg )) > 0 ) { + PKI_X509_CERT * cert = NULL; + for (i = 0; i < cert_num; i++ ) { + BIO_printf( bio, " [%d of %d] Certificate:\r\n", + i+1, cert_num); + if((cert = PKI_X509_PKCS7_get_cert ( msg, i )) == NULL ) { + BIO_printf( bio, " Error.\r\n"); + continue; + }; + tmp_str = PKI_X509_CERT_get_parsed( cert, + PKI_X509_DATA_SERIAL ); + BIO_printf( bio, " Serial=%s\r\n", + tmp_str ); + PKI_Free ( tmp_str ); + + tmp_str = PKI_X509_CERT_get_parsed( cert, + PKI_X509_DATA_ISSUER ); + BIO_printf( bio, " Issuer=%s\r\n", tmp_str ); + PKI_Free ( tmp_str ); + + tmp_str = PKI_X509_CERT_get_parsed( cert, + PKI_X509_DATA_SUBJECT ); + + BIO_printf( bio, " Subject=%s\r\n", tmp_str); + PKI_Free ( tmp_str ); + + digest = PKI_X509_CERT_fingerprint( cert, + PKI_DIGEST_ALG_DEFAULT ); + tmp_str = PKI_DIGEST_get_parsed ( digest ); + + BIO_printf( bio, " Fingerprint [%s]:", + PKI_DIGEST_ALG_get_parsed ( + PKI_DIGEST_ALG_DEFAULT )); + + for ( j=0; j < strlen(tmp_str); j++ ) { + if ( ( j % 60 ) == 0 ) { + BIO_printf (bio,"\r\n "); + } + BIO_printf( bio, "%c", tmp_str[j] ); + } BIO_printf( bio, "\r\n"); + + PKI_DIGEST_free ( digest ); + PKI_Free ( tmp_str ); + + PKI_X509_CERT_free ( cert ); + + // X509_signature_print(bp, + // br->signatureAlgorithm, br->signature); + + } + } else { + BIO_printf( bio, " None.\r\n"); + } + + BIO_printf(bio, "\r\n Certificate Revocation Lists:\r\n"); + if((crl_num = PKI_X509_PKCS7_get_crls_num ( msg )) > 0 ) { + PKI_X509_CRL * crl = NULL; + for ( i = 0; i < crl_num; i++ ) { + BIO_printf( bio, " [%d of %d] CRL Details:\r\n", + i+1, crl_num ); + + if(( crl = PKI_X509_PKCS7_get_crl ( msg, i )) == NULL ) { + BIO_printf(bio," ERROR::Missing Data\r\n"); + continue; + } + + tmp_str = PKI_X509_CRL_get_parsed(crl,PKI_X509_DATA_VERSION); + BIO_printf( bio, " Version=%s\r\n", tmp_str ); + PKI_Free ( tmp_str ); + + // tmp_str = PKI_X509_CRL_get_parsed(crl,PKI_X509_DATA_SERIAL); + // BIO_printf( bio, " Serial=%s\r\n", tmp_str ); + // PKI_Free ( tmp_str ); + + tmp_str = PKI_X509_CRL_get_parsed(crl,PKI_X509_DATA_ISSUER); + BIO_printf( bio, " Issuer=%s\r\n", tmp_str ); + PKI_Free ( tmp_str ); + + tmp_str = PKI_X509_CRL_get_parsed(crl, + PKI_X509_DATA_ALGORITHM); + BIO_printf( bio, " Algorithm=%s\r\n", tmp_str ); + PKI_Free ( tmp_str ); + + tmp_str = PKI_X509_CRL_get_parsed(crl, + PKI_X509_DATA_NOTBEFORE); + BIO_printf( bio, " Not Before=%s\r\n", tmp_str ); + PKI_Free ( tmp_str ); + + tmp_str = PKI_X509_CRL_get_parsed(crl, + PKI_X509_DATA_NOTAFTER); + BIO_printf( bio, " Not After=%s\r\n", tmp_str ); + PKI_Free ( tmp_str ); + + PKI_X509_CRL_free ( crl ); + } + } else { + BIO_printf( bio, " None.\r\n"); + } + BIO_printf(bio, "\r\n"); + + return PKI_OK; +} diff --git a/src/pkix/pki_x509_req.c b/src/pkix/pki_x509_req.c new file mode 100644 index 00000000..6ecc17de --- /dev/null +++ b/src/pkix/pki_x509_req.c @@ -0,0 +1,812 @@ +/* PKI_X509 object management */ + +#include +#include + +#include +#include + +#include "internal/x509_data_st.h" +#include + +PKI_X509_REQ * PKI_X509_REQ_new_null ( void ) { + return (PKI_X509_REQ *) PKI_X509_new ( PKI_DATATYPE_X509_REQ, NULL ); +} + +void PKI_X509_REQ_free_void( void *x ) { + if( x ) PKI_X509_free( (PKI_X509 *) x ); + + return; +} + +/*! \brief Frees the memory associated with a Certifcate Request object */ + +void PKI_X509_REQ_free( PKI_X509_REQ *x ) { + + // Free Memory + if (x) PKI_X509_free ( x ); + + // All Done + return; +} + +/*! \brief Generates a signed Certificate Request Object */ + +PKI_X509_REQ *PKI_X509_REQ_new(const PKI_X509_KEYPAIR * k, + const char * subj_s, + const PKI_X509_PROFILE * req_cnf, + const PKI_CONFIG * oids, + const PKI_DIGEST_ALG * digest, + HSM * hsm ) { + + PKI_X509_REQ *req = NULL; + PKI_X509_REQ_VALUE *val = NULL; + PKI_X509_KEYPAIR_VALUE *kVal = NULL; + + int rv = PKI_OK; + PKI_SCHEME_ID scheme = PKI_SCHEME_UNKNOWN; + + PKI_X509_NAME *subj = NULL; + + /* We need at least the private key for the request */ + if( !k || !k->value ) { + PKI_DEBUG("ERROR, no key for PKI_X509_REQ_new()!"); + return NULL; + } + kVal = (EVP_PKEY *) PKI_X509_get_value(k); + + + // Let's set the digest for the right signature scheme */ + // Open Quantum Safe Algos do not offer Digests, we are now + // more permissive with the digest + if (!digest) { + // Gets the default algorithm + if ((digest = PKI_DIGEST_ALG_get_by_key(k)) == NULL) { + PKI_DEBUG("No Default Digest is recommended for the PKEY algorithm"); + } + // Let's use the NULL one + digest = EVP_md_null(); + } + + /* This has to be fixed, to work on every option */ + if( subj_s ) { + subj = PKI_X509_NAME_new ( subj_s ); + } else if ( req_cnf ) { + char *tmp_s = NULL; + + if (( tmp_s = PKI_CONFIG_get_value( req_cnf, "/profile/subject/dn")) != NULL ) { + subj_s = tmp_s; + + // PKI_log_debug("Subject DN found => %s", tmp_s); + subj = PKI_X509_NAME_new ( tmp_s ); + } else { + PKI_log_debug("Subject DN not found in the profile, generating a default one"); + } + } + + // If no subject, yet, let's try to get the hostname + if (!subj) { + struct utsname myself; + char tmp_name[1024]; + + if (uname(&myself) < 0) { + subj = PKI_X509_NAME_new( "" ); + } else { + sprintf( tmp_name, "CN=%s", myself.nodename ); + subj = PKI_X509_NAME_new( tmp_name ); + } + + if (!subj) { + PKI_ERROR(PKI_ERR_X509_CERT_CREATE_SUBJECT, subj_s ); + goto err; + } + } + + if ((req = PKI_X509_REQ_new_null()) == NULL) { + PKI_ERROR(PKI_ERR_OBJECT_CREATE, NULL); + goto err; + } + + /* Generate the request */ + if((val = req->cb->create()) == NULL ) { + PKI_ERROR(PKI_ERR_OBJECT_CREATE, NULL ); + goto err; + } + + // Sets the value of the req internal structure + req->value = val; + + /* Now we need the PKI_REQ */ + if (req_cnf != NULL) { + + PKI_TOKEN * tk = NULL; + PKI_KEYPARAMS *kParams = NULL; + + char *tmp_s = NULL; + + if(( tmp_s = PKI_X509_PROFILE_get_value( req_cnf, + "/profile/keyParams/algorithm")) != NULL ) { + PKI_X509_ALGOR_VALUE *myAlg = NULL; + const PKI_DIGEST_ALG *dgst; + + if((myAlg = PKI_X509_ALGOR_VALUE_get_by_name( tmp_s )) != NULL ) { + scheme = PKI_X509_ALGOR_VALUE_get_scheme ( myAlg ); + if((dgst = PKI_X509_ALGOR_VALUE_get_digest( myAlg )) != NULL ) { + digest = (PKI_DIGEST_ALG *)dgst; + }; + }; + PKI_Free ( tmp_s ); + }; + + if (( tk = PKI_TOKEN_new_null()) == NULL ) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "PKI_TOKEN"); + PKI_X509_REQ_free ( req ); + return NULL; + } + + PKI_TOKEN_set_keypair(tk, (PKI_X509_KEYPAIR *) k); + PKI_TOKEN_set_req(tk, (PKI_X509_REQ *)req); + + /* Add Request Extensions */ + rv = PKI_X509_EXTENSIONS_req_add_profile( req_cnf, + oids, req, tk ); + + // Debugging Info + if ( rv == PKI_ERR ) { + PKI_DEBUG("Error while adding request extensions from the profile, ignored"); + // PKI_X509_REQ_free (req); + // return NULL; + } + + tk->keypair = NULL; + tk->req = NULL; + PKI_TOKEN_free ( tk ); + + if( scheme == PKI_SCHEME_UNKNOWN ) { + scheme = PKI_X509_KEYPAIR_get_scheme ( k ); + } + + kParams = PKI_KEYPARAMS_new(scheme, req_cnf); + if( kParams ) { + /* Sets the point compression */ + switch ( kParams->scheme ) { +#ifdef ENABLE_ECDSA + case PKI_SCHEME_ECDSA: + if ( kParams->ec.form != PKI_EC_KEY_FORM_UNKNOWN ) { +# if OPENSSL_VERSION_NUMBER >= 0x30000000L + EC_KEY_set_conv_form(EVP_PKEY_get1_EC_KEY(kVal), + (point_conversion_form_t)kParams->ec.form); +# elif OPENSSL_VERSION_NUMBER > 0x1010000fL + EC_KEY_set_conv_form(EVP_PKEY_get0_EC_KEY(kVal), + (point_conversion_form_t)kParams->ec.form); +# else + EC_KEY_set_conv_form(kVal->pkey.ec, (point_conversion_form_t)kParams->ec.form); +# endif + }; + break; +#endif + + default: + // Nothing to do + break; + } + } + } + + /* Set the version number */ + if (!X509_REQ_set_version((X509_REQ *)val, 2L)) { + PKI_ERROR(PKI_ERR_X509_REQ_CREATE_VERSION, NULL); + goto err; + } + + /* Set the pubkey */ + if (!X509_REQ_set_pubkey( (X509_REQ *) val, kVal )) { + PKI_ERROR(PKI_ERR_X509_REQ_CREATE_PUBKEY, NULL); + goto err; + } + + // Sets the Subject + if (!X509_REQ_set_subject_name((X509_REQ *)val, (X509_NAME *)subj)) { + if(subj) X509_NAME_free((X509_NAME *) subj); + PKI_ERROR(PKI_ERR_X509_REQ_CREATE_SUBJECT, subj_s); + goto err; + } + + // PKI_DEBUG("Calling PKI_X509_sign() with Digest => %p (%s)", digest, PKI_DIGEST_ALG_get_parsed(digest)); + + // Signs the Request + rv = PKI_X509_sign(req, digest, k); + if (rv != PKI_OK ) { + /* Error Signing the request */ + PKI_DEBUG("ERROR %d while signing the Request [%s]", rv, + ERR_error_string( ERR_get_error(), NULL )); + goto err; + } + + /* Return the requested PKI_X509_REQ structure */ + return req; + +err: + if (req) PKI_X509_REQ_free(req); + + return (NULL); +} + +/*! \brief Adds an extension to a Certificate Request */ + +int PKI_X509_REQ_add_extension(PKI_X509_REQ * x, PKI_X509_EXTENSION * ext) { + + STACK_OF(X509_EXTENSION) *sk = NULL; + // Stack of Crypto-Layer Extensions + + PKI_X509_REQ_VALUE *val = NULL; + // Crypto Layer REQ pointer + + int *nid_list = NULL; + int i = -1; + + // Input Checks + if (!x || !x->value || !ext || !ext->value.ptr ) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return PKI_ERR; + } + + // Gets the Internal Value + val = x->value; + + // Gets the crypto-layer stack of extensions + if ((sk = X509_REQ_get_extensions(val)) == NULL) { + // If none is available, let's build one + if ((sk = sk_X509_EXTENSION_new_null()) == NULL ) { + return PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + } + } + + // Pushes the crypto-layer extension to the stack + if (!sk_X509_EXTENSION_push(sk, ext->value.x509_ext)) { + // Error Condition + sk_X509_EXTENSION_free ( sk ); + return PKI_ERROR(PKI_ERR_GENERAL, "Cannot Add Extension to the request's stack"); + } + + // Gets the list of NIDs + nid_list = X509_REQ_get_extension_nids(); + for ( i = 0; ; i++ ) { + + PKI_ID nid = -1; + + // Retrieves the i-th NID + if((nid = nid_list[i]) == NID_undef ) { + break; + }; + + // Removes the attribute + PKI_X509_REQ_delete_attribute(x, nid_list[i]); + } + + // Let's now add all the extensions + if( !X509_REQ_add_extensions(val, sk)) { + // Error Condition + sk_X509_EXTENSION_free(sk); + return PKI_ERROR(PKI_ERR_GENERAL, "Cannot add the set of extensions to the request"); + } + + // Free the Stack of Extensions + sk_X509_EXTENSION_free ( sk ); + + // All Done + return PKI_OK; +} + + +/*! \brief Adds a stack of extensions to a Certificate Request */ + +int PKI_X509_REQ_add_extension_stack(PKI_X509_REQ * x, + PKI_X509_EXTENSION_STACK * sk_ext) { + + STACK_OF(X509_EXTENSION) *sk = NULL; + // Crypto layer stack of extensions + + int i = 0; + + // Input Checks + if (!x || !x->value || !sk_ext) { + return PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + } + + // Generates a new Crypto-Layer Stack of extensions + if((sk = sk_X509_EXTENSION_new_null()) == NULL ) { + return PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + } + + // Cycles through the LibPKI's stack of extensions and + // adds them to the crypto-layer's stack + for( i = 0; i < PKI_STACK_X509_EXTENSION_elements(sk_ext); i++ ) { + + PKI_X509_EXTENSION *tmp_e = NULL; + // LibPKI extensions' pointer + + // Retrieves the i-th LibPKI extension + tmp_e = PKI_STACK_X509_EXTENSION_get_num(sk_ext, i); + + // Checks for errors + if (!tmp_e) { + // Free the crypto-layer stack + while (sk && sk_X509_EXTENSION_num(sk) > 0) { + sk_X509_EXTENSION_pop_free(sk, X509_EXTENSION_free); + } sk_X509_EXTENSION_free(sk); + // Error Condition + return PKI_ERROR(PKI_ERR_GENERAL, "Cannot retrieve the i-th extension from the stack"); + } + + // Pushes the extension to the crypto layer's stack + sk_X509_EXTENSION_push(sk, tmp_e->value.x509_ext); + } + + // Let's now add all the extensions at once + if (!X509_REQ_add_extensions((X509_REQ *)x->value, sk)) { + // Free the crypto-layer stack + while (sk && sk_X509_EXTENSION_num(sk) > 0) { + sk_X509_EXTENSION_pop_free(sk, X509_EXTENSION_free); + } sk_X509_EXTENSION_free(sk); + // Error Condition + return PKI_ERROR(PKI_ERR_GENERAL, "Cannot Add the Stack of Crypto-Layer Extensions to the request"); + } + + // Free Allocated Memory + while (sk && sk_X509_EXTENSION_num(sk) > 0) { + sk_X509_EXTENSION_pop_free(sk, X509_EXTENSION_free); + } sk_X509_EXTENSION_free(sk); + + // All Done + return PKI_OK; +} + +/*! \brief Returns the size of the public key in the Certificate Request + */ + +int PKI_X509_REQ_get_keysize(const PKI_X509_REQ *x) { + + int keysize = 0; + PKI_X509_KEYPAIR_VALUE *pkey = NULL; + + if( !x || !x->value ) return (0); + + if(( pkey = (PKI_X509_KEYPAIR_VALUE *) PKI_X509_REQ_get_data(x, + PKI_X509_DATA_KEYPAIR_VALUE)) == NULL ) { + return (0); + } + + keysize = EVP_PKEY_size ( (EVP_PKEY *) pkey ); + + return keysize; +} + +/*! \brief Returns an attribute of the Certificate Request */ + +const void * PKI_X509_REQ_get_data(const PKI_X509_REQ * req, + PKI_X509_DATA type ) { + + void *ret = NULL; + LIBPKI_X509_REQ *tmp_x = NULL; + + if( !req || !req->value ) return (NULL); + + tmp_x = req->value; + + switch( type ) { + case PKI_X509_DATA_SUBJECT: + ret = (void *) X509_REQ_get_subject_name((X509_REQ *)tmp_x); + break; + case PKI_X509_DATA_KEYPAIR_VALUE: + ret = (void *)X509_REQ_get_pubkey((X509_REQ *)tmp_x); + break; + case PKI_X509_DATA_PUBKEY_BITSTRING: + ret = tmp_x->req_info.pubkey->public_key; + break; + case PKI_X509_DATA_X509_PUBKEY: + ret = (void *)X509_REQ_get_X509_PUBKEY((X509_REQ *)tmp_x); + break; + case PKI_X509_DATA_SIGNATURE: + ret = (void *) tmp_x->signature; + break; + case PKI_X509_DATA_ALGORITHM: + case PKI_X509_DATA_SIGNATURE_ALG1: +#if OPENSSL_VERSION_NUMBER > 0x1010000fL + ret = &(tmp_x->sig_alg); +#else + ret = tmp_x->sig_alg; +#endif + break; + case PKI_X509_DATA_SIGNATURE_ALG2: + break; +/* + // This shall be replaced with a dedicated + // function because this violates the memory + // contract (const for the returned item) + // PKI_X509_get_tbs_asn1(); + case PKI_X509_DATA_TBS_MEM_ASN1: + if((mem = PKI_MEM_new_null()) == NULL ) + break; + mem->size = (size_t) ASN1_item_i2d ( (void *) tmp_x->req_info, + &(mem->data), &X509_REQ_INFO_it ); + ret = mem; + break; +*/ + default: + return( NULL ); + } + + return (ret); +} + +/*! \brief Returns a char * representation of the data present in the + * request + */ + +const char * PKI_X509_REQ_get_parsed(const PKI_X509_REQ *req, + PKI_X509_DATA type ) { + + const char *ret = NULL; + + const PKI_X509_KEYPAIR_VALUE *pkey = NULL; + PKI_X509_KEYPAIR *k = NULL; + + if( !req || !req->value ) return ( NULL ); + + switch ( type ) { + case PKI_X509_DATA_SERIAL: + ret = PKI_INTEGER_get_parsed((PKI_INTEGER *) + PKI_X509_REQ_get_data ( req, type )); + break; + case PKI_X509_DATA_SUBJECT: + case PKI_X509_DATA_ISSUER: + ret = PKI_X509_NAME_get_parsed((PKI_X509_NAME*) + PKI_X509_REQ_get_data ( req, type)); + break; + case PKI_X509_DATA_NOTBEFORE: + case PKI_X509_DATA_NOTAFTER: + ret = PKI_TIME_get_parsed((PKI_TIME *) + PKI_X509_REQ_get_data ( req, type )); + break; + case PKI_X509_DATA_ALGORITHM: + ret = PKI_X509_ALGOR_VALUE_get_parsed((PKI_X509_ALGOR_VALUE *) + PKI_X509_REQ_get_data(req, type)); + break; + case PKI_X509_DATA_KEYPAIR_VALUE: + if((pkey = PKI_X509_REQ_get_data(req, type)) != NULL) { + k = PKI_X509_new_dup_value ( + PKI_DATATYPE_X509_KEYPAIR, pkey, NULL ); + ret = PKI_X509_KEYPAIR_get_parsed( k ); + PKI_X509_KEYPAIR_free ( k ); + } + break; + case PKI_X509_DATA_SIGNATURE: + ret = PKI_X509_SIGNATURE_get_parsed( + (PKI_X509_SIGNATURE *) + PKI_X509_REQ_get_data ( req, type )); + break; + default: + return ( NULL ); + } + + return ( ret ); +} + +/*! \brief Prints the requested data from the request to the file descriptor + * passed as an argument + */ + +int PKI_X509_REQ_print_parsed(const PKI_X509_REQ *req, + PKI_X509_DATA type, + int fd ) { + + const char *str = NULL; + int ret = PKI_OK; + + if( !req ) return ( PKI_ERR ); + + if((str = PKI_X509_REQ_get_parsed ( req, type )) == NULL ) { + return ( PKI_ERR ); + } else { + if( fd == 0 ) fd = 2; + if( write( fd, str, strlen(str)) == -1 ) { + ret = PKI_ERR; + } + PKI_Free( (char *) str ); + } + + return ( ret ); +} + +/*------------------------------- ATTRIBUTES --------------------------------- */ + +/*! Adds an Attribute to a PKI_X509_REQ */ + +int PKI_X509_REQ_add_attribute ( PKI_X509_REQ *req, PKI_X509_ATTRIBUTE *attr ) { + + PKI_X509_REQ_VALUE *val = NULL; + + if ( !req || !req->value || !attr ) return PKI_ERR; + + val = req->value; +#if OPENSSL_VERSION_NUMBER < 0x1010000fL + if (val->req_info != NULL) { + return PKI_STACK_X509_ATTRIBUTE_add(val->req_info->attributes, attr); + } else { + return PKI_ERR; + } +#else + return PKI_STACK_X509_ATTRIBUTE_add(val->req_info.attributes, attr); +#endif + +} + +/*! \brief Deletes an attribute by using its PKI_ID */ + +int PKI_X509_REQ_delete_attribute ( PKI_X509_REQ *req, PKI_ID id ) { + + int ret = PKI_OK; + PKI_X509_REQ_VALUE *val = NULL; + + if ( !req || !req->value ) return PKI_ERR; + + val = req->value; + +#if OPENSSL_VERSION_NUMBER > 0x1010000fL + if (!val->req_info.attributes) { + ret = PKI_ERROR(PKI_ERR_PARAM_NULL, "No Attributes present"); + } else { + ret = PKI_STACK_X509_ATTRIBUTE_delete(val->req_info.attributes, id ); + } +#else + if (!val->req_info || !val->req_info->attributes) { + ret = PKI_ERROR(PKI_ERR_PARAM_NULL, "No Attributes present"); + } else { + ret = PKI_STACK_X509_ATTRIBUTE_delete(val->req_info->attributes, id); + } +#endif + + return ret; +} + +/*! \brief Deletes an attribute by using its number (position) */ + +int PKI_X509_REQ_delete_attribute_by_num ( PKI_X509_REQ *req, int pos ) { + + int ret = PKI_ERR; + PKI_X509_REQ_VALUE *val = NULL; + + if ( !req || !req->value ) return PKI_ERR; + + val = req->value; + +#if OPENSSL_VERSION_NUMBER > 0x1010000fL + if (val->req_info.attributes != NULL) { + ret = PKI_STACK_X509_ATTRIBUTE_delete_by_num( + val->req_info.attributes, pos); + } +#else + if (val->req_info && val->req_info->attributes) { + ret = PKI_STACK_X509_ATTRIBUTE_delete_by_num( + val->req_info->attributes, pos); + } +#endif + + return ret; +} + +/*! \brief Deletes an attribute by using its name */ + +int PKI_X509_REQ_delete_attribute_by_name ( PKI_X509_REQ *req, char *name ) { + + int ret = PKI_ERR; + PKI_X509_REQ_VALUE *val = NULL; + + if (!req || !req->value || !name) return PKI_ERR; + val = req->value; + +#if OPENSSL_VERSION_NUMBER > 0x1010000fL + if (val->req_info.attributes != NULL) { + ret = PKI_STACK_X509_ATTRIBUTE_delete_by_name( + val->req_info.attributes, name); + } +#else + if (val->req_info && val->req_info->attributes) { + ret = PKI_STACK_X509_ATTRIBUTE_delete_by_name( + val->req_info->attributes, name); + } +#endif + + return ret; +} + +/*! \brief Clears the stack of attributes from a PKI_X509_REQ */ + +int PKI_X509_REQ_clear_attributes ( PKI_X509_REQ *req ) { + + int ret = PKI_ERR; + PKI_X509_REQ_VALUE *val = NULL; + PKI_X509_ATTRIBUTE *attr = NULL; + + if (!req || !req->value) return PKI_ERR; + + val = req->value; + + +#if OPENSSL_VERSION_NUMBER > 0x1010000fL + if (val->req_info.attributes != NULL) { + while ((attr = PKI_STACK_X509_ATTRIBUTE_pop ( + val->req_info.attributes )) != NULL) { + PKI_X509_ATTRIBUTE_free(attr); + } + ret = PKI_OK; + } +#else + if (val->req_info && val->req_info->attributes) { + while ((attr = PKI_STACK_X509_ATTRIBUTE_pop ( + val->req_info->attributes )) != NULL) { + PKI_X509_ATTRIBUTE_free ( attr ); + } + ret = PKI_OK; + } +#endif + + return ret; +} + +/*! \brief Gets the number of attributes present in a PKI_X509_REQ */ + +int PKI_X509_REQ_get_attributes_num(const PKI_X509_REQ *req) { + + int ret = 0; + PKI_X509_REQ_VALUE *val = NULL; + + // Input Checks + if ( !req || !req->value ) return PKI_ERR; + + // Retrieve the internal value + val = req->value; + + // If Attributes are present, get the number +#if OPENSSL_VERSION_NUMBER > 0x1010000fL + if (val->req_info.attributes) { + ret = PKI_STACK_X509_ATTRIBUTE_elements(val->req_info.attributes); + } +#else + // If Attribtues are present, get the number + if (val->req_info && val->req_info->attributes) { + ret = PKI_STACK_X509_ATTRIBUTE_elements(val->req_info->attributes); + } +#endif + + // Return the retrieved number + return ret; +} + +/*! \brief Returns an attribute from a PKI_X509_REQ by its number (position) */ + +const PKI_X509_ATTRIBUTE *PKI_X509_REQ_get_attribute_by_num(const PKI_X509_REQ * req, + int num) { + + const PKI_X509_ATTRIBUTE * ret = NULL; + // Return Value + + PKI_X509_REQ_VALUE *val = NULL; + // Pointer to the request value + + // Input Checks + if ( !req || !req->value ) return NULL; + + // Gets the internal pointer + val = req->value; + +#if OPENSSL_VERSION_NUMBER > 0x1010000fL + // Gets the attribute 'num' + ret = PKI_STACK_X509_ATTRIBUTE_get_by_num(val->req_info.attributes, num); +#else + // Checks for the info structure to be there + if (val->req_info != NULL) { + // Gets the attribute by 'num' + ret = PKI_STACK_X509_ATTRIBUTE_get_by_num(val->req_info->attributes,num); + } +#endif + + // Returns the Attribute or NULL + return ret; + +} + +/*! \brief Returns an attribute from a PKI_X509_REQ by its type (PKI_ID) */ + +const PKI_X509_ATTRIBUTE *PKI_X509_REQ_get_attribute(const PKI_X509_REQ *req, + PKI_ID type ) { + + const PKI_X509_ATTRIBUTE * ret = NULL; + // Return Value + + PKI_X509_REQ_VALUE *val = NULL; + // Pointer to the Internal Value + + // Input check + if ( !req || !req->value ) return NULL; + + // Gets the internal value + val = req->value; + +#if OPENSSL_VERSION_NUMBER > 0x1010000fL + // If we have a valid attributes structure + if (val->req_info.attributes != NULL) { + // Gets the Attributes + ret = PKI_STACK_X509_ATTRIBUTE_get( val->req_info.attributes, type); + } +#else + // If we have a valid req_info structure + if (val->req_info != NULL && val->req_info->attributes != NULL) { + // Gets the Attribute + ret = PKI_STACK_X509_ATTRIBUTE_get(val->req_info->attributes, type); + } +#endif + + return ret; +} + +/*! \brief Returns an attribute from a PKI_X509_REQ by its name */ + +const PKI_X509_ATTRIBUTE *PKI_X509_REQ_get_attribute_by_name( + const PKI_X509_REQ *req, + const char * name ) { + + const PKI_X509_ATTRIBUTE * ret = NULL; + // Return Pointer for the attribute + + PKI_X509_REQ_VALUE *val = NULL; + // Pointer to the internal value + + // Input Checks + if (!req || !req->value || !name) return NULL; + + // Gets the Internal Value + val = req->value; + +#if OPENSSL_VERSION_NUMBER > 0x1010000fL + // If we have a valid attributes structure... + if (val->req_info.attributes) { + // ... get the attribute pointer by name + ret = PKI_STACK_X509_ATTRIBUTE_get_by_name( + val->req_info.attributes, name); + } +#else + // If we have a valid req_info and attributes structure... + if (val->req_info && val->req_info->attributes) { + // ... get the pointer to the attribute + ret = PKI_STACK_X509_ATTRIBUTE_get_by_name( + val->req_info->attributes, name); + } +#endif + // Returns the attribute pointer or NULL + return ret; +} + +/* ---------------------------- X509 REQ Extensions --------------------------- */ + +int PKI_X509_REQ_get_extension_by_num(const PKI_X509_REQ *req, + int num ) { + + PKI_log_debug("%s:%d::Code still missing!",__FILE__, __LINE__ ); + return ( PKI_ERR ); +} + +int PKI_X509_REQ_get_extension_by_oid(const PKI_X509_REQ *req, + const PKI_OID *oid ) { + + PKI_log_debug("%s:%d::Code still missing!",__FILE__, __LINE__ ); + return ( PKI_ERR ); +} + +int PKI_X509_REQ_get_extension_by_name(const PKI_X509_REQ *req, + const char * name ) { + PKI_log_debug("%s:%d::Code still missing!",__FILE__, __LINE__ ); + return ( PKI_ERR ); +} + diff --git a/src/pkix/prqp/Makefile.am b/src/pkix/prqp/Makefile.am new file mode 100644 index 00000000..64fca652 --- /dev/null +++ b/src/pkix/prqp/Makefile.am @@ -0,0 +1,32 @@ +## OpenCA Makefile - by Massimiliano Pala +## (c) 1999-2007 by Massimiliano Pala and OpenCA Project +## All Rights Reserved + +TOP = .. +include $(TOP)/global-vars + +BASE_DEFS = + +DEFS = $(OPENCA_DEFS) +PRQP_VERSION = 0.1.0 + +AM_CPPFLAGS = -I$(TOP) \ + $(openssl_cflags) \ + $(libxml2_cflags) \ + $(COND_INCLUDES) + +PRQP_SRCS = \ + asn1_req.c \ + asn1_res.c \ + http_client.c \ + prqp_lib.c \ + prqp_bio.c \ + prqp_req_io.c \ + prqp_resp_io.c \ + prqp_srv.c + +noinst_LTLIBRARIES = libpki-prqp.la +libpki_prqp_la_SOURCES = $(PRQP_SRCS) +libpki_prqp_la_CFLAGS = $(BUILD_LIBPKI_CFLAGS) +# libpki_prqp_la_LIBADD = $(OPENSSL_LIBS) + diff --git a/src/pkix/prqp/Makefile.in b/src/pkix/prqp/Makefile.in new file mode 100644 index 00000000..a8df501a --- /dev/null +++ b/src/pkix/prqp/Makefile.in @@ -0,0 +1,844 @@ +# Makefile.in generated by automake 1.16.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = src/prqp +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(SHELL) $(top_srcdir)/build/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/src/libpki/config.h \ + $(top_builddir)/src/libpki/libpki_enables.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +libpki_prqp_la_LIBADD = +am__objects_1 = libpki_prqp_la-asn1_req.lo libpki_prqp_la-asn1_res.lo \ + libpki_prqp_la-http_client.lo libpki_prqp_la-prqp_lib.lo \ + libpki_prqp_la-prqp_bio.lo libpki_prqp_la-prqp_req_io.lo \ + libpki_prqp_la-prqp_resp_io.lo libpki_prqp_la-prqp_srv.lo +am_libpki_prqp_la_OBJECTS = $(am__objects_1) +libpki_prqp_la_OBJECTS = $(am_libpki_prqp_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libpki_prqp_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(libpki_prqp_la_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o \ + $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src/libpki +depcomp = $(SHELL) $(top_srcdir)/build/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/libpki_prqp_la-asn1_req.Plo \ + ./$(DEPDIR)/libpki_prqp_la-asn1_res.Plo \ + ./$(DEPDIR)/libpki_prqp_la-http_client.Plo \ + ./$(DEPDIR)/libpki_prqp_la-prqp_bio.Plo \ + ./$(DEPDIR)/libpki_prqp_la-prqp_lib.Plo \ + ./$(DEPDIR)/libpki_prqp_la-prqp_req_io.Plo \ + ./$(DEPDIR)/libpki_prqp_la-prqp_resp_io.Plo \ + ./$(DEPDIR)/libpki_prqp_la-prqp_srv.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libpki_prqp_la_SOURCES) +DIST_SOURCES = $(libpki_prqp_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/build/depcomp \ + $(top_srcdir)/build/mkinstalldirs +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_DATE = @BUILD_DATE@ +BUILD_DATE_FULL = @BUILD_DATE_FULL@ +BUILD_DATE_PRETTY = @BUILD_DATE_PRETTY@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CHMOD = @CHMOD@ +CHOWN = @CHOWN@ +CP = @CP@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CPU = @CPU@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CXX = @CXX@ +CYGPATH_W = @CYGPATH_W@ +DATE = @DATE@ +DEFS = $(OPENCA_DEFS) +DEPDIR = @DEPDIR@ +DESTDIR = @DESTDIR@ +DIST_NAME = @DIST_NAME@ +DIST_VERSION = @DIST_VERSION@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +GZIP = @GZIP@ +HAS_PKGCONF = @HAS_PKGCONF@ +INSTALL = @INSTALL@ +INSTALL_BUILDER = @INSTALL_BUILDER@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKE = @MAKE@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR = @MKDIR@ +MKDIR_P = @MKDIR_P@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PDFLATEX = @PDFLATEX@ +PERL = @PERL@ +PG_CONFIG = @PG_CONFIG@ +PG_CPPFLAGS = @PG_CPPFLAGS@ +PKGMK = @PKGMK@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POD2MAN = @POD2MAN@ +PWD = @PWD@ +RANLIB = @RANLIB@ +RC = @RC@ +RPM = @RPM@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TAR = @TAR@ +TODAY = @TODAY@ +VERSION = @VERSION@ +ZIP = @ZIP@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_aux_dir = @ac_aux_dir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +arch_target = @arch_target@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +composite_cflags = @composite_cflags@ +composite_ldadd = @composite_ldadd@ +composite_ldflags = @composite_ldflags@ +conf_dir = @conf_dir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +day = @day@ +dist_group = @dist_group@ +dist_user = @dist_user@ +docdir = @docdir@ +dvidir = @dvidir@ +enable_debug = @enable_debug@ +etc_dir = @etc_dir@ +exec_prefix = @exec_prefix@ +extra_checks = @extra_checks@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +hr = @hr@ +htmldir = @htmldir@ +iface_age = @iface_age@ +iface_current = @iface_current@ +iface_revision = @iface_revision@ +iface_version = @iface_version@ +include_dir = @include_dir@ +include_prefix = @include_prefix@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +kmf_cflags = @kmf_cflags@ +kmf_ldadd = @kmf_ldadd@ +kmf_libflags = @kmf_libflags@ +kmf_prefix = @kmf_prefix@ +ldap_cflags = @ldap_cflags@ +ldap_ldadd = @ldap_ldadd@ +ldap_ldflags = @ldap_ldflags@ +ldap_prefix = @ldap_prefix@ +ldap_vendor = @ldap_vendor@ +lib_major = @lib_major@ +lib_micro = @lib_micro@ +lib_minor = @lib_minor@ +lib_prefix = @lib_prefix@ +lib_revision = @lib_revision@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libpki_cflags = @libpki_cflags@ +libpki_ldadd = @libpki_ldadd@ +libpki_ldflags = @libpki_ldflags@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +min = @min@ +mkdir_p = @mkdir_p@ +mon = @mon@ +my_cflags = @my_cflags@ +my_ldadd = @my_ldadd@ +my_ldflags = @my_ldflags@ +myarch = @myarch@ +mybits = @mybits@ +mybits_install = @mybits_install@ +mysql_cflags = @mysql_cflags@ +mysql_config = @mysql_config@ +mysql_ldadd = @mysql_ldadd@ +mysql_ldflags = @mysql_ldflags@ +mysql_prefix = @mysql_prefix@ +oldincludedir = @oldincludedir@ +openssl_cflags = @openssl_cflags@ +openssl_include = @openssl_include@ +openssl_ldadd = @openssl_ldadd@ +openssl_ldflags = @openssl_ldflags@ +openssl_prefix = @openssl_prefix@ +openssl_static_libs = @openssl_static_libs@ +oqs_cflags = @oqs_cflags@ +oqs_ldadd = @oqs_ldadd@ +oqs_ldflags = @oqs_ldflags@ +oqsprov_cflags = @oqsprov_cflags@ +oqsprov_ldadd = @oqsprov_ldadd@ +oqsprov_ldflags = @oqsprov_ldflags@ +package_build = @package_build@ +package_prefix = @package_prefix@ +pdfdir = @pdfdir@ +pg_cflags = @pg_cflags@ +pg_config = @pg_config@ +pg_ldadd = @pg_ldadd@ +pg_ldflags = @pg_ldflags@ +pg_prefix = @pg_prefix@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pthread_opts = @pthread_opts@ +resolv_ldadd = @resolv_ldadd@ +rpath = @rpath@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sdkver = @sdkver@ +sec = @sec@ +sharedstatedir = @sharedstatedir@ +shlext = @shlext@ +shlib_history = @shlib_history@ +shlib_version = @shlib_version@ +srcdir = @srcdir@ +sys_cflags = @sys_cflags@ +sys_ldadd = @sys_ldadd@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +test_libs = @test_libs@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +txt_revision = @txt_revision@ +xml2_cflags = @xml2_cflags@ +xml2_config = @xml2_config@ +xml2_include = @xml2_include@ +xml2_ldadd = @xml2_ldadd@ +xml2_ldflags = @xml2_ldflags@ +xml2_prefix = @xml2_prefix@ +yr = @yr@ +TOP = .. +BASE_DEFS = +PRQP_VERSION = 0.1.0 +AM_CPPFLAGS = -I$(TOP) \ + $(openssl_cflags) \ + $(libxml2_cflags) \ + $(COND_INCLUDES) + +PRQP_SRCS = \ + asn1_req.c \ + asn1_res.c \ + http_client.c \ + prqp_lib.c \ + prqp_bio.c \ + prqp_req_io.c \ + prqp_resp_io.c \ + prqp_srv.c + +noinst_LTLIBRARIES = libpki-prqp.la +libpki_prqp_la_SOURCES = $(PRQP_SRCS) +libpki_prqp_la_CFLAGS = $(BUILD_LIBPKI_CFLAGS) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/prqp/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/prqp/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libpki-prqp.la: $(libpki_prqp_la_OBJECTS) $(libpki_prqp_la_DEPENDENCIES) $(EXTRA_libpki_prqp_la_DEPENDENCIES) + $(AM_V_CCLD)$(libpki_prqp_la_LINK) $(libpki_prqp_la_OBJECTS) $(libpki_prqp_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_prqp_la-asn1_req.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_prqp_la-asn1_res.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_prqp_la-http_client.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_prqp_la-prqp_bio.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_prqp_la-prqp_lib.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_prqp_la-prqp_req_io.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_prqp_la-prqp_resp_io.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_prqp_la-prqp_srv.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +libpki_prqp_la-asn1_req.lo: asn1_req.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_prqp_la_CFLAGS) $(CFLAGS) -MT libpki_prqp_la-asn1_req.lo -MD -MP -MF $(DEPDIR)/libpki_prqp_la-asn1_req.Tpo -c -o libpki_prqp_la-asn1_req.lo `test -f 'asn1_req.c' || echo '$(srcdir)/'`asn1_req.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_prqp_la-asn1_req.Tpo $(DEPDIR)/libpki_prqp_la-asn1_req.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='asn1_req.c' object='libpki_prqp_la-asn1_req.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_prqp_la_CFLAGS) $(CFLAGS) -c -o libpki_prqp_la-asn1_req.lo `test -f 'asn1_req.c' || echo '$(srcdir)/'`asn1_req.c + +libpki_prqp_la-asn1_res.lo: asn1_res.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_prqp_la_CFLAGS) $(CFLAGS) -MT libpki_prqp_la-asn1_res.lo -MD -MP -MF $(DEPDIR)/libpki_prqp_la-asn1_res.Tpo -c -o libpki_prqp_la-asn1_res.lo `test -f 'asn1_res.c' || echo '$(srcdir)/'`asn1_res.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_prqp_la-asn1_res.Tpo $(DEPDIR)/libpki_prqp_la-asn1_res.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='asn1_res.c' object='libpki_prqp_la-asn1_res.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_prqp_la_CFLAGS) $(CFLAGS) -c -o libpki_prqp_la-asn1_res.lo `test -f 'asn1_res.c' || echo '$(srcdir)/'`asn1_res.c + +libpki_prqp_la-http_client.lo: http_client.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_prqp_la_CFLAGS) $(CFLAGS) -MT libpki_prqp_la-http_client.lo -MD -MP -MF $(DEPDIR)/libpki_prqp_la-http_client.Tpo -c -o libpki_prqp_la-http_client.lo `test -f 'http_client.c' || echo '$(srcdir)/'`http_client.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_prqp_la-http_client.Tpo $(DEPDIR)/libpki_prqp_la-http_client.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='http_client.c' object='libpki_prqp_la-http_client.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_prqp_la_CFLAGS) $(CFLAGS) -c -o libpki_prqp_la-http_client.lo `test -f 'http_client.c' || echo '$(srcdir)/'`http_client.c + +libpki_prqp_la-prqp_lib.lo: prqp_lib.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_prqp_la_CFLAGS) $(CFLAGS) -MT libpki_prqp_la-prqp_lib.lo -MD -MP -MF $(DEPDIR)/libpki_prqp_la-prqp_lib.Tpo -c -o libpki_prqp_la-prqp_lib.lo `test -f 'prqp_lib.c' || echo '$(srcdir)/'`prqp_lib.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_prqp_la-prqp_lib.Tpo $(DEPDIR)/libpki_prqp_la-prqp_lib.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='prqp_lib.c' object='libpki_prqp_la-prqp_lib.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_prqp_la_CFLAGS) $(CFLAGS) -c -o libpki_prqp_la-prqp_lib.lo `test -f 'prqp_lib.c' || echo '$(srcdir)/'`prqp_lib.c + +libpki_prqp_la-prqp_bio.lo: prqp_bio.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_prqp_la_CFLAGS) $(CFLAGS) -MT libpki_prqp_la-prqp_bio.lo -MD -MP -MF $(DEPDIR)/libpki_prqp_la-prqp_bio.Tpo -c -o libpki_prqp_la-prqp_bio.lo `test -f 'prqp_bio.c' || echo '$(srcdir)/'`prqp_bio.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_prqp_la-prqp_bio.Tpo $(DEPDIR)/libpki_prqp_la-prqp_bio.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='prqp_bio.c' object='libpki_prqp_la-prqp_bio.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_prqp_la_CFLAGS) $(CFLAGS) -c -o libpki_prqp_la-prqp_bio.lo `test -f 'prqp_bio.c' || echo '$(srcdir)/'`prqp_bio.c + +libpki_prqp_la-prqp_req_io.lo: prqp_req_io.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_prqp_la_CFLAGS) $(CFLAGS) -MT libpki_prqp_la-prqp_req_io.lo -MD -MP -MF $(DEPDIR)/libpki_prqp_la-prqp_req_io.Tpo -c -o libpki_prqp_la-prqp_req_io.lo `test -f 'prqp_req_io.c' || echo '$(srcdir)/'`prqp_req_io.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_prqp_la-prqp_req_io.Tpo $(DEPDIR)/libpki_prqp_la-prqp_req_io.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='prqp_req_io.c' object='libpki_prqp_la-prqp_req_io.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_prqp_la_CFLAGS) $(CFLAGS) -c -o libpki_prqp_la-prqp_req_io.lo `test -f 'prqp_req_io.c' || echo '$(srcdir)/'`prqp_req_io.c + +libpki_prqp_la-prqp_resp_io.lo: prqp_resp_io.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_prqp_la_CFLAGS) $(CFLAGS) -MT libpki_prqp_la-prqp_resp_io.lo -MD -MP -MF $(DEPDIR)/libpki_prqp_la-prqp_resp_io.Tpo -c -o libpki_prqp_la-prqp_resp_io.lo `test -f 'prqp_resp_io.c' || echo '$(srcdir)/'`prqp_resp_io.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_prqp_la-prqp_resp_io.Tpo $(DEPDIR)/libpki_prqp_la-prqp_resp_io.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='prqp_resp_io.c' object='libpki_prqp_la-prqp_resp_io.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_prqp_la_CFLAGS) $(CFLAGS) -c -o libpki_prqp_la-prqp_resp_io.lo `test -f 'prqp_resp_io.c' || echo '$(srcdir)/'`prqp_resp_io.c + +libpki_prqp_la-prqp_srv.lo: prqp_srv.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_prqp_la_CFLAGS) $(CFLAGS) -MT libpki_prqp_la-prqp_srv.lo -MD -MP -MF $(DEPDIR)/libpki_prqp_la-prqp_srv.Tpo -c -o libpki_prqp_la-prqp_srv.lo `test -f 'prqp_srv.c' || echo '$(srcdir)/'`prqp_srv.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_prqp_la-prqp_srv.Tpo $(DEPDIR)/libpki_prqp_la-prqp_srv.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='prqp_srv.c' object='libpki_prqp_la-prqp_srv.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_prqp_la_CFLAGS) $(CFLAGS) -c -o libpki_prqp_la-prqp_srv.lo `test -f 'prqp_srv.c' || echo '$(srcdir)/'`prqp_srv.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/libpki_prqp_la-asn1_req.Plo + -rm -f ./$(DEPDIR)/libpki_prqp_la-asn1_res.Plo + -rm -f ./$(DEPDIR)/libpki_prqp_la-http_client.Plo + -rm -f ./$(DEPDIR)/libpki_prqp_la-prqp_bio.Plo + -rm -f ./$(DEPDIR)/libpki_prqp_la-prqp_lib.Plo + -rm -f ./$(DEPDIR)/libpki_prqp_la-prqp_req_io.Plo + -rm -f ./$(DEPDIR)/libpki_prqp_la-prqp_resp_io.Plo + -rm -f ./$(DEPDIR)/libpki_prqp_la-prqp_srv.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/libpki_prqp_la-asn1_req.Plo + -rm -f ./$(DEPDIR)/libpki_prqp_la-asn1_res.Plo + -rm -f ./$(DEPDIR)/libpki_prqp_la-http_client.Plo + -rm -f ./$(DEPDIR)/libpki_prqp_la-prqp_bio.Plo + -rm -f ./$(DEPDIR)/libpki_prqp_la-prqp_lib.Plo + -rm -f ./$(DEPDIR)/libpki_prqp_la-prqp_req_io.Plo + -rm -f ./$(DEPDIR)/libpki_prqp_la-prqp_resp_io.Plo + -rm -f ./$(DEPDIR)/libpki_prqp_la-prqp_srv.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-noinstLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + +include $(TOP)/global-vars +# libpki_prqp_la_LIBADD = $(OPENSSL_LIBS) + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/pkix/prqp/asn1_req.c b/src/pkix/prqp/asn1_req.c new file mode 100644 index 00000000..11d0e00b --- /dev/null +++ b/src/pkix/prqp/asn1_req.c @@ -0,0 +1,147 @@ +/* PKI Resource Query Protocol Message implementation + * (c) 2004-2007 by Massimiliano Pala and OpenCA Group + * All Rights Reserved + * + * This software is released under the GPL2 License included + * in the archive. You can not remove this copyright notice. + */ + +#include + +/* Signature ::= SEQUENCE { + * signatureAlgorithm AlgorithmIdentifier, + * signature BIT STRING, + * certs [0] EXPLICIT SEQUENCE OF Certificate OPT } + */ + +ASN1_SEQUENCE(PRQP_SIGNATURE) = { + ASN1_SIMPLE(PRQP_SIGNATURE, signatureAlgorithm, X509_ALGOR ), + ASN1_SIMPLE(PRQP_SIGNATURE, signature, ASN1_BIT_STRING), + ASN1_SIMPLE(PRQP_SIGNATURE, signerCert, X509), + ASN1_EXP_SEQUENCE_OF_OPT(PRQP_SIGNATURE, otherCerts, X509, 1) +} ASN1_SEQUENCE_END(PRQP_SIGNATURE) + +IMPLEMENT_ASN1_FUNCTIONS(PRQP_SIGNATURE) + +/* BasicCertIndentifier ::= SEQUENCE { + * serialNumber CertificateSerialNumber, + * issuerNameHash OCTET STRING } + */ + +/* +ASN1_SEQUENCE(BASIC_CERT_IDENTIFIER) = { + ASN1_SIMPLE(BASIC_CERT_IDENTIFIER,subjectNameHash,ASN1_OCTET_STRING), + ASN1_EXP_OPT(BASIC_CERT_IDENTIFIER,issuerNameHash,ASN1_OCTET_STRING,0), + ASN1_EXP_OPT(BASIC_CERT_IDENTIFIER,serialNumber,ASN1_INTEGER,1) +} ASN1_SEQUENCE_END(BASIC_CERT_IDENTIFIER) +*/ + +ASN1_SEQUENCE(BASIC_CERT_IDENTIFIER) = { + ASN1_SIMPLE(BASIC_CERT_IDENTIFIER,issuerNameHash,ASN1_OCTET_STRING), + ASN1_SIMPLE(BASIC_CERT_IDENTIFIER,serialNumber,ASN1_INTEGER) +} ASN1_SEQUENCE_END(BASIC_CERT_IDENTIFIER) + +IMPLEMENT_ASN1_FUNCTIONS(BASIC_CERT_IDENTIFIER) +IMPLEMENT_ASN1_DUP_FUNCTION( BASIC_CERT_IDENTIFIER ) + +/* ExtendedCertInfo ::= SEQUENCE { + * certificateHash OCTET STRING, + * subjectKeyHash OCTET STRING, + * subjectKeyIdentifier [0] KeyIdentifier OPTIONAL, + * issuerKeyIdentifier [1] KeyIdentifier OPTIONAL } + */ + +ASN1_SEQUENCE(EXTENDED_CERT_INFO) = { + ASN1_SIMPLE(EXTENDED_CERT_INFO, certificateHash, ASN1_OCTET_STRING), + ASN1_SIMPLE(EXTENDED_CERT_INFO, subjectKeyHash, ASN1_OCTET_STRING), + ASN1_EXP_OPT(EXTENDED_CERT_INFO, subjectKeyId, ASN1_OCTET_STRING, 0), + ASN1_EXP_OPT(EXTENDED_CERT_INFO, issuerKeyId, ASN1_OCTET_STRING, 1) +} ASN1_SEQUENCE_END(EXTENDED_CERT_INFO) + +IMPLEMENT_ASN1_FUNCTIONS( EXTENDED_CERT_INFO ) +IMPLEMENT_ASN1_DUP_FUNCTION( EXTENDED_CERT_INFO) + +/* CertIdentifier ::= SEQUENCE { + * hashAlgorithm AlgorithmIdentifier, + * basicCertIdentifier BasicCertIdentifier, + * extInfo [0] ExtendedCertInfo OPTIONAL, + * caCertificate [1] Certificate OPTIONAL, + * issuedCertificate [2] Certificate OPTIONAL } + */ + +ASN1_SEQUENCE(CERT_IDENTIFIER) = { + ASN1_SIMPLE(CERT_IDENTIFIER, hashAlgorithm, X509_ALGOR), + ASN1_SIMPLE(CERT_IDENTIFIER, basicCertId, BASIC_CERT_IDENTIFIER), + ASN1_EXP_OPT(CERT_IDENTIFIER, extInfo, EXTENDED_CERT_INFO, 0), + ASN1_EXP_OPT(CERT_IDENTIFIER, caCert, X509, 1), + ASN1_EXP_OPT(CERT_IDENTIFIER, issuedCert, X509, 2) +} ASN1_SEQUENCE_END(CERT_IDENTIFIER) + +IMPLEMENT_ASN1_FUNCTIONS(CERT_IDENTIFIER) +IMPLEMENT_ASN1_DUP_FUNCTION(CERT_IDENTIFIER) + +/* ResourceIdentifier ::= SEQUENCE { + * resourceId OBJECT IDENTIFIER, + * version [0] INTEGER OPTIONAL } + */ + +ASN1_SEQUENCE(RESOURCE_IDENTIFIER) = { + ASN1_SIMPLE( RESOURCE_IDENTIFIER, resourceId, ASN1_OBJECT ), + ASN1_EXP_OPT( RESOURCE_IDENTIFIER, version, ASN1_INTEGER, 0 ), + ASN1_EXP_OPT( RESOURCE_IDENTIFIER, oid, ASN1_OBJECT, 1 ) +} ASN1_SEQUENCE_END ( RESOURCE_IDENTIFIER ) + +IMPLEMENT_ASN1_FUNCTIONS( RESOURCE_IDENTIFIER ) +IMPLEMENT_ASN1_DUP_FUNCTION( RESOURCE_IDENTIFIER ) + +/* ResourceRequestToken ::= SEQUENCE { + * ca caCertIdentifier, + * resourceList [0] SEQUENCE OF OBJECT IDENTIFIER OPTIONAL } + */ + +ASN1_SEQUENCE(RESOURCE_REQUEST_TOKEN) = { + ASN1_SIMPLE(RESOURCE_REQUEST_TOKEN, ca, CERT_IDENTIFIER), + ASN1_EXP_SEQUENCE_OF(RESOURCE_REQUEST_TOKEN, resourceList, RESOURCE_IDENTIFIER, 0) +} ASN1_SEQUENCE_END(RESOURCE_REQUEST_TOKEN) + +IMPLEMENT_ASN1_FUNCTIONS(RESOURCE_REQUEST_TOKEN) + +/* TBSReqData ::= SEQUENCE { + * version INTEGER {v(1)}, + * nonce [0] INTEGER OPTIONAL, + * serviceToken ResourceRequestToken, + * extensions [1] IMPLICIT Extensions OPTIONAL } +*/ + +ASN1_SEQUENCE(PRQP_TBS_REQ_DATA) = { + ASN1_SIMPLE(PRQP_TBS_REQ_DATA, version, ASN1_INTEGER), + ASN1_EXP_OPT(PRQP_TBS_REQ_DATA, nonce, ASN1_INTEGER, 0), + ASN1_SIMPLE(PRQP_TBS_REQ_DATA, producedAt, ASN1_GENERALIZEDTIME), + ASN1_SIMPLE(PRQP_TBS_REQ_DATA, serviceToken, RESOURCE_REQUEST_TOKEN), + ASN1_IMP_SEQUENCE_OF_OPT(PRQP_TBS_REQ_DATA, extensions, X509_EXTENSION, 1) +} ASN1_SEQUENCE_END(PRQP_TBS_REQ_DATA) + +IMPLEMENT_ASN1_FUNCTIONS(PRQP_TBS_REQ_DATA) + + +/* PRQPReqest ::= SEQUENCE { + * requestData TBSReqData, + * signature [0] EXPLICIT Signature OPTIONAL } + */ + +ASN1_SEQUENCE(PKI_PRQP_REQ) = { + ASN1_SIMPLE(PKI_PRQP_REQ, requestData, PRQP_TBS_REQ_DATA ), + ASN1_EXP_OPT(PKI_PRQP_REQ, prqpSignature, PRQP_SIGNATURE, 0) +} ASN1_SEQUENCE_END(PKI_PRQP_REQ) + +IMPLEMENT_ASN1_FUNCTIONS(PKI_PRQP_REQ) + +IMPLEMENT_ASN1_DUP_FUNCTION(PKI_PRQP_REQ) + +/* +PKI_PRQP_REQ * PKI_PRQP_REQ_dup ( PKI_PRQP_REQ *req ) { + ASN1_item_dup ( &PKI_PRQP_REQ_it, req ); +} +*/ + +/* end */ diff --git a/src/pkix/prqp/asn1_res.c b/src/pkix/prqp/asn1_res.c new file mode 100644 index 00000000..f5a8ba15 --- /dev/null +++ b/src/pkix/prqp/asn1_res.c @@ -0,0 +1,132 @@ +/* PKI Resource Query Protocol Message implementation + * (c) 2004 by Massimiliano Pala and OpenCA Group + * All Rights Reserved + * + * This software is released under the GPL2 License included + * in the archive. You can not remove this copyright notice. + */ + +#include + +/* PKIStatus ::= INTEGER { + * ok {0}, + * badRequest {1}, + * caNotPresent {2}, + * systemFailure {3} } + */ + +/* PKIFailureInfo ::= BIT STRING { + * -- since we can fail in more than one way! + * -- More codes may be added in the future if/when required. + * badAlg (0), + * -- unrecognized or unsupported Algorithm Identifier + * badMessageCheck (1), + * -- integrity check failed (e.g., signature did not verify) + * badRequest (2), + * -- transaction not permitted or supported + * badTime (3), + * -- messageTime was not sufficiently close to the system time, + * -- as defined by local policy + * badCertId (4), + * -- no certificate could be found matching the provided criteria + * badDataFormat (5), + * -- the data submitted has the wrong format + * wrongAuthority (6), + * -- the authority indicated in the request is different from the + * -- one creating the response token + * incorrectData (7), + * -- the requester's data is incorrect (for notary services) + * missingTimeStamp (8), + * -- when the timestamp is missing but should be there (by policy) + */ + +/* PKIStatusInfo ::= SEQUENCE { + * status PKIStatus, + * statusString PKIFreeText OPTIONAL, + * failInfo PKIFailureInfo OPTIONAL } + */ + +ASN1_SEQUENCE(PKI_STATUS_INFO) = { + ASN1_SIMPLE(PKI_STATUS_INFO, status, ASN1_INTEGER), + ASN1_EXP_OPT(PKI_STATUS_INFO, statusString, ASN1_UTF8STRING, 0), + ASN1_EXP_OPT(PKI_STATUS_INFO, failInfo, ASN1_BIT_STRING, 1), + ASN1_EXP_SEQUENCE_OF_OPT(PKI_STATUS_INFO, referrals, ASN1_IA5STRING, 2) +} ASN1_SEQUENCE_END(PKI_STATUS_INFO) + +IMPLEMENT_ASN1_FUNCTIONS(PKI_STATUS_INFO) + +/* ResourceInfo ::= { + * resourceUri IA5String, + * version [0] INTEGER OPTIONAL } + */ + +/* +ASN1_SEQUENCE(RESOURCE_INFO) = { + ASN1_SIMPLE( RESOURCE_INFO, resourceUri, ASN1_IA5STRING ), + ASN1_EXP_OPT( RESOURCE_INFO, version, ASN1_INTEGER, 0 ), + ASN1_EXP_OPT( RESOURCE_INFO, textInfo, ASN1_UTF8STRING, 1 ) +} ASN1_SEQUENCE_END (RESOURCE_INFO) + +IMPLEMENT_ASN1_FUNCTIONS( RESOURCE_INFO ) +IMPLEMENT_ASN1_DUP_FUNCTION ( RESOURCE_INFO ) +*/ + +/* ResourceResponseToken ::= { + * serviceId OBJECT IDENTIFIER, + * resLocatorList [0] EXPLICIT SEQUENCE OF IA5String } + */ + +ASN1_SEQUENCE(RESOURCE_RESPONSE_TOKEN) = { + ASN1_SIMPLE(RESOURCE_RESPONSE_TOKEN, resourceId, ASN1_OBJECT), + ASN1_EXP_SEQUENCE_OF(RESOURCE_RESPONSE_TOKEN, resLocatorList, ASN1_IA5STRING, 0), + ASN1_EXP_OPT( RESOURCE_RESPONSE_TOKEN, version, ASN1_INTEGER, 1 ), + ASN1_EXP_OPT( RESOURCE_RESPONSE_TOKEN, oid, ASN1_OBJECT, 2 ), + ASN1_EXP_OPT( RESOURCE_RESPONSE_TOKEN, textInfo, ASN1_UTF8STRING, 3 ) +} ASN1_SEQUENCE_END(RESOURCE_RESPONSE_TOKEN) + +IMPLEMENT_ASN1_FUNCTIONS(RESOURCE_RESPONSE_TOKEN) +IMPLEMENT_ASN1_DUP_FUNCTION(RESOURCE_RESPONSE_TOKEN) + +/* TBSRespData ::= SEQUENCE { + * version INTEGER { v(1) }, + * pkiStatus PKIStatusInfo, + * nonce [0] INTEGER OPTIONAL, + * producedAt GeneralizedTime, + * nextUpdate [1] GeneralizedTime OPTIONAL, + * responseToken [2] SEQUENCE OF ResourceResponseToken OPTIONAL, + * extensions [3] EXPLICIT Extensions OPTIONAL } + */ +ASN1_SEQUENCE(PRQP_TBS_RESP_DATA) = { + ASN1_SIMPLE(PRQP_TBS_RESP_DATA, version, ASN1_INTEGER), + ASN1_EXP_OPT(PRQP_TBS_RESP_DATA, nonce, ASN1_INTEGER, 0), + ASN1_SIMPLE(PRQP_TBS_RESP_DATA, producedAt, ASN1_GENERALIZEDTIME), + ASN1_EXP_OPT(PRQP_TBS_RESP_DATA, nextUpdate, ASN1_GENERALIZEDTIME, 1), + ASN1_SIMPLE(PRQP_TBS_RESP_DATA, pkiStatus, PKI_STATUS_INFO), + ASN1_SIMPLE(PRQP_TBS_RESP_DATA, caCertId, CERT_IDENTIFIER), + ASN1_EXP_SEQUENCE_OF_OPT(PRQP_TBS_RESP_DATA, responseToken, RESOURCE_RESPONSE_TOKEN, 2), + ASN1_EXP_SEQUENCE_OF_OPT(PRQP_TBS_RESP_DATA, extensions, X509_EXTENSION, 3) +} ASN1_SEQUENCE_END(PRQP_TBS_RESP_DATA) + +IMPLEMENT_ASN1_FUNCTIONS(PRQP_TBS_RESP_DATA) + +/* PRQPResponse ::= SEQUENCE { + * respData TBSRespData, + * signature [0] EXPLICIT Signature OPTIONAL } + */ + +ASN1_SEQUENCE(PKI_PRQP_RESP) = { + ASN1_SIMPLE(PKI_PRQP_RESP, respData, PRQP_TBS_RESP_DATA), + ASN1_EXP_OPT(PKI_PRQP_RESP, prqpSignature, PRQP_SIGNATURE, 0) +} ASN1_SEQUENCE_END(PKI_PRQP_RESP) + +IMPLEMENT_ASN1_FUNCTIONS(PKI_PRQP_RESP) + +IMPLEMENT_ASN1_DUP_FUNCTION(PKI_PRQP_RESP) + +/* +PKI_PRQP_RESP * PKI_PRQP_RESP_dup ( PKI_PRQP_RESP *req ) { + ASN1_item_dup ( &PKI_PRQP_RESP_it, req ); +} +*/ + +/* end */ diff --git a/src/pkix/prqp/http_client.c b/src/pkix/prqp/http_client.c new file mode 100644 index 00000000..09c94e70 --- /dev/null +++ b/src/pkix/prqp/http_client.c @@ -0,0 +1,57 @@ +/* + * OCSP responder + * by Massimiliano Pala (madwolf@openca.org) + * OpenCA project 2001 + * + * Copyright (c) 2001 The OpenCA Project. All rights reserved. + * + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +PKI_X509_PRQP_RESP *PKI_X509_PRQP_RESP_get_http ( URL *url, + PKI_X509_PRQP_REQ *req, unsigned long max_size ) { + + PKI_MEM *mem = NULL; + PKI_X509_PRQP_RESP *resp = NULL; + PKI_MEM_STACK *mem_sk = NULL; + + if(( mem = PKI_X509_PRQP_REQ_put_mem ( req, + PKI_DATA_FORMAT_ASN1, NULL, NULL, NULL )) == NULL ) { + return NULL; + } + + if ( URL_put_data_url ( url, mem, "application/prqp-request", + &mem_sk, 60, 0, NULL ) == PKI_ERR ) { + PKI_MEM_free ( mem ); + return NULL; + } + + PKI_MEM_free ( mem ); + + if ( PKI_STACK_MEM_elements ( mem_sk ) <= 0 ) { + PKI_log_debug ("No Responses received!"); + } + + if((mem = PKI_STACK_MEM_pop ( mem_sk )) == NULL ) { + PKI_log_debug ("STACK Memory Error"); + PKI_STACK_MEM_free_all ( mem_sk ); + return NULL; + } + + if((resp = PKI_X509_PRQP_RESP_get_mem ( mem, + PKI_DATA_FORMAT_UNKNOWN, NULL, NULL )) == NULL ) { + PKI_log_debug ( "Can not read response from Memory."); + } + + PKI_STACK_MEM_free_all ( mem_sk ); + + return resp; + +} diff --git a/src/pkix/prqp/prqp_bio.c b/src/pkix/prqp/prqp_bio.c new file mode 100644 index 00000000..bbfefc54 --- /dev/null +++ b/src/pkix/prqp/prqp_bio.c @@ -0,0 +1,572 @@ +/* PKI Resource Query Protocol Message implementation + * (c) 2007 by Massimiliano Pala and OpenCA Group + * All Rights Reserved + * + * This software is released under the GPL2 License included + * in the archive. You can not remove this copyright notice. + */ + +#include + +/* +#define PEM_read_PKI_PRQP_REQ (fp,x,cb,u) (PKI_PRQP_REQ *) PEM_ASN1_read( \ + (char *(*)())d2i_PKI_PRQP_REQ,PEM_STRING_PKI_PRQP_REQ,fp,(char **)x,cb,u) +#define PEM_read_PKI_PRQP_RESP (fp,x,cb,u) (PKI_PRQP_RESP *) PEM_ASN1_read( \ + (char *(*)())d2i_PKI_PRQP_RESP,PEM_STRING_PKI_PRQP_RESP,fp,(char **)x,cb,u) +*/ + +/* +PKI_PRQP_REQ *d2i_PRQP_SIGNATURE_bio ( BIO *bp, PRQP_SIGNATURE *p ) { +#if OPENSSL_VERSION_NUMBER < 0x0090800fL + return (PRQP_SIGNATURE *) ASN1_d2i_bio( + (char *(*)(void))PRQP_SIGNATURE_new, + (char *(*)(void **, const unsigned char **, long))d2i_PRQP_SIGNATURE, + bp, (unsigned char **) &p); +#else + return (PRQP_SIGNATURE *) ASN1_d2i_bio( + (void *(*)(void))PRQP_SIGNATURE_new, + (void *(*)(void **, const unsigned char **, long))d2i_PRQP_SIGNATURE, + bp, (void **) &p); +#endif +} + +int i2d_PRQP_SIGNATURE_bio(BIO *bp, PRQP_SIGNATURE *o ) { +#if OPENSSL_VERSION_NUMBER < 0x0090800fL + return ASN1_i2d_bio( (int (*)(PRQP_SIGNATURE *, unsigned char **)) + i2d_PRQP_SIGNATURE, bp, (unsigned char *) o); +#else + return ASN1_i2d_bio( (i2d_of_void *) i2d_PRQP_SIGNATURE, + bp, (unsigned char *) o); +#endif +} +*/ + +/* DER <-> INTERNAL Macros */ +PKI_PRQP_REQ *d2i_PRQP_REQ_bio ( BIO *bp, PKI_PRQP_REQ *p ) { +#if OPENSSL_VERSION_NUMBER < 0x0090800fL + return (PKI_PRQP_REQ *) ASN1_d2i_bio( + (char *(*)(void))PKI_PRQP_REQ_new, + (char *(*)(void **, const unsigned char **, long))d2i_PKI_PRQP_REQ, + bp, (unsigned char **) &p); +#else + return (PKI_PRQP_REQ *) ASN1_d2i_bio( + (void *(*)(void))PKI_PRQP_REQ_new, + (void *(*)(void **, const unsigned char **, long))d2i_PKI_PRQP_REQ, + bp, (void **) &p); +#endif +} + +int i2d_PRQP_REQ_bio(BIO *bp, PKI_PRQP_REQ *o ) { +#if OPENSSL_VERSION_NUMBER < 0x0090800fL + return ASN1_i2d_bio( (int (*)(PKI_PRQP_REQ *, unsigned char **)) i2d_PKI_PRQP_REQ, bp, (unsigned char *) o); +#else + return ASN1_i2d_bio( (i2d_of_void *) i2d_PKI_PRQP_REQ, bp, (unsigned char *) o); +#endif +} + +PKI_PRQP_RESP *d2i_PRQP_RESP_bio( BIO *bp, PKI_PRQP_RESP *p ) { +#if OPENSSL_VERSION_NUMBER < 0x0090800fL + return (PKI_PRQP_RESP *) ASN1_d2i_bio( + (char *(*)(void))PKI_PRQP_RESP_new, + (char *(*)(void **, const unsigned char **, long))d2i_PKI_PRQP_RESP, + bp, (unsigned char **) &p); +#else + return (PKI_PRQP_RESP *) ASN1_d2i_bio( + (void *(*)(void))PKI_PRQP_RESP_new, + (void *(*)(void **, const unsigned char **, long))d2i_PKI_PRQP_RESP, + bp, (void **) &p); +#endif +} + +int i2d_PRQP_RESP_bio( BIO *bp, PKI_PRQP_RESP *o ) { +#if OPENSSL_VERSION_NUMBER < 0x0090800fL + return ASN1_i2d_bio( (int (*)(PKI_PRQP_RESP *, unsigned char **)) i2d_PKI_PRQP_RESP, bp, (unsigned char *) o); +#else + return ASN1_i2d_bio((i2d_of_void *)i2d_PKI_PRQP_RESP, bp, (unsigned char *) o); +#endif +} + + +/* PEM <-> INTERNAL Macros */ +PKI_PRQP_REQ *PEM_read_bio_PRQP_REQ( BIO *bp ) { +#if OPENSSL_VERSION_NUMBER < 0x0090800fL + return (PKI_PRQP_REQ *) PEM_ASN1_read_bio( (char *(*)()) d2i_PKI_PRQP_REQ, + PEM_STRING_PKI_PRQP_REQ, bp, NULL, NULL, NULL); +#else + return (PKI_PRQP_REQ *) PEM_ASN1_read_bio( (void *(*)()) d2i_PKI_PRQP_REQ, + PEM_STRING_PKI_PRQP_REQ, bp, NULL, NULL, NULL); +#endif +} + +PKI_PRQP_RESP *PEM_read_bio_PRQP_RESP( BIO *bp ) { +#if OPENSSL_VERSION_NUMBER < 0x0090800fL + return (PKI_PRQP_RESP *) PEM_ASN1_read_bio( (char *(*)()) d2i_PKI_PRQP_RESP, + PEM_STRING_PKI_PRQP_RESP, bp, NULL, NULL, NULL); +#else + return (PKI_PRQP_RESP *) PEM_ASN1_read_bio( (void *(*)()) d2i_PKI_PRQP_RESP, + PEM_STRING_PKI_PRQP_RESP, bp, NULL, NULL, NULL); +#endif +} + +int PEM_write_bio_PRQP_REQ( BIO *bp, PKI_PRQP_REQ *o ) { + return PEM_ASN1_write_bio ( (int (*)())i2d_PKI_PRQP_REQ, + PEM_STRING_PKI_PRQP_REQ, bp, (char *) o, NULL, + NULL, 0, NULL, NULL ); +} + +int PEM_write_bio_PRQP_RESP( BIO *bp, PKI_PRQP_RESP *o ) { + return PEM_ASN1_write_bio ( (int (*)()) i2d_PKI_PRQP_RESP, + PEM_STRING_PKI_PRQP_RESP, bp, (char *) o, NULL, + NULL, 0, NULL, NULL ); +} + +/* ======================== REQ get API ========================== */ + +/*! + * \brief Retrieves a PRQP request from the resource specified in the + * provided URI string +*/ + +/* +PKI_PRQP_REQ *PKI_PRQP_REQ_get( char *url_s ) { + + URL *url = NULL; + + if( !url_s ) return ( NULL ); + + if((url = URL_new( url_s )) == NULL ) { + return (NULL); + } + + return ( PKI_PRQP_REQ_get_url( url )); +} +*/ + +/*! + * \brief Retrieves a PRQP request from the resource specified in the + * provided URL structure +*/ + +/* +PKI_PRQP_REQ *PKI_PRQP_REQ_get_url( URL *url ) { + + PKI_PRQP_REQ *ret = NULL; + PKI_MEM_STACK *mem_sk = NULL; + PKI_MEM *in = NULL; + + if(!url) return NULL; + + if((mem_sk = URL_get_data_url ( url, 0 )) == NULL ) { + return(NULL); + } + + if((in = PKI_STACK_MEM_pop( mem_sk )) != NULL ) { + ret = PKI_PRQP_REQ_get_mem( in ); + } + + if( mem_sk ) PKI_STACK_MEM_free_all ( mem_sk ); + + return ( ret ); +} +*/ + +/*! + * \brief Retrieves a PRQP request from the specified file descriptor +*/ + +/* +PKI_PRQP_REQ *PKI_PRQP_REQ_get_fd( int fd ) { + + PKI_MEM *mem = NULL; + PKI_PRQP_REQ *ret = NULL; + + char buf[1024]; + int n = 0; + + if((mem = PKI_MEM_new_null()) == NULL ) { + PKI_log_debug("Memory Allocation error (%s:%d)!", + __FILE__, __LINE__ ); + + return ( NULL ); + } + + while( (n = _Read( fd, buf, sizeof( buf ))) > 0 ) { + PKI_MEM_add( mem, buf, n ); + } + + ret = PKI_PRQP_REQ_get_mem( mem ); + + PKI_MEM_free ( mem ); + + return ( ret ); +} +*/ + +/*! + * \brief Retrieves a PRQP request from the passed PKI_MEM +*/ + +/* +PKI_PRQP_REQ *PKI_PRQP_REQ_get_mem( PKI_MEM *mem ) { + + BIO *bp = NULL; + BUF_MEM *p = NULL; + PKI_PRQP_REQ *ret = NULL; + + int curr; + + bp = BIO_new_mem_buf( mem->data, mem->size ); + + p = (BUF_MEM *) bp->ptr; + curr = p->length; + + if((ret = PEM_read_bio_PKI_PRQP_REQ(bp)) == NULL){ + + p->length = curr; + p->data -= curr; + + if((ret = d2i_PKI_PRQP_REQ_bio(bp,NULL)) == NULL ) { + PKI_log_debug("ERROR, can not load PKI_PRQP_REQ!"); + } + } + + return ( ret ); +} +*/ + +/* =========================== PRQP REQ put API ========================= */ + +/*! + * \brief Sends/Store a PRQP request in a PKI_MEM structure +*/ + +/* +int PKI_PRQP_REQ_put_mem( PKI_PRQP_REQ *req, PKI_MEM *mem, int format ) { + + BIO *mem_bio = NULL; + BUF_MEM *buf = NULL; + + int rv = 0; + + if( !req || !mem ) return ( PKI_ERR ); + + if((mem_bio = BIO_new(BIO_s_mem())) == NULL ) { + return ( PKI_ERR ); + } + + switch ( format ) { + case PKI_FORMAT_PEM: + rv = PEM_write_bio_PKI_PRQP_REQ( mem_bio, req ); + break; + case PKI_FORMAT_ASN1: + rv = i2d_PKI_PRQP_REQ_bio( mem_bio, req ); + break; + default: + goto err; + } + + if ( rv == 0 ) goto err; + + BIO_get_mem_ptr( mem_bio, &buf ); + rv = PKI_MEM_add( mem, buf->data, buf->length ); + + if( mem_bio ) BIO_free ( mem_bio ); + + return ( rv ); +err: + + if( mem_bio ) BIO_free (mem_bio); + + return ( PKI_ERR ); +} +*/ + +/*! + * \brief Sends/Writes a PRQP request in the resource specified in the + * provided URL structure +*/ + +/* +int PKI_PRQP_REQ_put_url( PKI_PRQP_REQ *req, URL *url, int format ) { + + PKI_MEM *mem = NULL; + int ret = 0; + + if( !url ) return ( PKI_ERR ); + + if((mem = PKI_MEM_new_null()) == NULL ) { + return ( PKI_ERR ); + } + + if(PKI_PRQP_REQ_put_mem( req, mem, format ) == PKI_ERR ) { + if( mem ) PKI_MEM_free ( mem ); + return (PKI_ERR); + } + + ret = URL_put_data_url( url, mem, PKI_CONTENT_TYPE_PKI_PRQP_REQ ); + + if( mem ) PKI_MEM_free ( mem ); + + return ( ret ); +} +*/ + +/*! + * \brief Sends/Writes a PRQP request in the resource specified in the + * provided URI string +*/ + +/* +int PKI_PRQP_REQ_put( PKI_PRQP_REQ *req, char *url_s, int format ) { + + URL *url = NULL; + + if( !url_s ) return ( PKI_ERR ); + + if((url = URL_new( url_s )) == NULL ) { + return ( PKI_ERR ); + } + + return PKI_PRQP_REQ_put_url( req, url, format ); +} +*/ + +/* + * Writes a PRQP request in the provided file descriptior +*/ + +/* +int PKI_PRQP_REQ_put_fp( PKI_PRQP_REQ *req, FILE * file, int format ) { + + int ret = 0; + int n = 0; + int fd = 0; + PKI_MEM *mem = NULL; + + if((mem = PKI_MEM_new_null()) == NULL ) { + PKI_log_debug("Memory Allocation error (%s:%d)!", + __FILE__, __LINE__ ); + + return ( PKI_ERR ); + }; + + if( PKI_PRQP_REQ_put_mem( req, mem, format ) == PKI_ERR ) { + if( mem ) PKI_MEM_free ( mem ); + return ( PKI_ERR ); + } + + fd = fileno( file ); + + if((n = _Write( fd, mem->data, mem->size )) < 0 ) { + ret = PKI_ERR; + } else { + ret = PKI_OK; + } + + return ( ret ); +} +*/ + + +/* ======================== PRQP RESP get API ========================= */ + +/* +PKI_PRQP_RESP *PKI_PRQP_RESP_get( char *url_s, int timeout ) { + + URL *url = NULL; + + if( !url_s ) return ( NULL ); + + if((url = URL_new( url_s )) == NULL ) { + return (NULL); + } + + return ( PKI_PRQP_RESP_get_url( url )); +} + +PKI_PRQP_RESP *PKI_PRQP_RESP_get_url( URL *url, int timeout ) { + + PKI_PRQP_RESP *ret = NULL; + PKI_MEM_STACK *mem_sk = NULL; + PKI_MEM *in = NULL; + + if(!url) return NULL; + + if((mem_sk = URL_get_data_url ( url, timeout, 0 )) == NULL ) { + return(NULL); + } + + if((in = PKI_STACK_MEM_pop( mem_sk )) != NULL ) { + ret = PKI_PRQP_RESP_get_mem( in ); + } + + if( mem_sk ) PKI_STACK_MEM_free_all ( mem_sk ); + + return ( ret ); +} + +PKI_PRQP_RESP *PKI_PRQP_RESP_get_fd ( int fd ) { + + PKI_MEM *mem = NULL; + PKI_PRQP_RESP *ret = NULL; + int n = 0; + + char buf[1024]; + + if((mem = PKI_MEM_new_null()) == NULL ) { + PKI_log_debug("Memory Allocation error (%s:%d)!", + __FILE__, __LINE__ ); + + return ( NULL ); + } + + while( (n = _Read( fd, buf, sizeof( buf ))) > 0 ) { + PKI_MEM_add( mem, buf, (size_t) n ); + } + + ret = PKI_PRQP_RESP_get_mem( mem ); + + PKI_MEM_free ( mem ); + + return ( ret ); +} + +PKI_PRQP_RESP *PKI_PRQP_RESP_get_mem ( PKI_MEM *mem ) { + + BIO *bp = NULL; + BUF_MEM *p = NULL; + PKI_PRQP_RESP *ret = NULL; + + int curr; + + bp = BIO_new_mem_buf( mem->data, (int) mem->size ); + + p = (BUF_MEM *) bp->ptr; + curr = p->length; + + if((ret = PEM_read_bio_PRQP_RESP(bp)) == NULL){ + + p->length = curr; + p->data -= curr; + + if((ret = d2i_PRQP_RESP_bio(bp,NULL)) == NULL ) { + PKI_log_debug("ERROR, can not load PKI_PRQP_REQ!"); + } + } + + return ( ret ); +} +*/ + +/* ======================== PRQP RESP put API ============================ */ + +/* +int PKI_PRQP_RESP_put( PKI_PRQP_RESP *resp, char *url_s, PKI_DATA_FORMAT format ) { + + URL *url = NULL; + + if( !url_s ) return ( PKI_ERR ); + + if((url = URL_new( url_s )) == NULL ) { + return ( PKI_ERR ); + } + + return ( PKI_PRQP_RESP_put_url( resp, url, format )); +} + + +int PKI_PRQP_RESP_put_url( PKI_PRQP_RESP *resp, URL *url, PKI_DATA_FORMAT format ) { + + PKI_MEM *mem = NULL; + int ret = 0; + + if( !resp || !url ) return ( PKI_ERR ); + + if((mem = PKI_MEM_new_null()) == NULL ) { + PKI_log_debug("Memory Alloc Error (%s:%d)", + __FILE__, __LINE__ ); + return (PKI_ERR); + } + + if(PKI_PRQP_RESP_put_mem( resp, mem, format ) == PKI_ERR ) { + if( mem ) PKI_MEM_free ( mem ); + return ( PKI_ERR ); + } + + ret = URL_put_data_url( url, mem, PKI_CONTENT_TYPE_PKI_PRQP_RESP, NULL); + + if( mem ) PKI_MEM_free ( mem ); + + return ( ret ); +} + +int PKI_PRQP_RESP_put_fp( PKI_PRQP_RESP *resp, FILE * file, PKI_DATA_FORMAT format ) { + + int ret = 0; + int n = 0; + int fd = 0; + PKI_MEM *mem = NULL; + + if((mem = PKI_MEM_new_null()) == NULL ) { + PKI_log_debug("Memory Allocation error (%s:%d)!", + __FILE__, __LINE__ ); + + return ( PKI_ERR ); + }; + + if( PKI_PRQP_RESP_put_mem( resp, mem, format ) == PKI_ERR ) { + if( mem ) PKI_MEM_free ( mem ); + return ( PKI_ERR ); + } + + fd = fileno( file ); + + if((n = _Write( fd, mem->data, mem->size )) < 0 ) { + ret = PKI_ERR; + } else { + ret = PKI_OK; + } + + return ( ret ); +} + +int PKI_PRQP_RESP_put_mem( PKI_PRQP_RESP *resp, PKI_MEM *mem, + PKI_DATA_FORMAT format ) { + + BIO *mem_bio = NULL; + BUF_MEM *buf = NULL; + + int rv = 0; + + if( !resp || !mem ) return ( PKI_ERR ); + + if((mem_bio = BIO_new(BIO_s_mem())) == NULL ) { + return ( PKI_ERR ); + } + + switch ( format ) { + case PKI_DATA_FORMAT_PEM: + rv = PEM_write_bio_PRQP_RESP( mem_bio, resp ); + break; + case PKI_DATA_FORMAT_ASN1: + rv = i2d_PRQP_RESP_bio( mem_bio, resp ); + break; + default: + goto err; + } + + if ( rv == 0 ) goto err; + + BIO_get_mem_ptr( mem_bio, &buf ); + rv = PKI_MEM_add( mem, buf->data, (size_t) buf->length ); + + if( mem_bio ) BIO_free ( mem_bio ); + + return ( rv ); +err: + + if( mem_bio ) BIO_free (mem_bio); + + return ( PKI_ERR ); +} +*/ diff --git a/src/pkix/prqp/prqp_lib.c b/src/pkix/prqp/prqp_lib.c new file mode 100644 index 00000000..936e5ea9 --- /dev/null +++ b/src/pkix/prqp/prqp_lib.c @@ -0,0 +1,2448 @@ +/* + * PKI Resource Query Protocol Message implementation + * (c) 2006 by Massimiliano Pala and OpenCA Group + * All Rights Reserved + * + * This software is released under the GPL2 License included + * in the archive. You can not remove this copyright notice. + */ + +#define __PKI_PRQP_LIB_C__ + +#include +#include + +#include "../openssl/internal/x509_data_st.h" + +/* PKIX Defaults from http://www.imc.org/ietf-pkix/pkix-oid.asn + * + * id-pkix ::= { 1.3.6.1.5.5.7 } + * id-kp ::= { id-pkix 3 } + * id-ad ::= { id-pkix 48 } + */ + +//static char *prqp_exts_services[] = { +// "1.3.6.1.5.5.7.48.12.0", "unknown", "Unknown Service", +// "1.3.6.1.5.5.7.48.12.1", "ocsp", "OCSP Service", +// "1.3.6.1.5.5.7.48.12.2", "caIssuers", "CA Information", +// "1.3.6.1.5.5.7.48.12.3", "timeStamping", "TimeStamping Service", +// /* PKIX - not yet defined */ +// "1.3.6.1.5.5.7.48.12.4", "scvp", "SCVP Service", +// "1.3.6.1.5.5.7.48.12.5", "caRepository", "CA Repository", +// /* HTTP certificate Repository */ +// "1.3.6.1.5.5.7.48.12.6", "httpCertRepository", "HTTP Certificate Repository", +// /* HTTP CRL Repository */ +// "1.3.6.1.5.5.7.48.12.7", "httpCRLRepository", "HTTP CRL Repository", +// "1.3.6.1.5.5.7.48.12.8", "httpCrossCertRepository", "HTTP Cross Certificate Repository", +// /* Gateways */ +// "1.3.6.1.5.5.7.48.12.10", "xkmsGateway", "XKMS Gateway", +// "1.3.6.1.5.5.7.48.12.11", "cmsGateway", "CMS Gateway", +// "1.3.6.1.5.5.7.48.12.12", "scepGateway", "SCEP Gateway", +// /* Certificate Policies */ +// "1.3.6.1.5.5.7.48.12.20", "certPolicy", "Certificate Policy (CP) URL", +// "1.3.6.1.5.5.7.48.12.21", "certPracticesStatement", "Certificate Practices Statement (CPS) URL", +// /* Level of Assurance (LOA) */ +// "1.3.6.1.5.5.7.48.12.25", "certLOAPolicy", "LOA Policy URL", +// "1.3.6.1.5.5.7.48.12.26", "certLOALevel", "Certificate LOA Modifier URL", +// /* HTTP (Browsers) based services */ +// "1.3.6.1.5.5.7.48.12.30", "htmpRevoke", "HTML Based Certificate Revocation Service URL", +// "1.3.6.1.5.5.7.48.12.31", "htmlRequest", "HTML Certificate Request Service URL", +// "1.3.6.1.5.5.7.48.12.32", "htmlRenew", "HTML Certificate Renewal Service URL", +// "1.3.6.1.5.5.7.48.12.33", "htmlSuspend", "HTML Certificate Suspension Service", +// /* Webdav Services */ +// "1.3.6.1.5.5.7.48.12.40", "webdavCert", "Webdav Certificate Validation URL", +// "1.3.6.1.5.5.7.48.12.41", "webdavRev", "Webdav Certificate Revocation URL", +// /* Grid Specific Services */ +// "1.3.6.1.5.5.7.48.12.50", "gridAccreditationBody", "CA Accreditation Bodies", +// "1.3.6.1.5.5.7.48.12.51", "gridAccreditationPolicy", "CA Accreditation Policy Document(s) URL", +// "1.3.6.1.5.5.7.48.12.52", "gridAccreditationStatus", "CA Accreditation Status Document(s) URL", +// "1.3.6.1.5.5.7.48.12.53", "gridDistributionUpdate", "Grid Distribution Package(s) URL", +// "1.3.6.1.5.5.7.48.12.54", "gridAccreditedCACerts", "Certificates of Currently Accredited CAs", +// /* Trust Anchors Publishing */ +// "1.3.6.1.5.5.7.48.70", "tampUpdate", "Trust Anchors Update URL", +// /* PRQP Service */ +// "1.3.6.1.5.5.7.48.12.100", "prqp", "PRQP Service", +// /* Other PKI */ +// "2.5.29.27", "deltaCrl", "Delta CRL Base Address", +// "2.5.29.31", "crl", "CRL Repository", +// /* End of the List */ + // NULL, NULL, NULL +//}; + +//static char *prqp_exts[] = { +// /* PRQP extended key usage - id-kp-PRQPSigning ::= { id-kp 10 }*/ +// "1.3.6.1.5.5.7.3.10", "prqpSigning", "PRQP Signing", +// /* PRQP PKIX identifier - id-prqp ::= { id-pkix 23 } */ +// "1.3.6.1.5.5.7.23", "PRQP", "PKI Resource Query Protocol", +// /* PRQP PKIX - PTA identifier - { id-prqp 1 } */ +// "1.3.6.1.5.5.7.23.1", "PTA", "PRQP Trusted Authority", +// /* PRQP AD id-ad-prqp ::= { id-ad 12 } */ +// "1.3.6.1.5.5.7.48.12", "prqp", "PRQP Service", +// /* End of the List */ + // NULL, NULL, NULL +//}; + +char *PKI_X509_PRQP_STATUS_STRING[] = { + PKI_X509_PRQP_STATUS_STRING_OK, + PKI_X509_PRQP_STATUS_STRING_BAD_REQUEST, + PKI_X509_PRQP_STATUS_STRING_CA_NOT_PRESENT, + PKI_X509_PRQP_STATUS_STRING_SYS_FAILURE +}; + +/* ---------------------------- Static Functions ------------------------ */ +static int PKI_X509_PRQP_RESP_get_status_value ( PKI_X509_PRQP_RESP_VALUE *r ); + +static void *PKI_X509_PRQP_REQ_VALUE_get_data ( PKI_X509_PRQP_REQ_VALUE *r, + PKI_X509_DATA type ); +static void *PKI_X509_PRQP_RESP_VALUE_get_data ( PKI_X509_PRQP_RESP_VALUE *r, + PKI_X509_DATA type ); + +/* -------------------------------- Proper Code -------------------------- */ + +int CERT_IDENTIFIER_cmp ( CERT_IDENTIFIER *a, CERT_IDENTIFIER *b) { + + int ret = 0; + + EXTENDED_CERT_INFO * aInfo = NULL; + EXTENDED_CERT_INFO * bInfo = NULL; + + if( !a || !a->hashAlgorithm || !a->basicCertId ) return (-10); + if( !b || !b->hashAlgorithm || !b->basicCertId ) return (-20); + + if((ret = OBJ_cmp(a->hashAlgorithm->algorithm, + b->hashAlgorithm->algorithm)) != 0 ) { + return 1; + } + + if( !a->basicCertId->issuerNameHash ) return ( -11 ); + if( !b->basicCertId->issuerNameHash ) return ( -21 ); + + if((ret = ASN1_OCTET_STRING_cmp(a->basicCertId->issuerNameHash, + b->basicCertId->issuerNameHash)) != 0 ) { + return 2; + }; + + if((ret = ASN1_INTEGER_cmp( a->basicCertId->serialNumber, + b->basicCertId->serialNumber)) != 0 ) { + return 3; + }; + + if( a->extInfo && b->extInfo ) { + + char *tmp_a = NULL; + char *tmp_b = NULL; + + aInfo = a->extInfo; + bInfo = b->extInfo; + + if((ret = ASN1_STRING_cmp(aInfo->certificateHash, + bInfo->certificateHash)) != 0 ) { + + tmp_a = PKI_STRING_get_utf8( aInfo->certificateHash ); + tmp_b = PKI_STRING_get_utf8( bInfo->certificateHash ); + + PKI_log_debug( "aInfo->certHash => %s", tmp_a ); + PKI_log_debug( "bInfo->certHash => %s", tmp_b ); + + PKI_Free ( tmp_a ); + PKI_Free ( tmp_b ); + + return 4; + }; + + if((ret = ASN1_OCTET_STRING_cmp(aInfo->subjectKeyHash, + bInfo->subjectKeyHash)) != 0 ) { + return 5; + }; + + if( aInfo->subjectKeyId && bInfo->subjectKeyId ) { + + /* + if((ret = ASN1_OCTET_STRING_cmp(aInfo->subjectKeyId, + bInfo->subjectKeyId)) != 0 ) { + PKI_log_debug("PRQP_CMP (%d): a=%s, b=%s", + ret, + i2s_ASN1_OCTET_STRING( NULL, + aInfo->subjectKeyId), + i2s_ASN1_OCTET_STRING( NULL, + bInfo->subjectKeyId )); + return 6; + }; + */ + } + + if( aInfo->issuerKeyId && bInfo->issuerKeyId ) { + + if((ret = ASN1_OCTET_STRING_cmp(aInfo->issuerKeyId, + bInfo->issuerKeyId)) != 0 ) { + return 7; + }; + } + } + + return 0; +} + +int PRQP_init_all_services ( void ) { + + int i, ret; + + // Sets the Index + i = 0; + + // Creates the PRQP objects + while (prqp_exts[i] && prqp_exts[i+1]) { + if ((ret = OBJ_create(prqp_exts[i], + prqp_exts[i+1], + prqp_exts[i+2])) == NID_undef) { + // Error Condition + PKI_ERROR(PKI_RESOURCE_TYPE_PRQP, "Failed to add PRQP ext %s", prqp_exts[i+1] ); + return 0; + } + i = i+3; + } + + // Resets the Index + i = 0; + + // Creates the PRQP objects + while( prqp_exts_services[i] && prqp_exts_services[i+1] ) { + // Creates a new object + if((ret = OBJ_create(prqp_exts_services[i], + prqp_exts_services[i+1], + prqp_exts_services[i+2])) == NID_undef) { + // Error Condition + PKI_log_debug("PRQP_init_all_services():Failed to add PRQP service %s", prqp_exts_services[i+1] ); + return 0; + } + i = i+3; + } + + return 1; +} + +/*! \brief Generates a new CERT_IDENTIFIER to be used in a PRQP request */ + +CERT_IDENTIFIER * PKI_PRQP_CERTID_new_cert(PKI_X509_CERT * caCert, + PKI_X509_CERT * issuerCert, + PKI_X509_CERT * issuedCert, + char * subject_s, + char * serial_s, + PKI_DIGEST_ALG * dgst) { + + const PKI_X509_NAME *s_name = NULL; + const PKI_X509_NAME *i_name = NULL; + PKI_INTEGER *serial = NULL; + /* BIT STRINGS */ + PKI_STRING *caKeyHash = NULL; + PKI_STRING *issKeyHash = NULL; + PKI_STRING *cHash = NULL; + /* OCTET STRINGS */ + const PKI_STRING *skid = NULL; + const PKI_STRING *ikid = NULL; + + CERT_IDENTIFIER *ret = NULL; + + if (!dgst) dgst = (PKI_DIGEST_ALG *) PKI_DIGEST_ALG_SHA1; + + /* Now get the IssuerName and the Serial of the Certificate x */ + if (caCert && caCert->value) + { +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + LIBPKI_X509_CERT *xx = NULL; +#else + PKI_X509_CERT_VALUE *xx = NULL; +#endif + CRYPTO_DIGEST *myDigest = NULL; + + xx = (X509 *) caCert->value; + +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + + // Gets the SKID + skid = X509_get0_subject_key_id(xx); + + /* + int num = 0; + PKI_X509_EXTENSION_VALUE *ext_v = NULL; + + // Gets the SKID + num = X509_get_ext_by_NID(xx, NID_subject_key_identifier,-1); + if (num < 0) { + // Can not get SKID + skid = NULL; + } else if ((ext_v = X509_get_ext(xx, num)) != NULL) { + skid = ext_v->value; + } + */ + + // Gets the AKID + if (xx->akid) ikid = xx->akid->keyid; + + /* + num = X509_get_ext_by_NID(xx, NID_authority_key_identifier,-1); + if (num < 0) { + // Can not get SKID + skid = NULL; + } else if ((ext_v = X509_get_ext(xx, num)) != NULL) { + skid = ext_v->value; + } + */ +#else + if (xx->skid) skid = xx->skid; + if (xx->akid) ikid = xx->akid->keyid; +#endif + + s_name = (X509_NAME *) + PKI_X509_CERT_get_data( caCert, PKI_X509_DATA_SUBJECT ); + + i_name = (X509_NAME *) + PKI_X509_CERT_get_data( caCert, PKI_X509_DATA_ISSUER ); + + serial = (ASN1_INTEGER *) + PKI_X509_CERT_get_data( caCert, PKI_X509_DATA_SERIAL); + + /* calculate the certificate Hash */ + /* + if((cHash = PKI_STRING_new( PKI_STRING_OCTET )) == NULL ) { + return NULL; + }; + */ + + if ((myDigest = PKI_X509_CERT_fingerprint(caCert, dgst)) == NULL) + { + PKI_ERROR(PKI_ERR_GENERAL, "Can not get the CA certificate fingerprint"); + return NULL; + } + + if ((cHash = PKI_STRING_new(PKI_STRING_OCTET, (char *) myDigest->digest, + (int) myDigest->size)) == NULL) + { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return NULL; + } + PKI_DIGEST_free(myDigest); + + /* + else if (!X509_digest((X509 *)caCert->value, + (EVP_MD *) dgst, md, (unsigned int *) &i)) { + ASN1_OCTET_STRING_free( cHash ); + return(NULL); + } + + if (!(ASN1_OCTET_STRING_set(cHash, md, (int) i))) { + ASN1_OCTET_STRING_free( cHash ); + return( NULL ); + } + */ + + /* Calculate the Hash of the certificate Key */ + /* + if((caKeyHash = ASN1_OCTET_STRING_new()) == NULL ) { + if( cHash ) ASN1_OCTET_STRING_free ( cHash ); + return ( NULL ); + } + */ + + if ((myDigest = PKI_X509_CERT_key_hash(caCert, dgst)) == NULL) + { + PKI_log_debug( "Can not get CA Cert key hash"); + PKI_STRING_free ( cHash ); + return NULL; + } + + if (( caKeyHash = PKI_STRING_new( PKI_STRING_OCTET, + (char *) myDigest->digest, (int) myDigest->size)) == NULL ) + { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + PKI_DIGEST_free ( myDigest ); + PKI_STRING_free ( cHash ); + return NULL; + } + PKI_DIGEST_free ( myDigest ); + + /* + if(X509_pubkey_digest((X509 *) caCert->value, + (EVP_MD *)dgst, md, (unsigned int *) &i) == 0) { + if( caKeyHash ) ASN1_OCTET_STRING_free( caKeyHash ); + if( cHash ) ASN1_OCTET_STRING_free( cHash ); + return (NULL); + } + + if (!(ASN1_OCTET_STRING_set(caKeyHash, md, i))) { + if( caKeyHash ) ASN1_OCTET_STRING_free( caKeyHash ); + if( cHash ) ASN1_OCTET_STRING_free( cHash ); + return( NULL ); + } + */ + + } + else + { + if (serial_s) serial = PKI_INTEGER_new_char ( serial_s ); + if (!serial) + { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return NULL; + } + + if (subject_s) + { + s_name = PKI_X509_NAME_new(subject_s); + if(!s_name) + { + PKI_log_debug("%s:%d::Can not parse X509 NAME " + "%s!", __FILE__, __LINE__, subject_s ); + } + } + else if (issuedCert && issuedCert->value) + { + s_name = PKI_X509_CERT_get_data( issuedCert, PKI_X509_DATA_ISSUER); + if (!s_name) + { + PKI_log_debug("%s:%d::Can not get issuer from issuedCert [%s]", + __FILE__, __LINE__, subject_s ); + } + } + else + { + if (serial) PKI_INTEGER_free ( serial ); + return (NULL); + } + } + + if (issuerCert && issuerCert->value) + { + CRYPTO_DIGEST *myDigest = NULL; + + if ((myDigest = PKI_X509_CERT_key_hash(issuerCert, dgst)) == NULL) + { + PKI_ERROR(PKI_ERR_GENERAL, "Can not get issuerCert key Hash"); + PKI_STRING_free ( cHash ); + return NULL; + } + + issKeyHash = PKI_STRING_new ( PKI_STRING_OCTET, + (char *) myDigest->digest, (int) myDigest->size); + + if (issKeyHash == NULL) + { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + + if (myDigest) PKI_DIGEST_free(myDigest); + if (caKeyHash) PKI_STRING_free(caKeyHash); + if (cHash) PKI_STRING_free(cHash); + + return NULL; + } + + PKI_DIGEST_free ( myDigest ); + + /* Calculate the Hash of the certificate Key */ + /* + if((issKeyHash = ASN1_OCTET_STRING_new()) == NULL ) { + return ( NULL ); + } + + if(X509_pubkey_digest((X509 *) issuerCert->value, + (EVP_MD *)dgst, md, (unsigned int *) &i) == 0){ + if( issKeyHash ) ASN1_OCTET_STRING_free( issKeyHash ); + return (NULL); + } + + if (!(ASN1_OCTET_STRING_set(issKeyHash, md, i))) { + if( issKeyHash ) ASN1_OCTET_STRING_free( issKeyHash ); + return( NULL ); + } + */ + } + + /* Build the CERT_IDENTIFIER */ + if ((ret = PKI_PRQP_CERTID_new( s_name, i_name, serial, + cHash, caKeyHash, skid, ikid, dgst)) != NULL) + { + /* Now let's add the certificates to the identifier */ + /* + if( caCert ) { + ret->caCert = X509_dup( (X509 *) caCert ); + } + + if( issuedCert ) { + ret->issuedCert = X509_dup( (X509 *) issuedCert ); + } + */ + } + + /* Free data */ + if( cHash ) PKI_STRING_free ( cHash ); + if( caKeyHash ) PKI_STRING_free ( caKeyHash ); + + // if( skid ) PKI_STRING_free ( skid ); + // if( ikid ) PKI_STRING_free ( ikid ); + + /* return the resulting data structure */ + return( ret ); +} + + +CERT_IDENTIFIER *PKI_PRQP_CERTID_new( + const PKI_X509_NAME * caName, + const PKI_X509_NAME * caIssuerName, + const PKI_INTEGER * serial, + const PKI_STRING * caCertHash, + const PKI_STRING * caKeyHash, + const PKI_STRING * caKeyId, + const PKI_STRING * issKeyId, + const PKI_DIGEST_ALG * dgst) { + int nid; + PKI_X509_ALGOR_VALUE *alg; + CERT_IDENTIFIER *ca_id = NULL; + + /* To build the Basic Cert Info we need these informations! */ + if( !dgst || !caName || !caIssuerName) + { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return (NULL); + } + + if (!(ca_id = CERT_IDENTIFIER_new())) + { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return (NULL); + } + + if((ca_id->hashAlgorithm = X509_ALGOR_new()) == NULL ) + { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + + if(ca_id) CERT_IDENTIFIER_free (ca_id); + return(NULL); + } + + alg = ca_id->hashAlgorithm; + if (alg->algorithm != NULL) ASN1_OBJECT_free(alg->algorithm); + + if (((nid = EVP_MD_nid(dgst)) == NID_undef) || + (!(alg->algorithm=OBJ_nid2obj(nid))) || + ((alg->parameter=ASN1_TYPE_new()) == NULL)) + { + + if(ca_id) CERT_IDENTIFIER_free( ca_id ); + return( NULL ); + } + + alg->parameter->type=V_ASN1_NULL; + + /* Now build the BasicCertIdentifier */ + + if ((ca_id->basicCertId = BASIC_CERT_IDENTIFIER_new()) == NULL) + { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + if( ca_id ) CERT_IDENTIFIER_free( ca_id ); + return( NULL ); + } + + CRYPTO_DIGEST *digest = NULL; + PKI_STRING *str = NULL; + + digest = PKI_X509_NAME_get_digest(caIssuerName, dgst); + if (digest == NULL) + { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + if( ca_id ) CERT_IDENTIFIER_free ( ca_id ); + return NULL; + } + + if ((str = PKI_STRING_new(PKI_STRING_OCTET, (char *) digest->digest, + (int) digest->size))==NULL) + { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + + PKI_DIGEST_free ( digest ); + if( ca_id ) CERT_IDENTIFIER_free ( ca_id ); + return NULL; + } + + ca_id->basicCertId->issuerNameHash = str; + + PKI_DIGEST_free ( digest ); + + if ((serial) && (!(ca_id->basicCertId->serialNumber = PKI_INTEGER_dup(serial)))) + { + if(ca_id) CERT_IDENTIFIER_free( ca_id ); + return( NULL ); + } + + /* Now build the extInfo structure (if we have enough data!) */ + + if (caCertHash != NULL) + { + if ((ca_id->extInfo = EXTENDED_CERT_INFO_new()) == NULL) + { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + if( ca_id ) CERT_IDENTIFIER_free (ca_id); + return( NULL ); + } + + ca_id->extInfo->certificateHash = PKI_STRING_dup(caCertHash); + + if (caKeyHash) + ca_id->extInfo->subjectKeyHash = PKI_STRING_dup(caKeyHash); + + if (caKeyId) + ca_id->extInfo->subjectKeyId = PKI_STRING_dup(caKeyId); + + if (issKeyId) + ca_id->extInfo->issuerKeyId = PKI_STRING_dup(issKeyId); + } + + return ca_id; +} + +void *PKI_X509_PRQP_REQ_new_null( void ) +{ + return PKI_X509_new(PKI_DATATYPE_X509_PRQP_REQ, NULL); +} + +void PKI_X509_PRQP_REQ_free_void( void *x ) { + PKI_X509_free_void( x ); + return; +} + +void PKI_X509_PRQP_REQ_free ( PKI_X509_PRQP_REQ *x ) { + PKI_X509_free ( x ); + + return; +} + +PKI_X509_PRQP_REQ *PKI_PRQP_REQ_new_cert(PKI_X509_CERT *caCert, + PKI_X509_CERT *caIssuerCert, PKI_X509_CERT *issuedCert, + char *subject_s, char *serial_s, PKI_DIGEST_ALG *md ) { + + CERT_IDENTIFIER *ca_id = NULL; + RESOURCE_REQUEST_TOKEN *token = NULL; + PKI_X509_PRQP_REQ *p = NULL; + PKI_X509_PRQP_REQ_VALUE *val = NULL; + + if((token = RESOURCE_REQUEST_TOKEN_new()) == NULL ) { + return(NULL); + } + + ca_id = PKI_PRQP_CERTID_new_cert ( caCert, caIssuerCert, issuedCert, + subject_s, serial_s, md ); + if( ca_id == NULL ) { + PKI_log_debug( "Can not Generate the CA CERT identifier"); + if( token ) RESOURCE_REQUEST_TOKEN_free( token ); + return(NULL); + } + + if(( val = PKI_PRQP_REQ_new ()) == NULL ) { + PKI_log_debug( "Memory Error"); + if( ca_id ) CERT_IDENTIFIER_free ( ca_id ); + if( token ) RESOURCE_REQUEST_TOKEN_free( token ); + return(NULL); + } + + if((val->requestData = PRQP_TBS_REQ_DATA_new()) == NULL ) { + PKI_log_debug( "Memory Error"); + if( val ) PKI_PRQP_REQ_free ( val ); + if( ca_id ) CERT_IDENTIFIER_free ( ca_id ); + if( token ) RESOURCE_REQUEST_TOKEN_free( token ); + } + + if (!ASN1_INTEGER_set(val->requestData->version, 1)) { + PKI_log_debug( "Can not set version in requestData"); + if( ca_id ) CERT_IDENTIFIER_free ( ca_id ); + if( token ) RESOURCE_REQUEST_TOKEN_free( token ); + if( val ) PKI_PRQP_REQ_free ( val ); + return(NULL); + } + + if (( p = PKI_X509_new_value ( PKI_DATATYPE_X509_PRQP_REQ, + val, NULL)) == NULL ) { + PKI_log_err ( "Can not create a new PKI_X509 object."); + if( ca_id ) CERT_IDENTIFIER_free ( ca_id ); + if( token ) RESOURCE_REQUEST_TOKEN_free( token ); + if( val ) PKI_PRQP_REQ_free ( val ); + return(NULL); + } + + token->ca = ca_id; + token->resourceList = sk_RESOURCE_IDENTIFIER_new_null(); + + val->requestData->serviceToken = token; + val->requestData->nonce = PKI_X509_PRQP_NONCE_new(80); + + val->requestData->producedAt = (ASN1_GENERALIZEDTIME *) PKI_TIME_new(0); + + return(p); +} + +PKI_X509_PRQP_REQ *PKI_X509_PRQP_REQ_new_url( char * ca_cert_s, char *ca_issuer_cert_s, + char *issued_cert_s, char *subject_s, char *serial_s, EVP_MD *md ) { + + PKI_X509_PRQP_REQ *p = NULL; + + PKI_X509_CERT *caCert = NULL; + PKI_X509_CERT *caIssuerCert = NULL; + PKI_X509_CERT *issuedCert = NULL; + + if( ca_cert_s && + ((caCert = PKI_X509_CERT_get( ca_cert_s, PKI_DATA_FORMAT_UNKNOWN, NULL, NULL )) == NULL)) { + PKI_log_err ("Can not get CA Certificate from %s", ca_cert_s ); + return( NULL ); + } + + if( ca_issuer_cert_s && + ( ( caIssuerCert = PKI_X509_CERT_get ( + (char *)ca_issuer_cert_s, PKI_DATA_FORMAT_UNKNOWN, NULL, NULL ))== NULL)){ + if( caCert ) PKI_X509_CERT_free ( caCert ); + PKI_log_err ("Can not get Issuer Certificate from %s", + ca_issuer_cert_s ); + return( NULL ); + } + + if( issued_cert_s && + (( issuedCert = PKI_X509_CERT_get ( + (char *) issued_cert_s, PKI_DATA_FORMAT_UNKNOWN, NULL, NULL ) )== NULL) ){ + if( caIssuerCert ) PKI_X509_CERT_free ( caIssuerCert ); + if( caCert ) PKI_X509_CERT_free ( caCert ); + PKI_log_err ("Can not get Issued Certificate from %s", + issued_cert_s ); + return( NULL ); + } + + if((p = PKI_PRQP_REQ_new_cert(caCert, caIssuerCert, issuedCert, + subject_s, serial_s, md)) == NULL) { + if( issuedCert ) PKI_X509_CERT_free ( issuedCert ); + if( caIssuerCert ) PKI_X509_CERT_free ( caIssuerCert ); + if( caCert ) PKI_X509_CERT_free ( caCert ); + } + + return( p ); + +} + +/* +PKI_X509_PRQP_REQ *PKI_X509_PRQP_REQ_new_file( char *file, PKI_DATA_FORMAT format) { + + PKI_X509_PRQP_REQ *p = NULL; + BIO *req_bio = NULL; + + if ((req_bio=BIO_new(BIO_s_file())) == NULL) { + return(NULL); + } + + if (BIO_read_filename(req_bio,file) <= 0) { + return(NULL); + } + + if( format == PKI_DATA_FORMAT_PEM ) { + p = PEM_read_bio_PRQP_REQ( req_bio ); + } else if ( format == PKI_DATA_FORMAT_ASN1 ) { + // return d2i_PKI_PRQP_REQ_bio ( req_bio, NULL ); + } else { + return(NULL); + } + + return(p); +} +*/ + +PKI_X509_PRQP_REQ * PKI_X509_PRQP_REQ_new_certs_res( PKI_X509_CERT *caCert, + PKI_X509_CERT *caIssuerCert, PKI_X509_CERT *issuedCert, + PKI_STACK *sk_services ) { + + PKI_X509_PRQP_REQ *p = NULL; + PKI_X509_PRQP_REQ_VALUE *val = NULL; + + p = PKI_PRQP_REQ_new_cert( caCert, caIssuerCert, + issuedCert, NULL, NULL, NULL ); + if( !p || !p->value ) { + PKI_log_err ( "Cannot generate request!"); + return(NULL); + } + + val = p->value; + + if( !val->requestData || !val->requestData->serviceToken || + !val->requestData->serviceToken->resourceList ) { + PKI_X509_PRQP_REQ_free ( p ); + return( NULL ); + } + + if((PKI_X509_PRQP_REQ_add_service_stack ( p, sk_services )) == PKI_ERR ) { + PKI_X509_PRQP_REQ_free ( p ); + return ( NULL ); + } + + return( p ); +} + +/*! \brief Adds a stack of services to a PRQP REQUEST */ + +int PKI_X509_PRQP_REQ_add_service_stack ( PKI_X509_PRQP_REQ *p, + PKI_STACK *sk_services ) { + + int i = 0; + + if( !p || !p->value || !sk_services ) return ( PKI_ERR ); + + for( i = 0; i < PKI_STACK_elements(sk_services); i++ ) { + char *ss = NULL; + + ss = PKI_STACK_get_num( sk_services, i); + if(PKI_X509_PRQP_REQ_add_service( p, ss ) == PKI_ERR ) { + PKI_log( PKI_LOG_INFO, "PRQP REQ, Can not add %s", ss); + } + } + + return ( PKI_OK ); +} + +/*! \brief Adds a service identifier to a PRQP REQUEST */ + +int PKI_X509_PRQP_REQ_add_service ( PKI_X509_PRQP_REQ *p, char *ss ) { + + char tmp_str[1024]; + char *ver_s = NULL; + + PKI_OID *obj = NULL; + STACK_OF(RESOURCE_IDENTIFIER) *list = NULL; + + RESOURCE_IDENTIFIER *new_item = NULL; + PKI_X509_PRQP_REQ_VALUE *val = NULL; + + if( !p || !p->value || !ss ) return (PKI_ERR); + + val = p->value; + + if( !val->requestData || !val->requestData->serviceToken || + !val->requestData->serviceToken->resourceList ) return (PKI_ERR); + + list = val->requestData->serviceToken->resourceList; + + if((new_item = RESOURCE_IDENTIFIER_new()) == NULL ) { + PKI_log_err("Can not allocate memory!"); + return ( PKI_ERR ); + } + + new_item->resourceId = NULL; + new_item->version = NULL; + new_item->oid = NULL; + + strncpy(tmp_str, ss, sizeof(tmp_str) - strlen(ss) - 1); + if(( ver_s = strchr(tmp_str, ':')) != NULL ) { + *ver_s = '\x0'; + ver_s++; + }; + + if((obj = PKI_OID_get ( tmp_str )) != NULL ) { + new_item->resourceId = obj; + } else { + if((obj = PKI_OID_new( tmp_str, tmp_str, tmp_str )) == NULL) { + PKI_log_debug( "ERROR::Can not add %s", tmp_str ); + return( PKI_ERR ); + } else { + new_item->resourceId = obj; + } + } + + if( ver_s != NULL ) { + char * oid_s = NULL; + + if(( oid_s = strchr(ver_s, ':')) != NULL ) { + *oid_s = '\x0'; + oid_s++; + }; + + new_item->version = PKI_INTEGER_new_char( ver_s ); + + if( oid_s ) { + new_item->oid = PKI_OID_get( oid_s ); + } + } + + /* Now we shall parse for the Version - for now we skip it! */ + sk_RESOURCE_IDENTIFIER_push( list, new_item ); + + PKI_log_debug( "Service %s added ok!", ss ); + return( PKI_OK ); +} + + +PKI_INTEGER *PKI_X509_PRQP_NONCE_new(int bits) { + + unsigned char buf[33]; + ASN1_INTEGER *nonce = NULL; + int len; + int i; + + if(bits <= 0 ) { + bits = 80; + } + + len = (bits - 1) / 8 + 1; + + if (len > (int)sizeof(buf)) + return(NULL); + + if (!RAND_bytes(buf, len)) + return(NULL); + + for (i = 0; i < len && !buf[i]; ++i); + if (!(nonce = ASN1_INTEGER_new())) return (NULL); + OPENSSL_free(nonce->data); + + nonce->length = len - i; + if (!(nonce->data = OPENSSL_malloc((size_t)(nonce->length + 1)))) + return (NULL); + + memcpy(nonce->data, buf + i, (size_t) nonce->length); + + return(nonce); + +} + +// ***************** RESPONSE ****************** + +/*! \brief Sets the protocol version of a PRQP_RESP object */ + +int PKI_X509_PRQP_RESP_version_set ( PKI_X509_PRQP_RESP *resp, int ver ) { + + PKI_X509_PRQP_RESP_VALUE * val = NULL; + + if( !resp || !resp->value ) return PKI_ERR; + + val = resp->value; + + if ( !val->respData ) return PKI_ERR; + + ASN1_INTEGER_set(val->respData->version, ver); + + return PKI_OK; +} + +/*! \brief Duplicates the NONCE from a PRQP REQ to a PRQP RESP */ + +int PKI_X509_PRQP_RESP_nonce_dup ( PKI_X509_PRQP_RESP *resp, PKI_X509_PRQP_REQ *req ) { + + PKI_X509_PRQP_REQ_VALUE *req_val = NULL; + PKI_X509_PRQP_RESP_VALUE *resp_val = NULL; + + if( !resp || !req ) return PKI_ERR; + + req_val = req->value; + resp_val = resp->value; + + if (!resp_val->respData || !req_val->requestData ) return PKI_ERR; + + if( req_val->requestData->nonce != NULL ) { + resp_val->respData->nonce = + ASN1_OCTET_STRING_dup(req_val->requestData->nonce); + } + + return (PKI_OK); +} + +/*! \brief Sets the status of a PKI_X509_PRQP_RESP object */ + +int PKI_X509_PRQP_RESP_pkistatus_set ( PKI_X509_PRQP_RESP *resp, + long v, char *info ) { + + PKI_X509_PRQP_RESP_VALUE *resp_val = NULL; + + if( !resp || !resp->value ) return PKI_ERR; + + resp_val = resp->value; + + if (!resp_val->respData ) { + PKI_log_debug( "Memory Error (missing resp/respData)"); + return (PKI_ERR); + } + + /* + if(resp->respData->pkiStatus == NULL) { + if((resp->respData->pkiStatus = ASN1_INTEGER_new()) + == NULL) { + PKI_log_debug( "Memory Error (Alloc) [%s:%d]", + __FILE__, __LINE__ ); + return ( PKI_ERR ); + } + } + */ + + ASN1_INTEGER_set( resp_val->respData->pkiStatus->status, v); + + if (info) + { + PKI_STRING *str = NULL; + + if ((str = PKI_STRING_new_null( PKI_STRING_UTF8 )) == NULL) + { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return( PKI_ERR ); + } + + if (PKI_STRING_set( str, info, (ssize_t) strlen(info)) == PKI_ERR) + { + PKI_ERROR(PKI_ERR_GENERAL, "Can not set STRING content"); + PKI_STRING_free(str); + return PKI_ERR; + } + resp_val->respData->pkiStatus->statusString = str; + } + + return PKI_OK; +} + +/*! \brief Adds a stack of referrals (PKI_STACK) to a PRQP_RESP object */ + +int PKI_X509_PRQP_RESP_add_referrals ( PKI_X509_PRQP_RESP *resp, PKI_STACK *referrals) +{ + PKI_X509_PRQP_RESP_VALUE *r = NULL; + STACK_OF(ASN1_IA5STRING) *sk = NULL; + int i = 0; + + if( !resp || !resp->value || !referrals ) + { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return ( PKI_ERR ); + } + + r = resp->value; + + if( !r->respData || !r->respData->pkiStatus ) + { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return PKI_ERR; + } + + if ((sk = r->respData->pkiStatus->referrals) != NULL) + sk_ASN1_IA5STRING_free ( sk ); + + if ((sk = sk_ASN1_IA5STRING_new_null()) == NULL) + { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return PKI_ERR; + } + + for ( i = 0; i < PKI_STACK_elements(referrals); i++) + { + PKI_STRING *st = NULL; + char *val = NULL; + + if ((val = PKI_STACK_get_num(referrals, i)) == NULL) + continue; + + st = PKI_STRING_new( PKI_STRING_IA5, val, (ssize_t) strlen(val)); + if (st == NULL ) continue; + + sk_ASN1_IA5STRING_push( sk, (ASN1_IA5STRING *) st); + } + + r->respData->pkiStatus->referrals = sk; + + return PKI_OK; +} + +/*! \brief Adds a new service (single URL) to the stack of services + * in a PRQP_RESP */ + +int PKI_X509_PRQP_RESP_add_service ( PKI_X509_PRQP_RESP *r, + PKI_OID * resId, char * url, long long version, + char *comment, PKI_OID *oid ) +{ + + PKI_STACK *sk = NULL; + int ret = PKI_OK; + + if((sk = PKI_STACK_new_null()) == NULL ) + { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return PKI_ERR; + } + + ret = PKI_X509_PRQP_RESP_add_service_stack ( r, resId, sk, + version, comment, oid ); + + if ( sk ) PKI_STACK_free_all ( sk ); + + return ret; + +} + +/*! \brief Adds a new service (stack of URLs) to the stack of services + * in a PRQP_RESP */ + +int PKI_X509_PRQP_RESP_add_service_stack ( PKI_X509_PRQP_RESP *r, + PKI_OID *resId, PKI_STACK *url_stack, long long version, + char *comment, PKI_OID *oid ) +{ + PKI_X509_PRQP_RESP_VALUE *r_val = NULL; + RESOURCE_RESPONSE_TOKEN * resp_tk = NULL; + + int i = 0; + + if (!r || !r->value || !resId) + { + if ( !r || !r->value ) PKI_ERROR(PKI_ERR_PARAM_NULL, "Missing PRQP RESP object"); + if (!resId) PKI_ERROR(PKI_ERR_PARAM_NULL, "Missing service OID"); + return PKI_ERR; + } + + r_val = r->value; + + if (!r_val->respData) + PKI_log_debug("ERROR in PRQP RESP format (missing respData)"); + + + if ((resp_tk = RESOURCE_RESPONSE_TOKEN_new()) == NULL) + { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return PKI_ERR; + } + + resp_tk->resourceId = PKI_OID_dup ( resId ); + + if (version > -1) + resp_tk->version = PKI_INTEGER_new (version); + else + resp_tk->version = NULL; + + if (oid != NULL) + resp_tk->oid = PKI_OID_dup ( oid ); + else + resp_tk->oid = NULL; + + if (comment != NULL && strlen(comment) > 0 ) + { + resp_tk->textInfo = PKI_STRING_new(PKI_STRING_UTF8, + comment, (ssize_t) strlen(comment)); + } + else + { + resp_tk->textInfo = NULL; + } + + if (url_stack) + { + for (i = 0; i < PKI_STACK_elements( url_stack ); i++) + { + PKI_STRING *string = NULL; + char * tmp_s = NULL; + + if ((tmp_s = PKI_STACK_get_num(url_stack, i)) != NULL) + { + string = PKI_STRING_new(PKI_STRING_IA5, tmp_s, (ssize_t) strlen( tmp_s)); + sk_ASN1_IA5STRING_push( resp_tk->resLocatorList, string ); + } + } + } + + if (!r_val->respData->responseToken ) + { + if((r_val->respData->responseToken = + sk_RESOURCE_RESPONSE_TOKEN_new_null()) == NULL) + { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + RESOURCE_RESPONSE_TOKEN_free ( resp_tk ); + return PKI_ERR; + } + } + + sk_RESOURCE_RESPONSE_TOKEN_push(r_val->respData->responseToken, resp_tk ); + + return PKI_OK; +} + +/*! \brief Creates a new PRQP_RESP empty object */ + +void *PKI_X509_PRQP_RESP_new_null(void) +{ + return ((void *) PKI_X509_new( PKI_DATATYPE_X509_PRQP_RESP, NULL)); +} + +void PKI_X509_PRQP_RESP_free_void( void *x ) +{ + PKI_X509_free_void ( x ); + return; +} + +/*! \brief Releases the memory associated with a PRQP_RESP object */ + +void PKI_X509_PRQP_RESP_free(PKI_X509_PRQP_RESP *x) +{ + PKI_X509_free ( x ); + + return; +} + +/*! \brief Created a new PRQP_RESP from the contents of a PRQP_REQ */ + +PKI_X509_PRQP_RESP *PKI_X509_PRQP_RESP_new_req ( PKI_X509_PRQP_RESP **resp_pnt, + PKI_X509_PRQP_REQ *x_req, int status, long secs ) +{ + PKI_X509_PRQP_RESP_VALUE *resp = NULL; + PKI_X509_PRQP_REQ_VALUE *req = NULL; + PKI_X509_PRQP_RESP *r = NULL; + + if (resp_pnt) + { + if( *resp_pnt == NULL) + { + r = PKI_X509_PRQP_RESP_new_null(); + *resp_pnt = r; + } + else r = (*resp_pnt)->value; + } + else r = PKI_X509_PRQP_RESP_new_null(); + + if(r == NULL) + { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return NULL; + } + + if (!r->value ) r->value = r->cb->create(); + + resp = r->value; + + if( resp->respData == NULL) + { + if ((resp->respData = PRQP_TBS_RESP_DATA_new()) == NULL) + { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + PKI_X509_PRQP_RESP_free(r); + + resp = NULL; // Safety + return PKI_ERR; + } + } + + /* + if( resp->respData->pkiStatus == NULL ) { + if((resp->respData->pkiStatus = PKI_STATUS_INFO_new()) + == NULL) { + if( resp ) PKI_PRQP_RESP_free( resp ); + return ( PKI_ERR ); + } + } + */ + + PKI_X509_PRQP_RESP_version_set( r, 1); + + if (status) + PKI_X509_PRQP_RESP_pkistatus_set( r, status, NULL ); + else + PKI_X509_PRQP_RESP_pkistatus_set( r, 0, NULL ); + + resp->respData->producedAt = (ASN1_GENERALIZEDTIME *) PKI_TIME_new(0); + + if (x_req) req = x_req->value; + + if (req && req->requestData) + { + CERT_IDENTIFIER * req_caId = NULL; + CERT_IDENTIFIER * resp_caId = NULL; + + /* Let's duplicate the nonce */ + if(req->requestData->nonce) PKI_X509_PRQP_RESP_nonce_dup ( r, x_req ); + + if( !req->requestData || !req->requestData->serviceToken || + !req->requestData->serviceToken->ca ) + { + PKI_X509_PRQP_RESP_pkistatus_set( r, PKI_X509_PRQP_STATUS_BAD_REQUEST, + "Response is Malformed" ); + + PKI_log_debug("PKI_PRQP_RESP, error missing fields in REQ!"); + } + + // Let's duplicate the CA Id, maybe it is not needed + // as the request/response is tied by the NONCE, but + // it could be useful for forensics, in case a + // response is involved for later verifications + + PKI_log_debug( "Adding caCertId to Response!"); + + req_caId = req->requestData->serviceToken->ca; + + // Alloc new memory for the response cert identifier + /* resp_caId = CERT_IDENTIFIER_new(); */ + + resp_caId = (CERT_IDENTIFIER *) CERT_IDENTIFIER_dup( req_caId ); + + /* memset( resp_caId, 0, sizeof( BASIC_CERT_IDENTIFIER )); */ + + // Now let's duplicate the data + // resp_caId->subjectNameHash = + // ASN1_OCTET_STRING_dup ( req_caId->subjectNameHash ); + + /* + if( req_caId->hashAlgorithm ) { + resp_caId->hashAlgorithm = + X509_ALGOR_dup( req_caId->hashAlgorithm ); + } + + if( req_caId->basicCertId ) { + BASIC_CERT_IDENTIFIER_dup( resp_caId->basicCertId, + req_caId->basicCertId ); + // Theese field is optional + // resp_caId->serialNumber = + // ASN1_INTEGER_dup( req_caId->serialNumber ); + } + + if( req_caId->extInfo ) { + EXTENDED_CERT_INFO_dup( resp_caId->extInfo, + req_caId->extInfo ); + } + */ + + /* + if( req_caId->issuerNameHash ) { + // Theese field is optional + resp_caId->issuerNameHash = + ASN1_OCTET_STRING_dup(req_caId->issuerNameHash); + } + */ + + resp->respData->caCertId = resp_caId; + + // + // resp->respData->caCertId = (BASIC_CERT_IDENTIFIER *) + // BASIC_CERT_IDENTIFIER_dup( + // req->requestData->serviceToken->ca->basicCertId); + /* + } else { + PKI_log_debug("Some fields are missing!"); + if( !req->requestData->serviceToken ) { + PKI_log_debug("Field [serviceToken] is missing in req!"); + } else if( !req->requestData->serviceToken->ca ) { + PKI_log_debug("Field [serviceToken->ca] is missing in req!"); + } else if( !req->requestData->serviceToken->ca->basicCertId ) { + PKI_log_debug("Field [serviceToken->ca->basicCertId] is missing in req!"); + } + } + */ + } + + if( secs > 0 ) { + resp->respData->nextUpdate = PKI_TIME_new ( secs ); + } + + return r; +} + +/*! \brief Returns a PKI_STACK of URLs from a PRQP RESP object */ + +PKI_STACK * PKI_X509_PRQP_RESP_url_sk ( PKI_X509_PRQP_RESP *r ) { + + PKI_STACK *url_sk = NULL; + STACK_OF(PKI_RESOURCE_RESPONSE_TOKEN_STACK) *pki_sk=NULL; + + if( !r ) return (NULL); + + if((url_sk = PKI_STACK_new_null()) == NULL) { + return (NULL); + } + + if(( pki_sk = PKI_X509_PRQP_RESP_get_data( r, + PKI_X509_DATA_PRQP_SERVICES) ) != NULL){ + int i = 0; + RESOURCE_RESPONSE_TOKEN *res = NULL; + + url_sk = PKI_STACK_new_null(); + + for( i = 0; i < + PKI_STACK_RESOURCE_RESPONSE_TOKEN_elements (pki_sk ); + i++) { + ASN1_IA5STRING *resInfo = NULL; + char *url_s = NULL; + int j = 0; + + res = PKI_STACK_RESOURCE_RESPONSE_TOKEN_get_num ( + pki_sk, i); + + if( !res ) { + continue; + } + + for ( j = 0; j < sk_ASN1_IA5STRING_num( + res->resLocatorList); j++ ) { + + resInfo = sk_ASN1_IA5STRING_value( + res->resLocatorList, j ); + + url_s = PKI_STRING_get_utf8 ( resInfo ); + + if( url_s ) PKI_STACK_push( url_sk, url_s ); + } + } + } + + return ( url_sk ); +} + +/*! \brief Signs a PRQP object */ + +int PKI_X509_PRQP_sign( PKI_X509 *obj, PKI_X509_KEYPAIR *k, + PKI_X509_CERT *x, PKI_DIGEST_ALG *dgst, + PKI_X509_CERT_STACK * certs ) { + + PKI_X509_PRQP_REQ_VALUE *req = NULL; + PKI_X509_PRQP_RESP_VALUE *resp = NULL; + + const PKI_DIGEST_ALG *dd; + int i = 0; + + PRQP_SIGNATURE *psig = NULL; + + if( !k || !k->value || !x || !x->value || !obj || !obj->value ) { + PKI_log_debug("ERROR:PRQP:Sign key=%p, cert=%p\n", k, x ); + PKI_log_debug( "ERROR, missing needed args 2 signing PRQP!"); + return (PKI_ERR); + } + + if( !dgst ) + dd = PKI_DIGEST_ALG_get( PKI_ALGOR_SHA256 ); + else + dd = dgst; + + switch ( obj->type ) { + case PKI_DATATYPE_X509_PRQP_REQ: + req = obj->value; + break; + case PKI_DATATYPE_X509_PRQP_RESP: + resp = obj->value; + break; + default: + PKI_log_err("PRQP_sign called on non PRQP object %d (%d,%d)!", + obj->type, PKI_DATATYPE_X509_PRQP_REQ, PKI_DATATYPE_X509_PRQP_RESP ); + return ( PKI_ERR ); + } + + if ( req && !req->prqpSignature ) { + if((psig = PRQP_SIGNATURE_new()) == NULL ) { + PKI_log_err("Memory Allocation"); + return( PKI_ERR ); + } else { + req->prqpSignature = psig; + } + } else if ( resp && !resp->prqpSignature ) { + if((psig = PRQP_SIGNATURE_new()) == NULL ) { + PKI_log_err("Memory Allocation"); + return( PKI_ERR ); + } else { + resp->prqpSignature = psig; + } + } + + if( PKI_X509_sign ( obj, dd, k ) == PKI_ERR ) { + PKI_log_debug("ERROR, PRQP Sign Failed [%s]!", + ERR_error_string(ERR_get_error(), NULL)); + return(PKI_ERR); + } + + if( certs && psig ) { + if( psig->otherCerts == NULL ) { + if((psig->otherCerts = sk_X509_new_null()) == NULL) { + PKI_log_debug("ERROR, Can not Create stack " + "of certs in signature!"); + return( PKI_ERR ); + } + } + + for( i = 0; i < PKI_STACK_X509_CERT_elements( certs ); i++ ) { + PKI_X509_CERT *x_tmp = NULL; + + x_tmp = PKI_STACK_X509_CERT_get_num( certs, i ); + if (x_tmp && x_tmp->value ) { + sk_X509_push( psig->otherCerts, + PKI_X509_dup_value ( x_tmp )); + } + } + } + + PKI_log_debug("INFO, Adding certificate signer's certificate " + "to RESP!"); + psig->signerCert = PKI_X509_dup_value ( x ); + + return( PKI_OK ); +} + +/*! \brief Signs a PRQP object by using a provided TOKEN object */ + +int PKI_X509_PRQP_sign_tk ( PKI_X509_PRQP_RESP *resp, PKI_TOKEN *tk, + PKI_DIGEST_ALG *dgst ){ + + if( !tk || !tk->keypair || !tk->cert ) return ( PKI_ERR ); + + return ( PKI_X509_PRQP_sign( resp, tk->keypair, tk->cert, dgst, + tk->otherCerts )); +} + +/*! \brief Verifies that the signature on a PRQP object is correct */ + +int PKI_X509_PRQP_verify ( PKI_X509 *r ) { + + PKI_X509_CERT *x = NULL; + PKI_X509_KEYPAIR_VALUE *pkey = NULL; + PKI_X509_KEYPAIR *key = NULL; + int ret = PKI_OK; + + if ( (r->type != PKI_DATATYPE_X509_PRQP_REQ ) && + (r->type != PKI_DATATYPE_X509_PRQP_RESP ) ) { + return PKI_ERR; + } + + if( PKI_X509_is_signed ( r ) == PKI_ERR ) { + PKI_log_err("PKI_PRQP_verify() - Object not signed!"); + return ( PKI_ERR ); + } + + if( (x = PKI_X509_get_data ( r, + PKI_X509_DATA_SIGNER_CERT )) == NULL ) { + PKI_log_err("PKI_PRQP_verify() - Can not get Signer Cert!"); + return ( PKI_ERR ); + } + + if((pkey = PKI_X509_get_data( x, + PKI_X509_DATA_KEYPAIR_VALUE)) == NULL ) { + PKI_log_err("PKI_PRQP_verify() - Can not get Signer's Key!"); + return PKI_ERR; + } + + if (( key = PKI_X509_new_value ( PKI_DATATYPE_X509_KEYPAIR, + pkey, NULL)) == NULL ) { + return PKI_ERR; + } + + ret = PKI_X509_verify ( r, key ); + + key->value = NULL; + PKI_X509_KEYPAIR_free ( key ); + + return ret; + +} + +/*! \brief Verify Signature on the PRQP REQUEST */ + +int PKI_X509_PRQP_REQ_verify ( PKI_X509_PRQP_REQ *r ) { + + return PKI_X509_PRQP_verify ( r ); +} + +int PKI_X509_PRQP_RESP_verify ( PKI_X509_PRQP_RESP *r ) { + + return PKI_X509_PRQP_verify ( r ); +} + +// ===================== Print Functions for REQ/RESP ================= + +/*! \brief Prints out the contents of a PRQP_REQ on stdout */ + +int PKI_X509_PRQP_REQ_print ( PKI_X509_PRQP_REQ *req ) { + return PKI_X509_PRQP_REQ_print_fp( stdout, req ); +} + +/*! \brief Writes a PRQP_REQ in text format in the passed file pointer */ + +int PKI_X509_PRQP_REQ_print_fp ( FILE *fp, PKI_X509_PRQP_REQ *req ) { + + BIO *bio = NULL; + int ret = -1; + + if ( !req || !req->value ) return PKI_ERR; + + if ( !fp ) fp = stdout; + + if((bio = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL) { + return PKI_ERR; + } + + ret = PKI_X509_PRQP_REQ_VALUE_print_bio( req->value, bio ); + + BIO_free ( bio ); + + return ret; + +} + +int PKI_X509_PRQP_REQ_VALUE_print_bio ( PKI_PRQP_REQ *req, BIO *bio ) { + + PRQP_TBS_REQ_DATA *rd = NULL; + BASIC_CERT_IDENTIFIER *ci = NULL; + RESOURCE_REQUEST_TOKEN *rt = NULL; + STACK_OF(RESOURCE_IDENTIFIER) *list = NULL; + + PKI_TIME *time = NULL; + int i = 0; + + if( !req || !req->requestData || !bio ) return (PKI_ERR); + + rd = req->requestData; + + BIO_printf( bio, "PRQP Request:\r\n"); + BIO_printf( bio, " Version: %s (0x%s)\r\n", + i2s_ASN1_INTEGER(NULL, rd->version ), + i2s_ASN1_INTEGER(NULL, rd->version )); + + if( rd->nonce ) { + BIO_printf( bio, " Nonce: %s\r\n", + i2s_ASN1_OCTET_STRING(NULL, rd->nonce)); + // i2s_ASN1_INTEGER( NULL, rd->nonce )); + } else { + BIO_printf( bio, " Nonce: %s\r\n", "[ Not Present ]"); + } + if ( (time = rd->producedAt) != NULL ) { + char *tmp_time = NULL; + tmp_time = PKI_TIME_get_parsed ( time ); + BIO_printf( bio, " Produced At: %s\r\n", tmp_time); + PKI_Free ( tmp_time ); + } + + ci = rd->serviceToken->ca->basicCertId; + + BIO_printf( bio, "\r\n"); + BIO_printf( bio, " Certification Authority Identifier:\r\n" ); + + if( ci->serialNumber ) { + BIO_printf( bio, " Serial Number:\r\n"); + BIO_printf( bio, " %s (0x%s)\r\n", + i2s_ASN1_INTEGER(NULL,ci->serialNumber), + i2s_ASN1_OCTET_STRING(NULL,ci->serialNumber)); + } else { + BIO_printf( bio, " Serial Number: %s\r\n", + "[ Not Present ]" ); + } + + /* + if( ci->subjectNameHash ) { + fprintf( fp, " Subject Name Hash:\r\n"); + fprintf( fp, " %s\r\n", + i2s_ASN1_OCTET_STRING( NULL, ci->subjectNameHash) ); + } else { + fprintf( fp, " Subject Name Hash:\r\n"); + fprintf( fp, " %s\r\n", + "[ Not Present ]" ); + } + */ + + if( ci->issuerNameHash ) { + BIO_printf( bio, " Issuer Name Hash:\r\n"); + BIO_printf( bio, " %s\r\n", + i2s_ASN1_OCTET_STRING(NULL, ci->issuerNameHash)); + } + + BIO_printf( bio, "\r\n Requested Services:\r\n" ); + rt = req->requestData->serviceToken; + if( (rt == NULL) || ( rt->resourceList == NULL ) || + (sk_RESOURCE_IDENTIFIER_num( rt->resourceList ) < 1) ) { + BIO_printf( bio, " ALL\r\n"); + } else { + list = req->requestData->serviceToken->resourceList; + + for( i=0; i < sk_RESOURCE_IDENTIFIER_num( list ); i++ ) { + + RESOURCE_IDENTIFIER *ri = NULL; + + ri = sk_RESOURCE_IDENTIFIER_value(list, i); + + BIO_printf( bio, " %s:\r\n", + (char *) PKI_OID_get_descr ( ri->resourceId )); + + if( ri->version != NULL ) { + char *tmp_str = NULL; + tmp_str = PKI_INTEGER_get_parsed ( ri->version); + BIO_printf(bio, " Version: %s\r\n", + tmp_str); + PKI_Free ( tmp_str ); + } else { + BIO_printf(bio, " Version: Any\r\n"); + } + + if( ri->oid != NULL ) { + // char *oid_str = NULL; + + BIO_printf(bio, " " + "Identifier: %s\r\n", + PKI_OID_get_descr (ri->oid )); + /* + if(( oid_str = PKI_OID_get_descr ( ri->oid )) + != NULL ) { + fprintf(fp, " " + "Identifier: %s\r\n", oid_str); + // PKI_Free ( oid_str ); + } + + */ + } else { + BIO_printf( bio, + " Identifier: Any\r\n"); + } + } + } + + if( rd->extensions ) { + BIO_printf( bio, " Extensions:\r\n"); + BIO_printf( bio, " *** EXTENSIONS PRESENT ***\r\n"); + } + + if( req->prqpSignature && req->prqpSignature->signature ) { + PKI_X509_PRQP_REQ *x_obj = NULL; + + //if((out = BIO_new_fp( fp, BIO_NOCLOSE )) != NULL ) { + X509_signature_print( bio, + req->prqpSignature->signatureAlgorithm, + req->prqpSignature->signature ); + // BIO_free ( out ); + //} + + BIO_printf( bio, " Signature Verification: "); + if(( x_obj = PKI_X509_new_dup_value (PKI_DATATYPE_X509_PRQP_REQ, + req, NULL )) == NULL ) { + BIO_printf( bio, "ERROR."); + } else { + if(PKI_X509_PRQP_REQ_verify( x_obj ) == PKI_OK ) { + BIO_printf( bio, "Ok.\r\n" ); + } else { + BIO_printf( bio, "Error => %s\r\n", + ERR_error_string(ERR_get_error(),NULL)); + } + + PKI_X509_PRQP_REQ_free ( x_obj ); + } + } + + return (PKI_OK); +} + +/*! \brief Prints out the contents of a PRQP_RESP to stdout */ + +int PKI_X509_PRQP_RESP_print ( PKI_X509_PRQP_RESP *resp ) { + return PKI_X509_PRQP_RESP_print_fp( stdout, resp ); +} + +/*! \brief Writes a PRQP_RESP in text format to the passed file pointer */ + +int PKI_X509_PRQP_RESP_print_fp ( FILE *fp, PKI_X509_PRQP_RESP *resp ) { + + BIO *bio = NULL; + int ret = -1; + + if ( !resp || !resp->value ) return PKI_ERR; + + if ( !fp ) fp = stdout; + + if((bio = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL) { + return PKI_ERR; + } + + ret = PKI_X509_PRQP_RESP_VALUE_print_bio( resp->value , bio ); + + BIO_free ( bio ); + + return ret; +} + + +int PKI_X509_PRQP_RESP_VALUE_print_bio (PKI_X509_PRQP_RESP_VALUE *resp, BIO *bio) { + + PRQP_TBS_RESP_DATA *rd = NULL; + CERT_IDENTIFIER *ci = NULL; + BASIC_CERT_IDENTIFIER *bci = NULL; + STACK_OF(RESOURCE_RESPONSE_TOKEN) *pki_sk=NULL; + PKI_STACK *referrals = NULL; + + int i = 0; + int status = 0; + + PKI_TIME *time = NULL; + + if( !resp || !resp->respData || !bio ) return PKI_ERR; + + rd = resp->respData; + + BIO_printf( bio, "PRQP Response:\r\n"); + + BIO_printf( bio, " Version: %s (0x%s)\r\n", + i2s_ASN1_INTEGER(NULL, rd->version ), + i2s_ASN1_INTEGER(NULL, rd->version )); + ci = rd->caCertId; + if( rd->nonce ) { + BIO_printf( bio, " Nonce: %s\r\n", + i2s_ASN1_OCTET_STRING(NULL, rd->nonce)); + // i2s_ASN1_INTEGER( NULL, rd->nonce )); + } else { + BIO_printf( bio, " Nonce: %s\r\n", "[ Not Present ]"); + } + + if ( (time = rd->producedAt) != NULL ) { + char * tmp_time = NULL; + BIO_printf( bio, " Produced At: "); + tmp_time = PKI_TIME_get_parsed ( time ); + BIO_printf( bio, "%s\r\n", tmp_time); + PKI_Free ( tmp_time ); + } + + if ( (time = rd->nextUpdate) != NULL ) { + char * tmp_time = NULL; + BIO_printf( bio, " Next Update: "); + tmp_time = PKI_TIME_get_parsed ( time ); + BIO_printf( bio, "%s\r\n", tmp_time); + PKI_Free ( tmp_time ); + } + + BIO_printf( bio, "\r\n"); + status = PKI_X509_PRQP_RESP_get_status_value ( resp ); + BIO_printf( bio, " PKI Status:\r\n %s (%d)\r\n", + (char *) PKI_X509_PRQP_RESP_VALUE_get_data( resp, + PKI_X509_DATA_PRQP_STATUS_VALUE ), status); + + + if((referrals = PKI_X509_PRQP_RESP_VALUE_get_data(resp, + PKI_X509_DATA_PRQP_REFERRALS)) != NULL ) { + BIO_printf( bio, "\r\n"); + BIO_printf( bio, " Referrals:\r\n"); + for(i=0; i < PKI_STACK_elements ( referrals ); i++ ) { + char * val = NULL; + + if((val = PKI_STACK_get_num( referrals, i)) == NULL ) { + continue; + } + + BIO_printf( bio, " %s\r\n", val); + } + + PKI_STACK_free_all ( referrals ); + } + + + /* + fprintf( fp, " PRQP Referrals:\r\n"); + + if((referrals=PKI_PRQP_RESP_get_data(resp, PKI_X509_DATA_REFERRALS)) + == NULL ) { + fprintf(fp, " None.\r\n"); + } else { + for(i=0; i < PKI_STACK_elements ( referrals ); i++ ) { + char * val = NULL; + + if((val = PKI_STACK_get_num( referrals, i)) == NULL ) { + continue; + } + + fprintf( fp, " %s\r\n", val); + } + fprintf( fp, "\r\n"); + + PKI_STACK_free_all ( referrals ); + } + */ + + ci = rd->caCertId; + if((bci = ci->basicCertId) != NULL ) { + BIO_printf( bio, + "\r\n Certification Authority Identifier:\r\n"); + if( bci->serialNumber ) { + BIO_printf( bio, " Serial Number:\r\n"); + BIO_printf( bio, " %s (0x%s)\r\n", + i2s_ASN1_INTEGER(NULL,bci->serialNumber), + i2s_ASN1_OCTET_STRING(NULL,bci->serialNumber)); + } else { + BIO_printf( bio, " Serial Number: %s\r\n", + "[ Not Present ]" ); + } + + if( bci->issuerNameHash ) { + BIO_printf( bio, " Issuer Name Hash:\r\n"); + BIO_printf( bio, " %s\r\n", + i2s_ASN1_OCTET_STRING(NULL, bci->issuerNameHash)); + } + } + BIO_printf( bio, "\r\n"); + + if( strcmp ( PKI_X509_PRQP_RESP_VALUE_get_data( resp, + PKI_X509_DATA_PRQP_STATUS_VALUE ), + PKI_X509_PRQP_STATUS_STRING_OK) == 0 ) { + BIO_printf( bio, " Requested Services:\r\n"); + if(( pki_sk=PKI_X509_PRQP_RESP_VALUE_get_data(resp, + PKI_X509_DATA_PRQP_SERVICES))!= NULL){ + + RESOURCE_RESPONSE_TOKEN *res = NULL; + + for( i = 0; i < + PKI_STACK_RESOURCE_RESPONSE_TOKEN_elements (pki_sk ); + i++) { + /* + while( (res = PKI_STACK_RESOURCE_RESPONSE_TOKEN_pop( pki_sk )) + != NULL ) { + */ + ASN1_IA5STRING *resInfo = NULL; + + res = PKI_STACK_RESOURCE_RESPONSE_TOKEN_get_num ( + pki_sk,i); + + if( PKI_OID_get_id ( res->resourceId ) + != PKI_ID_UNKNOWN ) { + BIO_printf( bio, " %s:\r\n", + PKI_OID_get_descr( res->resourceId )); + + } else { + char *tmpIdStr = NULL; + tmpIdStr = PKI_OID_get_str ( res->resourceId); + if( tmpIdStr ) { + BIO_printf( bio, " %s:\r\n", + tmpIdStr); + PKI_Free ( tmpIdStr ); + } else { + BIO_printf( bio, " %s:\r\n", + "Unknown Service ID"); + } + } + + if( res->version != NULL ) { + BIO_printf(bio, " Version: %s\r\n", + PKI_INTEGER_get_parsed( res->version )); + } else { + BIO_printf(bio, " Version: Any\r\n"); + } + + if( res->oid != NULL ) { + char *tmp_ID = NULL; + + if( (tmp_ID = PKI_OID_get_str ( res->oid )) + != NULL ) { + BIO_printf ( bio, " " + "OID: %s\r\n", tmp_ID ); + } else { + BIO_printf(bio, " OID: None\r\n"); + } + } + + if( res->textInfo != NULL ) { + char *tmp_str = NULL; + tmp_str = PKI_STRING_get_utf8 ( res->textInfo ); + BIO_printf(bio, " Extra Information:" + "\r\n%s\r\n", tmp_str ); + PKI_Free ( tmp_str ); + } else { + BIO_printf(bio, " " + "Extra Information: None\r\n" ); + } + + while((resInfo = sk_ASN1_IA5STRING_pop( + res->resLocatorList )) != NULL) { + char *tmp_str = NULL; + BIO_printf( bio, " URI:"); + tmp_str = PKI_STRING_get_utf8(resInfo); + BIO_printf( bio, "%s\r\n", tmp_str); + PKI_Free ( tmp_str ); + } + BIO_printf (bio, "\r\n"); + + } + // if( res ) RESOURCE_RESPONSE_TOKEN_free ( res ); + } else { + PKI_log_debug("Parsing Response, no SERVICES found!"); + } + } + + BIO_printf( bio, "\r\n" ); + + if( rd->extensions ) { + BIO_printf( bio, " Extensions:\r\n"); + BIO_printf( bio, " *** EXTENSIONS PRESENT ***\r\n"); + } + + if( resp->prqpSignature && resp->prqpSignature->signature ) { + PKI_X509_PRQP_RESP *x_obj = NULL; + + // if((out = BIO_new_fp( fp, BIO_NOCLOSE )) != NULL ) { + X509_signature_print( bio, + resp->prqpSignature->signatureAlgorithm, + resp->prqpSignature->signature ); + // BIO_free ( out ); + // } + + BIO_printf(bio, " Signature Verification: "); + if(( x_obj = PKI_X509_new_dup_value(PKI_DATATYPE_X509_PRQP_RESP, + resp, NULL )) == NULL ) { + BIO_printf( bio, "ERROR."); + } else { + if(PKI_X509_PRQP_verify( x_obj ) == PKI_OK ) { + BIO_printf( bio, "Ok.\r\n" ); + } else { + BIO_printf( bio, "Error => %s", + ERR_error_string(ERR_get_error(),NULL)); + BIO_printf(bio, "\r\n"); + } + + PKI_X509_PRQP_RESP_free ( x_obj ); + } + } + + return PKI_OK; +} + +/* --------------------------- Data Retrieval --------------------------- */ + +/*! \brief Returns data pointers from a PRQP request */ + +void * PKI_X509_PRQP_REQ_get_data ( PKI_X509_PRQP_REQ *obj, PKI_X509_DATA type ) { + + PKI_X509_PRQP_REQ_VALUE *r = NULL; + + if( !obj || !obj->value ) return ( NULL ); + + r = obj->value; + + return PKI_X509_PRQP_REQ_VALUE_get_data( r, type ); + +} + +/*! \brief Returns data pointers from a PRQP_REQ_VALUE */ + +static void * PKI_X509_PRQP_REQ_VALUE_get_data ( PKI_X509_PRQP_REQ_VALUE *r, + PKI_X509_DATA type ) { + + PKI_X509_CERT_VALUE *cert_val = NULL; + void * ret = NULL; + + if (!r || !r->requestData ) return NULL; + + switch ( type ) + { + case PKI_X509_DATA_VERSION: + ret = r->requestData->version; + break; + + case PKI_X509_DATA_NONCE: + ret = r->requestData->nonce; + break; + + case PKI_X509_DATA_PRODUCEDAT: + case PKI_X509_DATA_NOTBEFORE: + ret = r->requestData->producedAt; + break; + + case PKI_X509_DATA_SIGNATURE_CERTS: + if( r->prqpSignature && r->prqpSignature->otherCerts) + { + int i = 0; + PKI_X509_CERT_STACK *s = NULL; + + s = PKI_STACK_X509_CERT_new(); + for (i = 0 ; i < sk_X509_num(r->prqpSignature->otherCerts ); i++ ) + { + PKI_STACK_X509_CERT_push(ret, + sk_X509_value(r->prqpSignature->otherCerts, i)); + } + ret = s; + } + break; + + case PKI_X509_DATA_SIGNATURE: + if (r->prqpSignature) ret = r->prqpSignature->signature; + break; + + case PKI_X509_DATA_ALGORITHM: + case PKI_X509_DATA_SIGNATURE_ALG1: + if (r->prqpSignature) ret = r->prqpSignature->signatureAlgorithm; + break; + + case PKI_X509_DATA_SIGNER_CERT: + if (r->prqpSignature) + { + cert_val = r->prqpSignature->signerCert; + if (cert_val) + { + ret = PKI_X509_new_dup_value(PKI_DATATYPE_X509_CERT, + cert_val, NULL); + } + ret = r->prqpSignature->signerCert; + } + break; + + case PKI_X509_DATA_SIGNATURE_ALG2: + // Nothing to do here + break; + +/* + // This shall be replaced with a dedicated + // function because this violates the memory + // contract (const for the returned item) + // PKI_X509_get_tbs_asn1(); + case PKI_X509_DATA_TBS_MEM_ASN1: + if ((mem = PKI_MEM_new_null()) == NULL) + { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + break; + } + mem->size = (size_t) ASN1_item_i2d((void *) r->requestData, + &(mem->data), &PRQP_TBS_REQ_DATA_it ); + ret = mem; + break; +*/ + + case PKI_X509_DATA_PRQP_CAID: + if (r->requestData && r->requestData->serviceToken) + ret = r->requestData->serviceToken->ca; + break; + + case PKI_X509_DATA_PRQP_SERVICES: + if(r->requestData && r->requestData->serviceToken && + r->requestData->serviceToken->resourceList) + { + STACK_OF(RESOURCE_IDENTIFIER) *ri_sk = NULL; + PKI_RESOURCE_IDENTIFIER_STACK *ret_sk = NULL; + + int i = 0; + + PKI_log_debug("get_data() - Request has a resourceList"); + + ret_sk = PKI_STACK_RESOURCE_IDENTIFIER_new_null(); + ri_sk = r->requestData->serviceToken->resourceList; + + PKI_log_debug("get_data() - Number of OIDs in request is %d", + PKI_STACK_RESOURCE_IDENTIFIER_elements( ri_sk ) ); + + for( i=0; i < sk_RESOURCE_IDENTIFIER_num (ri_sk); i++ ) + { + RESOURCE_IDENTIFIER *p = NULL; + + p = sk_RESOURCE_IDENTIFIER_value(ri_sk, i); + PKI_STACK_RESOURCE_IDENTIFIER_push(ret_sk, p ); + } + + ret = ret_sk; + + } + else + { + PKI_log_debug( "get_data() - No resources in request"); + PKI_log_debug( "get_data() - r->requestData %p", r->requestData ); + PKI_log_debug( "get_data() - " "r->requestData->serviceToken %p", + r->requestData->serviceToken ); + PKI_log_debug( "get_data() - " "r->requestData->serviceToken->resourceList %p", + r->requestData->serviceToken->resourceList ); + } + break; + + default: + /* Datatype not supported */ + return ( NULL ); + } + + return ret; +} + +/*! \brief Returns a pointer to the specified PKI_X509_DATA field of a + * PRQP response */ + +void * PKI_X509_PRQP_RESP_get_data ( PKI_X509_PRQP_RESP *obj, + PKI_X509_DATA type ) { + + PKI_X509_PRQP_RESP_VALUE *r = NULL; + + if( !obj || !obj->value ) return ( NULL ); + + r = obj->value; + + return PKI_X509_PRQP_RESP_VALUE_get_data ( r, type ); + +} + +/*! \brief Returns a pointer to the specified PKI_X509_DATA field of a + * PKI_X509_PRQP_RESP_VALUE data structure */ + +static void *PKI_X509_PRQP_RESP_VALUE_get_data ( PKI_X509_PRQP_RESP_VALUE *r, + PKI_X509_DATA type ) { + + PKI_X509_CERT_VALUE *cert_val = NULL; + void *ret = NULL; + + if ( !r || !r->respData ) return NULL; + + switch (type) + { + case PKI_X509_DATA_VERSION: + ret = r->respData->version; + break; + + case PKI_X509_DATA_NONCE: + ret = r->respData->nonce; + break; + + case PKI_X509_DATA_PRODUCEDAT: + case PKI_X509_DATA_NOTBEFORE: + ret = r->respData->producedAt; + break; + + case PKI_X509_DATA_NEXTUPDATE: + case PKI_X509_DATA_NOTAFTER: + ret = r->respData->nextUpdate; + break; + + case PKI_X509_DATA_PRQP_STATUS_VALUE: + if(r->respData && r->respData->pkiStatus) + { + ASN1_INTEGER *tmp_int = NULL; + long a = 0; + + tmp_int = r->respData->pkiStatus->status; + ret = i2s_ASN1_INTEGER( NULL, tmp_int ); + if (ret) + { + a = atol( ret ); + PKI_Free( ret ); + + if (a < PKI_X509_PRQP_STATUS_STRING_NUM) + ret=PKI_X509_PRQP_STATUS_STRING[a]; + else + ret=PKI_X509_PRQP_STATUS_STRING_UNKNOWN; + } + else ret = PKI_X509_PRQP_STATUS_STRING_UNKNOWN; + } + break; + + case PKI_X509_DATA_PRQP_REFERRALS: + if( r->respData && r->respData->pkiStatus && + r->respData->pkiStatus->referrals ) + { + int i = 0; + PKI_STACK *s = NULL; + STACK_OF(ASN1_IA5STRING) *sk = NULL; + + sk = r->respData->pkiStatus->referrals; + + if((s = PKI_STACK_new_null()) == NULL ) + { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + ret = NULL; + break; + } + + for ( i = 0; i < sk_ASN1_IA5STRING_num(sk); i++) + { + PKI_STRING *st = NULL; + char *val = NULL; + + st = sk_ASN1_IA5STRING_value( sk, i); + if( !st ) continue; + + val = PKI_STRING_get_utf8(st); + if (val) PKI_STACK_push ( s, val); + } + ret = s; + } + break; + + case PKI_X509_DATA_PRQP_STATUS_STRING: + if( r->respData && r->respData->pkiStatus ) + { + PKI_STRING *s = NULL; + s = r->respData->pkiStatus->statusString; + ret = PKI_STRING_get_utf8( s ); + } + break; + + case PKI_X509_DATA_PRQP_CAID: + if (r->respData) ret = r->respData->caCertId; + break; + + case PKI_X509_DATA_SIGNATURE_CERTS: + if( r->prqpSignature && r->prqpSignature->otherCerts) + { + int i = 0; + PKI_X509_CERT_STACK *s = NULL; + + s = PKI_STACK_X509_CERT_new(); + for( i = 0 ; i < sk_X509_num( r->prqpSignature->otherCerts ); i++ ) + { + PKI_STACK_X509_CERT_push( ret, + sk_X509_value( r->prqpSignature->otherCerts, i)); + } + ret = s; + } + break; + + case PKI_X509_DATA_SIGNER_CERT: + if (r->prqpSignature) + { + cert_val = r->prqpSignature->signerCert; + if (cert_val) + { + ret = PKI_X509_new_dup_value(PKI_DATATYPE_X509_CERT, + cert_val, NULL); + } + } + break; + + case PKI_X509_DATA_SIGNATURE: + if (r->prqpSignature) ret = r->prqpSignature->signature; + break; + + case PKI_X509_DATA_ALGORITHM: + case PKI_X509_DATA_SIGNATURE_ALG1: + if (r->prqpSignature) + ret = r->prqpSignature->signatureAlgorithm; + else + PKI_log_debug("DEBUG::No DATA_SIGNATURE_ALG1"); + break; + + case PKI_X509_DATA_SIGNATURE_ALG2: + // Nothing to do here + break; + +/* + // This shall be replaced with a dedicated + // function because this violates the memory + // contract (const for the returned item) + // PKI_X509_get_tbs_asn1(); + case PKI_X509_DATA_TBS_MEM_ASN1: + if ((mem = PKI_MEM_new_null()) == NULL) + { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + break; + } + mem->size = (size_t) ASN1_item_i2d ( (void *) r->respData, + &(mem->data), &PRQP_TBS_RESP_DATA_it ); + ret = mem; + break; +*/ + + case PKI_X509_DATA_PRQP_SERVICES: + if( r->respData && r->respData->responseToken ) + { + int i = 0; + int num = 0; + + STACK_OF(RESOURCE_RESPONSE_TOKEN) *rrt = NULL; + PKI_RESOURCE_RESPONSE_TOKEN_STACK *pki_sk=NULL; + + PKI_log_debug("Response Token Present"); + + pki_sk = PKI_STACK_RESOURCE_RESPONSE_TOKEN_new_null(); + if( !pki_sk ) return ( NULL ); + + rrt = r->respData->responseToken; + + num = sk_RESOURCE_RESPONSE_TOKEN_num ( rrt ); + PKI_log_debug("Services in Response Token: %d", num); + + for (i=0; i < num; i++) + { + RESOURCE_RESPONSE_TOKEN *p = NULL; + + p = sk_RESOURCE_RESPONSE_TOKEN_value(rrt, i); + PKI_STACK_RESOURCE_RESPONSE_TOKEN_push(pki_sk, + RESOURCE_RESPONSE_TOKEN_dup( p ) ); + } + ret = pki_sk; + } + else + { + if (!r->respData) + PKI_log_debug("PRQP RESP:Missing r->respData [get_data]"); + else if (!r->respData->responseToken) + PKI_log_debug("PRQP RESP:Missing r->respData->responseToken [get_data]"); + } + break; + + default: + /* Datatype not supported */ + return ( NULL ); + } + + return ( ret ); +} + +PKI_OID *PRQP_RESOURCE_RESPONSE_TOKEN_get_oid ( RESOURCE_RESPONSE_TOKEN *rrt ) +{ + if (!rrt) + { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return ( NULL ); + } + + return (PKI_OID *) rrt->resourceId; +} + +PKI_STACK *PRQP_RESOURCE_RESPONSE_TOKEN_get_services( RESOURCE_RESPONSE_TOKEN *rrt ) { + + int i = 0; + PKI_STACK *ret = NULL; + ASN1_IA5STRING *resInfo = NULL; + + if ( !rrt || !rrt->resourceId ) return (NULL); + + if((ret = PKI_STACK_new( NULL )) == NULL ) { + PKI_log_debug( "Memory Allocation Failed"); + return ( NULL ); + } + + for(i=0; i< sk_ASN1_IA5STRING_num( rrt->resLocatorList ); i++ ) { + + char *ret_s = NULL; + + resInfo = sk_ASN1_IA5STRING_value( rrt->resLocatorList, i ); + if( !resInfo ) { + continue; + } + + // s = sk_ASN1_IA5STRING_value( rrt->resLocatorList, i ); + // ret_s = i2s_ASN1_IA5STRING( NULL, resInfo ); + ret_s = PKI_STRING_get_parsed ( resInfo ); + PKI_STACK_push( ret, ret_s ); + } + + return( ret ); +} + +/*! \brief Returns the PKI_X509_PRQP_STATUS associated to a PRQP + * response */ + +int PKI_X509_PRQP_RESP_get_status ( PKI_X509_PRQP_RESP *obj ) { + + PKI_X509_PRQP_RESP_VALUE *r = NULL; + + if ( !obj || !obj->value ) return PKI_X509_PRQP_STATUS_UNKNOWN; + + r = obj->value; + + return PKI_X509_PRQP_RESP_get_status_value ( r ); + +} + +static int PKI_X509_PRQP_RESP_get_status_value(PKI_X509_PRQP_RESP_VALUE *r) +{ + ASN1_INTEGER *tmp_int = NULL; + char *tmp_s = NULL; + + long a = 0; + int ret = PKI_X509_PRQP_STATUS_UNKNOWN; + if( !r || !r->respData || !r->respData->pkiStatus ) + { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return ( PKI_X509_PRQP_STATUS_UNKNOWN ); + } + + tmp_int = r->respData->pkiStatus->status; + tmp_s = i2s_ASN1_INTEGER( NULL, tmp_int ); + + if (tmp_s) + { + a = atol(tmp_s); + PKI_Free(tmp_s); + + if (a < PKI_X509_PRQP_STATUS_STRING_NUM) + ret = (int) a; + else + ret = PKI_X509_PRQP_STATUS_UNKNOWN; + } + + return ret; +} + diff --git a/src/pkix/prqp/prqp_req_io.c b/src/pkix/prqp/prqp_req_io.c new file mode 100644 index 00000000..ce9f9e58 --- /dev/null +++ b/src/pkix/prqp/prqp_req_io.c @@ -0,0 +1,86 @@ +/* PKI_X509_PRQP_REQ I/O management */ + +#include + +/* ----------------------------- REQ get functions ------------------------------- */ + +PKI_X509_PRQP_REQ *PKI_X509_PRQP_REQ_get ( char *url_s, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_get ( url_s, PKI_DATATYPE_X509_PRQP_REQ, format, cred, hsm ); + +} + +PKI_X509_PRQP_REQ *PKI_X509_PRQP_REQ_get_url ( URL *url, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_get_url ( url, PKI_DATATYPE_X509_PRQP_REQ, format, cred, hsm ); + +} + +PKI_X509_PRQP_REQ *PKI_X509_PRQP_REQ_get_mem ( PKI_MEM *mem, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_get_mem ( mem, PKI_DATATYPE_X509_PRQP_REQ, format, cred, hsm ); +} + +PKI_X509_PRQP_REQ_STACK *PKI_X509_PRQP_REQ_STACK_get (char *url_s, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm) { + + return PKI_X509_STACK_get ( url_s, PKI_DATATYPE_X509_PRQP_REQ, format, cred, hsm ); +} + +PKI_X509_PRQP_REQ_STACK *PKI_X509_PRQP_REQ_STACK_get_url ( URL *url, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_STACK_get_url ( url, PKI_DATATYPE_X509_PRQP_REQ, format, cred, hsm ); +} + +PKI_X509_PRQP_REQ_STACK *PKI_X509_PRQP_REQ_STACK_get_mem(PKI_MEM *mem, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm) { + + return PKI_X509_STACK_get_mem ( mem, PKI_DATATYPE_X509_PRQP_REQ, + format, cred, hsm ); +} + +/* ---------------------------- REQ put operations ------------------ */ + +int PKI_X509_PRQP_REQ_put (PKI_X509_PRQP_REQ *req, PKI_DATA_FORMAT format, char *url_s, + char *mime, PKI_CRED *cred, HSM *hsm) { + + return PKI_X509_put ( req, format, url_s, mime, cred, hsm ); +} + +int PKI_X509_PRQP_REQ_put_url(PKI_X509_PRQP_REQ *req, PKI_DATA_FORMAT format, URL *url, + char *mime, PKI_CRED *cred, HSM *hsm) { + + return PKI_X509_put_url ( req, format, url, mime, cred, hsm ); +} + +PKI_MEM * PKI_X509_PRQP_REQ_put_mem ( PKI_X509_PRQP_REQ *req, + PKI_DATA_FORMAT format, PKI_MEM **pki_mem, + PKI_CRED *cred, HSM *hsm ) { + return PKI_X509_put_mem ( req, format, pki_mem, cred ); +} + + +int PKI_X509_PRQP_REQ_STACK_put ( PKI_X509_PRQP_REQ_STACK *sk, PKI_DATA_FORMAT format, + char *url_s, char *mime, PKI_CRED *cred, HSM *hsm) { + + return PKI_X509_STACK_put ( sk, format, url_s, mime, cred, hsm ); +} + +int PKI_X509_PRQP_REQ_STACK_put_url (PKI_X509_PRQP_REQ_STACK *sk, + PKI_DATA_FORMAT format, URL *url, char * mime, + PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_STACK_put_url ( sk, format, url, mime, cred, hsm ); +} + +PKI_MEM * PKI_X509_PRQP_REQ_STACK_put_mem ( PKI_X509_PRQP_REQ_STACK *sk, + PKI_DATA_FORMAT format, PKI_MEM **pki_mem, PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_STACK_put_mem ( sk, format, pki_mem, cred, hsm ); + +} + diff --git a/src/pkix/prqp/prqp_resp_io.c b/src/pkix/prqp/prqp_resp_io.c new file mode 100644 index 00000000..6f58bcee --- /dev/null +++ b/src/pkix/prqp/prqp_resp_io.c @@ -0,0 +1,86 @@ +/* PKI_X509_PRQP_RESP I/O management */ + +#include + +PKI_X509_PRQP_RESP *PKI_X509_PRQP_RESP_get ( char *url_s, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_get ( url_s, PKI_DATATYPE_X509_PRQP_RESP, format, cred, hsm ); +} + +PKI_X509_PRQP_RESP *PKI_X509_PRQP_RESP_get_url ( URL *url, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_get_url ( url, PKI_DATATYPE_X509_PRQP_RESP, format, cred, hsm ); + +} + +PKI_X509_PRQP_RESP_STACK *PKI_X509_PRQP_RESP_STACK_get (char *url_s, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm) { + + return PKI_X509_STACK_get ( url_s, PKI_DATATYPE_X509_PRQP_RESP, format, cred, hsm ); + +} + +PKI_X509_PRQP_RESP_STACK *PKI_X509_PRQP_RESP_STACK_get_url ( URL *url, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_STACK_get_url ( url, PKI_DATATYPE_X509_PRQP_RESP, format, cred, hsm ); + +} + +/* ---------------------------- RESP put operations ------------------ */ + +int PKI_X509_PRQP_RESP_put (PKI_X509_PRQP_RESP *resp, PKI_DATA_FORMAT format, char *url_s, + char *mime, PKI_CRED *cred, HSM *hsm) { + + return PKI_X509_put ( resp, format, url_s, mime, cred, hsm ); +} + +int PKI_X509_PRQP_RESP_put_url(PKI_X509_PRQP_RESP *resp, PKI_DATA_FORMAT format, URL *url, + char *mime, PKI_CRED *cred, HSM *hsm) { + + return PKI_X509_put_url ( resp, format, url, mime, cred, hsm ); + +} + + +int PKI_X509_PRQP_RESP_STACK_put ( PKI_X509_PRQP_RESP_STACK *sk, PKI_DATA_FORMAT format, + char *url_s, char *mime, PKI_CRED *cred, HSM *hsm) { + + return PKI_X509_STACK_put ( sk, format, url_s, mime, cred, hsm ); +} + +int PKI_X509_PRQP_RESP_STACK_put_url (PKI_X509_PRQP_RESP_STACK *sk, PKI_DATA_FORMAT format, + URL *url, char * mime, PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_STACK_put_url ( sk, format, url, mime, cred, hsm ); +} + +/* -------------------------- RESP mem Operations -------------------- */ + +PKI_X509_PRQP_RESP * PKI_X509_PRQP_RESP_get_mem ( PKI_MEM *mem, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_get_mem ( mem, PKI_DATATYPE_X509_PRQP_RESP, format, cred, hsm ); +} + +PKI_X509_PRQP_RESP_STACK *PKI_X509_PRQP_RESP_STACK_get_mem(PKI_MEM *mem, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm) { + + return PKI_X509_STACK_get_mem ( mem, PKI_DATATYPE_X509_PRQP_RESP, + format, cred, hsm ); +} + +PKI_MEM * PKI_X509_PRQP_RESP_put_mem ( PKI_X509_PRQP_RESP *resp, + PKI_DATA_FORMAT format, PKI_MEM **pki_mem, PKI_CRED *cred, HSM * hsm ) { + + return PKI_X509_put_mem ( resp, format, pki_mem, cred ); +} + +PKI_MEM * PKI_X509_PRQP_RESP_STACK_put_mem ( PKI_X509_PRQP_RESP_STACK *sk, PKI_DATA_FORMAT format, + PKI_MEM **pki_mem, PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_STACK_put_mem ( sk, format, pki_mem, cred, hsm ); +} + diff --git a/src/pkix/prqp/prqp_srv.c b/src/pkix/prqp/prqp_srv.c new file mode 100644 index 00000000..f7eee9a2 --- /dev/null +++ b/src/pkix/prqp/prqp_srv.c @@ -0,0 +1,286 @@ +/* PKI Resource Query Protocol Message implementation + * (c) 2006 by Massimiliano Pala and OpenCA Group + * All Rights Reserved + * + * This software is released under the GPL2 License included + * in the archive. You can not remove this copyright notice. + */ + +#include + +/*! + * \brief Retireve a PKI_STACK of addresses from a PRQP server. + * + * Retrieve informations about services provided by a CA from a PRQP server. + * The function returns a stack of strings containing URLs of the requested + * services. If no URL (char *) is passed, then the library will search for + * the default config file /etc/pki.conf for the configured Resource Query + * Authority (PRQP Server). + * + */ + +PKI_STACK * PKI_get_ca_resources(PKI_X509_CERT *caCert, + PKI_X509_CERT *caIssuerCert, PKI_X509_CERT *issuedCert, + PKI_STACK *sk_services, char *url_s ) { + + PKI_X509_PRQP_REQ *p = NULL; + PKI_X509_PRQP_RESP *r = NULL; + PKI_STACK *addr_sk = NULL; + + p = PKI_X509_PRQP_REQ_new_certs_res ( caCert, caIssuerCert, + issuedCert, sk_services ); + + if( !p ) { + PKI_log_debug ("PKI_get_ca_resources()::Can not generate PRQP REQ"); + return NULL; + } + + if((r = PKI_DISCOVER_get_resp ( p, url_s )) == NULL ) { + PKI_log_debug("PKI_get_ca_resources()::No response retrieved!"); + PKI_X509_PRQP_REQ_free ( p ); + return NULL; + } + + // PKI_PRQP_RESP_print( r->value ); + + if((addr_sk = PKI_X509_PRQP_RESP_url_sk ( r )) == NULL ) { + PKI_log_debug ("PKI_get_ca_responses()::No list of address is returned!"); + } + + if ( p ) PKI_X509_PRQP_REQ_free ( p ); + if ( r ) PKI_X509_PRQP_RESP_free ( r ); + + return addr_sk; +} + +/*! + * \brief Retireve a stack of configured URL for a PKI service from a PRQP + * server + * + * Retrieve information about a specific service provided by a CA. + * The function returns a PKI_STACK containing the URLs of the requested + * service (if available). + * + * If no URL (char *) is passed, then the library will search for + * the default config file /etc/pki.conf for the configured Resource Query + * Authority (PRQP Server). + * + */ + +PKI_STACK * PKI_get_ca_service_sk( PKI_X509_CERT *caCert, + char *srv, char *url_s ) { + + PKI_STACK *services = NULL; + PKI_STACK *ret_sk = NULL; + + if( !srv || !caCert ) return ( NULL ); + + if((services = PKI_STACK_new_null()) == NULL ) { + PKI_log_debug("Stack creation error in %s:%d", + __FILE__, __LINE__ ); + return ( NULL ); + } + + PKI_STACK_push( services, strdup( srv )); + + ret_sk = PKI_get_ca_resources( caCert, NULL, NULL, services, url_s ); + + PKI_STACK_free_all( services ); + + return ( ret_sk ); +} + +PKI_STACK * PKI_get_cert_service_sk( PKI_X509_CERT *cert, + char *srv, char *url_s ) { + + PKI_STACK *services = NULL; + PKI_STACK *ret_sk = NULL; + + if( !srv || !cert ) return ( NULL ); + + if((services = PKI_STACK_new_null()) == NULL ) { + PKI_log_debug("Stack creation error"); + return ( NULL ); + } + + PKI_STACK_push( services, strdup( srv )); + + ret_sk = PKI_get_ca_resources( NULL, NULL, cert, services, url_s ); + + PKI_STACK_free_all( services ); + + return ( ret_sk ); +} + +/*! + * \brief Retireve the first configured URL for a PKI service from a PRQP + * server + * + * Retrieve informations about a specific service provided by a CA. + * The function returns a string containing the URL of the requested + * service (if available). + * + * If no URL (char *) is passed, then the library will search for + * the default config file /etc/pki.conf for the configured Resource Query + * Authority (PRQP Server). + * + */ + +char * PKI_get_ca_service( PKI_X509_CERT *caCert, char *srv, char *url_s ) { + + PKI_STACK *services = NULL; + PKI_STACK *ret_sk = NULL; + + char *ret_s = NULL; + + if( !srv || !caCert ) return ( NULL ); + + if((services = PKI_STACK_new_null()) == NULL ) { + PKI_log_debug("Stack creation error in %s:%d", + __FILE__, __LINE__ ); + return ( NULL ); + } + + PKI_log_debug ("Getting Address for %s", srv ); + + PKI_STACK_push( services, strdup(srv) ); + ret_sk = PKI_get_ca_resources( caCert, NULL, NULL, services, url_s ); + + PKI_STACK_free_all( services ); + + if( !ret_sk ) { + PKI_log_debug("No address returned for %s", srv ); + return ( NULL ); + } else { + ret_s = PKI_STACK_pop( ret_sk ); + PKI_STACK_free_all( ret_sk ); + } + + PKI_log_debug ( "Returned address %s", ret_s ); + + return ( ret_s ); +} + +/*! + * \brief Retireve a PRQP response from the passed url or from one of the + * configured RQAs in /etc/pki.conf + */ + +PKI_X509_PRQP_RESP * PKI_DISCOVER_get_resp ( PKI_X509_PRQP_REQ *p, char *url_s ) { + + URL *url = NULL; + + if( p == NULL ) return (NULL); + + if( url_s != NULL ) { + if((url = URL_new( url_s )) == NULL) { + return(NULL); + } + } + + return( PKI_DISCOVER_get_resp_url( p, url )); +} + +/*! + * \brief Retrieve a PRQP Response from a server. + * + * The function returns a PKI_X509_PRQP_RESP if succesful or NULL if an error occurs + * when contacting the PRQP server. + */ + +PKI_X509_PRQP_RESP * PKI_DISCOVER_get_resp_url ( PKI_X509_PRQP_REQ *p, URL *url ) { + + PKI_X509_PRQP_RESP * ret = NULL; + + char line[1024], name[1024], addr[1024]; + + FILE *file; + + if( !p || !p->value ) { + PKI_log_debug( "WARNING, no PRQP request when trying to get" + " the response!"); + return ( NULL ); + } + + if( url ) { + if (( ret = PKI_X509_PRQP_RESP_get_http ( url, p, 0)) != NULL ) { + return ret; + } else { + return NULL; + } + } + + file = fopen( PKI_PRQP_LIB_CONF_FILE, "r"); + if( !file ) { + PKI_log_debug( "WARNING, PRQP config file %s not found!", + PKI_PRQP_LIB_CONF_FILE ); + return ( NULL ); + } + + while(!feof(file)) { + if( fgets(line, sizeof(line), file) ) { + if((memcmp(line, ";", 1) == 0) || + (memcmp(line, "#", 1) == 0)) + continue; + + if(sscanf(line, "%1023s %1023s", name, addr ) > 1 ) { + char *full_url_s = NULL; + size_t full_len = 0; + + if((strcmp_nocase( name, + PKI_PRQP_LIB_CONF_ENTRY_LONG)==0) || + (strcmp_nocase ( name, + PKI_PRQP_LIB_CONF_ENTRY_SHORT ) + == 0)) { + + URL *l_url = NULL; + + full_len = sizeof( addr ) + 12; + full_url_s = PKI_Malloc ( full_len ); + snprintf( full_url_s, full_len, "http://%s", addr ); + if ( strchr ( addr, ':') == NULL ) { + strncat ( full_url_s, ":830", full_len ); + } + + PKI_log_debug( "Trying PRQP RQA -> %s", + full_url_s ); + + if((l_url = URL_new( full_url_s )) == NULL) { + PKI_log_debug("Can not parse address %s", + full_url_s ); + PKI_Free ( full_url_s ); + continue; + } + + if( l_url->port <= 0 ) + l_url->port = PKI_PRQP_DEFAULT_PORT; + + l_url->proto = URI_PROTO_HTTP; + ret = PKI_X509_PRQP_RESP_get_http ( l_url, p, 0); + + PKI_Free ( full_url_s ); + + if( ret == NULL ) { + PKI_log( PKI_LOG_ERR, + "Can not get response " + "from server (%s:%d)!", + l_url->addr, + l_url->port); + URL_free ( l_url ); + } else { + /* Exit the cycle */ + PKI_log_debug("Got PRQP response from server"); + URL_free ( l_url ); + fclose(file); + return ret; + } + } + } + } + } + + fclose(file); + + return ret; +} + diff --git a/src/pkix/scep/Makefile.am b/src/pkix/scep/Makefile.am new file mode 100644 index 00000000..5f99f77a --- /dev/null +++ b/src/pkix/scep/Makefile.am @@ -0,0 +1,32 @@ +## OpenCA Makefile - by Massimiliano Pala +## (c) 1999-2007 by Massimiliano Pala and OpenCA Project +## All Rights Reserved + +TOP = .. +include $(TOP)/global-vars + +BASE_DEFS = + +DEFS = $(OPENCA_DEFS) + +MYSCEP = \ + pki_x509_scep_attr.c \ + pki_x509_scep_data.c \ + pki_x509_scep_asn1.c \ + pki_x509_scep_msg.c + +AM_CPPFLAGS = -I$(TOP) \ + $(openssl_cflags) \ + $(libxml2_cflags) \ + $(COND_INCLUDES) + +# bin_PROGRAMS = scep +# scep_SOURCES = $(MYSCEP) scep.c +# scep_LDADD = $(OPENSSL_LIBS) +# scep_CFLAGS = $(BUILD_LIBPKI_CFLAGS) + + +noinst_LTLIBRARIES = libpki-scep.la +libpki_scep_la_SOURCES = $(MYSCEP) +libpki_scep_la_CFLAGS = $(BUILD_LIBPKI_CFLAGS) + diff --git a/src/pkix/scep/Makefile.in b/src/pkix/scep/Makefile.in new file mode 100644 index 00000000..1a351e6d --- /dev/null +++ b/src/pkix/scep/Makefile.in @@ -0,0 +1,800 @@ +# Makefile.in generated by automake 1.16.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = src/scep +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(SHELL) $(top_srcdir)/build/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/src/libpki/config.h \ + $(top_builddir)/src/libpki/libpki_enables.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +libpki_scep_la_LIBADD = +am__objects_1 = libpki_scep_la-pki_x509_scep_attr.lo \ + libpki_scep_la-pki_x509_scep_data.lo \ + libpki_scep_la-pki_x509_scep_asn1.lo \ + libpki_scep_la-pki_x509_scep_msg.lo +am_libpki_scep_la_OBJECTS = $(am__objects_1) +libpki_scep_la_OBJECTS = $(am_libpki_scep_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libpki_scep_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(libpki_scep_la_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o \ + $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src/libpki +depcomp = $(SHELL) $(top_srcdir)/build/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = \ + ./$(DEPDIR)/libpki_scep_la-pki_x509_scep_asn1.Plo \ + ./$(DEPDIR)/libpki_scep_la-pki_x509_scep_attr.Plo \ + ./$(DEPDIR)/libpki_scep_la-pki_x509_scep_data.Plo \ + ./$(DEPDIR)/libpki_scep_la-pki_x509_scep_msg.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libpki_scep_la_SOURCES) +DIST_SOURCES = $(libpki_scep_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/build/depcomp \ + $(top_srcdir)/build/mkinstalldirs +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_DATE = @BUILD_DATE@ +BUILD_DATE_FULL = @BUILD_DATE_FULL@ +BUILD_DATE_PRETTY = @BUILD_DATE_PRETTY@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CHMOD = @CHMOD@ +CHOWN = @CHOWN@ +CP = @CP@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CPU = @CPU@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CXX = @CXX@ +CYGPATH_W = @CYGPATH_W@ +DATE = @DATE@ +DEFS = $(OPENCA_DEFS) +DEPDIR = @DEPDIR@ +DESTDIR = @DESTDIR@ +DIST_NAME = @DIST_NAME@ +DIST_VERSION = @DIST_VERSION@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +GZIP = @GZIP@ +HAS_PKGCONF = @HAS_PKGCONF@ +INSTALL = @INSTALL@ +INSTALL_BUILDER = @INSTALL_BUILDER@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKE = @MAKE@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR = @MKDIR@ +MKDIR_P = @MKDIR_P@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PDFLATEX = @PDFLATEX@ +PERL = @PERL@ +PG_CONFIG = @PG_CONFIG@ +PG_CPPFLAGS = @PG_CPPFLAGS@ +PKGMK = @PKGMK@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POD2MAN = @POD2MAN@ +PWD = @PWD@ +RANLIB = @RANLIB@ +RC = @RC@ +RPM = @RPM@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TAR = @TAR@ +TODAY = @TODAY@ +VERSION = @VERSION@ +ZIP = @ZIP@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_aux_dir = @ac_aux_dir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +arch_target = @arch_target@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +composite_cflags = @composite_cflags@ +composite_ldadd = @composite_ldadd@ +composite_ldflags = @composite_ldflags@ +conf_dir = @conf_dir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +day = @day@ +dist_group = @dist_group@ +dist_user = @dist_user@ +docdir = @docdir@ +dvidir = @dvidir@ +enable_debug = @enable_debug@ +etc_dir = @etc_dir@ +exec_prefix = @exec_prefix@ +extra_checks = @extra_checks@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +hr = @hr@ +htmldir = @htmldir@ +iface_age = @iface_age@ +iface_current = @iface_current@ +iface_revision = @iface_revision@ +iface_version = @iface_version@ +include_dir = @include_dir@ +include_prefix = @include_prefix@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +kmf_cflags = @kmf_cflags@ +kmf_ldadd = @kmf_ldadd@ +kmf_libflags = @kmf_libflags@ +kmf_prefix = @kmf_prefix@ +ldap_cflags = @ldap_cflags@ +ldap_ldadd = @ldap_ldadd@ +ldap_ldflags = @ldap_ldflags@ +ldap_prefix = @ldap_prefix@ +ldap_vendor = @ldap_vendor@ +lib_major = @lib_major@ +lib_micro = @lib_micro@ +lib_minor = @lib_minor@ +lib_prefix = @lib_prefix@ +lib_revision = @lib_revision@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libpki_cflags = @libpki_cflags@ +libpki_ldadd = @libpki_ldadd@ +libpki_ldflags = @libpki_ldflags@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +min = @min@ +mkdir_p = @mkdir_p@ +mon = @mon@ +my_cflags = @my_cflags@ +my_ldadd = @my_ldadd@ +my_ldflags = @my_ldflags@ +myarch = @myarch@ +mybits = @mybits@ +mybits_install = @mybits_install@ +mysql_cflags = @mysql_cflags@ +mysql_config = @mysql_config@ +mysql_ldadd = @mysql_ldadd@ +mysql_ldflags = @mysql_ldflags@ +mysql_prefix = @mysql_prefix@ +oldincludedir = @oldincludedir@ +openssl_cflags = @openssl_cflags@ +openssl_include = @openssl_include@ +openssl_ldadd = @openssl_ldadd@ +openssl_ldflags = @openssl_ldflags@ +openssl_prefix = @openssl_prefix@ +openssl_static_libs = @openssl_static_libs@ +oqs_cflags = @oqs_cflags@ +oqs_ldadd = @oqs_ldadd@ +oqs_ldflags = @oqs_ldflags@ +oqsprov_cflags = @oqsprov_cflags@ +oqsprov_ldadd = @oqsprov_ldadd@ +oqsprov_ldflags = @oqsprov_ldflags@ +package_build = @package_build@ +package_prefix = @package_prefix@ +pdfdir = @pdfdir@ +pg_cflags = @pg_cflags@ +pg_config = @pg_config@ +pg_ldadd = @pg_ldadd@ +pg_ldflags = @pg_ldflags@ +pg_prefix = @pg_prefix@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pthread_opts = @pthread_opts@ +resolv_ldadd = @resolv_ldadd@ +rpath = @rpath@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sdkver = @sdkver@ +sec = @sec@ +sharedstatedir = @sharedstatedir@ +shlext = @shlext@ +shlib_history = @shlib_history@ +shlib_version = @shlib_version@ +srcdir = @srcdir@ +sys_cflags = @sys_cflags@ +sys_ldadd = @sys_ldadd@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +test_libs = @test_libs@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +txt_revision = @txt_revision@ +xml2_cflags = @xml2_cflags@ +xml2_config = @xml2_config@ +xml2_include = @xml2_include@ +xml2_ldadd = @xml2_ldadd@ +xml2_ldflags = @xml2_ldflags@ +xml2_prefix = @xml2_prefix@ +yr = @yr@ +TOP = .. +BASE_DEFS = +MYSCEP = \ + pki_x509_scep_attr.c \ + pki_x509_scep_data.c \ + pki_x509_scep_asn1.c \ + pki_x509_scep_msg.c + +AM_CPPFLAGS = -I$(TOP) \ + $(openssl_cflags) \ + $(libxml2_cflags) \ + $(COND_INCLUDES) + + +# bin_PROGRAMS = scep +# scep_SOURCES = $(MYSCEP) scep.c +# scep_LDADD = $(OPENSSL_LIBS) +# scep_CFLAGS = $(BUILD_LIBPKI_CFLAGS) +noinst_LTLIBRARIES = libpki-scep.la +libpki_scep_la_SOURCES = $(MYSCEP) +libpki_scep_la_CFLAGS = $(BUILD_LIBPKI_CFLAGS) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/scep/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/scep/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libpki-scep.la: $(libpki_scep_la_OBJECTS) $(libpki_scep_la_DEPENDENCIES) $(EXTRA_libpki_scep_la_DEPENDENCIES) + $(AM_V_CCLD)$(libpki_scep_la_LINK) $(libpki_scep_la_OBJECTS) $(libpki_scep_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_scep_la-pki_x509_scep_asn1.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_scep_la-pki_x509_scep_attr.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_scep_la-pki_x509_scep_data.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_scep_la-pki_x509_scep_msg.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +libpki_scep_la-pki_x509_scep_attr.lo: pki_x509_scep_attr.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_scep_la_CFLAGS) $(CFLAGS) -MT libpki_scep_la-pki_x509_scep_attr.lo -MD -MP -MF $(DEPDIR)/libpki_scep_la-pki_x509_scep_attr.Tpo -c -o libpki_scep_la-pki_x509_scep_attr.lo `test -f 'pki_x509_scep_attr.c' || echo '$(srcdir)/'`pki_x509_scep_attr.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_scep_la-pki_x509_scep_attr.Tpo $(DEPDIR)/libpki_scep_la-pki_x509_scep_attr.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pki_x509_scep_attr.c' object='libpki_scep_la-pki_x509_scep_attr.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_scep_la_CFLAGS) $(CFLAGS) -c -o libpki_scep_la-pki_x509_scep_attr.lo `test -f 'pki_x509_scep_attr.c' || echo '$(srcdir)/'`pki_x509_scep_attr.c + +libpki_scep_la-pki_x509_scep_data.lo: pki_x509_scep_data.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_scep_la_CFLAGS) $(CFLAGS) -MT libpki_scep_la-pki_x509_scep_data.lo -MD -MP -MF $(DEPDIR)/libpki_scep_la-pki_x509_scep_data.Tpo -c -o libpki_scep_la-pki_x509_scep_data.lo `test -f 'pki_x509_scep_data.c' || echo '$(srcdir)/'`pki_x509_scep_data.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_scep_la-pki_x509_scep_data.Tpo $(DEPDIR)/libpki_scep_la-pki_x509_scep_data.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pki_x509_scep_data.c' object='libpki_scep_la-pki_x509_scep_data.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_scep_la_CFLAGS) $(CFLAGS) -c -o libpki_scep_la-pki_x509_scep_data.lo `test -f 'pki_x509_scep_data.c' || echo '$(srcdir)/'`pki_x509_scep_data.c + +libpki_scep_la-pki_x509_scep_asn1.lo: pki_x509_scep_asn1.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_scep_la_CFLAGS) $(CFLAGS) -MT libpki_scep_la-pki_x509_scep_asn1.lo -MD -MP -MF $(DEPDIR)/libpki_scep_la-pki_x509_scep_asn1.Tpo -c -o libpki_scep_la-pki_x509_scep_asn1.lo `test -f 'pki_x509_scep_asn1.c' || echo '$(srcdir)/'`pki_x509_scep_asn1.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_scep_la-pki_x509_scep_asn1.Tpo $(DEPDIR)/libpki_scep_la-pki_x509_scep_asn1.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pki_x509_scep_asn1.c' object='libpki_scep_la-pki_x509_scep_asn1.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_scep_la_CFLAGS) $(CFLAGS) -c -o libpki_scep_la-pki_x509_scep_asn1.lo `test -f 'pki_x509_scep_asn1.c' || echo '$(srcdir)/'`pki_x509_scep_asn1.c + +libpki_scep_la-pki_x509_scep_msg.lo: pki_x509_scep_msg.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_scep_la_CFLAGS) $(CFLAGS) -MT libpki_scep_la-pki_x509_scep_msg.lo -MD -MP -MF $(DEPDIR)/libpki_scep_la-pki_x509_scep_msg.Tpo -c -o libpki_scep_la-pki_x509_scep_msg.lo `test -f 'pki_x509_scep_msg.c' || echo '$(srcdir)/'`pki_x509_scep_msg.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_scep_la-pki_x509_scep_msg.Tpo $(DEPDIR)/libpki_scep_la-pki_x509_scep_msg.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pki_x509_scep_msg.c' object='libpki_scep_la-pki_x509_scep_msg.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_scep_la_CFLAGS) $(CFLAGS) -c -o libpki_scep_la-pki_x509_scep_msg.lo `test -f 'pki_x509_scep_msg.c' || echo '$(srcdir)/'`pki_x509_scep_msg.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/libpki_scep_la-pki_x509_scep_asn1.Plo + -rm -f ./$(DEPDIR)/libpki_scep_la-pki_x509_scep_attr.Plo + -rm -f ./$(DEPDIR)/libpki_scep_la-pki_x509_scep_data.Plo + -rm -f ./$(DEPDIR)/libpki_scep_la-pki_x509_scep_msg.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/libpki_scep_la-pki_x509_scep_asn1.Plo + -rm -f ./$(DEPDIR)/libpki_scep_la-pki_x509_scep_attr.Plo + -rm -f ./$(DEPDIR)/libpki_scep_la-pki_x509_scep_data.Plo + -rm -f ./$(DEPDIR)/libpki_scep_la-pki_x509_scep_msg.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-noinstLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + +include $(TOP)/global-vars + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/pkix/scep/pki_x509_scep_asn1.c b/src/pkix/scep/pki_x509_scep_asn1.c new file mode 100644 index 00000000..e0cce6b7 --- /dev/null +++ b/src/pkix/scep/pki_x509_scep_asn1.c @@ -0,0 +1,17 @@ +/* SCEP ASN.1 implementation + * (c) 2003-2009 by Massimiliano Pala and OpenCA Group + * All Rights Reserved + * + * This software is released under the OpenCA License included + * in the archive. You can not remove this copyright notice. + */ + +#include + +ASN1_SEQUENCE(SCEP_ISSUER_AND_SUBJECT) = { + ASN1_SIMPLE(SCEP_ISSUER_AND_SUBJECT, issuer, X509_NAME), + ASN1_SIMPLE(SCEP_ISSUER_AND_SUBJECT, subject, X509_NAME) +} ASN1_SEQUENCE_END(SCEP_ISSUER_AND_SUBJECT) + +IMPLEMENT_ASN1_FUNCTIONS(SCEP_ISSUER_AND_SUBJECT) + diff --git a/src/pkix/scep/pki_x509_scep_attr.c b/src/pkix/scep/pki_x509_scep_attr.c new file mode 100644 index 00000000..d9815473 --- /dev/null +++ b/src/pkix/scep/pki_x509_scep_attr.c @@ -0,0 +1,563 @@ +/* + * OpenCA SCEP -- signed attributes handling routines + * (c) 2009 by Massimiliano Pala and OpenCA Group + * + */ + +#include + +#define SCEP_CONF_LIST_SIZE 8 + +SCEP_CONF_ATTRIBUTE SCEP_ATTRIBUTE_list [SCEP_CONF_LIST_SIZE] = { + { SCEP_ATTRIBUTE_MESSAGE_TYPE, "2.16.840.1.113733.1.9.2", + "scepMessageType", "SCEP Message Type", -1 }, + { SCEP_ATTRIBUTE_PKI_STATUS, "2.16.840.1.113733.1.9.3", + "pkiStatus", "Status", -1 }, + { SCEP_ATTRIBUTE_FAIL_INFO, "2.16.840.1.113733.1.9.4", + "failInfo", "Failure Info", -1 }, + { SCEP_ATTRIBUTE_SENDER_NONCE, "2.16.840.1.113733.1.9.5", + "senderNonce", "Sender Nonce", -1 }, + { SCEP_ATTRIBUTE_RECIPIENT_NONCE, "2.16.840.1.113733.1.9.6", + "recipientNonce", "Recipient Nonce", -1 }, + { SCEP_ATTRIBUTE_TRANS_ID, "2.16.840.1.113733.1.9.7", + "transId", "Transaction Identifier", -1 }, + { SCEP_ATTRIBUTE_EXTENSION_REQ, "2.16.840.1.113733.1.9.8", + "extensionReq", "Extension Request", -1 }, + { SCEP_ATTRIBUTE_PROXY_AUTH, "1.3.6.1.4.1.4263.5.5", + "proxyAuth", "Proxy Authenticator", -1 }, +}; + +void PKI_X509_SCEP_init ( void ) { + int i = 0; + int nid = NID_undef; + + SCEP_CONF_ATTRIBUTE *curr_oid = NULL; + + i = 0; + while( i < SCEP_CONF_LIST_SIZE ) { + curr_oid = &SCEP_ATTRIBUTE_list[i]; + if(( nid = OBJ_create(curr_oid->oid_s, curr_oid->descr, + curr_oid->long_descr)) == NID_undef) { + return; + } + + curr_oid->nid = nid; + i++; + } + + return; +} + +/*! \brief Returns the SCEP_ATTRIBUTE_TYPE from the attribute name */ + +SCEP_ATTRIBUTE_TYPE PKI_X509_SCEP_ATTRIBUTE_get_txt(const char * txt) { + + SCEP_CONF_ATTRIBUTE *curr = NULL; + int i = 0; + + while( i < SCEP_CONF_LIST_SIZE ) { + + // Gets the i-th attribute + curr = &SCEP_ATTRIBUTE_list[i]; + + // Check if the attribute matches + if (strcmp_nocase(curr->descr, txt) == 0) break; + + i++; + } + + // Returns the type value + if (curr) return (SCEP_ATTRIBUTE_TYPE)curr->attr_type; + + // Not found + return SCEP_ATTRIBUTE_TYPE_UNKNOWN; +} + +/*! \brief Returns the PKI_ID of the specified SCEP_ATTRIBUTE_TYPE */ + +PKI_ID PKI_X509_SCEP_ATTRIBUTE_get_nid ( SCEP_ATTRIBUTE_TYPE num ) { + + SCEP_CONF_ATTRIBUTE *curr = NULL; + int i = 0; + + i = 0; + while( i < SCEP_CONF_LIST_SIZE ) { + curr = &SCEP_ATTRIBUTE_list[i]; + if ( curr->attr_type == num ) + break; + i++; + } + + if ( curr ) return curr->nid; + + return NID_undef; +} + +/*! \brief Returns the PKI_OID for the specified SCEP attribute */ + +PKI_OID *PKI_X509_SCEP_MSG_get_oid ( SCEP_ATTRIBUTE_TYPE scep_attribute ) { + + SCEP_CONF_ATTRIBUTE *curr = NULL; + + int i = 0; + + i = 0; + while( i < SCEP_CONF_LIST_SIZE ) { + curr = &SCEP_ATTRIBUTE_list[i]; + if ( curr->attr_type == scep_attribute ) + break; + i++; + } + + if ( curr ) return PKI_OID_get ( curr->descr ); + + return NULL; +} + +/*! \brief Sets the message type attribute in a SCEP message (signed P7) */ +int PKI_X509_SCEP_MSG_set_attribute(PKI_X509_SCEP_MSG * msg, + SCEP_ATTRIBUTE_TYPE type, + const unsigned char * const data, + size_t size) { + + PKI_X509_ATTRIBUTE *a = NULL; + PKI_ID id = 0; + + if (!msg || !data) return PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + + // Gets the Type of the attribute + if ((id = PKI_X509_SCEP_ATTRIBUTE_get_nid ( type )) == NID_undef ) { + return PKI_ERROR(PKI_ERR_SCEP_ATTRIBUTE_UNKNOWN, NULL); + } + + // Creates the Attribute based on the type + switch (type) { + + // PRINTABLESTRING Attributes + case SCEP_ATTRIBUTE_MESSAGE_TYPE: + case SCEP_ATTRIBUTE_PKI_STATUS: + case SCEP_ATTRIBUTE_FAIL_INFO: + case SCEP_ATTRIBUTE_TRANS_ID: + case SCEP_ATTRIBUTE_EXTENSION_REQ: + case SCEP_ATTRIBUTE_PROXY_AUTH: { + a = PKI_X509_ATTRIBUTE_new(id, + V_ASN1_PRINTABLESTRING, + data, + size ); + } break; + + // OCTET_STRING Attributes + case SCEP_ATTRIBUTE_SENDER_NONCE: + case SCEP_ATTRIBUTE_RECIPIENT_NONCE: { + a = PKI_X509_ATTRIBUTE_new(id, + V_ASN1_OCTET_STRING, + data, + size); + } break; + + default: + return PKI_ERROR(PKI_ERR_SCEP_ATTRIBUTE_UNKNOWN, NULL); + } + + // Checks we have a valid object + if (!a) return PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + + // Removes the attribute (if already present) + PKI_X509_PKCS7_delete_signed_attribute(msg, id); + + // Returns the result of adding the signed attribute + return PKI_X509_PKCS7_add_signed_attribute( msg, a); +} + +/*! \brief Adds an attribute (identified by its name) to a SCEP message */ + +int PKI_X509_SCEP_MSG_set_attribute_by_name(PKI_X509_SCEP_MSG * msg, + const char * const name, + const unsigned char * const data, + size_t size) { + + PKI_ID type = 0; + + // Input Check + if (!msg || !data || !name) + return PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + + // Gets the Attribute Type + if ((type = PKI_X509_SCEP_ATTRIBUTE_get_txt(name)) == -1) + return PKI_ERROR(PKI_ERR_SCEP_ATTRIBUTE_UNKNOWN, NULL); + + // Sets the Attribute in the Message + return PKI_X509_SCEP_MSG_set_attribute(msg, type, data, size); + +} + +/*! \brief Adds the specified attribute (int) as a string */ + +int PKI_X509_SCEP_MSG_set_attribute_int(PKI_X509_SCEP_MSG * msg, + PKI_ID id, + int val) { + + char buf[BUFF_MAX_SIZE]; + + if (!msg ) return PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + + snprintf(buf, sizeof(buf), "%d%c", val, '\x0'); + + return PKI_X509_SCEP_MSG_set_attribute(msg, id, + (const unsigned char*) buf, strlen(buf)); +} + +/*! \brief Returns the value of the specified attribute in a PKI_MEM */ + +PKI_MEM * PKI_X509_SCEP_MSG_get_attr_value(const PKI_X509_SCEP_MSG * const msg, + SCEP_ATTRIBUTE_TYPE type) { + + const PKI_X509_ATTRIBUTE *attr = NULL; + PKI_MEM *ret = NULL; + + const PKI_STRING *st = NULL; + int nid = NID_undef; + + // Input Check + if (!msg || msg->value) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return NULL; + } + + // Attribute Type Check + if ((nid = PKI_X509_SCEP_ATTRIBUTE_get_nid(type)) == NID_undef) { + PKI_ERROR(PKI_ERR_SCEP_ATTRIBUTE_UNKNOWN, NULL); + return NULL; + } + + // Retrieves the Signed Attribute from the message + if ((attr = PKI_X509_PKCS7_get_signed_attribute(msg, nid)) == NULL) { + + // Attribute not present + return NULL; + } + + // If we have a value, let's return it in a PKI_MEM container + if ((st = PKI_X509_ATTRIBUTE_get_value(attr)) != NULL) { + + // Build the container + ret = PKI_MEM_new_null (); + ret->data = PKI_Malloc((size_t) st->length); + ret->size = (size_t) st->length; + + // Copy the data from the attribute to the container + memcpy(ret->data, st->data, (size_t)st->length); + } + + // Returns the container + return ret; +} + +int PKI_X509_SCEP_MSG_get_attr_value_int(const PKI_X509_SCEP_MSG * const msg, + SCEP_ATTRIBUTE_TYPE type) { + + + PKI_MEM *mem = NULL; + int ret = -1; + + // Input Checks + if (!msg || !msg->value) return -1; + + // Gets the Value from the message + if ((mem = PKI_X509_SCEP_MSG_get_attr_value(msg, type)) == NULL) { + + // Attribute not found, let's return -1 as the error value + return -1; + } + + // If we have a good value, let's convert it to an integer + if ( mem && mem->data && mem->size > 0 ) { + + // Gets the integer + ret = atoi((const char *) mem->data); + } + + // Free the allocated memory + PKI_MEM_free(mem); + + // Returns the Attribute value as an integer + return ret; +} + + +/* ------------------------ Specific Attributes ------------------------ */ + +/*! \brief Generates a new PKI_MEM suitable for the transId of a SCEP message */ + +PKI_MEM *PKI_X509_SCEP_MSG_new_trans_id(const PKI_X509_KEYPAIR * key) { + + CRYPTO_DIGEST *dgst = NULL; + PKI_MEM *mem = NULL; + + if (!key || !key->value ) return NULL; + + if((dgst = PKI_X509_KEYPAIR_pub_digest(key, PKI_DIGEST_ALG_DEFAULT )) + == NULL ) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, + "Can not retrieve digest of public key (%d)", + PKI_DIGEST_ALG_DEFAULT); + + return NULL; + } + + // Allocates a new PKI_MEM container + if(( mem = PKI_MEM_new_null()) == NULL ) { + + // Memory Allocation Error + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + PKI_DIGEST_free ( dgst ); + return NULL; + } + + // Retrieves the parsed digest value + if ((mem->data = (unsigned char *) PKI_DIGEST_get_parsed(dgst)) + == NULL ) { + // Error while getting the parsed digest + PKI_ERROR(PKI_ERR_DIGEST_VALUE_NULL, NULL); + + // Free Allocated Memory + PKI_MEM_free(mem); + PKI_DIGEST_free(dgst); + + // Nothing to return + return NULL; + } + + // Sets the Size of the data + mem->size = strlen((const char *) mem->data); + + // Free the DIGEST structure + if (dgst) PKI_DIGEST_free(dgst); + + // All Done + return mem; +} + +/*! \brief Sets the transactionId attribute in a SCEP message */ + +int PKI_X509_SCEP_MSG_set_trans_id(PKI_X509_SCEP_MSG * msg, + const PKI_MEM * const mem) { + + int ret = PKI_OK; + + // Input Checks + if (!msg || !mem) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return ( PKI_ERR ); + } + + // Sets the Attribute + ret = PKI_X509_SCEP_MSG_set_attribute(msg, + SCEP_ATTRIBUTE_TRANS_ID, + mem->data, + mem->size ); + + // Returns the return code from setting the attribute + return ret; +} + +char * PKI_X509_SCEP_MSG_get_trans_id(const PKI_X509_SCEP_MSG * const msg) { + + PKI_MEM * mem = NULL; + char * ret = NULL; + + if((mem = PKI_X509_SCEP_MSG_get_attr_value(msg, + SCEP_ATTRIBUTE_TRANS_ID)) == NULL) { + return NULL; + } + + // Checks the returned MEM structure for data + if (!mem->data || mem->size <= 0) { + PKI_MEM_free(mem); + return NULL; + } + + // Get a reference + ret = (char *) mem->data; + mem->data = NULL; + mem->size = 0; + + // Releases the PKI_MEM structure + PKI_MEM_free(mem); + + // Returns the duplicated value + return ret; +} + +/*! \brief Sets the senderNonce attribute in a SCEP message */ + +int PKI_X509_SCEP_MSG_set_sender_nonce(PKI_X509_SCEP_MSG * msg, + const PKI_MEM * const mem) { + + int ret = PKI_OK; + + // Input Check + if (!msg) return PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + + if (mem != NULL) { + ret = PKI_X509_SCEP_MSG_set_attribute(msg, + SCEP_ATTRIBUTE_SENDER_NONCE, + mem->data, + mem->size); + } else { + + PKI_MEM * aMem = NULL; + // Locally allocated entry + + // Allocates the local mem structure + if ((aMem = PKI_MEM_new(NONCE_SIZE)) == NULL) + return PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + + // Use random bytes to fill in the data + RAND_bytes(aMem->data, NONCE_SIZE); + + // Sets the Attribute + ret = PKI_X509_SCEP_MSG_set_attribute(msg, + SCEP_ATTRIBUTE_SENDER_NONCE, + aMem->data, + aMem->size); + + // Free locally allocated memory + if (aMem) PKI_MEM_free(aMem); + + } + + return ret; +} + + +/*! \brief Sets the recipientNonce attribute from a SCEP message */ + +int PKI_X509_SCEP_MSG_set_recipient_nonce(PKI_X509_SCEP_MSG * msg, + const PKI_MEM * const mem) { + + int ret = PKI_OK; + + // Input Check + if (!msg || !msg->value) return PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + + if( mem != NULL ) { + ret = PKI_X509_SCEP_MSG_set_attribute(msg, + SCEP_ATTRIBUTE_RECIPIENT_NONCE, + mem->data, + mem->size ); + } else { + + PKI_MEM * aMem = NULL; + // Locally allocated structure + + // Allocate the structure + if ((aMem = PKI_MEM_new(NONCE_SIZE)) == NULL) + return PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + + // Fill in with random bytes + RAND_bytes(aMem->data, NONCE_SIZE); + + // Sets the attribute + ret = PKI_X509_SCEP_MSG_set_attribute(msg, + SCEP_ATTRIBUTE_RECIPIENT_NONCE, + aMem->data, + aMem->size); + + // Free locally allocated memory + PKI_MEM_free(aMem); + } + + // All Done + return ret; +} + +/*! \brief Sets the messageType attribute in a SCEP message */ + +int PKI_X509_SCEP_MSG_set_type(PKI_X509_SCEP_MSG * msg, + SCEP_MESSAGE_TYPE type) { + + return PKI_X509_SCEP_MSG_set_attribute_int(msg, + SCEP_ATTRIBUTE_MESSAGE_TYPE, + type); +} + +/*! \brief Returns the messageType attribute from a SCEP message */ + +SCEP_MESSAGE_TYPE PKI_X509_SCEP_MSG_get_type(const PKI_X509_SCEP_MSG * const msg) { + + return PKI_X509_SCEP_MSG_get_attr_value_int(msg, + SCEP_ATTRIBUTE_MESSAGE_TYPE); +} + +/*! \brief Sets the pkiStatus attribute in a SCEP message */ + +int PKI_X509_SCEP_MSG_set_status(PKI_X509_SCEP_MSG * msg, + SCEP_STATUS status) { + + return PKI_X509_SCEP_MSG_set_attribute_int(msg, + SCEP_ATTRIBUTE_PKI_STATUS, + (int)status); +} + + +/*! \brief Returns the pkiStatus attribute from a SCEP message */ + +SCEP_STATUS PKI_X509_SCEP_MSG_get_status(const PKI_X509_SCEP_MSG * const msg) { + + return (SCEP_STATUS) PKI_X509_SCEP_MSG_get_attr_value_int(msg, + SCEP_ATTRIBUTE_PKI_STATUS); +} + +/*! \brief Sets the failInfo attribute in a SCEP message */ + +int PKI_X509_SCEP_MSG_set_failinfo(PKI_X509_SCEP_MSG * msg, + int fail) { + + return PKI_X509_SCEP_MSG_set_attribute_int(msg, + SCEP_ATTRIBUTE_FAIL_INFO, + fail); +} + +/*! \brief Returns the failInfo attribute from a SCEP message */ + +SCEP_FAILURE PKI_X509_SCEP_MSG_get_failinfo(const PKI_X509_SCEP_MSG * const msg) { + + return (SCEP_FAILURE) PKI_X509_SCEP_MSG_get_attr_value_int(msg, + SCEP_ATTRIBUTE_FAIL_INFO); +} + + +/*! \brief Returns the senderNonce attribute from a SCEP message */ + +PKI_MEM *PKI_X509_SCEP_MSG_get_sender_nonce(const PKI_X509_SCEP_MSG * const msg) { + + return PKI_X509_SCEP_MSG_get_attr_value(msg, + SCEP_ATTRIBUTE_SENDER_NONCE); +} + +/*! \brief Returns the recipientNonce attribute from a SCEP message */ + +PKI_MEM *PKI_X509_SCEP_MSG_get_recipient_nonce(PKI_X509_SCEP_MSG * const msg) { + + return PKI_X509_SCEP_MSG_get_attr_value ( msg, + SCEP_ATTRIBUTE_RECIPIENT_NONCE ); +} + +/*! \brief Sets the proxyAuthenticator attribute from a SCEP message */ + +int PKI_X509_SCEP_MSG_set_proxy(PKI_X509_SCEP_MSG * msg, + int auth) { + + return PKI_X509_SCEP_MSG_set_attribute_int(msg, + SCEP_ATTRIBUTE_PROXY_AUTH, + auth ); +} + +int PKI_X509_SCEP_MSG_get_proxy(const PKI_X509_SCEP_MSG * const msg) { + + return PKI_X509_SCEP_MSG_get_attr_value_int(msg, + SCEP_ATTRIBUTE_PROXY_AUTH ); + +} + diff --git a/src/pkix/scep/pki_x509_scep_data.c b/src/pkix/scep/pki_x509_scep_data.c new file mode 100644 index 00000000..1c73eff1 --- /dev/null +++ b/src/pkix/scep/pki_x509_scep_data.c @@ -0,0 +1,91 @@ +/* SCEP msg handling + * (c) 2009 by Massimiliano Pala and OpenCA Labs + * All Rights Reserved + */ + +#include + +/*! \brief Generates a new SCEP_DATA */ + +PKI_X509_SCEP_DATA * PKI_X509_SCEP_DATA_new ( void ) { + + return PKI_X509_PKCS7_new ( PKI_X509_PKCS7_TYPE_ENCRYPTED ); +} + +/*! \brief Frees the memory associated with a PKI_X509_SCEP_DATA */ + +void PKI_X509_SCEP_DATA_free ( PKI_X509_SCEP_DATA *data ) { + + PKI_X509_PKCS7_free ( data ); + + return; +} + + +/*! \brief Adds a recipient to a SCEP_DATA */ + +int PKI_X509_SCEP_DATA_add_recipient ( PKI_X509_SCEP_DATA *data, + PKI_X509_CERT *recipient ) { + return PKI_X509_PKCS7_add_recipient ( data, recipient ); +} + +/*! \brief Adds a stack of recipients for a SCEP_DATA */ + +int PKI_X509_SCEP_DATA_set_recipients ( PKI_X509_SCEP_DATA *data, + PKI_X509_CERT_STACK *sk ) { + return PKI_X509_PKCS7_set_recipients ( data, sk ); +} + +/*! \brief Sets the content of the SCEP_DATA via a PKI_X509 object */ + +int PKI_X509_SCEP_DATA_set_x509_obj ( PKI_X509_SCEP_DATA *data, PKI_X509 *obj ) +{ + PKI_MEM *mem = NULL; + int ret = PKI_ERR; + + if ( !data || !data->value || !obj || !obj->value ) + return PKI_ERR; + + if (( mem = PKI_X509_put_mem ( obj, PKI_DATA_FORMAT_ASN1, NULL, NULL )) == NULL ) + return PKI_ERROR(PKI_ERR_GENERAL, NULL); + + ret = PKI_X509_SCEP_DATA_set_raw_data ( data, mem->data, (ssize_t) mem->size ); + + PKI_MEM_free ( mem ); + + return ret; +} + +/*! \brief Sets the content of the SCEP_DATA via a SCEP_ISSUER_AND_SUBJECT */ + +int PKI_X509_SCEP_DATA_set_ias ( PKI_X509_SCEP_DATA *scep_data, SCEP_ISSUER_AND_SUBJECT *ias ) +{ + unsigned char *data = NULL; + ssize_t size = 0; + + if ( !scep_data || !scep_data->value || !ias ) return PKI_ERR; + + if( (size = i2d_SCEP_ISSUER_AND_SUBJECT(ias, NULL)) <= 0 ) return PKI_ERR; + + if ((data = ( unsigned char * ) PKI_Malloc ( (size_t) size )) == NULL ) return PKI_ERR; + + if (i2d_SCEP_ISSUER_AND_SUBJECT( ias, &data ) <= 0 ) + { + PKI_Free ( data ); + return PKI_ERR; + } + + return PKI_X509_SCEP_DATA_set_raw_data ( scep_data, data, size ); +} + +/*! \brief Sets the content of the SCEP_DATA (raw data) */ + +int PKI_X509_SCEP_DATA_set_raw_data ( PKI_X509_SCEP_DATA *data, + unsigned char *raw_val, ssize_t size ) { + + if ( !data || !data->value || !raw_val || size <= 0 ) + return PKI_ERR; + + return PKI_X509_PKCS7_encode ( data, raw_val, (size_t) size ); +} + diff --git a/src/pkix/scep/pki_x509_scep_msg.c b/src/pkix/scep/pki_x509_scep_msg.c new file mode 100644 index 00000000..bee801ae --- /dev/null +++ b/src/pkix/scep/pki_x509_scep_msg.c @@ -0,0 +1,216 @@ +/* SCEP msg handling + * (c) 2009 by Massimiliano Pala and OpenCA Labs + * All Rights Reserved + */ + +#include + +/*! \brief Generates a new PKI_X509_SCEP message */ + +PKI_X509_SCEP_MSG *PKI_X509_SCEP_MSG_new ( SCEP_MESSAGE_TYPE type ) { + + PKI_X509_SCEP_MSG * ret = NULL; + + if ((ret = PKI_X509_PKCS7_new (PKI_X509_PKCS7_TYPE_SIGNED)) == NULL){ + return NULL; + } + + return ret; +} + +/*! \brief Frees the memory associated with a PKI_X509_SCEP_MSG */ + +void PKI_X509_SCEP_MSG_free ( PKI_X509_SCEP_MSG *msg ) { + + PKI_X509_PKCS7_free ( msg ); + + return; +} + +/*! \brief Encodes a SCEP_MSG to a PKCS7 structure */ + +int PKI_X509_SCEP_MSG_encode ( PKI_X509_SCEP_MSG *msg, + PKI_X509_SCEP_DATA *data ) { + + PKI_MEM *mem = NULL; + int ret = PKI_OK; + + if ((mem = PKI_X509_PKCS7_put_mem ( data, PKI_DATA_FORMAT_ASN1, + NULL, NULL, NULL )) == NULL ) { + return PKI_ERR; + } + + ret = PKI_X509_PKCS7_encode ( msg, mem->data, mem->size ); + PKI_MEM_free ( mem ); + + return ret; +} + +/*! \brief Retrieves the decoded data (raw) from a SCEP_MSG */ + +PKI_MEM *PKI_X509_SCEP_MSG_decode ( PKI_X509_SCEP_MSG *msg, + PKI_X509_KEYPAIR * key, PKI_X509_CERT *x ) { + + return PKI_X509_PKCS7_decode ( msg, key, x ); +} + +/*! + * \brief Retrieves the X509 object from the SCEP_MSG + */ + +PKI_X509 *PKI_X509_SCEP_MSG_get_x509_obj ( PKI_X509_SCEP_MSG *msg, + PKI_DATATYPE type, PKI_DATA_FORMAT format, + PKI_X509_KEYPAIR *key, PKI_X509_CERT *x ) { + + PKI_MEM *mem = NULL; + PKI_X509 *ret = NULL; + + if((mem = PKI_X509_PKCS7_decode ( msg, key, x )) == NULL ) { + PKI_log_debug("Can not decode SCEP message"); + return NULL; + }; + + if((ret = PKI_X509_get_mem( mem, type, format, NULL, NULL )) == NULL ) { + PKI_log_debug("Can not get X509 object (%d) from raw data.", type); + }; + + if(mem) PKI_MEM_free ( mem ); + + return ret; +} + +/*! \brief Add a signer to a SCEP_MSG */ + +int PKI_X509_SCEP_MSG_add_signer ( PKI_X509_SCEP_MSG *msg, + PKI_X509_CERT *signer, PKI_X509_KEYPAIR *key, + PKI_DIGEST_ALG *md ) { + + return PKI_X509_PKCS7_add_signer (msg, signer, key, md); +} + +/*! \brief Add a signer to a SCEP_MSG by using the passed toke data */ + +int PKI_X509_SCEP_MSG_add_signer_tk ( PKI_X509_SCEP_MSG *msg, + PKI_TOKEN *tk, PKI_DIGEST_ALG *md ) { + + return PKI_X509_PKCS7_add_signer_tk ( msg, tk, md ); +} + +/*! \brief Generates a PKCSReq message from a keypair and a subject */ + +PKI_X509_SCEP_MSG * PKI_X509_SCEP_MSG_new_certreq ( PKI_X509_KEYPAIR *key, + PKI_X509_REQ *req, PKI_X509_CERT *signer, + PKI_X509_CERT_STACK *recipients, PKI_DIGEST_ALG *md ) { + + PKI_X509_SCEP_MSG *ret = NULL; + PKI_X509_SCEP_DATA *scep_data = NULL; + + PKI_X509_REQ *my_request = NULL; + PKI_X509_CERT *my_signer = NULL; + + if ( !key || !key->value ) { + PKI_log_err ( "Signing Key is required!"); + return NULL; + } + + if ( ( !req || !req->value ) && (!signer || !signer->value ) ) { + PKI_log_err ( "ERROR, a request or singer is required!"); + return NULL; + } + + if ( !recipients ) { + PKI_log_err ("Recipients are required to encrypt SCEP messge!"); + return NULL; + } + + if ( req && req->value ) { + my_request = req; + } else { + char *subject = NULL; + + subject = PKI_X509_CERT_get_parsed( signer, + PKI_X509_DATA_SUBJECT ); + + if ( !subject ) return NULL; + + /* We need the request for the inner P7 (encrypted) */ + if((my_request = PKI_X509_REQ_new( key, subject, NULL, + NULL, NULL, NULL )) == NULL ) { + PKI_log_err( "SCEP_MSG_new_certreq()::Can not generate " + "a new PKCS#10 request"); + PKI_Free ( subject ); + goto err; + }; + + PKI_Free ( subject ); + } + + if ( signer && signer->value ) { + my_signer = signer; + } else { + // char * subject = NULL; + + // if (( subject = PKI_X509_REQ_get_parsed ( my_request, + // PKI_X509_DATA_SUBJECT )) == NULL ) { + // return NULL; + // } + + if ((my_signer = PKI_X509_CERT_new ( NULL, key, + my_request, NULL, NULL, PKI_VALIDITY_ONE_MONTH, NULL, + NULL, NULL, NULL )) == NULL ) { + + PKI_log_err ( "Can not generate a self-sign cert for " + "SCEP message"); + goto err; + } + // PKI_Free ( subject ); + } + + if ( (scep_data = PKI_X509_SCEP_DATA_new ()) == NULL ) { + PKI_log_err ( "Memory Failure"); + goto err; + } + + if ( PKI_X509_SCEP_DATA_set_recipients ( scep_data, + recipients ) == PKI_ERR ) { + PKI_log_err ( "Can not set recipients in SCEP message!"); + goto err; + } + + if ( PKI_X509_SCEP_DATA_set_x509_obj( scep_data, + my_request ) == PKI_ERR ) { + goto err; + } + + // Now we have the encrypted content, let's generate the outer + // message and set the content + + if(( ret = PKI_X509_SCEP_MSG_new(PKI_X509_SCEP_MSG_PKCSREQ)) == NULL ) { + PKI_log_err ( "Memory Failure"); + goto err; + } + + if( PKI_X509_SCEP_MSG_add_signer ( ret, my_signer, key, md ) + == PKI_ERR ) { + PKI_log_err ( "Can not set the SCEP message signer"); + goto err; + } + + PKI_X509_SCEP_MSG_set_sender_nonce ( ret, NULL ); + PKI_X509_SCEP_MSG_set_type ( ret, PKI_X509_SCEP_MSG_PKCSREQ ); + + if (PKI_X509_SCEP_MSG_encode ( ret, scep_data ) == PKI_ERR ) { + PKI_log_err ( "Can not encode SCEP message!"); + goto err; + } + + return ret; + +err: + if ( my_request && !req ) PKI_X509_REQ_free (my_request); + if ( my_signer && !signer ) PKI_X509_CERT_free (my_signer); + if ( scep_data ) PKI_X509_SCEP_DATA_free ( scep_data ); + if ( ret ) PKI_X509_SCEP_MSG_free ( ret ); + + return NULL; +} diff --git a/src/utils/banners.c b/src/utils/banners.c new file mode 100644 index 00000000..2d9b3721 --- /dev/null +++ b/src/utils/banners.c @@ -0,0 +1,26 @@ +// file: banners.c + +#ifndef LIBPKI_HEADER_BANNERS_H +# include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +const char * libpki_banner = + "\n " BOLD "OpenCA PKI Library " NORM "(" LIBPKI_VERSION_TEXT ")\n" + " (c) 2008-" LIBPKI_BUILD_DATE_YEAR_TEXT " by " BOLD "Massimiliano Pala" NORM + " and " BOLD BLUE "Open" RED "CA" NORM BOLD " Labs\n" NORM +// " " BOLD BLUE "Open" RED "CA" NORM " Licensed software\n\n" + " [ Built with " OPENSSL_VERSION_TEXT " from " BOLD BLACK "Open" RED "SSL" NORM " ]\n\n"; + +const char * prog_banner = + "\n " BOLD "%s " NORM "(%s)\n" + " (c) %d by " BOLD "%s" NORM "\n" + " [ Built with " LIBPKI_VERSION_TEXT " " LIBPKI_BUILD_DATE_TEXT_PRETTY " from " BOLD BLUE "Open" RED "CA" NORM " Labs ]\n" + " [ Built with " OPENSSL_VERSION_TEXT " from " BOLD BLACK "Open" RED "SSL" NORM " ]\n\n"; + +#ifdef __cplusplus +} +#endif diff --git a/src/utils/io/Makefile.am b/src/utils/io/Makefile.am new file mode 100644 index 00000000..21c0b16d --- /dev/null +++ b/src/utils/io/Makefile.am @@ -0,0 +1,35 @@ +## OpenCA Makefile - by Massimiliano Pala +## (c) 1999-2014 by Massimiliano Pala and OpenCA Project +## All Rights Reserved + +TOP = .. +include $(TOP)/global-vars + +BASE_DEFS = + +DEFS = $(OPENCA_DEFS) + +AM_CPPFLAGS = -I$(TOP) \ + $(openssl_cflags) \ + $(libxml2_cflags) \ + $(COND_INCLUDES) + +SRCS = \ + pki_keypair_io.c \ + pki_msg_resp_io.c \ + pki_ocsp_resp_io.c \ + pki_x509_crl_io.c \ + pki_x509_p12_io.c \ + pki_x509_req_io.c \ + pki_msg_req_io.c \ + pki_ocsp_req_io.c \ + pki_x509_cert_io.c \ + pki_x509_io.c \ + pki_x509_pkcs7_io.c \ + pki_x509_cms_io.c \ + pki_x509_xpair_io.c + +noinst_LTLIBRARIES = libpki-io.la +libpki_io_la_SOURCES = $(SRCS) +libpki_io_la_CFLAGS = $(BUILD_LIBPKI_CFLAGS) + diff --git a/src/utils/io/Makefile.in b/src/utils/io/Makefile.in new file mode 100644 index 00000000..eff32959 --- /dev/null +++ b/src/utils/io/Makefile.in @@ -0,0 +1,908 @@ +# Makefile.in generated by automake 1.16.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = src/io +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(SHELL) $(top_srcdir)/build/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/src/libpki/config.h \ + $(top_builddir)/src/libpki/libpki_enables.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +libpki_io_la_LIBADD = +am__objects_1 = libpki_io_la-pki_keypair_io.lo \ + libpki_io_la-pki_msg_resp_io.lo \ + libpki_io_la-pki_ocsp_resp_io.lo \ + libpki_io_la-pki_x509_crl_io.lo \ + libpki_io_la-pki_x509_p12_io.lo \ + libpki_io_la-pki_x509_req_io.lo libpki_io_la-pki_msg_req_io.lo \ + libpki_io_la-pki_ocsp_req_io.lo \ + libpki_io_la-pki_x509_cert_io.lo libpki_io_la-pki_x509_io.lo \ + libpki_io_la-pki_x509_pkcs7_io.lo \ + libpki_io_la-pki_x509_cms_io.lo \ + libpki_io_la-pki_x509_xpair_io.lo +am_libpki_io_la_OBJECTS = $(am__objects_1) +libpki_io_la_OBJECTS = $(am_libpki_io_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libpki_io_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libpki_io_la_CFLAGS) \ + $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src/libpki +depcomp = $(SHELL) $(top_srcdir)/build/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/libpki_io_la-pki_keypair_io.Plo \ + ./$(DEPDIR)/libpki_io_la-pki_msg_req_io.Plo \ + ./$(DEPDIR)/libpki_io_la-pki_msg_resp_io.Plo \ + ./$(DEPDIR)/libpki_io_la-pki_ocsp_req_io.Plo \ + ./$(DEPDIR)/libpki_io_la-pki_ocsp_resp_io.Plo \ + ./$(DEPDIR)/libpki_io_la-pki_x509_cert_io.Plo \ + ./$(DEPDIR)/libpki_io_la-pki_x509_cms_io.Plo \ + ./$(DEPDIR)/libpki_io_la-pki_x509_crl_io.Plo \ + ./$(DEPDIR)/libpki_io_la-pki_x509_io.Plo \ + ./$(DEPDIR)/libpki_io_la-pki_x509_p12_io.Plo \ + ./$(DEPDIR)/libpki_io_la-pki_x509_pkcs7_io.Plo \ + ./$(DEPDIR)/libpki_io_la-pki_x509_req_io.Plo \ + ./$(DEPDIR)/libpki_io_la-pki_x509_xpair_io.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libpki_io_la_SOURCES) +DIST_SOURCES = $(libpki_io_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/build/depcomp \ + $(top_srcdir)/build/mkinstalldirs +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_DATE = @BUILD_DATE@ +BUILD_DATE_FULL = @BUILD_DATE_FULL@ +BUILD_DATE_PRETTY = @BUILD_DATE_PRETTY@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CHMOD = @CHMOD@ +CHOWN = @CHOWN@ +CP = @CP@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CPU = @CPU@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CXX = @CXX@ +CYGPATH_W = @CYGPATH_W@ +DATE = @DATE@ +DEFS = $(OPENCA_DEFS) +DEPDIR = @DEPDIR@ +DESTDIR = @DESTDIR@ +DIST_NAME = @DIST_NAME@ +DIST_VERSION = @DIST_VERSION@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +GZIP = @GZIP@ +HAS_PKGCONF = @HAS_PKGCONF@ +INSTALL = @INSTALL@ +INSTALL_BUILDER = @INSTALL_BUILDER@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKE = @MAKE@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR = @MKDIR@ +MKDIR_P = @MKDIR_P@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PDFLATEX = @PDFLATEX@ +PERL = @PERL@ +PG_CONFIG = @PG_CONFIG@ +PG_CPPFLAGS = @PG_CPPFLAGS@ +PKGMK = @PKGMK@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POD2MAN = @POD2MAN@ +PWD = @PWD@ +RANLIB = @RANLIB@ +RC = @RC@ +RPM = @RPM@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TAR = @TAR@ +TODAY = @TODAY@ +VERSION = @VERSION@ +ZIP = @ZIP@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_aux_dir = @ac_aux_dir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +arch_target = @arch_target@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +composite_cflags = @composite_cflags@ +composite_ldadd = @composite_ldadd@ +composite_ldflags = @composite_ldflags@ +conf_dir = @conf_dir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +day = @day@ +dist_group = @dist_group@ +dist_user = @dist_user@ +docdir = @docdir@ +dvidir = @dvidir@ +enable_debug = @enable_debug@ +etc_dir = @etc_dir@ +exec_prefix = @exec_prefix@ +extra_checks = @extra_checks@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +hr = @hr@ +htmldir = @htmldir@ +iface_age = @iface_age@ +iface_current = @iface_current@ +iface_revision = @iface_revision@ +iface_version = @iface_version@ +include_dir = @include_dir@ +include_prefix = @include_prefix@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +kmf_cflags = @kmf_cflags@ +kmf_ldadd = @kmf_ldadd@ +kmf_libflags = @kmf_libflags@ +kmf_prefix = @kmf_prefix@ +ldap_cflags = @ldap_cflags@ +ldap_ldadd = @ldap_ldadd@ +ldap_ldflags = @ldap_ldflags@ +ldap_prefix = @ldap_prefix@ +ldap_vendor = @ldap_vendor@ +lib_major = @lib_major@ +lib_micro = @lib_micro@ +lib_minor = @lib_minor@ +lib_prefix = @lib_prefix@ +lib_revision = @lib_revision@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libpki_cflags = @libpki_cflags@ +libpki_ldadd = @libpki_ldadd@ +libpki_ldflags = @libpki_ldflags@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +min = @min@ +mkdir_p = @mkdir_p@ +mon = @mon@ +my_cflags = @my_cflags@ +my_ldadd = @my_ldadd@ +my_ldflags = @my_ldflags@ +myarch = @myarch@ +mybits = @mybits@ +mybits_install = @mybits_install@ +mysql_cflags = @mysql_cflags@ +mysql_config = @mysql_config@ +mysql_ldadd = @mysql_ldadd@ +mysql_ldflags = @mysql_ldflags@ +mysql_prefix = @mysql_prefix@ +oldincludedir = @oldincludedir@ +openssl_cflags = @openssl_cflags@ +openssl_include = @openssl_include@ +openssl_ldadd = @openssl_ldadd@ +openssl_ldflags = @openssl_ldflags@ +openssl_prefix = @openssl_prefix@ +openssl_static_libs = @openssl_static_libs@ +oqs_cflags = @oqs_cflags@ +oqs_ldadd = @oqs_ldadd@ +oqs_ldflags = @oqs_ldflags@ +oqsprov_cflags = @oqsprov_cflags@ +oqsprov_ldadd = @oqsprov_ldadd@ +oqsprov_ldflags = @oqsprov_ldflags@ +package_build = @package_build@ +package_prefix = @package_prefix@ +pdfdir = @pdfdir@ +pg_cflags = @pg_cflags@ +pg_config = @pg_config@ +pg_ldadd = @pg_ldadd@ +pg_ldflags = @pg_ldflags@ +pg_prefix = @pg_prefix@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pthread_opts = @pthread_opts@ +resolv_ldadd = @resolv_ldadd@ +rpath = @rpath@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sdkver = @sdkver@ +sec = @sec@ +sharedstatedir = @sharedstatedir@ +shlext = @shlext@ +shlib_history = @shlib_history@ +shlib_version = @shlib_version@ +srcdir = @srcdir@ +sys_cflags = @sys_cflags@ +sys_ldadd = @sys_ldadd@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +test_libs = @test_libs@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +txt_revision = @txt_revision@ +xml2_cflags = @xml2_cflags@ +xml2_config = @xml2_config@ +xml2_include = @xml2_include@ +xml2_ldadd = @xml2_ldadd@ +xml2_ldflags = @xml2_ldflags@ +xml2_prefix = @xml2_prefix@ +yr = @yr@ +TOP = .. +BASE_DEFS = +AM_CPPFLAGS = -I$(TOP) \ + $(openssl_cflags) \ + $(libxml2_cflags) \ + $(COND_INCLUDES) + +SRCS = \ + pki_keypair_io.c \ + pki_msg_resp_io.c \ + pki_ocsp_resp_io.c \ + pki_x509_crl_io.c \ + pki_x509_p12_io.c \ + pki_x509_req_io.c \ + pki_msg_req_io.c \ + pki_ocsp_req_io.c \ + pki_x509_cert_io.c \ + pki_x509_io.c \ + pki_x509_pkcs7_io.c \ + pki_x509_cms_io.c \ + pki_x509_xpair_io.c + +noinst_LTLIBRARIES = libpki-io.la +libpki_io_la_SOURCES = $(SRCS) +libpki_io_la_CFLAGS = $(BUILD_LIBPKI_CFLAGS) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/io/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/io/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libpki-io.la: $(libpki_io_la_OBJECTS) $(libpki_io_la_DEPENDENCIES) $(EXTRA_libpki_io_la_DEPENDENCIES) + $(AM_V_CCLD)$(libpki_io_la_LINK) $(libpki_io_la_OBJECTS) $(libpki_io_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_io_la-pki_keypair_io.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_io_la-pki_msg_req_io.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_io_la-pki_msg_resp_io.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_io_la-pki_ocsp_req_io.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_io_la-pki_ocsp_resp_io.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_io_la-pki_x509_cert_io.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_io_la-pki_x509_cms_io.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_io_la-pki_x509_crl_io.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_io_la-pki_x509_io.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_io_la-pki_x509_p12_io.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_io_la-pki_x509_pkcs7_io.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_io_la-pki_x509_req_io.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_io_la-pki_x509_xpair_io.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +libpki_io_la-pki_keypair_io.lo: pki_keypair_io.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_io_la_CFLAGS) $(CFLAGS) -MT libpki_io_la-pki_keypair_io.lo -MD -MP -MF $(DEPDIR)/libpki_io_la-pki_keypair_io.Tpo -c -o libpki_io_la-pki_keypair_io.lo `test -f 'pki_keypair_io.c' || echo '$(srcdir)/'`pki_keypair_io.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_io_la-pki_keypair_io.Tpo $(DEPDIR)/libpki_io_la-pki_keypair_io.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pki_keypair_io.c' object='libpki_io_la-pki_keypair_io.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_io_la_CFLAGS) $(CFLAGS) -c -o libpki_io_la-pki_keypair_io.lo `test -f 'pki_keypair_io.c' || echo '$(srcdir)/'`pki_keypair_io.c + +libpki_io_la-pki_msg_resp_io.lo: pki_msg_resp_io.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_io_la_CFLAGS) $(CFLAGS) -MT libpki_io_la-pki_msg_resp_io.lo -MD -MP -MF $(DEPDIR)/libpki_io_la-pki_msg_resp_io.Tpo -c -o libpki_io_la-pki_msg_resp_io.lo `test -f 'pki_msg_resp_io.c' || echo '$(srcdir)/'`pki_msg_resp_io.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_io_la-pki_msg_resp_io.Tpo $(DEPDIR)/libpki_io_la-pki_msg_resp_io.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pki_msg_resp_io.c' object='libpki_io_la-pki_msg_resp_io.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_io_la_CFLAGS) $(CFLAGS) -c -o libpki_io_la-pki_msg_resp_io.lo `test -f 'pki_msg_resp_io.c' || echo '$(srcdir)/'`pki_msg_resp_io.c + +libpki_io_la-pki_ocsp_resp_io.lo: pki_ocsp_resp_io.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_io_la_CFLAGS) $(CFLAGS) -MT libpki_io_la-pki_ocsp_resp_io.lo -MD -MP -MF $(DEPDIR)/libpki_io_la-pki_ocsp_resp_io.Tpo -c -o libpki_io_la-pki_ocsp_resp_io.lo `test -f 'pki_ocsp_resp_io.c' || echo '$(srcdir)/'`pki_ocsp_resp_io.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_io_la-pki_ocsp_resp_io.Tpo $(DEPDIR)/libpki_io_la-pki_ocsp_resp_io.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pki_ocsp_resp_io.c' object='libpki_io_la-pki_ocsp_resp_io.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_io_la_CFLAGS) $(CFLAGS) -c -o libpki_io_la-pki_ocsp_resp_io.lo `test -f 'pki_ocsp_resp_io.c' || echo '$(srcdir)/'`pki_ocsp_resp_io.c + +libpki_io_la-pki_x509_crl_io.lo: pki_x509_crl_io.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_io_la_CFLAGS) $(CFLAGS) -MT libpki_io_la-pki_x509_crl_io.lo -MD -MP -MF $(DEPDIR)/libpki_io_la-pki_x509_crl_io.Tpo -c -o libpki_io_la-pki_x509_crl_io.lo `test -f 'pki_x509_crl_io.c' || echo '$(srcdir)/'`pki_x509_crl_io.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_io_la-pki_x509_crl_io.Tpo $(DEPDIR)/libpki_io_la-pki_x509_crl_io.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pki_x509_crl_io.c' object='libpki_io_la-pki_x509_crl_io.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_io_la_CFLAGS) $(CFLAGS) -c -o libpki_io_la-pki_x509_crl_io.lo `test -f 'pki_x509_crl_io.c' || echo '$(srcdir)/'`pki_x509_crl_io.c + +libpki_io_la-pki_x509_p12_io.lo: pki_x509_p12_io.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_io_la_CFLAGS) $(CFLAGS) -MT libpki_io_la-pki_x509_p12_io.lo -MD -MP -MF $(DEPDIR)/libpki_io_la-pki_x509_p12_io.Tpo -c -o libpki_io_la-pki_x509_p12_io.lo `test -f 'pki_x509_p12_io.c' || echo '$(srcdir)/'`pki_x509_p12_io.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_io_la-pki_x509_p12_io.Tpo $(DEPDIR)/libpki_io_la-pki_x509_p12_io.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pki_x509_p12_io.c' object='libpki_io_la-pki_x509_p12_io.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_io_la_CFLAGS) $(CFLAGS) -c -o libpki_io_la-pki_x509_p12_io.lo `test -f 'pki_x509_p12_io.c' || echo '$(srcdir)/'`pki_x509_p12_io.c + +libpki_io_la-pki_x509_req_io.lo: pki_x509_req_io.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_io_la_CFLAGS) $(CFLAGS) -MT libpki_io_la-pki_x509_req_io.lo -MD -MP -MF $(DEPDIR)/libpki_io_la-pki_x509_req_io.Tpo -c -o libpki_io_la-pki_x509_req_io.lo `test -f 'pki_x509_req_io.c' || echo '$(srcdir)/'`pki_x509_req_io.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_io_la-pki_x509_req_io.Tpo $(DEPDIR)/libpki_io_la-pki_x509_req_io.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pki_x509_req_io.c' object='libpki_io_la-pki_x509_req_io.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_io_la_CFLAGS) $(CFLAGS) -c -o libpki_io_la-pki_x509_req_io.lo `test -f 'pki_x509_req_io.c' || echo '$(srcdir)/'`pki_x509_req_io.c + +libpki_io_la-pki_msg_req_io.lo: pki_msg_req_io.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_io_la_CFLAGS) $(CFLAGS) -MT libpki_io_la-pki_msg_req_io.lo -MD -MP -MF $(DEPDIR)/libpki_io_la-pki_msg_req_io.Tpo -c -o libpki_io_la-pki_msg_req_io.lo `test -f 'pki_msg_req_io.c' || echo '$(srcdir)/'`pki_msg_req_io.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_io_la-pki_msg_req_io.Tpo $(DEPDIR)/libpki_io_la-pki_msg_req_io.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pki_msg_req_io.c' object='libpki_io_la-pki_msg_req_io.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_io_la_CFLAGS) $(CFLAGS) -c -o libpki_io_la-pki_msg_req_io.lo `test -f 'pki_msg_req_io.c' || echo '$(srcdir)/'`pki_msg_req_io.c + +libpki_io_la-pki_ocsp_req_io.lo: pki_ocsp_req_io.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_io_la_CFLAGS) $(CFLAGS) -MT libpki_io_la-pki_ocsp_req_io.lo -MD -MP -MF $(DEPDIR)/libpki_io_la-pki_ocsp_req_io.Tpo -c -o libpki_io_la-pki_ocsp_req_io.lo `test -f 'pki_ocsp_req_io.c' || echo '$(srcdir)/'`pki_ocsp_req_io.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_io_la-pki_ocsp_req_io.Tpo $(DEPDIR)/libpki_io_la-pki_ocsp_req_io.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pki_ocsp_req_io.c' object='libpki_io_la-pki_ocsp_req_io.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_io_la_CFLAGS) $(CFLAGS) -c -o libpki_io_la-pki_ocsp_req_io.lo `test -f 'pki_ocsp_req_io.c' || echo '$(srcdir)/'`pki_ocsp_req_io.c + +libpki_io_la-pki_x509_cert_io.lo: pki_x509_cert_io.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_io_la_CFLAGS) $(CFLAGS) -MT libpki_io_la-pki_x509_cert_io.lo -MD -MP -MF $(DEPDIR)/libpki_io_la-pki_x509_cert_io.Tpo -c -o libpki_io_la-pki_x509_cert_io.lo `test -f 'pki_x509_cert_io.c' || echo '$(srcdir)/'`pki_x509_cert_io.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_io_la-pki_x509_cert_io.Tpo $(DEPDIR)/libpki_io_la-pki_x509_cert_io.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pki_x509_cert_io.c' object='libpki_io_la-pki_x509_cert_io.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_io_la_CFLAGS) $(CFLAGS) -c -o libpki_io_la-pki_x509_cert_io.lo `test -f 'pki_x509_cert_io.c' || echo '$(srcdir)/'`pki_x509_cert_io.c + +libpki_io_la-pki_x509_io.lo: pki_x509_io.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_io_la_CFLAGS) $(CFLAGS) -MT libpki_io_la-pki_x509_io.lo -MD -MP -MF $(DEPDIR)/libpki_io_la-pki_x509_io.Tpo -c -o libpki_io_la-pki_x509_io.lo `test -f 'pki_x509_io.c' || echo '$(srcdir)/'`pki_x509_io.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_io_la-pki_x509_io.Tpo $(DEPDIR)/libpki_io_la-pki_x509_io.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pki_x509_io.c' object='libpki_io_la-pki_x509_io.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_io_la_CFLAGS) $(CFLAGS) -c -o libpki_io_la-pki_x509_io.lo `test -f 'pki_x509_io.c' || echo '$(srcdir)/'`pki_x509_io.c + +libpki_io_la-pki_x509_pkcs7_io.lo: pki_x509_pkcs7_io.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_io_la_CFLAGS) $(CFLAGS) -MT libpki_io_la-pki_x509_pkcs7_io.lo -MD -MP -MF $(DEPDIR)/libpki_io_la-pki_x509_pkcs7_io.Tpo -c -o libpki_io_la-pki_x509_pkcs7_io.lo `test -f 'pki_x509_pkcs7_io.c' || echo '$(srcdir)/'`pki_x509_pkcs7_io.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_io_la-pki_x509_pkcs7_io.Tpo $(DEPDIR)/libpki_io_la-pki_x509_pkcs7_io.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pki_x509_pkcs7_io.c' object='libpki_io_la-pki_x509_pkcs7_io.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_io_la_CFLAGS) $(CFLAGS) -c -o libpki_io_la-pki_x509_pkcs7_io.lo `test -f 'pki_x509_pkcs7_io.c' || echo '$(srcdir)/'`pki_x509_pkcs7_io.c + +libpki_io_la-pki_x509_cms_io.lo: pki_x509_cms_io.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_io_la_CFLAGS) $(CFLAGS) -MT libpki_io_la-pki_x509_cms_io.lo -MD -MP -MF $(DEPDIR)/libpki_io_la-pki_x509_cms_io.Tpo -c -o libpki_io_la-pki_x509_cms_io.lo `test -f 'pki_x509_cms_io.c' || echo '$(srcdir)/'`pki_x509_cms_io.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_io_la-pki_x509_cms_io.Tpo $(DEPDIR)/libpki_io_la-pki_x509_cms_io.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pki_x509_cms_io.c' object='libpki_io_la-pki_x509_cms_io.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_io_la_CFLAGS) $(CFLAGS) -c -o libpki_io_la-pki_x509_cms_io.lo `test -f 'pki_x509_cms_io.c' || echo '$(srcdir)/'`pki_x509_cms_io.c + +libpki_io_la-pki_x509_xpair_io.lo: pki_x509_xpair_io.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_io_la_CFLAGS) $(CFLAGS) -MT libpki_io_la-pki_x509_xpair_io.lo -MD -MP -MF $(DEPDIR)/libpki_io_la-pki_x509_xpair_io.Tpo -c -o libpki_io_la-pki_x509_xpair_io.lo `test -f 'pki_x509_xpair_io.c' || echo '$(srcdir)/'`pki_x509_xpair_io.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_io_la-pki_x509_xpair_io.Tpo $(DEPDIR)/libpki_io_la-pki_x509_xpair_io.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pki_x509_xpair_io.c' object='libpki_io_la-pki_x509_xpair_io.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_io_la_CFLAGS) $(CFLAGS) -c -o libpki_io_la-pki_x509_xpair_io.lo `test -f 'pki_x509_xpair_io.c' || echo '$(srcdir)/'`pki_x509_xpair_io.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/libpki_io_la-pki_keypair_io.Plo + -rm -f ./$(DEPDIR)/libpki_io_la-pki_msg_req_io.Plo + -rm -f ./$(DEPDIR)/libpki_io_la-pki_msg_resp_io.Plo + -rm -f ./$(DEPDIR)/libpki_io_la-pki_ocsp_req_io.Plo + -rm -f ./$(DEPDIR)/libpki_io_la-pki_ocsp_resp_io.Plo + -rm -f ./$(DEPDIR)/libpki_io_la-pki_x509_cert_io.Plo + -rm -f ./$(DEPDIR)/libpki_io_la-pki_x509_cms_io.Plo + -rm -f ./$(DEPDIR)/libpki_io_la-pki_x509_crl_io.Plo + -rm -f ./$(DEPDIR)/libpki_io_la-pki_x509_io.Plo + -rm -f ./$(DEPDIR)/libpki_io_la-pki_x509_p12_io.Plo + -rm -f ./$(DEPDIR)/libpki_io_la-pki_x509_pkcs7_io.Plo + -rm -f ./$(DEPDIR)/libpki_io_la-pki_x509_req_io.Plo + -rm -f ./$(DEPDIR)/libpki_io_la-pki_x509_xpair_io.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/libpki_io_la-pki_keypair_io.Plo + -rm -f ./$(DEPDIR)/libpki_io_la-pki_msg_req_io.Plo + -rm -f ./$(DEPDIR)/libpki_io_la-pki_msg_resp_io.Plo + -rm -f ./$(DEPDIR)/libpki_io_la-pki_ocsp_req_io.Plo + -rm -f ./$(DEPDIR)/libpki_io_la-pki_ocsp_resp_io.Plo + -rm -f ./$(DEPDIR)/libpki_io_la-pki_x509_cert_io.Plo + -rm -f ./$(DEPDIR)/libpki_io_la-pki_x509_cms_io.Plo + -rm -f ./$(DEPDIR)/libpki_io_la-pki_x509_crl_io.Plo + -rm -f ./$(DEPDIR)/libpki_io_la-pki_x509_io.Plo + -rm -f ./$(DEPDIR)/libpki_io_la-pki_x509_p12_io.Plo + -rm -f ./$(DEPDIR)/libpki_io_la-pki_x509_pkcs7_io.Plo + -rm -f ./$(DEPDIR)/libpki_io_la-pki_x509_req_io.Plo + -rm -f ./$(DEPDIR)/libpki_io_la-pki_x509_xpair_io.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-noinstLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + +include $(TOP)/global-vars + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/utils/io/pki_keypair_io.c b/src/utils/io/pki_keypair_io.c new file mode 100644 index 00000000..7c2d11fe --- /dev/null +++ b/src/utils/io/pki_keypair_io.c @@ -0,0 +1,155 @@ +/* PKI_X509 object management */ + +#include + +/* ------------------------ KEYPAIR get (load) functions ------------------- */ + +/*! \brief Returns a PKI_X509_KEYPAIR obejct from a url address (string) */ + +PKI_X509_KEYPAIR *PKI_X509_KEYPAIR_get (char *url_s, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm) { + + return PKI_X509_get ( url_s, PKI_DATATYPE_X509_KEYPAIR, format, cred, hsm ); +} + +/*! \brief Returns a PKI_X509_KEYPAIR obejct from a URL */ + +PKI_X509_KEYPAIR *PKI_X509_KEYPAIR_get_url ( URL *url, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_get_url ( url, PKI_DATATYPE_X509_KEYPAIR, format, cred, hsm ); +} + +/*! \brief Returns a STACK of PKI_X509_KEYPAIR obejcts from a url address */ + +PKI_X509_KEYPAIR_STACK *PKI_X509_KEYPAIR_STACK_get ( char *url_s, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_STACK_get (url_s, PKI_DATATYPE_X509_KEYPAIR, format, cred, hsm); +} + +/*! \brief Returns a STACK of PKI_X509_KEYPAIR obejcts from the passed URL */ + +PKI_X509_KEYPAIR_STACK *PKI_X509_KEYPAIR_STACK_get_url ( URL *url, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_STACK_get_url ( url, PKI_DATATYPE_X509_KEYPAIR, + format, cred, hsm ); +} + +/* ---------------------- KEYPAIR put (write) functions ------------------- */ + +int PKI_X509_KEYPAIR_put ( PKI_X509_KEYPAIR *x, PKI_DATA_FORMAT format, + char *url_string, PKI_CRED *cred, HSM *hsm) { + + if ( x->type != PKI_DATATYPE_X509_KEYPAIR) return PKI_ERR; + + return PKI_X509_put ( x, format, url_string, NULL, cred, hsm ); +} + +int PKI_X509_KEYPAIR_put_url(PKI_X509_KEYPAIR *x, PKI_DATA_FORMAT format, + URL *url, PKI_CRED * cred, HSM *hsm) { + + if ( x->type != PKI_DATATYPE_X509_KEYPAIR ) return PKI_ERR; + + return PKI_X509_put_url ( x, format, url, NULL, cred, hsm ); +} + +/* --------------------------- MEM I/O ---------------------------------- */ + +PKI_X509_KEYPAIR * PKI_X509_KEYPAIR_get_mem(const PKI_MEM * const mem, + const PKI_DATA_FORMAT format, + const PKI_CRED * const cred ) { + + return PKI_X509_get_mem((PKI_MEM *)mem, PKI_DATATYPE_X509_KEYPAIR, format, (PKI_CRED *)cred, NULL); +} + +/*! \brief Reads a PKI_X509_KEYPAIR_VALUE object from a PKI_MEM */ + +PKI_X509_KEYPAIR_VALUE * PKI_X509_KEYPAIR_VALUE_get_mem(const PKI_MEM * const mem, + const PKI_DATA_FORMAT format, + const PKI_CRED * const cred ) { + + PKI_X509_KEYPAIR * key = NULL; + PKI_X509_KEYPAIR_VALUE * val = NULL; + + // Gets the Key in the generic format + key = PKI_X509_get_mem((PKI_MEM *)mem, PKI_DATATYPE_X509_KEYPAIR, format, (PKI_CRED *)cred, NULL); + if (!key) return NULL; + + // Extracts the crypto-library specific value + val = PKI_X509_get_value(key); + + // Resets the generic container and free the + // memory for the generic wrapper + key->value = NULL; + PKI_X509_free(key); + + // All Done + return val; +} + +PKI_MEM * PKI_X509_KEYPAIR_put_mem(const PKI_X509_KEYPAIR * const key, + const PKI_DATA_FORMAT format, + PKI_MEM ** const pki_mem, + const PKI_CRED * cred, + const HSM * hsm) { + return PKI_X509_put_mem((PKI_X509_KEYPAIR *)key, format, pki_mem, (PKI_CRED *)cred); +} + +PKI_MEM * PKI_X509_KEYPAIR_VALUE_put_mem(const PKI_X509_KEYPAIR_VALUE * const key, + const PKI_DATA_FORMAT format, + PKI_MEM ** const pki_mem, + const PKI_CRED * cred, + const HSM * hsm) { + + PKI_X509_KEYPAIR * wrapper = NULL; + PKI_X509_KEYPAIR_VALUE * key_val = NULL; + + PKI_MEM * buff = NULL; + + // Input Checks + if (!key) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return NULL; + } + + // Wraps the VALUE into a PKI_X509 + wrapper = PKI_X509_new_value(PKI_DATATYPE_X509_KEYPAIR, (void *)key, (HSM *)hsm); + if (!wrapper) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return NULL; + } + + // Assigns the existing buffer, if any was passed + if (pki_mem && *pki_mem) { + buff = (PKI_MEM *)*pki_mem; + } + + // Saves the keypair into the output buffer + PKI_X509_KEYPAIR_put_mem(wrapper, format, &buff, cred, hsm); + + // Detaches the VALUE from the PKI_X509 + if (wrapper->value) PKI_X509_detach(wrapper, (void **)&key_val, NULL, NULL); + PKI_X509_free(wrapper); + wrapper = NULL; + + // Checks the results + if (!buff || !buff->data) { + *pki_mem = NULL; + return *pki_mem; + } + + // Detaches the value from the wrapper + PKI_X509_detach(wrapper, NULL, NULL, NULL); + + // Free the wrapper's memory + PKI_X509_free(wrapper); + wrapper = NULL; + + // Sets the output buffer + *pki_mem = buff; + + // All done + return buff; +} \ No newline at end of file diff --git a/src/utils/io/pki_msg_req_io.c b/src/utils/io/pki_msg_req_io.c new file mode 100644 index 00000000..6da6585f --- /dev/null +++ b/src/utils/io/pki_msg_req_io.c @@ -0,0 +1,80 @@ +/* src/io/pki_msg_req.c - General PKI message I/O + * (c) 2009 by Massimiliano Pala and OpenCA Labs + * All Rights Reserved + */ + +#include + +/*! \brief Writes the message in a memory buffer */ + +PKI_MEM *PKI_MSG_REQ_put_mem ( PKI_MSG_REQ *msg, PKI_DATA_FORMAT format, + PKI_MEM **pki_mem, PKI_CRED *cred, HSM *hsm ) { + + if( !msg ) return ( NULL ); + + if( !msg->msg_data || !msg->msg_data->value ) { + PKI_MSG_PROTO proto; + proto = PKI_MSG_REQ_get_proto ( msg ); + + if (PKI_MSG_REQ_encode ( msg, proto ) == PKI_ERR ) { + PKI_log_err ("Can not encode message (Proto::%d)", proto); + return ( NULL ); + } + } + + PKI_log_debug("PKI_MSG_REQ_put_mem()::Start"); + + switch ( msg->proto ) { + case PKI_MSG_PROTO_SCEP: + return PKI_X509_PKCS7_put_mem ( msg->msg_data, + format, pki_mem, cred, hsm ); + break; + case PKI_MSG_PROTO_CMC: + case PKI_MSG_PROTO_XKMS: + default: + PKI_log_debug("MSG protocol not supported!"); + } + + return ( NULL ); +} + + +/*! \brief Writes the message to a URL */ + +int PKI_MSG_REQ_put ( PKI_MSG_REQ *msg, PKI_DATA_FORMAT format, + char *url, char *mime, PKI_CRED *cred, + HSM *hsm, PKI_MEM_STACK **ret_sk ) { + + PKI_MEM *mem = NULL; + + if( !msg ) return ( PKI_ERR ); + + if( !msg->msg_data ) { + PKI_MSG_PROTO proto; + + proto = PKI_MSG_REQ_get_proto ( msg ); + + if (PKI_MSG_REQ_encode ( msg, proto ) == PKI_ERR ) { + return ( PKI_ERR ); + } + } + + PKI_log_debug("PKI_MSG_REQ_put()::Start"); + + switch ( msg->proto ) { + case PKI_MSG_PROTO_SCEP: + mem = PKI_X509_PKCS7_put_mem ( msg->msg_data, + format, NULL, cred, hsm ); + break; + case PKI_MSG_PROTO_CMC: + case PKI_MSG_PROTO_XKMS: + default: + PKI_log_debug("MSG protocol not supported!"); + } + + if (!mem || !mem->data ) return ( PKI_ERR ); + + return URL_put_data( url, mem, "application/x-pki-message", + ret_sk, 120, 64*1024, NULL); +} + diff --git a/src/utils/io/pki_msg_resp_io.c b/src/utils/io/pki_msg_resp_io.c new file mode 100644 index 00000000..f7e9b99a --- /dev/null +++ b/src/utils/io/pki_msg_resp_io.c @@ -0,0 +1,76 @@ +/* src/io/pki_msg_resp_io.c - General PKI message (responses) + * (c) 2009 by Massimiliano Pala and OpenCA Labs + * All Rights Reserved + */ + +#include + +/*! \brief Writes the message to a URL */ + +int PKI_MSG_RESP_put ( PKI_MSG_RESP *msg, PKI_DATA_FORMAT format, + char *url, char *mime, PKI_CRED *cred, HSM *hsm ) { + + PKI_MEM *mem = NULL; + + if( !msg ) return ( PKI_ERR ); + + if( !msg->msg_data ) { + PKI_MSG_PROTO proto; + + proto = PKI_MSG_RESP_get_proto ( msg ); + + if (PKI_MSG_RESP_encode ( msg, proto ) == NULL ) { + return ( PKI_ERR ); + } + } + + switch ( msg->proto ) { + case PKI_MSG_PROTO_SCEP: + mem = PKI_X509_PKCS7_put_mem ( + (PKI_X509_PKCS7 *) msg->msg_data, format, + NULL, cred, hsm ); + break; + case PKI_MSG_PROTO_CMC: + case PKI_MSG_PROTO_XKMS: + default: + PKI_log_debug("MSG protocol not supported!"); + } + + if (!mem || !mem->data ) return ( PKI_ERR ); + + return URL_put_data( url, mem, "application/x-pki-message", + NULL, 120, 64*1024, NULL ); +} + +/*! \brief Writes the message in a memory buffer */ + +PKI_MEM *PKI_MSG_RESP_put_mem ( PKI_MSG_RESP *msg, PKI_DATA_FORMAT format, + PKI_MEM **pki_mem, PKI_CRED *cred, HSM *hsm ) { + + if( !msg ) return ( NULL ); + + if( !msg->msg_data ) { + PKI_MSG_PROTO proto; + proto = PKI_MSG_RESP_get_proto ( msg ); + + if (PKI_MSG_RESP_encode ( msg, proto ) == NULL ) { + return ( NULL ); + } + } + + switch ( msg->proto ) { + case PKI_MSG_PROTO_SCEP: + return PKI_X509_PKCS7_put_mem ( + (PKI_X509_PKCS7 *) msg->msg_data, + format, NULL, cred, hsm ); + break; + case PKI_MSG_PROTO_CMC: + case PKI_MSG_PROTO_XKMS: + default: + PKI_log_debug("MSG protocol not supported!"); + } + + return ( NULL ); +} + + diff --git a/src/utils/io/pki_ocsp_req_io.c b/src/utils/io/pki_ocsp_req_io.c new file mode 100644 index 00000000..2cdffcfc --- /dev/null +++ b/src/utils/io/pki_ocsp_req_io.c @@ -0,0 +1,265 @@ +/* PKI_X509_OCSP_REQ I/O management */ + +#include + +PKI_X509_OCSP_REQ *PKI_X509_OCSP_REQ_get ( char *url_s, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ) { + return PKI_X509_get ( url_s, PKI_DATATYPE_X509_OCSP_REQ, format, cred, hsm ); + +/* + PKI_X509_OCSP_REQ_STACK *r_sk = NULL; + PKI_X509_OCSP_REQ *tmp_r = NULL; + PKI_X509_OCSP_REQ *ret = NULL; + + if( !url_s ) return (NULL); + + if((r_sk = PKI_X509_OCSP_REQ_STACK_get( url_s, cred, hsm )) == NULL ) { + return(NULL); + } + + if( PKI_STACK_OCSP_REQ_elements( r_sk ) >= 1 ) { + ret = PKI_STACK_OCSP_REQ_pop( r_sk ); + } + + while( (tmp_r = PKI_STACK_OCSP_REQ_pop( r_sk )) != NULL ) { + PKI_X509_OCSP_REQ_free ( tmp_r ); + } + + return( ret ); +*/ +} + +PKI_X509_OCSP_REQ *PKI_X509_OCSP_REQ_get_url ( URL *url, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_get_url ( url, PKI_DATATYPE_X509_OCSP_REQ, format, cred, hsm ); +/* + PKI_X509_OCSP_REQ_STACK *r_sk = NULL; + PKI_X509_OCSP_REQ *tmp_r = NULL; + PKI_X509_OCSP_REQ *ret = NULL; + + if( !url ) return (NULL); + + if((r_sk = PKI_X509_OCSP_REQ_STACK_get_url( url, cred, hsm )) == NULL ) { + return(NULL); + } + + if( PKI_STACK_OCSP_REQ_elements( r_sk ) >= 1 ) { + ret = PKI_STACK_OCSP_REQ_pop( r_sk ); + } + + while( (tmp_r = PKI_STACK_OCSP_REQ_pop( r_sk )) != NULL ) { + PKI_X509_OCSP_REQ_free ( tmp_r ); + } + + return (ret); +*/ +} + +PKI_X509_OCSP_REQ *PKI_X509_OCSP_REQ_get_mem ( PKI_MEM *mem, + PKI_DATA_FORMAT format, PKI_CRED *cred ) { + return PKI_X509_get_mem ( mem, PKI_DATATYPE_X509_OCSP_REQ, format, cred, NULL); +} + + +PKI_X509_OCSP_REQ_STACK *PKI_X509_OCSP_REQ_STACK_get (char *url_s, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm) { + + return PKI_X509_STACK_get (url_s, PKI_DATATYPE_X509_OCSP_REQ, format, cred, hsm); +/* + URL *url = NULL; + PKI_X509_OCSP_REQ_STACK *ret_sk = NULL; + + if( !url_s ) return (NULL); + + if((url = URL_new(url_s)) == NULL ) { + return (NULL); + } + + ret_sk = PKI_X509_OCSP_REQ_STACK_get_url ( url, cred, hsm ); + + URL_free( url ); + + return( ret_sk ); +*/ +} + +PKI_X509_OCSP_REQ_STACK *PKI_X509_OCSP_REQ_STACK_get_url ( URL *url, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_STACK_get_url (url, PKI_DATATYPE_X509_OCSP_REQ, + format, cred, hsm ); +/* + PKI_X509_OCSP_REQ_STACK *ret = NULL; + PKI_X509_OCSP_REQ_STACK *tmp_x_sk = NULL; + PKI_MEM_STACK *mem_sk = NULL; + PKI_X509_OCSP_REQ *x = NULL; + + int i = 0, count = 1; + + if( !url ) return (NULL); + + if ( url->proto == URI_PROTO_ID ) { + PKI_log_err("ERROR::Protocol id:// not supported with " + "OCSP REQs"); + return NULL; + }; + + if((mem_sk = URL_get_data_url ( url, 0 )) == NULL ) { + return(NULL); + } + + if((ret = PKI_STACK_OCSP_REQ_new()) == NULL ) { + return(NULL); + } + + count = 0; + for( i = 0; i < PKI_STACK_MEM_elements( mem_sk ); i++ ) { + PKI_MEM *n = NULL; + + if(( n = PKI_STACK_MEM_get_num( mem_sk, i )) == NULL ) { + break; + } + + if((tmp_x_sk = PKI_X509_OCSP_REQ_STACK_get_mem(n, cred)) != NULL ) { + while ( (x = PKI_STACK_OCSP_REQ_pop( tmp_x_sk )) + != NULL ) { + count++; + if( url->object_num > 0 ) { + if (url->object_num == count ) { + PKI_STACK_OCSP_REQ_push( ret, x ); + } + } else { + PKI_STACK_OCSP_REQ_push( ret, x ); + } + } + PKI_STACK_OCSP_REQ_free ( tmp_x_sk ); + } + } + + if( mem_sk ) PKI_STACK_MEM_free_all ( mem_sk ); + + return ( ret ); +*/ +} + +PKI_X509_OCSP_REQ_STACK *PKI_X509_OCSP_REQ_STACK_get_mem( PKI_MEM *mem, + PKI_DATA_FORMAT format, PKI_CRED *cred) { + + return PKI_X509_STACK_get_mem (mem, PKI_DATATYPE_X509_OCSP_REQ, + format, cred, NULL ); +/* + PKI_X509_OCSP_REQ * x = NULL; + PKI_X509_OCSP_REQ_VALUE *x_val = NULL; + PKI_X509_OCSP_REQ_STACK *sk = NULL; + + BUF_MEM *p = NULL; + PKI_IO *membio = NULL; + + char *temp = NULL; + int cont = 1; + long curr = 0; + + size_t mem_size = 0; + char * mem_buf = NULL; + + if( !mem || mem->size <= 0 ) return (NULL); + + if((temp = strstr((char *) mem->data, + PKI_X509_OCSP_REQ_BEGIN_ARMOUR )) == NULL ) { + mem_buf = (char *) mem->data; + mem_size = mem->size; + } else { + mem_buf = temp; + mem_size = (size_t) ((char *)mem->data - temp) + mem->size; + } + + if((membio = BIO_new_mem_buf( mem_buf, (int) mem_size )) == NULL ) { + return( NULL ); + } + + if(BIO_set_close(membio, BIO_NOCLOSE) != 1 ) { + BIO_free (membio); + return(NULL); + } + + if((sk = PKI_STACK_OCSP_REQ_new()) == NULL ) { + BIO_free( membio ); + return(NULL); + } + + cont = 1; + p = (BUF_MEM *) membio->ptr; + curr = p->length; + while ((cont == 1) && (p->length > 0)) { + + curr = p->length; + + if(( x_val = PEM_read_bio_OCSP_REQ(membio, NULL, + NULL, NULL)) == NULL){ + + p->length = curr; + p->data -= curr; + + if((x_val = d2i_OCSP_REQUEST_bio ( membio, + NULL)) == NULL ) { + cont = 0; + } + } + + if ( x_val ) { + if((x = PKI_X509_new ( PKI_DATATYPE_X509_OCSP_REQ)) != NULL ) { + x->value = x_val; + PKI_STACK_OCSP_REQ_push ( sk, x ); + } + } + } + + if(membio) BIO_free( membio ); + return( sk ); +*/ +} + +/* ---------------------------- OCSP_REQ put operations ------------------ */ + +int PKI_X509_OCSP_REQ_put (PKI_X509_OCSP_REQ *req, PKI_DATA_FORMAT format, + char *url_s, char *mime, PKI_CRED *cred, HSM *hsm) { + + return PKI_X509_put ( req, format, url_s, mime, cred, hsm ); +} + +int PKI_X509_OCSP_REQ_put_url(PKI_X509_OCSP_REQ *req, PKI_DATA_FORMAT format, + URL *url, char *mime, PKI_CRED *cred, HSM *hsm) { + + return PKI_X509_put_url ( req, format, url, mime, cred, hsm ); +} + +PKI_MEM *PKI_X509_OCSP_REQ_put_mem ( PKI_X509_OCSP_REQ *req, + PKI_DATA_FORMAT format, PKI_MEM **pki_mem, + PKI_CRED *cred, HSM *hsm ) { + return PKI_X509_put_mem ( req, format, pki_mem, cred ); +} + + +int PKI_X509_OCSP_REQ_STACK_put ( PKI_X509_OCSP_REQ_STACK *sk, + PKI_DATA_FORMAT format, char *url_s, char *mime, + PKI_CRED *cred, HSM *hsm) { + + return PKI_X509_STACK_put ( sk, format, url_s, mime, cred, hsm ); + +} + +int PKI_X509_OCSP_REQ_STACK_put_url (PKI_X509_OCSP_REQ_STACK *sk, + PKI_DATA_FORMAT format, URL *url, char *mime, + PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_STACK_put_url ( sk, format, url, mime, cred, hsm ); +} + +PKI_MEM * PKI_X509_OCSP_REQ_STACK_put_mem ( PKI_X509_OCSP_REQ_STACK *sk, + PKI_DATA_FORMAT format, PKI_MEM **pki_mem, + PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_STACK_put_mem ( sk, format, pki_mem, cred, hsm ); +} + diff --git a/src/utils/io/pki_ocsp_resp_io.c b/src/utils/io/pki_ocsp_resp_io.c new file mode 100644 index 00000000..5e4f1157 --- /dev/null +++ b/src/utils/io/pki_ocsp_resp_io.c @@ -0,0 +1,83 @@ +/* PKI_X509_OCSP_RESP I/O management */ + +#include + +PKI_X509_OCSP_RESP *PKI_X509_OCSP_RESP_get(char *url_s, PKI_DATA_FORMAT format, + PKI_CRED *cred,HSM *hsm){ + + return PKI_X509_get ( url_s, PKI_DATATYPE_X509_OCSP_RESP, format, cred, hsm ); +} + +PKI_X509_OCSP_RESP *PKI_X509_OCSP_RESP_get_url (URL *url, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_get_url ( url, PKI_DATATYPE_X509_OCSP_RESP, format, cred, hsm); +} + +PKI_X509_OCSP_RESP *PKI_X509_OCSP_RESP_get_mem ( PKI_MEM *mem, + PKI_DATA_FORMAT format, PKI_CRED *cred ){ + return PKI_X509_get_mem ( mem, PKI_DATATYPE_X509_OCSP_RESP, format, cred, NULL); +} + +PKI_X509_OCSP_RESP_STACK *PKI_X509_OCSP_RESP_STACK_get (char *url_s, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm) { + + return PKI_X509_STACK_get(url_s, PKI_DATATYPE_X509_OCSP_RESP, format, cred, hsm); +} + +PKI_X509_OCSP_RESP_STACK *PKI_X509_OCSP_RESP_STACK_get_url ( URL *url, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_STACK_get_url ( url, PKI_DATATYPE_X509_OCSP_RESP, + format, cred, hsm ); +} + +PKI_X509_OCSP_RESP_STACK *PKI_X509_OCSP_RESP_STACK_get_mem ( PKI_MEM *mem, + PKI_DATA_FORMAT format, PKI_CRED *cred ) { + + return PKI_X509_STACK_get_mem ( mem, PKI_DATATYPE_X509_OCSP_RESP, + format, cred, NULL ); +} + + +/* ---------------------------- OCSP_REQ put operations ------------------ */ + +int PKI_X509_OCSP_RESP_put (PKI_X509_OCSP_RESP *r, PKI_DATA_FORMAT format, + char *url_s, char *mime, PKI_CRED *cred, HSM *hsm) { + + return PKI_X509_put ( r, format, url_s, mime, cred, hsm ); +} + +int PKI_X509_OCSP_RESP_put_url(PKI_X509_OCSP_RESP *r, PKI_DATA_FORMAT format, + URL *url, char *mime, PKI_CRED *cred, HSM *hsm) { + + return PKI_X509_put_url ( r, format, url, mime, cred, hsm ); +} + +PKI_MEM *PKI_X509_OCSP_RESP_put_mem(PKI_X509_OCSP_RESP *r, + PKI_DATA_FORMAT format, PKI_MEM **pki_mem, + PKI_CRED *cred, HSM *hsm) { + return PKI_X509_put_mem (r, format, pki_mem, cred ); +} + +int PKI_X509_OCSP_RESP_STACK_put ( PKI_X509_OCSP_RESP_STACK *sk, + PKI_DATA_FORMAT format, char *url_s, char *mime, + PKI_CRED *cred, HSM *hsm) { + + return PKI_X509_STACK_put( sk, format, url_s, mime, cred, hsm ); +} + +int PKI_X509_OCSP_RESP_STACK_put_url (PKI_X509_OCSP_RESP_STACK *sk, + PKI_DATA_FORMAT format, URL *url, char *mime, + PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_STACK_put_url (sk, format, url, mime, cred, hsm ); +} + + +PKI_MEM *PKI_X509_OCSP_RESP_STACK_put_mem ( PKI_X509_OCSP_RESP_STACK *sk, + PKI_DATA_FORMAT format, PKI_MEM **pki_mem, + PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_STACK_put_mem (sk, format, pki_mem, cred, hsm ); +} diff --git a/src/utils/io/pki_x509_cert_io.c b/src/utils/io/pki_x509_cert_io.c new file mode 100644 index 00000000..f0a551e3 --- /dev/null +++ b/src/utils/io/pki_x509_cert_io.c @@ -0,0 +1,131 @@ +/* PKI_X509 I/O management */ + +#include + +/*! \brief Retrieve a certificate from a URL + * + * Downloads a certificate from a given URL (file://, http://, ldap://...) + * in (char *) format. + * The returned data is of type PKI_X509_CERT in case of success or NULL if + * any error occurred. If multiple objects are returned from the URL, only + * the first one is returned. Use PKI_X509_CERT_STACK_get() function + * to retrieve a PKI_X509_CERT_STACK * object. + * + */ + +PKI_X509_CERT *PKI_X509_CERT_get ( char *url_s, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_get ( url_s, PKI_DATATYPE_X509_CERT, format, cred, hsm ); +} + +/*! \brief Retrieve a certificate from a URL pointer. + * + * Downloads a certificate from a given URL (file://, http://, ldap://...) + * in (URL *) format. To generate a URL * from a char * use URL_new(). + * The returned data is of type PKI_X509_CERT in case of success or NULL if + * any error occurred. If multiple objects are returned from the URL, only + * the first one is returned. Use PKI_X509_CERT_STACK_get_url() function + * to retrieve a PKI_X509_CERT_STACK * object. + * + */ + +PKI_X509_CERT *PKI_X509_CERT_get_url ( URL *url, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_get_url ( url, PKI_DATATYPE_X509_CERT, format, cred, hsm ); + +} + +PKI_X509_CERT *PKI_X509_CERT_get_mem ( PKI_MEM *mem, PKI_DATA_FORMAT format, + PKI_CRED *cred ) { + + return PKI_X509_get_mem ( mem, PKI_DATATYPE_X509_CERT, format, cred, NULL ); + +} + +/*! \brief Retrieve a stack of certificates from a URL (char *). + * + * Downloads a stack of certificates from a given URL (file://, http://, + * ldap://...) passed as a (char *). + * + * The returned data is a pointer to a PKI_X509_CERT_STACK data structure + * in case of success or NULL if any error occurred. + * If only the first object is required from the URL, use the + * PKI_X509_CERT_get_url() function instead. + * + */ + +PKI_X509_CERT_STACK *PKI_X509_CERT_STACK_get ( char *url_s, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_STACK_get ( url_s, PKI_DATATYPE_X509_CERT, format, cred, hsm ); +} + +/*! \brief Retrieve a stack of certificates from a URL (URL *) pointer. + * + * Downloads a stack of certificates from a given URL (file://, http://, + * ldap://...) passed as a (URL *). To generate a (URL *) from a (char *) + * use URL_new(). + * + * The returned data is a pointer to a PKI_X509_CERT_STACK data structure + * in case of success or NULL if any error occurred. + * If only the first object is required from the URL, use the + * PKI_X509_CERT_get_url() function instead. + * + */ + +PKI_X509_CERT_STACK *PKI_X509_CERT_STACK_get_url ( URL *url, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_STACK_get_url ( url, PKI_DATATYPE_X509_CERT, format, cred, hsm); +} + +PKI_X509_CERT_STACK *PKI_X509_CERT_STACK_get_mem(PKI_MEM *mem, + PKI_DATA_FORMAT format, PKI_CRED *cred) { + + return PKI_X509_STACK_get_mem (mem, PKI_DATATYPE_X509_CERT, format, cred, NULL); +} + +/* --------------------------- X509_CERT put (write) ----------------------- */ + +int PKI_X509_CERT_put ( PKI_X509_CERT *x, PKI_DATA_FORMAT format, + char *url_s, char *mime, PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_put ( x, format, url_s, mime, cred, hsm ); +} + +int PKI_X509_CERT_put_url ( PKI_X509_CERT *x, PKI_DATA_FORMAT format, + URL *url, char *mime, PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_put_url (x, format, url, mime, cred, hsm ); +} + +PKI_MEM *PKI_X509_CERT_put_mem ( PKI_X509_CERT *x, PKI_DATA_FORMAT format, + PKI_MEM **pki_mem, PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_put_mem ( x, format, pki_mem, cred ); +} + +int PKI_X509_CERT_STACK_put (PKI_X509_CERT_STACK *sk, PKI_DATA_FORMAT format, + char *url_s, char *mime, PKI_CRED *cred, HSM *hsm) { + + return PKI_X509_STACK_put ( sk, format, url_s, mime, cred, hsm ); +} + +int PKI_X509_CERT_STACK_put_url (PKI_X509_CERT_STACK *sk, + PKI_DATA_FORMAT format, URL *url, char *mime, + PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_STACK_put_url ( sk, format, url, mime, cred, hsm ); +} + +/* -------------------------- X509_CERT mem Operations -------------------- */ + +PKI_MEM *PKI_X509_CERT_STACK_put_mem ( PKI_X509_CERT_STACK *sk, + PKI_DATA_FORMAT format, PKI_MEM **pki_mem, + PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_STACK_put_mem ( sk, format, pki_mem, cred, hsm ); +} + diff --git a/src/utils/io/pki_x509_cms_io.c b/src/utils/io/pki_x509_cms_io.c new file mode 100644 index 00000000..e68c993b --- /dev/null +++ b/src/utils/io/pki_x509_cms_io.c @@ -0,0 +1,71 @@ +/* PKI_X509_CMS I/O management */ + +#include + +PKI_X509_CMS *PKI_X509_CMS_get ( char *url_s, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ) { + return PKI_X509_get ( url_s, PKI_DATATYPE_X509_CMS, format, cred, hsm ); +} + +PKI_X509_CMS *PKI_X509_CMS_get_url ( URL *url, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_get_url ( url, PKI_DATATYPE_X509_CMS, format, cred, hsm ); +} + +PKI_X509_CMS * PKI_X509_CMS_get_mem ( PKI_MEM *mem, PKI_DATA_FORMAT format, + PKI_CRED *cred ) { + return PKI_X509_get_mem ( mem, PKI_DATATYPE_X509_CMS, format, cred, NULL ); +} + +PKI_X509_CMS_STACK *PKI_X509_CMS_STACK_get (char *url_s, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm) { + return PKI_X509_STACK_get ( url_s, PKI_DATATYPE_X509_CMS, format, cred, hsm); +} + +PKI_X509_CMS_STACK *PKI_X509_CMS_STACK_get_url ( URL *url, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ) { + return PKI_X509_STACK_get_url (url, PKI_DATATYPE_X509_CMS, format, cred, hsm); +} + +PKI_X509_CMS_STACK *PKI_X509_CMS_STACK_get_mem( PKI_MEM *mem, + PKI_DATA_FORMAT format, PKI_CRED *cred) { + return PKI_X509_STACK_get_mem ( mem, PKI_DATATYPE_X509_CMS, + format, cred, NULL ); +} + +/* ---------------------------- PKCS7 put operations ------------------ */ + +int PKI_X509_CMS_put (PKI_X509_CMS *cms, PKI_DATA_FORMAT format, + char *url_s, char *mime, PKI_CRED *cred, HSM *hsm) { + return PKI_X509_put ( cms, format, url_s, mime, cred, hsm ); +} + +int PKI_X509_CMS_put_url(PKI_X509_CMS *cms, PKI_DATA_FORMAT format, + URL *url, char *mime, PKI_CRED *cred, HSM *hsm) { + return PKI_X509_put_url ( cms, format, url, mime, cred, hsm ); +} + + +PKI_MEM *PKI_X509_CMS_put_mem ( PKI_X509_CMS *cms, PKI_DATA_FORMAT format, + PKI_MEM **pki_mem, PKI_CRED *cred, HSM *hsm ) { + return PKI_X509_put_mem ( cms, format, pki_mem, cred ); +} + +int PKI_X509_CMS_STACK_put (PKI_X509_CMS_STACK *sk, PKI_DATA_FORMAT format, + char *url_s, char *mime, PKI_CRED *cred, HSM *hsm) { + return PKI_X509_STACK_put ( sk, format, url_s, mime, cred, hsm ); +} + +int PKI_X509_CMS_STACK_put_url (PKI_X509_CMS_STACK *sk, + PKI_DATA_FORMAT format, URL *url, char *mime, + PKI_CRED *cred, HSM *hsm ) { + return PKI_X509_STACK_put_url ( sk, format, url, mime, cred, hsm ); +} + +PKI_MEM * PKI_X509_CMS_STACK_put_mem ( PKI_X509_CMS_STACK *sk, + PKI_DATA_FORMAT format, PKI_MEM **pki_mem, PKI_CRED *cred, + HSM *hsm ) { + return PKI_X509_STACK_put_mem ( sk, format, pki_mem, cred, hsm ); +} + diff --git a/src/utils/io/pki_x509_crl_io.c b/src/utils/io/pki_x509_crl_io.c new file mode 100644 index 00000000..e92e94fd --- /dev/null +++ b/src/utils/io/pki_x509_crl_io.c @@ -0,0 +1,116 @@ +/* PKI_X509 I/O management */ + +#include + +/*! \brief Retrieve a CRL from a URL + * + * Downloads a CRL from a given URL (file://, http://, ldap://...) + * in (char *) format. + * The returned data is of type PKI_X509_CRL in case of success or NULL if + * any error occurred. If multiple objects are returned from the URL, only + * the first one is returned. Use PKI_X509_CRL_STACK_get() function + * to retrieve a PKI_X509_CERT_STACK * object. + * + */ + +PKI_X509_CRL *PKI_X509_CRL_get ( char *url_s, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_get ( url_s, PKI_DATATYPE_X509_CRL, format, cred, hsm ); +} + +/*! \brief Retrieve a CRL from a URL pointer. + * + * Downloads a CRL from a given URL (file://, http://, ldap://...) + * in (URL *) format. To generate a URL * from a char * use URL_new(). + * The returned data is of type PKI_X509_CRL * in case of success or NULL if + * any error occurred. If multiple objects are returned from the URL, only + * the first one is returned. Use PKI_X509_CRL_get_url() function + * to retrieve a PKI_X509_CRL_STACK * object. + * + */ + +PKI_X509_CRL *PKI_X509_CRL_get_url ( URL *url, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_get_url ( url, PKI_DATATYPE_X509_CRL, format, cred, hsm ); +} + +PKI_X509_CRL * PKI_X509_CRL_get_mem ( PKI_MEM *mem, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ) { + return PKI_X509_get_mem ( mem, PKI_DATATYPE_X509_CRL, format, cred, NULL ); +} + +/*! \brief Retrieve a stack of CRLs from a URL (char *). + * + * Downloads a stack of CRLs from a given URL (file://, http://, + * ldap://...) passed as a (char *). + * + * The returned data is a pointer to a PKI_X509_CRL_STACK data structure + * in case of success or NULL if any error occurred. + * If only the first object is required from the URL, use the + * PKI_X509_CRL_get_url() function instead. + * + */ + +PKI_X509_CRL_STACK *PKI_X509_CRL_STACK_get (char *url_s, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm) { + + return PKI_X509_STACK_get ( url_s, PKI_DATATYPE_X509_CRL, format, cred, hsm ); +} + +/*! \brief Retrieve a stack of CRLs from a URL (URL *) pointer. + * + * Downloads a stack of CRLs from a given URL (file://, http://, + * ldap://...) passed as a (URL *). To generate a (URL *) from a (char *) + * use URL_new(). + * + * The returned data is a pointer to a PKI_X509_CRL_STACK data structure + * in case of success or NULL if any error occurred. + * If only the first object is required from the URL, use the + * PKI_X509_CRL_get_url() function instead. + * + */ + +PKI_X509_CRL_STACK *PKI_X509_CRL_STACK_get_url ( URL *url, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_STACK_get_url ( url, PKI_DATATYPE_X509_CRL, format, cred, hsm ); +} + +PKI_X509_CRL_STACK *PKI_X509_CRL_STACK_get_mem( PKI_MEM *mem, PKI_DATA_FORMAT format, + PKI_CRED *cred ) { + + return PKI_X509_STACK_get_mem (mem, PKI_DATATYPE_X509_CRL, format, cred, NULL ); +} + +int PKI_X509_CRL_put ( PKI_X509_CRL *crl, PKI_DATA_FORMAT format, char *url_s, + PKI_CRED *cred, HSM *hsm ) { + return PKI_X509_put ( crl, format, url_s, NULL, cred, hsm ); +} + +int PKI_X509_CRL_put_url ( PKI_X509_CRL *crl, PKI_DATA_FORMAT format, + URL *url, PKI_CRED *cred, HSM *hsm ) { + return PKI_X509_put_url ( crl, format, url, NULL, cred, hsm ); +} + +PKI_MEM *PKI_X509_CRL_put_mem ( PKI_X509_CRL *crl, PKI_DATA_FORMAT format, + PKI_MEM **mem, PKI_CRED *cred, HSM *hsm ) { + return PKI_X509_put_mem ( crl, format, mem, cred ); +} + +int PKI_X509_CRL_STACK_put ( PKI_X509_CRL_STACK *sk, PKI_DATA_FORMAT format, + char *url_s, PKI_CRED *cred, HSM *hsm ) { + return PKI_X509_STACK_put ( sk, format, url_s, NULL, cred, hsm ); +} + +int PKI_X509_CRL_STACK_put_url ( PKI_X509_CRL_STACK *sk, PKI_DATA_FORMAT format, + URL *url, PKI_CRED *cred, HSM *hsm ) { + return PKI_X509_STACK_put_url ( sk, format, url, NULL, cred, hsm ); +} + +PKI_MEM *PKI_X509_CRL_STACK_put_mem (PKI_X509_CRL_STACK *sk, + PKI_DATA_FORMAT format, PKI_MEM **pki_mem, PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_STACK_put_mem ( sk, format, pki_mem, cred, hsm ); +} diff --git a/src/utils/io/pki_x509_io.c b/src/utils/io/pki_x509_io.c new file mode 100644 index 00000000..6bcba483 --- /dev/null +++ b/src/utils/io/pki_x509_io.c @@ -0,0 +1,550 @@ +/* PKI_X509 I/O management */ + +#include + +/*! \brief Returns the PKI_X509_XXX_VALUE * from the passed URL */ + +void *PKI_get_value ( char *url_s, PKI_DATATYPE type, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ) { + + PKI_X509 *x_obj = NULL; + void *ret = NULL; + + if( !url_s ) return NULL; + + if((x_obj = PKI_X509_get ( url_s, type, format, cred, hsm )) == NULL ) { + return NULL; + } + + ret = PKI_X509_dup_value ( x_obj ); + + PKI_X509_free ( x_obj ); + + return ( ret ); +} + +/*! \brief Retrieve an X509 object from a URL + * + * Downloads an X509 object from a given URL (file://, http://, ldap://...) + * in (char *) format. + * The returned data is of type PKI_X509 in case of success or NULL if + * any error occurred. If multiple objects are returned from the URL, only + * the first one is returned. Use PKI_X509_STACK_get() function + * to retrieve a PKI_X509_STACK * object. + * + */ + +PKI_X509 *PKI_X509_get ( char *url_s, PKI_DATATYPE type, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ) { + + PKI_X509 * ret = NULL; + URL *url = NULL; + + if( !url_s ) return (NULL); + + if((url = URL_new( url_s )) == NULL ) { + return (NULL); + } + + ret = PKI_X509_get_url ( url, type, format, cred, hsm ); + + if( url ) URL_free ( url ); + return( ret ); + +} + +/*! \brief Retrieve an X509 object from a URL pointer. + * + * Downloads a certificate from a given URL (file://, http://, ldap://...) + * in (URL *) format. To generate a URL * from a char * use URL_new(). + * The returned data is of type PKI_X509 in case of success or NULL if + * any error occurred. If multiple objects are returned from the URL, only + * the first one is returned. Use PKI_X509_STACK_get_url() function + * to retrieve a PKI_X509_STACK * object. + * + */ + +PKI_X509 *PKI_X509_get_url(URL * url, + PKI_DATATYPE type, + PKI_DATA_FORMAT format, + PKI_CRED * cred, + HSM * hsm ) { + + PKI_X509_STACK *sk = NULL; + PKI_X509 * ret = NULL; + + // Checks the pased argument + if (!url) { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return (NULL); + } + + // Gets the stack of PKI_X509 from the provided URL + if ((sk = PKI_X509_STACK_get_url(url, type, format, cred, hsm)) == NULL) { + return (NULL); + } + + // Checks we have at least one element, otherwise we return null + if (PKI_STACK_X509_elements(sk) <= 0) { + // Free the memory for the Stack + PKI_STACK_X509_free_all(sk); + // Returns + return NULL; + } + + // Gets the first element as the one to keep + ret = PKI_STACK_X509_pop(sk); + + // Free all the other elements in the stack + PKI_STACK_X509_free_all(sk); + + // Returns the first element from the stack + return ret; + +} + +/*! \brief Retrieve a stack of X509 objects from a URL (char *). + * + * Downloads a stack of X509 objects from a given URL (file://, http://, + * ldap://...) passed as a (char *). + * + * The returned data is a pointer to a PKI_X509_STACK data structure + * in case of success or NULL if any error occurred. + * If only the first object is required from the URL, use the + * PKI_X509_get_url() function instead. + * + */ + +PKI_X509_STACK *PKI_X509_STACK_get ( char *url_s, PKI_DATATYPE type, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ) { + + URL *url = NULL; + PKI_X509_STACK *ret = NULL; + + if( !url_s ) return (NULL); + + if((url = URL_new( url_s )) == NULL ) { + return(NULL); + } + + ret = PKI_X509_STACK_get_url ( url, type, format, cred, hsm ); + + if( url ) URL_free ( url ); + return ( ret ); +} + +/*! \brief Retrieve a stack of X509 objects from a URL (URL *) pointer. + * + * Downloads a stack of certificates from a given URL (file://, http://, + * ldap://...) passed as a (URL *). To generate a (URL *) from a (char *) + * use URL_new(). + * + * The returned data is a pointer to a PKI_X509_STACK data structure + * in case of success or NULL if any error occurred. + * If only the first object is required from the URL, use the + * PKI_X509_get_url() function instead. + * + */ + +PKI_X509_STACK *PKI_X509_STACK_get_url ( URL *url, PKI_DATATYPE type, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ) { + + PKI_X509_STACK *ret = NULL; + // Return Stack of X509 + + PKI_X509_STACK *tmp_x_sk = NULL; + // Stack of X509 returned from the URL + + PKI_MEM_STACK *mem_sk = NULL; + PKI_MEM * tmp_mem = NULL; + + PKI_X509_CERT *x = NULL; + + PKI_SSL *ssl = NULL; + + int i, j, count; + + PKI_DATATYPE x509_types[] = { + PKI_DATATYPE_PUBKEY, + PKI_DATATYPE_PRIVKEY, + PKI_DATATYPE_X509_KEYPAIR, + PKI_DATATYPE_X509_REQ, + PKI_DATATYPE_X509_CERT, + PKI_DATATYPE_X509_CRL, + PKI_DATATYPE_X509_PKCS7, + PKI_DATATYPE_X509_CMS, + PKI_DATATYPE_X509_PKCS12, + PKI_DATATYPE_X509_OCSP_REQ, + PKI_DATATYPE_X509_OCSP_RESP, + PKI_DATATYPE_X509_PRQP_REQ, + PKI_DATATYPE_X509_PRQP_RESP, + PKI_DATATYPE_X509_CMS_MSG, + PKI_DATATYPE_X509_CA, + PKI_DATATYPE_X509_TRUSTED, + PKI_DATATYPE_X509_OTHER + }; + + int x509_types_len = sizeof( x509_types ) / sizeof (int); + + if(!url) return NULL; + + // Checks for the use of the ID protocol (for HSM/Hardware) + if ( url->proto == URI_PROTO_ID ) { + + // If there is no associated HSM, that is an error + if( !hsm ) { + PKI_log_err("Protocol id:// used but no HSM!"); + return NULL ; + } + + // Returns the stack of returned items (ID Protocol) + return ( HSM_X509_STACK_get_url ( type, url, format, cred, hsm )); + } + + // If Credentials are to be used + if (cred) { + + // Gets the Credentials from the SSL + ssl = (PKI_SSL *) cred->ssl; + + // Checks for Username in the URL itself + if (!url->usr && cred->username) { + if (url->usr) PKI_Free(url->usr); + url->usr = strdup(cred->username); + } + + // Checks for the Password in the URL itself + if (!url->pwd && cred->password) { + if (url->pwd) PKI_Free(url->pwd); + url->pwd = strdup(cred->password); + } + + } + + // Gets the Stack of PKI_MEM structure from the URL + if ((mem_sk = URL_get_data_url(url, 60, 0, ssl)) == NULL) { + + // Nothing more to do + return NULL; + } + + // Allocates a new stack of X509 structures + if ((ret = PKI_STACK_X509_new()) == NULL ) { + + // Reports the error + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, + "Can not allocate PKI_STACK_X509"); + + // Free all memory + PKI_STACK_MEM_free_all(mem_sk); + + // Nothing more to do + return NULL; + } + + // Resets the counter + count = 0; + + // Cycles through the PKI_MEM from the returned 'mem_sk' + for (i = 0; i < PKI_STACK_MEM_elements(mem_sk); i++ ) { + + PKI_MEM *mem_data = NULL; + + // Gets the i-th PKI_MEM from the stack of elements + if ((mem_data = PKI_STACK_MEM_get_num(mem_sk, i)) == NULL) { + + // Reports the Error + PKI_DEBUG("Can not retrieve object from PKI_MEM stack [%d of %d]", + i, PKI_STACK_MEM_elements(mem_sk)); + + // Go to the next item + continue; + } + + // If no Datatype is specified, let's try to load any of the + // supported X509 types (X509_types array) + if ( type == PKI_DATATYPE_ANY ) { + + // Cycle through all the types + for (j = 0; j < x509_types_len; j++) { + + PKI_DATATYPE curr_type; + // Tracks the current type + + curr_type = x509_types[j]; + // Gets the current type from the array + + // Retrieves the Stack of PKI_MEM structure from the stack + if ((tmp_x_sk = PKI_X509_STACK_get_mem(mem_data, + curr_type, + format, + cred, + hsm)) != NULL) { + + // For each of the returned objects (if any) we get + // the next PKI_X509 generic structure + while ((x = PKI_STACK_X509_pop(tmp_x_sk)) != NULL) { + + // Updates the counter + count++; + + // Checks if the URL specifies an object number + if (url->object_num > 0) { + + // Adds only object with the same number + if (count == url->object_num) { + // Pushes the PKI_MEM to the returned stack + PKI_STACK_X509_push(ret, x); + } else { + // Free the Memory + PKI_X509_free(x); + } + + } else { + + // No object number was specified, let's add + // every PKI_MEM we get from the stack + PKI_STACK_X509_push(ret, x); + } + } + + // Free the memory associated with the Stack + PKI_STACK_X509_free_all(tmp_x_sk); + } + } + + } else { + + // Here we have a specific datatype we are looking for so we + // do not have to cycle through all the supported datatypes + if ((tmp_x_sk = PKI_X509_STACK_get_mem(mem_data, + type, + format, + cred, + hsm)) != NULL) { + + // Processes (removes) next element from the inner stack + while ((x = PKI_STACK_X509_pop(tmp_x_sk)) != NULL ) { + + // Updates the counter + count++; + + // Checks if an object number was specified in the URL + if (url->object_num > 0) { + + // If a number was provided, check the counter is + // reflecting the right object number + if (count == url->object_num) { + // Push the selected value to the return stack + PKI_STACK_X509_push(ret, x); + } else { + // Free the memory for the value since + // it is not the one we were looking for + PKI_X509_free(x); + } + + } else { + + // No specific object number was provided in the + // URL, therefore let's add all objects to the + // return stack + PKI_STACK_X509_push(ret, x); + } + } + + // Nothing more to do with the stack, let's free it + PKI_STACK_X509_free_all(tmp_x_sk); + } + } + } + + // Checks if we have memory to free + if (mem_sk) { + + // Free all the elements from the Stack of PKI_MEM + while ((tmp_mem = PKI_STACK_MEM_pop(mem_sk)) != NULL) { + // Free the memory for the node + PKI_MEM_free(tmp_mem); + } + + // Free the stack itself + PKI_STACK_MEM_free_all(mem_sk); + } + + // Returns the Stack of PKI_X509 structures + return ret; +} + +/* --------------------------- X509_CERT put (write) ----------------------- */ + +/*! \brief Puts a PKI_X509 object into the passed url (string) */ + +int PKI_X509_put ( PKI_X509 *x, PKI_DATA_FORMAT format, char *url_string, + const char *mime, PKI_CRED *cred, HSM *hsm ) { + + PKI_X509_STACK *sk = NULL; + int ret = PKI_OK; + + if (!x || !url_string) return (PKI_ERR); + + if ((sk = PKI_STACK_X509_new()) == NULL) { + return PKI_ERR; + } + + if (PKI_STACK_X509_push(sk, x) == PKI_ERR) { + PKI_STACK_X509_free(sk); + return PKI_ERR; + } + + ret = PKI_X509_STACK_put(sk, format, url_string, mime, cred, hsm); + + if (sk) { + + // We just need to pop the cert - not free the mem! + while ((x = PKI_STACK_X509_pop(sk)) != NULL) { /* Nop */ }; + + // Let's free the list itself + PKI_STACK_X509_free( sk ); + } + + return (ret); + +} + +/*! \brief Put a PKI_X509 object to the specified URL */ + +int PKI_X509_put_url ( PKI_X509 *x, PKI_DATA_FORMAT format, URL *url, + const char *mime, PKI_CRED *cred, HSM *hsm ) { + + PKI_X509_STACK *sk = NULL; + int ret = PKI_OK; + + if (!x || !url) return (PKI_ERR); + + if ((sk = PKI_STACK_X509_new()) == NULL) { + return PKI_ERR; + } + + if (PKI_STACK_X509_push(sk, x) == PKI_ERR) { + PKI_STACK_X509_free(sk); + return PKI_ERR; + } + + ret = PKI_X509_STACK_put_url(sk, format, url, mime, cred, hsm); + + if( sk ) { + // We just need to pop the cert - not free the mem + while ((x = PKI_STACK_X509_pop(sk)) != NULL) { /* Nop */ }; + + // Let's free the list itself + PKI_STACK_X509_free(sk); + } + + return (ret); +} + +/*! \brief Writes the PKI_X509_XXX_VALUE to the passed url */ + +int PKI_X509_put_value ( void *x, PKI_DATATYPE type, PKI_DATA_FORMAT format, + char *url_string, const char *mime, PKI_CRED *cred, HSM *hsm ) { + + PKI_X509 *x_obj = NULL; + int ret = PKI_OK; + + if (!x || !url_string) return PKI_ERR; + + if ((x_obj = PKI_X509_new(type, hsm)) == NULL) { + return PKI_ERR; + } + + x_obj->value = x; + + ret = PKI_X509_put(x_obj, format, url_string, mime, cred, hsm); + + x_obj->value = NULL; + + PKI_X509_free(x_obj); + + return ret; +} + +/*! \brief Puts a stack of PKI_X509 objects to the url passed as a string */ + +int PKI_X509_STACK_put (PKI_X509_STACK *sk, PKI_DATA_FORMAT format, + char *url_string, const char *mime, PKI_CRED *cred, HSM *hsm) { + + URL *url = NULL; + int ret = PKI_OK; + + if (!sk || !url_string) return PKI_ERR; + + if ((url = URL_new(url_string)) == NULL) + return PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Can not parse URL (%s)", url_string); + + ret = PKI_X509_STACK_put_url(sk, format, url, mime, cred, hsm); + + if (url) URL_free(url); + + return ret; + +} + +/*! \brief Puts a stack of PKI_X509 objects to a specified URL */ + +int PKI_X509_STACK_put_url (PKI_X509_STACK *sk, PKI_DATA_FORMAT format, + URL *url, const char *mime, PKI_CRED *cred, HSM *hsm) { + + PKI_MEM *mem = NULL; + PKI_X509 *x_obj = NULL; + PKI_SSL *ssl = NULL; + + int idx = 0; + int ret = 0; + + // Input Checks + if( !sk || !url ) + return PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + + // Checks we have at least one element in the stack + if((idx = PKI_STACK_X509_elements (sk)) < 1 ) + return PKI_ERROR(PKI_ERR_PARAM_NULL, "No Elements in passed Stack"); + + // Checks we are not using an HSM + if( url->proto == URI_PROTO_ID && hsm ) + return ( HSM_X509_STACK_put_url ( sk, url, cred, hsm )); + + // Put the content of the stack into the destination URL + if(PKI_X509_STACK_put_mem(sk, format, &mem, cred, hsm) == NULL) { + // Free the Memory + if (mem) PKI_MEM_free(mem); + // Returns and reports the error + return PKI_ERROR(PKI_ERR_POINTER_NULL, NULL); + } + + // Lets get the type of X509 objects we have on the stack + if((x_obj = PKI_STACK_X509_get_num ( sk, 0 )) != NULL ) { + mime = PKI_X509_get_mimetype(x_obj->type); + } else { + mime = PKI_X509_get_mimetype(PKI_DATATYPE_UNKNOWN); + } + + // Let's copy the credentials, if any were provided + if ( cred ) { + ssl = (PKI_SSL *) cred->ssl; + if ( !url->usr && cred->username ) { + url->usr = strdup ( cred->username ); + } + + if ( !url->pwd && cred->password ) { + url->pwd = strdup ( cred->password ); + } + } + + ret = URL_put_data_url(url, mem, (char *) mime, NULL, 60, 0, ssl); + + if ( mem ) PKI_MEM_free ( mem ); + + return ( ret ); +} + + diff --git a/src/utils/io/pki_x509_p12_io.c b/src/utils/io/pki_x509_p12_io.c new file mode 100644 index 00000000..30f5f351 --- /dev/null +++ b/src/utils/io/pki_x509_p12_io.c @@ -0,0 +1,124 @@ +/* PKI_X509_PKCS12 I/O management */ + +#include + +/* --------------------------- General I/O functions --------------------- */ + +PKI_X509_PKCS12 *PKI_X509_PKCS12_get ( char *url_s, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_get ( url_s, PKI_DATATYPE_X509_PKCS12, format, cred, hsm ); +} + +PKI_X509_PKCS12 *PKI_X509_PKCS12_get_url ( URL *url, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm) { + + return PKI_X509_get_url ( url, PKI_DATATYPE_X509_PKCS12, format, cred, hsm ); +} + +PKI_X509_PKCS12 *PKI_X509_PKCS12_get_mem ( PKI_MEM *mem, PKI_DATA_FORMAT format, + PKI_CRED *cred ) { + + PKI_X509_PKCS12 *tmp_p12 = NULL; + + tmp_p12 = PKI_X509_get_mem ( mem, PKI_DATATYPE_X509_PKCS12, format, cred, NULL); + + if ( PKI_X509_PKCS12_verify_cred ( tmp_p12, cred ) == PKI_ERR ) { + PKI_log_debug("Wrong Credentials provided!"); + PKI_X509_PKCS12_free ( tmp_p12 ); + return NULL; + } + + return tmp_p12; +} + +PKI_X509_PKCS12_STACK *PKI_X509_PKCS12_STACK_get (char *url_s, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm) { + return PKI_X509_STACK_get ( url_s, PKI_DATATYPE_X509_PKCS12, format, cred, hsm); +} + +PKI_X509_PKCS12_STACK *PKI_X509_PKCS12_STACK_get_url ( URL *url, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_STACK_get_url(url, PKI_DATATYPE_X509_PKCS12, format, cred, hsm); +} + +PKI_X509_PKCS12_STACK *PKI_X509_PKCS12_STACK_get_mem ( PKI_MEM *mem, + PKI_DATA_FORMAT format, PKI_CRED *cred) { + + PKI_X509_PKCS12_STACK *tmp_sk = NULL; + PKI_X509_PKCS12_STACK *ret_sk = NULL; + PKI_X509_PKCS12 *tmp_p12 = NULL; + + /* We need to get the internal format first and then perform some + additional operations, i.e. verify the creds if present */ + + if(( tmp_sk = PKI_X509_STACK_get_mem ( mem, + PKI_DATATYPE_X509_PKCS12, format, cred, NULL)) == NULL ) { + return NULL; + } + + if((ret_sk = PKI_STACK_X509_PKCS12_new()) == NULL ) { + return NULL; + } + + while ((tmp_p12 = PKI_STACK_X509_PKCS12_pop ( tmp_sk )) != NULL ) { + /* Let's add only the ones that we can decrypt */ + if ( PKI_X509_PKCS12_verify_cred ( tmp_p12, cred ) == PKI_OK ) { + PKI_STACK_X509_PKCS12_push( ret_sk, tmp_p12 ); + } else { + PKI_X509_PKCS12_free ( tmp_p12 ); + } + } + + PKI_STACK_X509_PKCS12_free ( ret_sk ); + + return ret_sk; +} + +/* ---------------------------- PKCS12 put operations ------------------ */ + +int PKI_X509_PKCS12_put (PKI_X509_PKCS12 *p12, PKI_DATA_FORMAT format, + char *url_s, char *mime, PKI_CRED *cred, HSM *hsm) { + + return PKI_X509_put ( p12, format, url_s, mime, cred, hsm ); +} + +int PKI_X509_PKCS12_put_url(PKI_X509_PKCS12 *p12, PKI_DATA_FORMAT format, + URL *url, char *mime, PKI_CRED *cred, HSM *hsm) { + + return PKI_X509_put_url ( p12, format, url, mime, cred, hsm ); +} + + +int PKI_X509_PKCS12_STACK_put ( PKI_X509_PKCS12_STACK *sk, + PKI_DATA_FORMAT format, char *url_s, char *mime, + PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_STACK_put ( sk, format, url_s, mime, cred, hsm ); +} + +int PKI_X509_PKCS12_STACK_put_url (PKI_X509_PKCS12_STACK *sk, + PKI_DATA_FORMAT format, URL *url, char *mime, + PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_STACK_put_url ( sk, format, url, mime, cred, hsm ); +} + + +PKI_MEM *PKI_X509_PKCS12_STACK_put_mem ( PKI_X509_PKCS12_STACK *sk, + PKI_DATA_FORMAT format, PKI_MEM **pki_mem, + PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_STACK_put_mem ( sk, format, pki_mem, cred, hsm ); +} + + +/*! \brief Puts a PKI_X509_PKCS12 in a PKI_MEM structure */ + +PKI_MEM *PKI_X509_PKCS12_put_mem ( PKI_X509_PKCS12 *p12, + PKI_DATA_FORMAT format, PKI_MEM **pki_mem, + PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_put_mem ( p12, format, pki_mem, cred ); +} diff --git a/src/utils/io/pki_x509_pkcs7_io.c b/src/utils/io/pki_x509_pkcs7_io.c new file mode 100644 index 00000000..617dc5a5 --- /dev/null +++ b/src/utils/io/pki_x509_pkcs7_io.c @@ -0,0 +1,81 @@ +/* PKI_X509_PKCS7 I/O management */ + +#include + +PKI_X509_PKCS7 *PKI_X509_PKCS7_get ( char *url_s, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_get ( url_s, PKI_DATATYPE_X509_PKCS7, format, cred, hsm ); +} + +PKI_X509_PKCS7 *PKI_X509_PKCS7_get_url ( URL *url, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_get_url ( url, PKI_DATATYPE_X509_PKCS7, format, cred, hsm ); +} + +PKI_X509_PKCS7 * PKI_X509_PKCS7_get_mem ( PKI_MEM *mem, PKI_DATA_FORMAT format, + PKI_CRED *cred ) { + return PKI_X509_get_mem ( mem, PKI_DATATYPE_X509_PKCS7, format, cred, NULL ); +} + +PKI_X509_PKCS7_STACK *PKI_X509_PKCS7_STACK_get (char *url_s, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm) { + + return PKI_X509_STACK_get ( url_s, PKI_DATATYPE_X509_PKCS7, format, cred, hsm); +} + +PKI_X509_PKCS7_STACK *PKI_X509_PKCS7_STACK_get_url ( URL *url, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_STACK_get_url (url, PKI_DATATYPE_X509_PKCS7, format, cred, hsm); +} + +PKI_X509_PKCS7_STACK *PKI_X509_PKCS7_STACK_get_mem( PKI_MEM *mem, + PKI_DATA_FORMAT format, PKI_CRED *cred) { + + return PKI_X509_STACK_get_mem ( mem, PKI_DATATYPE_X509_PKCS7, + format, cred, NULL ); +} + +/* ---------------------------- PKCS7 put operations ------------------ */ + +int PKI_X509_PKCS7_put (PKI_X509_PKCS7 *p7, PKI_DATA_FORMAT format, + char *url_s, char *mime, PKI_CRED *cred, HSM *hsm) { + + return PKI_X509_put ( p7, format, url_s, mime, cred, hsm ); +} + +int PKI_X509_PKCS7_put_url(PKI_X509_PKCS7 *p7, PKI_DATA_FORMAT format, + URL *url, char *mime, PKI_CRED *cred, HSM *hsm) { + + return PKI_X509_put_url ( p7, format, url, mime, cred, hsm ); +} + + +PKI_MEM *PKI_X509_PKCS7_put_mem ( PKI_X509_PKCS7 *p7, PKI_DATA_FORMAT format, + PKI_MEM **pki_mem, PKI_CRED *cred, HSM *hsm ) { + + PKI_log_debug("B64_DEBUG"); + return PKI_X509_put_mem ( p7, format, pki_mem, cred ); +} + +int PKI_X509_PKCS7_STACK_put (PKI_X509_PKCS7_STACK *sk, PKI_DATA_FORMAT format, + char *url_s, char *mime, PKI_CRED *cred, HSM *hsm) { + + return PKI_X509_STACK_put ( sk, format, url_s, mime, cred, hsm ); +} + +int PKI_X509_PKCS7_STACK_put_url (PKI_X509_PKCS7_STACK *sk, + PKI_DATA_FORMAT format, URL *url, char *mime, + PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_STACK_put_url ( sk, format, url, mime, cred, hsm ); +} + +PKI_MEM * PKI_X509_PKCS7_STACK_put_mem ( PKI_X509_PKCS7_STACK *sk, + PKI_DATA_FORMAT format, PKI_MEM **pki_mem, PKI_CRED *cred, + HSM *hsm ) { + + return PKI_X509_STACK_put_mem ( sk, format, pki_mem, cred, hsm ); +} diff --git a/src/utils/io/pki_x509_req_io.c b/src/utils/io/pki_x509_req_io.c new file mode 100644 index 00000000..6a355492 --- /dev/null +++ b/src/utils/io/pki_x509_req_io.c @@ -0,0 +1,83 @@ +/* PKI_X509_REQ I/O management */ + +#include + +PKI_X509_REQ *PKI_X509_REQ_get ( char *url_s, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_get ( url_s, PKI_DATATYPE_X509_REQ, format, cred, hsm ); +} + +PKI_X509_REQ *PKI_X509_REQ_get_url ( URL *url, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_get_url ( url, PKI_DATATYPE_X509_REQ, format, cred, hsm ); +} + +PKI_X509_REQ *PKI_X509_REQ_get_mem ( PKI_MEM *mem, PKI_DATA_FORMAT format, + PKI_CRED *cred ) { + + return PKI_X509_get_mem (mem, PKI_DATATYPE_X509_REQ, format, cred, NULL ); +} + +PKI_X509_REQ_STACK *PKI_X509_REQ_STACK_get (char *url_s, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm) { + + return PKI_X509_STACK_get ( url_s, PKI_DATATYPE_X509_REQ, format, cred, hsm ); +} + + +PKI_X509_REQ_STACK *PKI_X509_REQ_STACK_get_url ( URL *url, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_STACK_get_url ( url, PKI_DATATYPE_X509_REQ, format, cred, hsm ); +} + + +PKI_X509_REQ_STACK *PKI_X509_REQ_STACK_get_mem ( PKI_MEM *mem, + PKI_DATA_FORMAT format, PKI_CRED *cred) { + + return PKI_X509_STACK_get_mem ( mem, PKI_DATATYPE_X509_REQ, format, cred, NULL); +} + +/* ---------------------------- X509_REQ put operations ------------------ */ + +int PKI_X509_REQ_put (PKI_X509_REQ *req, PKI_DATA_FORMAT format, + char *url_s, char *mime, PKI_CRED *cred, HSM *hsm) { + + return PKI_X509_put ( req, format, url_s, NULL, cred, hsm ); +} + +int PKI_X509_REQ_put_url(PKI_X509_REQ *req, PKI_DATA_FORMAT format, + URL *url, char *mime, PKI_CRED *cred, HSM *hsm) { + + return PKI_X509_put_url ( req, format, url, mime, cred, hsm ); +} + +PKI_MEM *PKI_X509_REQ_put_mem ( PKI_X509_REQ *r, PKI_DATA_FORMAT format, + PKI_MEM **pki_mem, PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_put_mem ( r, format, pki_mem, cred ); +} + + +int PKI_X509_REQ_STACK_put ( PKI_X509_REQ_STACK *sk, PKI_DATA_FORMAT format, + char *url_s, char *mime, + PKI_CRED *cred, HSM *hsm) { + + return PKI_X509_STACK_put ( sk, format, url_s, mime, cred, hsm ); +} + +int PKI_X509_REQ_STACK_put_url (PKI_X509_REQ_STACK *sk, PKI_DATA_FORMAT format, + URL *url, char *mime, PKI_CRED *cred, + HSM *hsm ) { + + return PKI_X509_STACK_put_url (sk, format, url, mime, cred, hsm ); +} + +PKI_MEM *PKI_X509_REQ_STACK_put_mem (PKI_X509_REQ_STACK *sk, + PKI_DATA_FORMAT format, + PKI_MEM **pki_mem, PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_STACK_put_mem ( sk, format, pki_mem, cred, hsm ); +} diff --git a/src/utils/io/pki_x509_xpair_io.c b/src/utils/io/pki_x509_xpair_io.c new file mode 100644 index 00000000..b6b00b9c --- /dev/null +++ b/src/utils/io/pki_x509_xpair_io.c @@ -0,0 +1,164 @@ +/* PKI_X509 I/O management */ + +#include + + +/*! \brief Retrieve a Cross Cert Pair from a URL + * + * Downloads a XPAIR from a given URL (file://, http://, ldap://...) + * in (char *) format. + * The returned data is of type PKI_X509_XPAIR in case of success or NULL if + * any error occurred. If multiple objects are returned from the URL, only + * the first one is returned. Use PKI_X509_XPAIR_STACK_get() function + * to retrieve a PKI_X509_XPAIR_STACK * object. + */ + +PKI_X509_XPAIR *PKI_X509_XPAIR_get ( char *url_s, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_get ( url_s, PKI_DATATYPE_X509_XPAIR, format, cred, hsm ); +} + +/*! \brief Retrieve a cross certificate pair from a URL pointer. + * + * Downloads a XPAIR from a given URL (file://, http://, ldap://...) + * in (URL *) format. To generate a URL * from a char * use URL_new(). + * The returned data is of type PKI_X509_XPAIR in case of success or NULL if + * any error occurred. If multiple objects are returned from the URL, only + * the first one is returned. Use PKI_X509_XPAIR_STACK_get_url() function + * to retrieve a PKI_X509_XPAIR_STACK * object. + * + */ + +PKI_X509_XPAIR *PKI_X509_XPAIR_get_url ( URL *url, PKI_DATA_FORMAT format, + PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_get_url ( url, PKI_DATATYPE_X509_XPAIR, format, cred, hsm ); +} + +/*! \brief Retrieve a stack of cross cert pair from a URL (char *). + * + * Downloads a stack of certificates from a given URL (file://, http://, + * ldap://...) passed as a (char *). + * + * The returned data is a pointer to a PKI_X509_XPAIR_STACK data structure + * in case of success or NULL if any error occurred. + * If only the first object is required from the URL, use the + * PKI_X509_XPAIR_get_url() function instead. + * + */ + +PKI_X509_XPAIR_STACK *PKI_X509_XPAIR_STACK_get ( char *url_s, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_STACK_get ( url_s, PKI_DATATYPE_X509_XPAIR, format, cred, hsm); +} + +/*! \brief Retrieve a stack of cross cert pair from a URL (URL *) pointer. + * + * Downloads a stack of XPAIR from a given URL (file://, http://, + * ldap://...) passed as a (URL *). To generate a (URL *) from a (char *) + * use URL_new(). + * + * The returned data is a pointer to a PKI_X509_XPAIR_STACK data structure + * in case of success or NULL if any error occurred. + * If only the first object is required from the URL, use the + * PKI_X509_XPAIR_get_url() function instead. + * + */ + +PKI_X509_XPAIR_STACK *PKI_X509_XPAIR_STACK_get_url ( URL *url, + PKI_DATA_FORMAT format, PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_STACK_get_url ( url, PKI_DATATYPE_X509_XPAIR, format, cred, hsm ); +} + +/* --------------------------- X509_XPAIR put (write) ----------------------- */ + +int PKI_X509_XPAIR_put ( PKI_X509_XPAIR *x, PKI_DATA_FORMAT format, + char *url_s, char *mime, PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_put ( x, format, url_s, mime, cred, hsm ); +} + +PKI_MEM *PKI_X509_XPAIR_put_mem ( PKI_X509_XPAIR *x, PKI_DATA_FORMAT format, + PKI_MEM **pki_mem, PKI_CRED *cred, HSM *hsm ) { + return PKI_X509_put_mem ( x, format, pki_mem, cred ); +} + +int PKI_X509_XPAIR_STACK_put (PKI_X509_XPAIR_STACK *sk, PKI_DATA_FORMAT format, + char *url_s, char *mime, PKI_CRED *cred, HSM *hsm) { + + return PKI_X509_STACK_put ( sk, format, url_s, mime, cred, hsm ); +} + + +int PKI_X509_XPAIR_STACK_put_url (PKI_X509_XPAIR_STACK *sk, + PKI_DATA_FORMAT format, URL *url, + char *mime, PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_STACK_put_url ( sk, format, url, mime, cred, hsm ); +} + +/* -------------------------- X509_XPAIR mem Operations -------------------- */ + +PKI_X509_XPAIR_STACK *PKI_X509_XPAIR_STACK_get_mem(PKI_MEM *mem, + PKI_DATA_FORMAT format, PKI_CRED *cred) { + return PKI_X509_STACK_get_mem ( mem, PKI_DATATYPE_X509_XPAIR, + format, cred, NULL ); +} + +PKI_MEM * PKI_X509_XPAIR_STACK_put_mem ( PKI_X509_XPAIR_STACK *sk, + PKI_DATA_FORMAT format, PKI_MEM **pki_mem, + PKI_CRED *cred, HSM *hsm ) { + + return PKI_X509_STACK_put_mem ( sk, format, pki_mem, cred, hsm ); +} + +int PKI_XPAIR_print( BIO *bio, PKI_XPAIR *xp_val ) { + + PKI_X509_CERT *x_tmp = NULL; + + if ( !bio || !xp_val ) return ( PKI_ERR ); + + BIO_printf(bio, "\nCross Certificate Pair:\n"); + + BIO_printf(bio, " Forward Certificate:\n" ); + if (( x_tmp = PKI_X509_new_dup_value ( PKI_DATATYPE_X509_CERT, + xp_val->forward, NULL )) != NULL ) { + + BIO_printf(bio, " Serial=%s\n", + PKI_X509_CERT_get_parsed ( x_tmp, + PKI_X509_DATA_SERIAL )); + BIO_printf(bio, " Subject=%s\n", + PKI_X509_CERT_get_parsed ( x_tmp, + PKI_X509_DATA_SUBJECT )); + BIO_printf(bio, " Issuer=%s\n", + PKI_X509_CERT_get_parsed ( x_tmp, + PKI_X509_DATA_ISSUER )); + x_tmp->cb->to_pem ( (PKI_IO *) bio, (void *) xp_val->forward ); + PKI_X509_free ( x_tmp ); + } else { + BIO_printf(bio, " No forward certificate present.\n\n"); + } + + BIO_printf(bio, " Reverse Certificate:\n" ); + if (( x_tmp = PKI_X509_new_dup_value ( PKI_DATATYPE_X509_CERT, + xp_val->reverse, NULL )) != NULL ) { + BIO_printf(bio, " Serial=%s\n", + PKI_X509_CERT_get_parsed ( x_tmp, + PKI_X509_DATA_SERIAL )); + BIO_printf(bio, " Subject=%s\n", + PKI_X509_CERT_get_parsed ( x_tmp, + PKI_X509_DATA_SUBJECT )); + BIO_printf(bio, " Issuer=%s\n", + PKI_X509_CERT_get_parsed ( x_tmp, + PKI_X509_DATA_ISSUER )); + x_tmp->cb->to_pem ( (PKI_IO *) bio, (void *) xp_val->reverse ); + PKI_X509_free ( x_tmp ); + } else { + BIO_printf(bio, " No reverse certificate present.\n\n"); + } + + return ( PKI_OK ); +} diff --git a/src/utils/net/Makefile.am b/src/utils/net/Makefile.am new file mode 100644 index 00000000..939a611e --- /dev/null +++ b/src/utils/net/Makefile.am @@ -0,0 +1,31 @@ +## OpenCA Makefile - by Massimiliano Pala +## (c) 1999-2014 by Massimiliano Pala and OpenCA Project +## All Rights Reserved + +TOP = .. +include $(TOP)/global-vars + +BASE_DEFS = + +DEFS = $(OPENCA_DEFS) + +AM_CPPFLAGS = -I$(TOP) \ + $(openssl_cflags) \ + $(libxml2_cflags) \ + $(COND_INCLUDES) + +SRCS = \ + dns.c \ + ldap.c \ + pg.c \ + pki_socket.c ssl.c \ + http_s.c \ + mysql.c \ + pkcs11.c \ + sock.c \ + url.c + +noinst_LTLIBRARIES = libpki-net.la +libpki_net_la_SOURCES = $(SRCS) +libpki_net_la_CFLAGS = $(BUILD_LIBPKI_CFLAGS) + diff --git a/src/utils/net/Makefile.in b/src/utils/net/Makefile.in new file mode 100644 index 00000000..95db8cc5 --- /dev/null +++ b/src/utils/net/Makefile.in @@ -0,0 +1,865 @@ +# Makefile.in generated by automake 1.16.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = src/net +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(SHELL) $(top_srcdir)/build/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/src/libpki/config.h \ + $(top_builddir)/src/libpki/libpki_enables.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +libpki_net_la_LIBADD = +am__objects_1 = libpki_net_la-dns.lo libpki_net_la-ldap.lo \ + libpki_net_la-pg.lo libpki_net_la-pki_socket.lo \ + libpki_net_la-ssl.lo libpki_net_la-http_s.lo \ + libpki_net_la-mysql.lo libpki_net_la-pkcs11.lo \ + libpki_net_la-sock.lo libpki_net_la-url.lo +am_libpki_net_la_OBJECTS = $(am__objects_1) +libpki_net_la_OBJECTS = $(am_libpki_net_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libpki_net_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libpki_net_la_CFLAGS) \ + $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src/libpki +depcomp = $(SHELL) $(top_srcdir)/build/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/libpki_net_la-dns.Plo \ + ./$(DEPDIR)/libpki_net_la-http_s.Plo \ + ./$(DEPDIR)/libpki_net_la-ldap.Plo \ + ./$(DEPDIR)/libpki_net_la-mysql.Plo \ + ./$(DEPDIR)/libpki_net_la-pg.Plo \ + ./$(DEPDIR)/libpki_net_la-pkcs11.Plo \ + ./$(DEPDIR)/libpki_net_la-pki_socket.Plo \ + ./$(DEPDIR)/libpki_net_la-sock.Plo \ + ./$(DEPDIR)/libpki_net_la-ssl.Plo \ + ./$(DEPDIR)/libpki_net_la-url.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libpki_net_la_SOURCES) +DIST_SOURCES = $(libpki_net_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/build/depcomp \ + $(top_srcdir)/build/mkinstalldirs +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_DATE = @BUILD_DATE@ +BUILD_DATE_FULL = @BUILD_DATE_FULL@ +BUILD_DATE_PRETTY = @BUILD_DATE_PRETTY@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CHMOD = @CHMOD@ +CHOWN = @CHOWN@ +CP = @CP@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CPU = @CPU@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CXX = @CXX@ +CYGPATH_W = @CYGPATH_W@ +DATE = @DATE@ +DEFS = $(OPENCA_DEFS) +DEPDIR = @DEPDIR@ +DESTDIR = @DESTDIR@ +DIST_NAME = @DIST_NAME@ +DIST_VERSION = @DIST_VERSION@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +GZIP = @GZIP@ +HAS_PKGCONF = @HAS_PKGCONF@ +INSTALL = @INSTALL@ +INSTALL_BUILDER = @INSTALL_BUILDER@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKE = @MAKE@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR = @MKDIR@ +MKDIR_P = @MKDIR_P@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PDFLATEX = @PDFLATEX@ +PERL = @PERL@ +PG_CONFIG = @PG_CONFIG@ +PG_CPPFLAGS = @PG_CPPFLAGS@ +PKGMK = @PKGMK@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POD2MAN = @POD2MAN@ +PWD = @PWD@ +RANLIB = @RANLIB@ +RC = @RC@ +RPM = @RPM@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TAR = @TAR@ +TODAY = @TODAY@ +VERSION = @VERSION@ +ZIP = @ZIP@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_aux_dir = @ac_aux_dir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +arch_target = @arch_target@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +composite_cflags = @composite_cflags@ +composite_ldadd = @composite_ldadd@ +composite_ldflags = @composite_ldflags@ +conf_dir = @conf_dir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +day = @day@ +dist_group = @dist_group@ +dist_user = @dist_user@ +docdir = @docdir@ +dvidir = @dvidir@ +enable_debug = @enable_debug@ +etc_dir = @etc_dir@ +exec_prefix = @exec_prefix@ +extra_checks = @extra_checks@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +hr = @hr@ +htmldir = @htmldir@ +iface_age = @iface_age@ +iface_current = @iface_current@ +iface_revision = @iface_revision@ +iface_version = @iface_version@ +include_dir = @include_dir@ +include_prefix = @include_prefix@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +kmf_cflags = @kmf_cflags@ +kmf_ldadd = @kmf_ldadd@ +kmf_libflags = @kmf_libflags@ +kmf_prefix = @kmf_prefix@ +ldap_cflags = @ldap_cflags@ +ldap_ldadd = @ldap_ldadd@ +ldap_ldflags = @ldap_ldflags@ +ldap_prefix = @ldap_prefix@ +ldap_vendor = @ldap_vendor@ +lib_major = @lib_major@ +lib_micro = @lib_micro@ +lib_minor = @lib_minor@ +lib_prefix = @lib_prefix@ +lib_revision = @lib_revision@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libpki_cflags = @libpki_cflags@ +libpki_ldadd = @libpki_ldadd@ +libpki_ldflags = @libpki_ldflags@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +min = @min@ +mkdir_p = @mkdir_p@ +mon = @mon@ +my_cflags = @my_cflags@ +my_ldadd = @my_ldadd@ +my_ldflags = @my_ldflags@ +myarch = @myarch@ +mybits = @mybits@ +mybits_install = @mybits_install@ +mysql_cflags = @mysql_cflags@ +mysql_config = @mysql_config@ +mysql_ldadd = @mysql_ldadd@ +mysql_ldflags = @mysql_ldflags@ +mysql_prefix = @mysql_prefix@ +oldincludedir = @oldincludedir@ +openssl_cflags = @openssl_cflags@ +openssl_include = @openssl_include@ +openssl_ldadd = @openssl_ldadd@ +openssl_ldflags = @openssl_ldflags@ +openssl_prefix = @openssl_prefix@ +openssl_static_libs = @openssl_static_libs@ +oqs_cflags = @oqs_cflags@ +oqs_ldadd = @oqs_ldadd@ +oqs_ldflags = @oqs_ldflags@ +oqsprov_cflags = @oqsprov_cflags@ +oqsprov_ldadd = @oqsprov_ldadd@ +oqsprov_ldflags = @oqsprov_ldflags@ +package_build = @package_build@ +package_prefix = @package_prefix@ +pdfdir = @pdfdir@ +pg_cflags = @pg_cflags@ +pg_config = @pg_config@ +pg_ldadd = @pg_ldadd@ +pg_ldflags = @pg_ldflags@ +pg_prefix = @pg_prefix@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pthread_opts = @pthread_opts@ +resolv_ldadd = @resolv_ldadd@ +rpath = @rpath@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sdkver = @sdkver@ +sec = @sec@ +sharedstatedir = @sharedstatedir@ +shlext = @shlext@ +shlib_history = @shlib_history@ +shlib_version = @shlib_version@ +srcdir = @srcdir@ +sys_cflags = @sys_cflags@ +sys_ldadd = @sys_ldadd@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +test_libs = @test_libs@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +txt_revision = @txt_revision@ +xml2_cflags = @xml2_cflags@ +xml2_config = @xml2_config@ +xml2_include = @xml2_include@ +xml2_ldadd = @xml2_ldadd@ +xml2_ldflags = @xml2_ldflags@ +xml2_prefix = @xml2_prefix@ +yr = @yr@ +TOP = .. +BASE_DEFS = +AM_CPPFLAGS = -I$(TOP) \ + $(openssl_cflags) \ + $(libxml2_cflags) \ + $(COND_INCLUDES) + +SRCS = \ + dns.c \ + ldap.c \ + pg.c \ + pki_socket.c ssl.c \ + http_s.c \ + mysql.c \ + pkcs11.c \ + sock.c \ + url.c + +noinst_LTLIBRARIES = libpki-net.la +libpki_net_la_SOURCES = $(SRCS) +libpki_net_la_CFLAGS = $(BUILD_LIBPKI_CFLAGS) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/net/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/net/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libpki-net.la: $(libpki_net_la_OBJECTS) $(libpki_net_la_DEPENDENCIES) $(EXTRA_libpki_net_la_DEPENDENCIES) + $(AM_V_CCLD)$(libpki_net_la_LINK) $(libpki_net_la_OBJECTS) $(libpki_net_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_net_la-dns.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_net_la-http_s.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_net_la-ldap.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_net_la-mysql.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_net_la-pg.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_net_la-pkcs11.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_net_la-pki_socket.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_net_la-sock.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_net_la-ssl.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpki_net_la-url.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +libpki_net_la-dns.lo: dns.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_net_la_CFLAGS) $(CFLAGS) -MT libpki_net_la-dns.lo -MD -MP -MF $(DEPDIR)/libpki_net_la-dns.Tpo -c -o libpki_net_la-dns.lo `test -f 'dns.c' || echo '$(srcdir)/'`dns.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_net_la-dns.Tpo $(DEPDIR)/libpki_net_la-dns.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dns.c' object='libpki_net_la-dns.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_net_la_CFLAGS) $(CFLAGS) -c -o libpki_net_la-dns.lo `test -f 'dns.c' || echo '$(srcdir)/'`dns.c + +libpki_net_la-ldap.lo: ldap.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_net_la_CFLAGS) $(CFLAGS) -MT libpki_net_la-ldap.lo -MD -MP -MF $(DEPDIR)/libpki_net_la-ldap.Tpo -c -o libpki_net_la-ldap.lo `test -f 'ldap.c' || echo '$(srcdir)/'`ldap.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_net_la-ldap.Tpo $(DEPDIR)/libpki_net_la-ldap.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ldap.c' object='libpki_net_la-ldap.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_net_la_CFLAGS) $(CFLAGS) -c -o libpki_net_la-ldap.lo `test -f 'ldap.c' || echo '$(srcdir)/'`ldap.c + +libpki_net_la-pg.lo: pg.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_net_la_CFLAGS) $(CFLAGS) -MT libpki_net_la-pg.lo -MD -MP -MF $(DEPDIR)/libpki_net_la-pg.Tpo -c -o libpki_net_la-pg.lo `test -f 'pg.c' || echo '$(srcdir)/'`pg.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_net_la-pg.Tpo $(DEPDIR)/libpki_net_la-pg.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pg.c' object='libpki_net_la-pg.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_net_la_CFLAGS) $(CFLAGS) -c -o libpki_net_la-pg.lo `test -f 'pg.c' || echo '$(srcdir)/'`pg.c + +libpki_net_la-pki_socket.lo: pki_socket.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_net_la_CFLAGS) $(CFLAGS) -MT libpki_net_la-pki_socket.lo -MD -MP -MF $(DEPDIR)/libpki_net_la-pki_socket.Tpo -c -o libpki_net_la-pki_socket.lo `test -f 'pki_socket.c' || echo '$(srcdir)/'`pki_socket.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_net_la-pki_socket.Tpo $(DEPDIR)/libpki_net_la-pki_socket.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pki_socket.c' object='libpki_net_la-pki_socket.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_net_la_CFLAGS) $(CFLAGS) -c -o libpki_net_la-pki_socket.lo `test -f 'pki_socket.c' || echo '$(srcdir)/'`pki_socket.c + +libpki_net_la-ssl.lo: ssl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_net_la_CFLAGS) $(CFLAGS) -MT libpki_net_la-ssl.lo -MD -MP -MF $(DEPDIR)/libpki_net_la-ssl.Tpo -c -o libpki_net_la-ssl.lo `test -f 'ssl.c' || echo '$(srcdir)/'`ssl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_net_la-ssl.Tpo $(DEPDIR)/libpki_net_la-ssl.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ssl.c' object='libpki_net_la-ssl.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_net_la_CFLAGS) $(CFLAGS) -c -o libpki_net_la-ssl.lo `test -f 'ssl.c' || echo '$(srcdir)/'`ssl.c + +libpki_net_la-http_s.lo: http_s.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_net_la_CFLAGS) $(CFLAGS) -MT libpki_net_la-http_s.lo -MD -MP -MF $(DEPDIR)/libpki_net_la-http_s.Tpo -c -o libpki_net_la-http_s.lo `test -f 'http_s.c' || echo '$(srcdir)/'`http_s.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_net_la-http_s.Tpo $(DEPDIR)/libpki_net_la-http_s.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='http_s.c' object='libpki_net_la-http_s.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_net_la_CFLAGS) $(CFLAGS) -c -o libpki_net_la-http_s.lo `test -f 'http_s.c' || echo '$(srcdir)/'`http_s.c + +libpki_net_la-mysql.lo: mysql.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_net_la_CFLAGS) $(CFLAGS) -MT libpki_net_la-mysql.lo -MD -MP -MF $(DEPDIR)/libpki_net_la-mysql.Tpo -c -o libpki_net_la-mysql.lo `test -f 'mysql.c' || echo '$(srcdir)/'`mysql.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_net_la-mysql.Tpo $(DEPDIR)/libpki_net_la-mysql.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mysql.c' object='libpki_net_la-mysql.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_net_la_CFLAGS) $(CFLAGS) -c -o libpki_net_la-mysql.lo `test -f 'mysql.c' || echo '$(srcdir)/'`mysql.c + +libpki_net_la-pkcs11.lo: pkcs11.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_net_la_CFLAGS) $(CFLAGS) -MT libpki_net_la-pkcs11.lo -MD -MP -MF $(DEPDIR)/libpki_net_la-pkcs11.Tpo -c -o libpki_net_la-pkcs11.lo `test -f 'pkcs11.c' || echo '$(srcdir)/'`pkcs11.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_net_la-pkcs11.Tpo $(DEPDIR)/libpki_net_la-pkcs11.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pkcs11.c' object='libpki_net_la-pkcs11.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_net_la_CFLAGS) $(CFLAGS) -c -o libpki_net_la-pkcs11.lo `test -f 'pkcs11.c' || echo '$(srcdir)/'`pkcs11.c + +libpki_net_la-sock.lo: sock.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_net_la_CFLAGS) $(CFLAGS) -MT libpki_net_la-sock.lo -MD -MP -MF $(DEPDIR)/libpki_net_la-sock.Tpo -c -o libpki_net_la-sock.lo `test -f 'sock.c' || echo '$(srcdir)/'`sock.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_net_la-sock.Tpo $(DEPDIR)/libpki_net_la-sock.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sock.c' object='libpki_net_la-sock.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_net_la_CFLAGS) $(CFLAGS) -c -o libpki_net_la-sock.lo `test -f 'sock.c' || echo '$(srcdir)/'`sock.c + +libpki_net_la-url.lo: url.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_net_la_CFLAGS) $(CFLAGS) -MT libpki_net_la-url.lo -MD -MP -MF $(DEPDIR)/libpki_net_la-url.Tpo -c -o libpki_net_la-url.lo `test -f 'url.c' || echo '$(srcdir)/'`url.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpki_net_la-url.Tpo $(DEPDIR)/libpki_net_la-url.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='url.c' object='libpki_net_la-url.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpki_net_la_CFLAGS) $(CFLAGS) -c -o libpki_net_la-url.lo `test -f 'url.c' || echo '$(srcdir)/'`url.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/libpki_net_la-dns.Plo + -rm -f ./$(DEPDIR)/libpki_net_la-http_s.Plo + -rm -f ./$(DEPDIR)/libpki_net_la-ldap.Plo + -rm -f ./$(DEPDIR)/libpki_net_la-mysql.Plo + -rm -f ./$(DEPDIR)/libpki_net_la-pg.Plo + -rm -f ./$(DEPDIR)/libpki_net_la-pkcs11.Plo + -rm -f ./$(DEPDIR)/libpki_net_la-pki_socket.Plo + -rm -f ./$(DEPDIR)/libpki_net_la-sock.Plo + -rm -f ./$(DEPDIR)/libpki_net_la-ssl.Plo + -rm -f ./$(DEPDIR)/libpki_net_la-url.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/libpki_net_la-dns.Plo + -rm -f ./$(DEPDIR)/libpki_net_la-http_s.Plo + -rm -f ./$(DEPDIR)/libpki_net_la-ldap.Plo + -rm -f ./$(DEPDIR)/libpki_net_la-mysql.Plo + -rm -f ./$(DEPDIR)/libpki_net_la-pg.Plo + -rm -f ./$(DEPDIR)/libpki_net_la-pkcs11.Plo + -rm -f ./$(DEPDIR)/libpki_net_la-pki_socket.Plo + -rm -f ./$(DEPDIR)/libpki_net_la-sock.Plo + -rm -f ./$(DEPDIR)/libpki_net_la-ssl.Plo + -rm -f ./$(DEPDIR)/libpki_net_la-url.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-noinstLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + +include $(TOP)/global-vars + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/utils/net/dns.c b/src/utils/net/dns.c new file mode 100644 index 00000000..6ef55ca5 --- /dev/null +++ b/src/utils/net/dns.c @@ -0,0 +1,278 @@ + +/* OpenCA libpki package + * (c) 2000-2012 by Massimiliano Pala and OpenCA Labs + * All Rights Reserved + * + * =================================================================== + * Released under OpenCA LICENSE + */ + +#include + +#ifdef HAVE_LIBRESOLV +#include +#include +#include +#include +#ifndef T_AAAA +#include +#endif +#include +#endif + +// get_dnsRecords() - Returns an array of char * of requested records +// @name - requested domain name +// @type - Type of records. Supported types are: +// T_A = 1 - Internet Address; +// T_NS = 2 - Name Server; +// T_MX = 15 - Mail Routing; +// T_TXT = 16 - Used for different purposes (SPF, etc.); +// T_AAAA = 28 - IPv6 Addresses; +// T_SRV = 33 - Service Records; +// T_CERT = 36 - Certificates) +// @result - Returned Array. NULL if none are found. +// +// Return value is -1 on Error and 0 on success + +/*! \brief Returns a MEM STACK with the requested DNS records */ +PKI_MEM_STACK *URL_get_data_dns_url(const URL * url, + ssize_t size) { + + PKI_MEM_STACK *ret = NULL; + +#ifdef HAVE_LIBRESOLV + + int type = T_A; + PKI_MEM *obj = NULL; + + if( (!url) || (!url->addr)) { + return NULL; + } + + unsigned char response[NS_PACKETSZ]; + + ns_msg dnsMessage; + ns_rr dnsRecord; + + int dnsRecordSection = ns_s_an; + int dns_msgCount = 0; + int len = 0; + + // Check the Type of record + if ((type = URL_get_dns_type(url->attrs)) == -1) return NULL; + + PKI_log_debug("DNS URI: Searching for %s (%s/%d)", + url->addr, url->attrs, type); + + if ((len = res_search(url->addr, C_IN, type, response, sizeof(response))) < 0) + { + // An Error Occurred + PKI_log_err("DNS URI: search failed\n"); + return NULL; + } + + if (ns_initparse(response, len, &dnsMessage) < 0) + { + // This should not happen if the record is correct + PKI_log_err("DNS URI: can not init DNS parsing of the dnsMessage\n"); + return NULL; + } + + len = ns_msg_count(dnsMessage, dnsRecordSection); + PKI_log_debug("DNS_URI: msg count ==> %d\n", len); + + if (len <= 0) return NULL; + + if((ret = PKI_STACK_MEM_new()) == NULL ) { + PKI_log_debug ("DNS URI: Memory Failure"); + return NULL; + } + + for (dns_msgCount = 0; dns_msgCount < len; dns_msgCount++) + { + PKI_log_debug("DNS URI: Retrieving DNS record #%d",dns_msgCount); + + if (ns_parserr(&dnsMessage, dnsRecordSection, dns_msgCount, &dnsRecord)) + { + // ERROR: ns_parserr failed, let's continue to the next record + PKI_log_err("DNS URI: Can not parse record %d of %d", dns_msgCount, len); + continue; + } + + PKI_log_debug("DNS URI: type = %d (req: %d)\n", ns_rr_type(dnsRecord), type); + + if (type == pki_ns_t_address) + { + switch (ns_rr_type(dnsRecord)) + { + case T_A: + case T_AAAA: + case T_CNAME: + break; + default: + continue; + } + } + else if (type != ns_rr_type(dnsRecord)) + { + PKI_log_debug("DNS URI: recived type %d is different from requested (%d)", + type, ns_rr_type(dnsRecord)); + // continue; + } + + // int i = 0; + int rv = 0; + // int len = 0; + int offset = 0; + + char dnsRecordName[MAXDNAME]; + + memset(dnsRecordName, '\x0', MAXDNAME); + // Parse the different types of DNS records + if ((ns_rr_type(dnsRecord) == T_A) || (ns_rr_type(dnsRecord) == T_AAAA)) + { + // These require Translation using IPv4/IPv6 functions + int family = AF_INET; + + if (ns_rr_type(dnsRecord) == T_A) family = AF_INET; + else family = AF_INET6; + + if(inet_ntop(family, ns_rr_rdata(dnsRecord), dnsRecordName, + sizeof(dnsRecordName)) == NULL) + { + // Can not convert + continue; + } + } + else if ((ns_rr_type(dnsRecord) == T_CNAME) || (ns_rr_type(dnsRecord) == T_MX) || + (ns_rr_type(dnsRecord) == T_NS)) + { + if (ns_rr_type(dnsRecord) == T_MX) offset = NS_INT16SZ; + + rv = ns_name_uncompress(ns_msg_base(dnsMessage), ns_msg_end(dnsMessage), + ns_rr_rdata(dnsRecord) + offset, dnsRecordName, MAXDNAME); + + // ERROR, can not uncompress the names + if (rv < 0) continue; + } + else if (ns_rr_type(dnsRecord) == T_SRV) + { + // This requires special handling, the format is [SHORT][SHORT][SHORT][DATA] + // unsigned short *pri = (unsigned short *) ns_rr_rdata(dnsRecord); + // unsigned short *weight = (unsigned short *) &(ns_rr_rdata(dnsRecord)[2]); + // unsigned short *port = (unsigned short *) &(ns_rr_rdata(dnsRecord)[4]); + + // Shall we return the additional data too ? + // printf("PRI : %d\n", *pri); + // printf("WEIGHT : %d\n", ntohs(*weight)); + // printf("PORT : %d\n", ntohs(*port)); + + offset = 6; + rv = ns_name_uncompress(ns_msg_base(dnsMessage), ns_msg_end(dnsMessage), + ns_rr_rdata(dnsRecord) + offset, dnsRecordName, MAXDNAME); + + if (rv < 0) continue; + } + else if (ns_rr_type(dnsRecord) == T_TXT) + { + // Special handling required. Format is [BYTE][DATA] + unsigned char *p = (unsigned char *)ns_rr_rdata(dnsRecord); + + snprintf(dnsRecordName, (size_t) *p+1, "%s", &ns_rr_rdata(dnsRecord)[1]); + } + else + { + PKI_log_debug("DNS URI: record type not supported [%d]", ns_rr_type(dnsRecord)); + continue; + } + + if((obj = PKI_MEM_new_null()) == NULL ) { + // Memory Allocation Error, we abort + break; + } + + if (strlen(dnsRecordName) > 0) { + // If it is a printable value, we add the parsed version of the + // record + if(PKI_MEM_add(obj, (const unsigned char *)dnsRecordName, strlen(dnsRecordName)) == PKI_ERR) { + /* ERROR in memory growth */; + PKI_log_err("DNS URI: Memory Allocation Error"); + break; + } + } else { + // The value is not parsed/parsable, we return the raw data + // the application should know what to do with the data! + if(PKI_MEM_add(obj, ns_rr_rdata(dnsRecord), + ns_rr_rdlen(dnsRecord)) == PKI_ERR) { + /* ERROR in memory growth */; + PKI_log_err("DNS URI: Memory Allocation Error"); + break; + } + } + +/* + printf("MSG Data [%d]:\n", ns_rr_rdlen(dnsRecord)); + for (i=0; i < ns_rr_rdlen(dnsRecord); i++) + { + unsigned char *kk; + + kk = (unsigned char *) &ns_rr_rdata(dnsRecord)[i]; + printf("%x:", *kk); + }; + printf("\n"); + + fprintf(stderr, "DEBUG: RV => %d (err: %d, %s)\n", rv, h_errno, hstrerror(h_errno)); + fprintf(stderr, "DEBUG: name => %s (%s)\n", ns_rr_name(dnsRecord), url->addr); + fprintf(stderr, "DEBUG: value => %s\n", dnsRecordName); + fprintf(stderr, "DEBUG: type => %d\n", ns_rr_type(dnsRecord)); + fprintf(stderr, "DEBUG: class => %d\n", ns_rr_class(dnsRecord)); +*/ + + PKI_STACK_MEM_push(ret, obj); + + // PKI_log_debug("DNS URI: Added object #%d to stack", PKI_STACK_MEM_elements(ret)); + } + +#endif + + return ret; +}; + +/*! \brief Returns the type of DNS records identified by the passed char * arg */ +int URL_get_dns_type(const char *str) { + + int ret = -1; + if (!str) return ret; + +#ifdef HAVE_LIBRESOLV + + if (strncmp_nocase(str, "AAAA", 4) == 0) { + ret = T_AAAA; + } else if (strncmp_nocase(str, "A", 1) == 0) { + ret = T_A; + } else if (strncmp_nocase(str, "NS", 2) == 0) { + ret = T_NS; + } else if (strncmp_nocase(str, "MX", 2) == 0) { + ret = T_MX; + } else if (strncmp_nocase(str, "CNAME", 5) == 0) { + ret = T_CNAME; + } else if (strncmp_nocase(str, "SRV", 3) == 0) { + ret = T_SRV; + } else if (strncmp_nocase(str, "TXT", 3) == 0) { + ret = T_TXT; + } else if (strncmp_nocase(str, "CERT", 4) == 0) { + ret = T_CERT; + } else if (strncmp_nocase(str, "ANY", 3) == 0) { + ret = T_ANY; + } else if (atoi(str) > 0) { + ret = atoi(str); + } else { + PKI_log_err("DNS URI: record type (%s) not supported.", str); + } + + PKI_log_debug("DNS URI: record type (%s=%d) parsed", str, ret); +#else + PKI_log_debug("DNS URI: dns support disabled at compile time"); +#endif + return ret; +} diff --git a/src/utils/net/http_s.c b/src/utils/net/http_s.c new file mode 100644 index 00000000..e45cc5a6 --- /dev/null +++ b/src/utils/net/http_s.c @@ -0,0 +1,988 @@ +/* OpenCA libpki package +* (c) 2000-2007 by Massimiliano Pala and OpenCA Group +* All Rights Reserved +* +* =================================================================== +* Released under OpenCA LICENSE +*/ + +#include + +#define HTTP_BUF_SIZE 65535 + +/* ----------------------------- AUXILLARY FUNCS ------------------------------ */ + + +/* + * Returns the pointer to the end of the header, if found. Starts searching + * from the provided offset or from the beginning if offset is < 0 + */ +char * __find_end_of_header(PKI_MEM *m, ssize_t offset) +{ + ssize_t idx = 0; + ssize_t size = 0; + char * ret = NULL; + static char bytes[4] = { '\r', '\n', '\r', '\n' }; + + // Input check + if (!m || offset >= m->size) return NULL; + + if (m->size <= 4) return NULL; + + size = (ssize_t)m->size; + + // Fix the offset if it is < 0 + if (offset < 0) offset = 0; + + // Looks for the eoh + for (idx = size - 4; idx >= offset; idx--) + { + int i, found; + + // Searches for the "bytes" starting from the offset + for (i = 0, found = 0; i < sizeof(bytes); i++) + { + if (m->data[idx + i] != bytes[i]) break; + } + + // If i is 4 then we have a match on the whole string + if (i == 4) found = 1; + + // If we found the End Of Header we return that + if (found == 1) ret = (char *) &(m->data[idx + 3]); + } + + return ret; +} + +/* + * Parses the PKI_MEM that contains the header looking for specific HTTP + * headers, the requested path, and the HTTP version and code. Returns + * PKI_OK in case of success, PKI_ERR otherwise. + */ +int __parse_http_header(PKI_HTTP *msg) +{ + // Let's parse the first line of the HTTP message + char *eol = NULL; + char *method = NULL; + char *path = NULL; + char *http_version = NULL; + char *line = NULL; + char *tmp_ptr = NULL; + size_t line_size = 0; + + // Shortcut for msg->head + PKI_MEM *m = NULL; + + // Checks the input + if (msg == NULL || msg->head == NULL || msg->head->data == NULL || msg->head->size < 1) + { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return PKI_ERR; + } + + // For better understanding, we use a proxy variable to access the head + m = msg->head; + + // Let's parse the path and the details from the first line in the header + if (((eol = strchr((char *)m->data, '\n')) == NULL) && + (eol = strchr((char*)m->data, '\r')) == NULL) + { + // ERROR: here we should have at least one line (since we already + // have the eoh detected, return the error by returning NULL + return PKI_ERR; + } + + // Let's parse the path and version number + line_size = (size_t) (eol - (char*)m->data); + if ((line = PKI_Malloc(line_size + 1)) == NULL) + { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return PKI_ERR; + } + + // Copy the first line (strtok_r alters the original string) + memcpy(line, m->data, line_size); + + // Retrieves the first token - [i.e., GET/POST/HTTP ...] + method = strtok_r(line, " ", &tmp_ptr); + if (method == NULL) + { + PKI_log_err("Can not parse HTTP method"); + PKI_Free(line); + + return PKI_ERR; + } + + if (strncmp_nocase(method, PKI_HTTP_METHOD_HTTP_TXT, 4) == 0) + { + // This is usually an HTTP response + msg->method = PKI_HTTP_METHOD_HTTP; + + // Let's get the version and the code + if (sscanf((const char *)msg->head->data,"HTTP/%f %d", &msg->version, &msg->code) < 1) + { + PKI_log_debug("ERROR Parsing HTTP Version and Code"); + PKI_Free(line); + + return PKI_ERR; + } + } + else if (strncmp_nocase(method, PKI_HTTP_METHOD_GET_TXT, 3) == 0 || + strncmp_nocase(method, PKI_HTTP_METHOD_POST_TXT, 4) == 0) + { + if (strncmp_nocase(method, PKI_HTTP_METHOD_GET_TXT, 3) == 0) + msg->method = PKI_HTTP_METHOD_GET; + else + msg->method = PKI_HTTP_METHOD_POST; + + path = strtok_r(NULL, " ", &tmp_ptr); + if (path == NULL) + { + // This is an error, we should get the path for a POST or a GET + PKI_Free(line); + + return PKI_ERR; + } + + msg->path = strdup(path); + + http_version = strtok_r(NULL, " ", &tmp_ptr); + if (http_version == NULL) + { + // This is an error, we should be able to get the HTTP version from the third token + PKI_Free(line); + + return PKI_ERR; + } + else if(sscanf(http_version,"HTTP/%f", &msg->version) < 1) + { + PKI_log_debug("ERROR Parsing HTTP Version"); + PKI_Free(line); + return PKI_ERR; + } + } + else + { + PKI_log_err("Unsupported HTTP Method detected (%s)", method); + PKI_Free(line); + + return PKI_ERR; + } + + // We do not need the line anymore, let's free the memory + if (line) PKI_Free(line); + + // Success + return PKI_OK; +} + +/* ----------------------------- MAIN FUNCS ----------------------------------- */ + + +/*! \brief Frees the memory associated with a PKI_HTTP data structure */ + +void PKI_HTTP_free ( PKI_HTTP *rv ) +{ + if ( !rv ) return; + + if ( rv->location ) PKI_Free ( rv->location ); + if ( rv->type ) PKI_Free ( rv->type ); + + if ( rv->body ) PKI_MEM_free ( rv->body ); + if ( rv->head ) PKI_MEM_free ( rv->head ); + if ( rv->path ) PKI_Free ( rv->path ); + + PKI_Free ( rv ); + + return; +} + + +/*! \brief Allocates the memory for a new PKI_HTTP data structure */ + +PKI_HTTP * PKI_HTTP_new ( void ) +{ + + PKI_HTTP *ret = NULL; + + if((ret = PKI_Malloc ( sizeof( PKI_HTTP ))) == NULL) + { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return NULL; + } + + /* Standard Header Codes */ + ret->code = 0; + ret->type = NULL; + ret->location = NULL; + + /* Data */ + ret->body = NULL; + ret->head = NULL; + ret->path = NULL; + + return ( ret ); +} + +/*! \brief Returns a PKI_HTTP from the content of a char * */ + +char * PKI_HTTP_get_header_txt (const char * orig_data, + const char * header) { + + char *tk = NULL, *pnt = NULL; + char *ret = NULL; + + char *data = NULL; + int found = 0; + + if( !orig_data || !header || !strlen(orig_data) || !strlen(header)) + { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return NULL; + } + + if ((data = strdup(orig_data)) == NULL) + { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return NULL; + } + + for (tk = strtok_r ( data, "\r\n", &pnt ); tk; tk = strtok_r(NULL, "\r\n", &pnt)) + { + if ( tk == NULL ) break; + + if (strncmp_nocase(tk, header, (int) strlen(header)) == 0) + { + found = 1; + break; + } + } + + if (!found) + { + PKI_Free ( data ); + return NULL; + } + + if ((pnt = strchr( tk, ':' )) == NULL) + { + PKI_Free ( data ); + return NULL; + } + pnt++; + + while ((pnt != NULL ) && (*pnt == ' ' )) { + pnt++; + } + + if (pnt) ret = strdup( pnt ); + + PKI_Free ( data ); + + return ret; +} + + +/*! \brief Returns a PKI_HTTP from the content of a PKI_MEM */ + +char * PKI_HTTP_get_header ( const PKI_HTTP * http, + const char * header ) { + + if( !http || !http->head || !header ) return NULL; + + return PKI_HTTP_get_header_txt ( (char *)http->head->data, header); +} + +/* Internal version, can handle both HTTP and HTTPS */ + +PKI_HTTP *PKI_HTTP_get_message (const PKI_SOCKET * sock, + int timeout, + size_t max_size) { + + PKI_HTTP * ret = NULL; + + char * eoh = NULL; + char * body = NULL; + + ssize_t read = 0; // Keeps track of the single reading + ssize_t free = 0; // Keeps track of the remaining buffer space + ssize_t idx = 0; // Keeps track of how much data we poured into MEM + ssize_t size = 0; // Keeps track of the read data from socket + + // Let's initialize some useful variables (code readability) + long long content_length = -1; + + // Buffer where to keep the data + PKI_MEM *m = NULL; + + // Allocates the HTTP message container + if ((ret = PKI_HTTP_new()) == NULL) + { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL ); + goto err; + } + ret->method = PKI_HTTP_METHOD_UNKNOWN; + + if (max_size > 0) + { + // Allocates a new MEM object + m = PKI_MEM_new(max_size + 1); + } + else + { + // Allocates the default buffer for HTTP messages + m = PKI_MEM_new(HTTP_BUF_SIZE + 1); + } + + if (m == NULL) + { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return NULL; + } + + // Sets the free space in the buffer + free = (ssize_t) m->size - 1; + + // Let's retrieve the data from the socket. Note that this for + // always read at most 'free' bytes which carries the amount of + // free space in the buffer -> safe + for (read = PKI_SOCKET_read(sock, (char *)(&(m->data[idx])), (size_t) free, timeout); + read > 0; + read = PKI_SOCKET_read(sock, (char *)(&(m->data[idx])), (size_t) free, timeout)) + { + // If read is negative, there was an error on the socket + // let's just report it as an error and move on + if (read < 0) + { + if (!eoh) + { + PKI_log_err("Error while reading from socket"); + goto err; + } + else + { + // Nothing to read anymore - let's break + PKI_log_err("Nothing to read anymore (read = %d)", read); + break; + } + } + else if (read == 0 && eoh) + { + // No data was read, let's assume the stream is complete and + // break from the for loop + break; + } + + // Let's be sure there is a NULL-bound limit to the read data + size += read; + free -= read; + m->data[size] = '\x0'; + + // If we don't have a header yet, let's look for it + if (!eoh && ((eoh = __find_end_of_header(m, idx)) != NULL)) + { + // We want the header to finish with just one '\r\n' - since the + // pointer we receive is at the end of the '\r\n\r\n' sequence, + // we need to shrink by 2 bytes + size_t header_size = (size_t) (eoh - (char *) m->data - 2); + ret->head = PKI_MEM_new_data(header_size + 1, m->data); + ret->head->data[header_size] = '\x0'; + + // If we can not parse the header - we have to return error + if (PKI_ERR == __parse_http_header(ret)) goto err; + + // Let's get the pointer to the start of the body + body = eoh + 1; + + // Checks for the content-length is in the header - if we have not found it, yet + if (ret->method != PKI_HTTP_METHOD_GET && content_length < 0) + { + char *cnt_len_s = NULL; + if ((cnt_len_s = PKI_HTTP_get_header(ret, "Content-Length" )) != NULL) + { + content_length = atoll(cnt_len_s); + PKI_Free(cnt_len_s); + // PKI_log_debug ( "HTTP Content-Length: %d bytes", content_length); + } + } + } // End of if (!eoh) ... + + // Updates the start pointer for the next read operation + idx += read; + + // Let's check if we need to expand the buffer + if (max_size <= 0) + { + // We expand the mem if the buffer has less than 2K free + if (free < 2048) + { + ssize_t ofs = 0; + + if(body) + { + ofs = (ssize_t)(body - (char *)m->data); + + if(ofs < 0) + { + PKI_log_debug ( "Invalid offset for HTTP body: Start: %p - Body: %p", m->data, body); + PKI_ERROR(PKI_ERR_URI_READ, NULL); + goto err; + } + } + + // Grow the memory for the HTTP message + if(content_length > 0 && body && m->size < (size_t)(content_length + ofs)) + { + size_t len = ((size_t)(content_length + ofs) - m->size); + + if (PKI_MEM_grow(m, len + 1) == PKI_ERR) + { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + goto err; + } + free += (ssize_t)len; + } + else + { + if (PKI_MEM_grow(m, HTTP_BUF_SIZE) == PKI_ERR) + { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + goto err; + } + free += HTTP_BUF_SIZE; + } + + // Let's update the pointer to the body + if(body) body = (char *)m->data + ofs; + } + } + + // Let's check if we need to perform the next read or not + if (eoh && ret->method == PKI_HTTP_METHOD_GET) + { + // We do not need to wait for any other read as GETs do not have + // a full body + break; + } + else if ((content_length >= 0) && (&m->data[size] - (unsigned char *)body >= content_length)) + { + // Here we have received the full body (since the size of the body corresponds or exceeds the + // contents of the Content-Length: header line), therefore we can safely get out of the cycle + break; + } + + } /* End of for..loop */ + + // Here we should have both the eoh and the body - if not, there was + // an error and we return the malformed request message + if (!eoh) + { + // PKI_log_err ( "Read data (so far): %d bytes - Last read: %d bytes", idx, read); + PKI_ERROR(PKI_ERR_URI_READ, NULL); + goto err; + } + + // Sets some HTTP specific data + ret->location = PKI_HTTP_get_header ( ret, "Location" ); + ret->type = PKI_HTTP_get_header ( ret, "Content-Type" ); + + if (ret->method != PKI_HTTP_METHOD_GET && content_length > 0 && body) + { + ssize_t body_start = (ssize_t)(body - (char *)m->data); + ssize_t body_size = idx - body_start; + + if (body_start < 0 || body_size < 0) + { + PKI_log_err ( "Invalid offset for HTTP body - body_start: %d bytes - body_size: %d bytes", body_start, body_size); + PKI_ERROR(PKI_ERR_URI_READ, NULL); + goto err; + } + + //Check if Content-Length > 0 but body_size is 0 + if (body_size == 0) goto err; + + // Let's allocate the body for the HTTP message (if any) + ret->body = PKI_MEM_new_data((size_t)body_size+1, (unsigned char *)body); + if(ret->body == NULL) + { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + goto err; + } + ret->body->size = (size_t) body_size; + } + else + { + ret->body = PKI_MEM_new_null(); + } + + // Let's free the buffer memory + if (m) PKI_MEM_free(m); + + // Now we can return the HTTP message + return ret; + +err: + + // First we free the return message + if (ret) PKI_HTTP_free(ret); + + // We then free the buffer memory object + if (m) PKI_MEM_free(m); + + return NULL; +} + +/*! \brief Sends a HTTP message to a URL and retrieve the response + * + * Sends (POST/GET) data to a url and (if a pointer to a mem stack + * is provided) returns the received response. PKI_ERR is returned + * in case of error, otherwise PKI_OK is returned. + */ + +int PKI_HTTP_get_url (const URL * url, + const char * data, + size_t data_size, + const char * content_type, + int method, + int timeout, + size_t max_size, + PKI_MEM_STACK ** sk, + PKI_SSL * ssl) { + + PKI_SOCKET *sock = NULL; + int ret = 0; + + if (!url) return PKI_ERR; + + sock = PKI_SOCKET_new(); + if (ssl) PKI_SOCKET_set_ssl(sock, ssl); + + if (PKI_SOCKET_open_url(sock, url, timeout) == PKI_ERR) + { + PKI_SOCKET_free ( sock ); + return PKI_ERR; + } + + ret = PKI_HTTP_get_socket ( sock, data, data_size, content_type, + method, timeout, max_size, sk ); + + PKI_SOCKET_close ( sock ); + PKI_SOCKET_free ( sock ); + + return ret; +} + +/*! \brief Reads a data from an HTTP server */ + +int PKI_HTTP_get_socket (const PKI_SOCKET * sock, + const char * data, + size_t data_size, + const char * content_type, + int method, + int timeout, + size_t max_size, + PKI_MEM_STACK ** sk ) { + + size_t len = 0; + + const char *my_cont_type = "application/unknown"; + + PKI_HTTP *http_rv = NULL; + + int rv = -1; + int ret = PKI_OK; + + size_t max_len = 0; + size_t auth_len = 0; + + char *tmp = NULL; + char *auth_tmp = NULL; + + char *head_get = + "GET %s HTTP/1.1\r\n" + "Host: %s\r\n" + "User-Agent: LibPKI\r\n" + "Connection: close\r\n" + "%s"; + + char *head_post = + "POST %s HTTP/1.1\r\n" + "Host: %s\r\n" + "User-Agent: LibPKI\r\n" + "Connection: close\r\n" + "Content-type: %s\r\n" + "Content-Length: %d\r\n" + "%s"; + + char *head = NULL; + + if ( timeout < 0 ) timeout = 0; + + if ( !sock || !sock->url ) return PKI_ERR; + + // Process the authentication information if provided by the caller + if (sock->url && sock->url->usr && sock->url->pwd) + { + // Rough estimate for the auth string + max_len = strlen(sock->url->usr) + strlen(sock->url->pwd) + 100; + + // Special case for when a usr/pwd was specified in the URL + auth_tmp = PKI_Malloc(len); + auth_len = (size_t)snprintf(auth_tmp, len, "Authentication: user %s:%s\r\n\r\n", sock->url->usr, sock->url->pwd); + } + else + { + // If we do not have the auth info, we just add the end of header + auth_len = 2; + auth_tmp = "\r\n"; + } + + if (method == PKI_HTTP_METHOD_GET) + { + // Gets the right header + head = head_get; + + // Estimate the header's final size + max_len = + strlen(head) + + strlen(sock->url->path) + + strlen(sock->url->addr) + + 101; + + // Allocates enough space for the header + tmp = PKI_Malloc ( max_len + auth_len ); + + // Prints the header into the tmp container + len = (size_t) snprintf(tmp, max_len, head, sock->url->path, sock->url->addr, auth_tmp); + } + else if (method == PKI_HTTP_METHOD_POST) + { + // Gets the right head + head = head_post; + + // Determines the right content type + if ( content_type ) my_cont_type = content_type; + else my_cont_type = "text/html"; + + // Checks the max len for the allocated header + max_len = + strlen(head) + + strlen(sock->url->path) + + strlen(sock->url->addr) + + strlen(my_cont_type) + + 101; + + // Allocates the memory for the header + tmp = PKI_Malloc ( max_len + auth_len ); + + // Prints the header into the tmp container + len = (size_t) snprintf(tmp, max_len, head, sock->url->path, sock->url->addr, + my_cont_type, data_size, auth_tmp ); + } + else + { + PKI_log_err ( "Method (%d) not supported!", method ); + return PKI_ERR; + } + + // PKI_MEM *r = PKI_MEM_new_data(len, tmp); + // URL_put_data("file://http_req.txt", r, NULL, NULL, 0, 0, NULL); + // PKI_MEM_free(r); + + if ((rv = (int) PKI_SOCKET_write(sock, tmp, len)) < 0) + { + PKI_log_err("Can not write HTTP header to socket"); + PKI_Free(tmp); + goto err; + } + + // Free the tmp pointer that held the request header + if (tmp) PKI_Free (tmp); + + // If we were using a POST method, we need to actually send the data + if(data != NULL) + { + if ((PKI_SOCKET_write(sock, data, data_size)) < 0) + { + PKI_log_err ("Can not write POST to socket."); + goto err; + } + } + + // Let's now wait for the response from the server + if ((http_rv = PKI_HTTP_get_message(sock, timeout, max_size)) == NULL) + { + PKI_log_err ("HTTP retrieval error\n"); + goto err; + } + + // We shall now check for the return code + if (http_rv->code >= 400 ) + { + goto err; + } + else if (http_rv->code >= 300) + { + /* Redirection - let's try that */ + if (http_rv->location == NULL) + { + PKI_log_debug ( "HTTP Redirection but no location provided!"); + goto err; + } + + PKI_log_debug("HTTP Redirection Detected [URL: %s]", http_rv->location ); + + if (strstr(http_rv->location, "://") != NULL) + { + URL *url_tmp = NULL; + + if( strncmp_nocase( http_rv->location, sock->url->url_s, + (int) strlen(http_rv->location)) == 0) + { + PKI_log_debug( "HTTP cyclic redirection!"); + goto err; + } + + if ((url_tmp = URL_new ( http_rv->location )) == NULL) + { + PKI_log_debug("HTTP location is not a valid URI (%s)", http_rv->location ); + goto err; + } + + if ( sock->url->ssl == 0 ) + { + ret = PKI_HTTP_get_url ( url_tmp, data, + data_size, content_type, method, timeout, + max_size, sk, NULL ); + } + else + { + PKI_SSL *ssl2 = PKI_SSL_dup ( sock->ssl ); + + ret = PKI_HTTP_get_url ( url_tmp, data, + data_size, content_type, method, timeout, + max_size, sk, ssl2 ); + } + + if ( url_tmp ) URL_free ( url_tmp ); + + goto end; + + } + else + { + const char *prot_s = NULL; + char new_url[2048]; + URL *my_new_url = NULL; + PKI_SSL *ssl2 = PKI_SSL_dup ( sock->ssl ); + + prot_s = URL_proto_to_string ( sock->url->proto ); + if( !prot_s ) goto err; + + snprintf(new_url, sizeof(new_url),"%s://%s%s", prot_s, sock->url->addr, http_rv->location ); + + if( strncmp_nocase( new_url, sock->url->url_s, (int) strlen ( new_url )) == 0 ) + { + PKI_log_debug( "HTTP cyclic redirection!"); + goto err; + } + + my_new_url = URL_new ( new_url ); + + ret = PKI_HTTP_get_url ( my_new_url, data, data_size, content_type, method, + timeout, max_size, sk, ssl2 ); + + if (ssl2) PKI_SSL_free ( ssl2 ); + } + } + else if (http_rv->code != 200) + { + PKI_log_debug( "Unknown HTTP Return code [Code: %d]", http_rv->code ); + goto err; + } + + /* + PKI_log_err("{DEBUG} method = %d, header->size = %d, body = %p, body_size = %d", + http_rv->method, http_rv->head->size, http_rv->body, http_rv->body->size); + URL_put_data("file://http-resp-header.txt", http_rv->head, NULL, NULL, 0, 0, NULL); + URL_put_data("file://http-resp-data.txt", http_rv->body, NULL, NULL, 0, 0, NULL); + */ + + // If a Pointer was provided, we want the data back + if (sk) { + + // Checks if the caller provided an already allocated data + // structure. If not, we allocate it. + if (*sk) PKI_STACK_MEM_free_all(*sk); + + // Allocates a new structure + if ((*sk = PKI_STACK_MEM_new()) == NULL) { + + // If a memory error occurs report it and exit + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + + // Nothing more to do + goto err; + } + + // Add the returned value to the stack + if (PKI_STACK_MEM_push(*sk, http_rv->body) != PKI_OK) { + PKI_log_err("Can not push the HTTP result body in the result stack"); + goto err; + } + + // Remove ownership of the body PKI_MEM from the original + // HTTP msg container + http_rv->body = NULL; + } + +end: + // Finally free the HTTP message memory + if (http_rv) PKI_HTTP_free(http_rv); + + // Returns the result + return ret; + +err: + // Error condition + if (http_rv) PKI_HTTP_free ( http_rv ); + + // Free the locally allocated memory + if (*sk) PKI_STACK_MEM_free_all(*sk); + *sk = NULL; + + return PKI_ERR; +} + +/* ------------------------------- HTTP GET --------------------------- */ + +/*! \brief Returns the data from an HTTP source by using the GET command */ + +int PKI_HTTP_GET_data (const char * url_s, + int timeout, + size_t max_size, + PKI_MEM_STACK ** ret, + PKI_SSL * ssl ) { + + URL *url = NULL; + int rv = PKI_OK; + + if( !url_s ) return PKI_ERR; + + if((url = URL_new( url_s )) == NULL ) { + return PKI_ERR; + } + + rv = PKI_HTTP_get_url ( url, NULL, 0, NULL, + PKI_HTTP_METHOD_GET, timeout, max_size, ret, ssl ); + + if ( url ) URL_free ( url ); + return rv; +} + +/*! \brief Returns the data from an HTTP URL by using the GET command */ + +int PKI_HTTP_GET_data_url (const URL * url, + int timeout, + size_t max_size, + PKI_MEM_STACK ** ret, + PKI_SSL * ssl ) { + + if ( !url ) return PKI_ERR; + + return PKI_HTTP_get_url ( url, NULL, 0, NULL, + PKI_HTTP_METHOD_GET, timeout, max_size, ret, ssl ); +} + +/*! \brief Returns HTTP data from a PKI_SOCKET by using the GET command */ + +int PKI_HTTP_GET_data_socket (const PKI_SOCKET * sock, + int timeout, + size_t max_size, + PKI_MEM_STACK ** ret ) { + + if ( !sock ) return PKI_ERR; + + return PKI_HTTP_get_socket ( sock, NULL, 0, NULL, + PKI_HTTP_METHOD_GET, timeout, max_size, ret ); +} + +/* ------------------------------- HTTP POST --------------------------- */ + +/*! \brief Use POST method to transfer data via HTTP. If a pointer to a + * PKI_MEM_STACK (eg., &stack) is provided, the returned data isi + * added to it + */ + +int PKI_HTTP_POST_data (const char * url_s, + const char * data, + size_t size, + const char * content_type, + int timeout, + size_t max_size, + PKI_MEM_STACK ** ret_sk, + PKI_SSL * ssl ) { + + URL *url = NULL; + int ret = PKI_OK; + + if( !url_s || !data || !content_type ) { + /* ERROR: All data are strictly required! */ + return PKI_ERR; + } + + if((url = URL_new(url_s)) == NULL ) { + /* Error in creating the URL structure */ + return PKI_ERR; + } + + ret = PKI_HTTP_get_url ( url, data, size, content_type, + PKI_HTTP_METHOD_POST, timeout, max_size, ret_sk, ssl); + + if ( url ) URL_free (url); + + return ret; +} + +/*! \brief Use POST method to transfer data via HTTP. If a pointer to a + * PKI_MEM_STACK (eg., &stack) is provided, the returned data is + * added to it + */ + +int PKI_HTTP_POST_data_url (const URL * url, + const char * data, + size_t size, + const char * content_type, + int timeout, + size_t max_size, + PKI_MEM_STACK **ret_sk, + PKI_SSL *ssl ) { + + + if ( !url ) return PKI_ERR; + + return PKI_HTTP_get_url ( url, data, size, content_type, + PKI_HTTP_METHOD_POST, timeout, max_size, ret_sk, ssl); +} + +/*! \brief Use POST method to transfer data via HTTP. If a pointer to a + * PKI_MEM_STACK (eg., &stack) is provided, the returned data is + * added to it + */ + +int PKI_HTTP_POST_data_socket (const PKI_SOCKET * sock, + const char * data, + size_t size, + const char * content_type, + int timeout, + size_t max_size, + PKI_MEM_STACK ** ret_sk ) { + + + if ( !sock ) return PKI_ERR; + + return PKI_HTTP_get_socket ( sock, data, size, content_type, + PKI_HTTP_METHOD_POST, timeout, max_size, ret_sk ); +} + diff --git a/src/utils/net/ldap.c b/src/utils/net/ldap.c new file mode 100644 index 00000000..badc2758 --- /dev/null +++ b/src/utils/net/ldap.c @@ -0,0 +1,232 @@ +/* + * LIBPKI - Easy PKI Library + * by Massimiliano Pala (madwolf@openca.org) + * OpenCA project 2007 + * + * Copyright (c) 2007 The OpenCA Project. All rights reserved. + * + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#ifdef HAVE_LDAP + + +LDAP *URL_LDAP_connect(const URL *url, int tout ) { + + LDAP *ld = NULL; + int protocol = -1; + + char *ldap_server = NULL; + + struct berval cred; + int rc = 0; + + cred.bv_val = NULL; + cred.bv_len = 0; + +#if (LIBPKI_OS_CLASS == LIBPKI_OS_POSIX) + (void) signal( SIGPIPE, SIG_IGN ); +#endif + + if( (!url) || (!url->addr) || (!url->path)) { + return NULL; + } + +#if defined(LDAP_VENDOR_OPENLDAP) + if((ldap_server = PKI_Malloc ( strlen(url->addr) + 20 )) == NULL ) { + return NULL; + } + + snprintf( ldap_server, strlen(url->addr) + 19, + "ldap://%s:%d", url->addr, url->port ); + PKI_log_debug("LDAP: connecting to %s", ldap_server ); + + if((ldap_initialize( &ld, ldap_server )) != LDAP_SUCCESS ) { +#else + ldap_server = strdup( url->addr ); + if((ld = ldap_init( ldap_server, url->port)) == NULL ) { +#endif + PKI_Free ( ldap_server ); + + PKI_log_err ( "ERROR::Can not initialize LDAP connection to %s", + url->addr ); + return ( NULL ); + } + + PKI_Free ( ldap_server ); + + (void) ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &protocol ); + +#if defined(LDAP_VENDOR_OPENLDAP) + (void) ldap_set_option( ld, LDAP_OPT_TIMELIMIT, &tout ); +#endif + +#if defined(LDAP_VENDOR_MICROSOFT) + (void) ldap_set_option( ld, LDAP_OPT_TCP_KEEPALIVE, LDAP_OPT_ON ); +#endif + +#if defined(LDAP_VENDOR_MICROSOFT) || defined(LDAP_VENDOR_SUN) + PKI_log_debug("LDAP: bind"); + if( ldap_bind ( ld, url->usr, url->pwd, LDAP_AUTH_SIMPLE) != + LDAP_SUCCESS ) { + PKI_log_err("LDAP::Can not bind to %s", url->addr ); + goto err; + return NULL; + }; +#else +# ifdef LDAP_OPT_X_KEEPALIVE_IDLE + (void) ldap_set_option( ld, LDAP_OPT_X_KEEPALIVE_IDLE, LDAP_OPT_ON ); +# endif + PKI_log_debug("LDAP: SASL bind_s"); + + if(( rc = ldap_sasl_bind_s( ld, NULL, LDAP_SASL_SIMPLE, &cred, + NULL, NULL, NULL )) != LDAP_SUCCESS ) { + + switch ( rc ) { + case LDAP_BUSY: + PKI_log_err("LDAP: Server is Busy"); + break; + case LDAP_UNAVAILABLE: + PKI_log_err("LDAP: Server is Unavailable"); + break; + default: + PKI_log_err("LDAP: Can not bind to server"); + } + + goto err; + } +# endif + + PKI_log_debug("LDAP::Initialization Successful!"); + return(ld); +err: + /* Error, We have to free the LDAP structure */ +#if defined(LDAP_VENDOR_OPENLDAP) + if (ld) ldap_unbind_ext ( ld, NULL, NULL ); +#else + if (ld) ldap_unbind ( ld ); +#endif + return NULL; +} + +PKI_MEM_STACK *URL_get_data_ldap_url(const URL *url, int timeout, ssize_t size ) { + +#ifdef _WINDOWS + struct l_timeval zerotime; + struct l_timeval *time; +#else + struct timeval zerotime; + struct timeval *time; +#endif + + LDAP *ld = NULL; + int i,rc; + char *attrs[] = { url->attrs, NULL } ; + char *filter = "objectclass=*"; + struct berval **vals = NULL; +#if defined(LDAP_VENDOR_OPENLDAP) || defined(LDAP_VENDOR_MICROSOFT) + // int msgid = 0; +#endif + LDAPMessage *res = NULL; + PKI_MEM_STACK *ret = NULL; + PKI_MEM *obj = NULL; + + if( (!url) || (!url->addr) || (!url->path)) { + return NULL; + } + + /* We search for the exact match, so LDAP_SCOPE_BASE is used here */ + if ( timeout > 0 ) { + zerotime.tv_sec = timeout; + zerotime.tv_usec = 0L; + time = &zerotime; + } else { + time = NULL; + timeout = 0; + zerotime.tv_sec = 0L; + zerotime.tv_usec = 0L; + } + + PKI_log_debug("LDAP: Search Timeout is %d", timeout ); + + if((ld = URL_LDAP_connect ( url, timeout )) == NULL ) { + PKI_log_debug("LDAP: can not connect to server (%s)", + url->url_s ); + return NULL; + }; + + +#if defined(LDAP_VENDOR_OPENLDAP) || defined(LDAP_VENDOR_MICROSOFT) + if ((rc = ldap_search_ext_s(ld, url->path, LDAP_SCOPE_BASE, + filter, attrs, 0, NULL, NULL, time, (int) size, &res )) != LDAP_SUCCESS) + { + PKI_log_err("LDAP: Search Error (0x%8.8x)", rc); + goto end; + } + + /* + if (( rc = ldap_result (ld, msgid, LDAP_MSG_ONE, + &zerotime, &res)) <= 0 ) { + PKI_log_err("LDAP: [%s] object not found (0x%8.8x)", + url->path, rc); + goto end; + } + */ + +#else + if (( rc = ldap_search_s( ld, url->path, LDAP_SCOPE_BASE, + filter, attrs, 0, &res )) != LDAP_SUCCESS ) { + + PKI_log_err("LDAP: [%s] object not found (0x%8.8x)", url->path, rc); + + goto end; + } +#endif + + if (( i = ldap_count_entries( ld, res )) <= 0 ) { + PKI_log_err("No Returned Entries (%s)", i); + } + + if((ret = PKI_STACK_MEM_new()) == NULL ) { + /* ERROR: Allocating memory */ + goto end; + } + if((vals = ldap_get_values_len (ld, res, attrs[0])) != NULL ) { + + for( i=0; vals[i] != NULL; i++ ) { + if((obj = PKI_MEM_new_null()) == NULL ) { + goto end; + } + if(PKI_MEM_add( obj, (char *) vals[i]->bv_val, + vals[i]->bv_len) == PKI_ERR) { + /* ERROR in memory growth */; + break; + } + PKI_STACK_MEM_push( ret, obj ); + } + + ldap_value_free_len( vals ); + vals = NULL; + } else { + return NULL; + } + +end: + if(res) ldap_msgfree( res ); +#if defined(LDAP_VENDOR_OPENLDAP) + if(ld) ldap_unbind_ext( ld, NULL, NULL ); +#else + if(ld) ldap_unbind( ld ); +#endif + + return (ret); +} + +#endif /* LDAP */ diff --git a/src/utils/net/mysql.c b/src/utils/net/mysql.c new file mode 100644 index 00000000..a4f20050 --- /dev/null +++ b/src/utils/net/mysql.c @@ -0,0 +1,457 @@ +/* src/net/mysql.c */ +/* + * MySQL URL Interface + * Copyright (c) 2007 by Massimiliano Pala and OpenCA Project + * OpenCA Licensed Code + */ + + +#include + +char *parse_url_query ( const URL * url ) { + + char * ret = NULL; + char * table = NULL; + char * tmp_s = NULL; + char * tmp_s2 = NULL; + int where = 0; + int add_and = 0; + + char col[1024]; + char val[1024]; + char tmp[1024]; + + PKI_MEM *buf = NULL; + + if( !url || !url->path ) return( NULL ); + + tmp_s = url->path; + + while((tmp_s2 = strchr(tmp_s, '/')) != NULL ) { + tmp_s2++; + tmp_s = tmp_s2; + } + + if((table = parse_url_table ( url )) == NULL) { + return (NULL); + } + + if((buf = PKI_MEM_new_null()) == NULL ) { + return ( NULL ); + } + + snprintf( tmp, sizeof( tmp ), "SELECT %s from %s ", url->attrs, table ); + PKI_Free (table); + + PKI_MEM_add( buf, (const unsigned char *)tmp, strlen( tmp )); + + where = 0; + while( sscanf(tmp_s, "(%[^)=]=%[^)])", col, val) > 1 ) { + if( where == 0 ) { + /* Let's add the WHERE clause */ + PKI_MEM_add(buf, (const unsigned char *)"WHERE ", 6); + where = 1; + } + /* The tmp_s should point to the next token */ + tmp_s += strlen(col) + strlen(val) + 3; + + /* Control if we need to add the AND in the SQL statement */ + if( add_and == 1 ) { + PKI_MEM_add( buf, (const unsigned char *)" AND ", 5); + } + + PKI_MEM_add( buf, (const unsigned char *)col, strlen( col )); + PKI_MEM_add( buf, (const unsigned char *)"='", 2); + PKI_MEM_add( buf, (const unsigned char *)val, strlen( val )); + PKI_MEM_add( buf, (const unsigned char *)"' ", 2); + + /* This triggers the adding of AND on the next iteration */ + add_and = 1; + } + + if( (ret = PKI_Malloc (buf->size+1)) == NULL ) { + PKI_MEM_free ( buf ); + return( NULL ); + } + + memcpy( ret, buf->data, buf->size ); + + PKI_MEM_free ( buf ); + return( ret ); +} + +char *parse_url_put_query ( const URL * url, const PKI_MEM *data ) { + + char * ret = NULL; + char * table = NULL; + char * tmp_s = NULL; + char * tmp_s2 = NULL; + + int where = 0; + int add_and = 0; + + char col[1024]; + char val[1024]; + char tmp[1024]; + + // char buf[BUFF_MAX_SIZE]; + + PKI_MEM *buf = NULL; + + if( !url || !url->path ) return( NULL ); + + tmp_s = url->path; + + while((tmp_s2 = strchr(tmp_s, '/')) != NULL ) { + tmp_s2++; + tmp_s = tmp_s2; + } + + if((table = parse_url_table ( url )) == NULL) { + return (NULL); + } + + if((buf = PKI_MEM_new_null()) == NULL ) { + return ( NULL ); + } + + sprintf( tmp, "INSERT INTO %s (%s) VALUES ('", table, url->attrs ); + PKI_MEM_add( buf, (const unsigned char *)tmp, strlen( tmp )); + PKI_MEM_add( buf, data->data, data->size ); + PKI_MEM_add( buf, (const unsigned char *)"') ", 3); + + where = 0; + while( (sscanf(tmp_s, "(%[^)=]=\"%[^)\"]\")", col, val) > 1) || + (sscanf(tmp_s, "(%[^)=]=%[^)])", col, val) > 1)) { + if( where == 0 ) { + /* It is actually an update, let's update! */ + snprintf( tmp, sizeof( tmp ), + "UPDATE %s SET %s='", table, url->attrs); + if( buf ) PKI_MEM_free ( buf ); + + buf = PKI_MEM_new_null(); + PKI_MEM_add( buf, (const unsigned char *)tmp, strlen( tmp )); + PKI_MEM_add( buf, data->data, data->size ); + PKI_MEM_add( buf, (const unsigned char *)"' WHERE ", 8); + + /* Let's add the WHERE clause */ + where = 1; + } + /* The tmp_s should point to the next token */ + tmp_s += strlen(col) + strlen(val) + 3; + + /* Control if we need to add the AND in the SQL statement */ + if( add_and == 1 ) { + PKI_MEM_add( buf, (const unsigned char *)" AND ", 5); + } + + PKI_MEM_add( buf, (const unsigned char *)col, strlen( col )); + PKI_MEM_add( buf, (const unsigned char *)"='", 2); + PKI_MEM_add( buf, (const unsigned char *)val, strlen( val )); + PKI_MEM_add( buf, (const unsigned char *)"' ", 2 ); + + /* This triggers the adding of AND on the next iteration */ + add_and = 1; + } + + PKI_Free (table); + + if( (ret = PKI_Malloc(buf->size) + 1) == NULL ) { + if( buf ) PKI_MEM_free ( buf ); + return( NULL ); + } + memcpy( ret, buf->data, buf->size ); + + PKI_MEM_free ( buf ); + + return( ret ); +} + +char *parse_url_table ( const URL * url ) { + char *tmp_s = NULL; + char *tmp_s2 = NULL; + char *ret = NULL; + char *dbname = NULL; + + size_t size = 0; + + if(!url || !url->path ) return (NULL); + + if((dbname = parse_url_dbname( url )) == NULL ) { + return (NULL); + } + + tmp_s = url->path + strlen(dbname) + 1; + PKI_Free( dbname ); + + if((tmp_s2 = strchr( tmp_s, '/' )) == NULL ) { + size = strlen( tmp_s ); + } else { + size = (size_t) (tmp_s2 - tmp_s); + } + + if((ret = PKI_Malloc ( size + 1 )) == NULL ) { + return(NULL); + } + + memcpy(ret, tmp_s, size ); + ret[size] = '\x0'; + + return( ret ); +} + +char *parse_url_dbname ( const URL *url ) { + + char *tmp_s = NULL; + char *ret = NULL; + size_t size = 0; + + if( !url || !url->path ) return (NULL); + + if((tmp_s = strchr( url->path, '/')) == NULL ) { + return (NULL); + } + + size = (size_t) (tmp_s - url->path); + if((ret = PKI_Malloc ( size + 1 )) == NULL ) { + return(NULL); + } + + memcpy(ret, url->path, size ); + ret[size] = '\x0'; + + return( ret ); +} + +#ifdef HAVE_MYSQL + +MYSQL *db_connect ( const URL *url ) { + + MYSQL *sql = NULL; + char * table = NULL; + char * dbname = NULL; + + if( (sql = mysql_init( NULL )) == NULL ) { + return NULL; + } + + dbname = parse_url_dbname ( url ); + table = parse_url_table ( url ); + + /* The old mysql_connect is no more supported, it seems! */ + /* mysql_connect( sql, url->addr, url->usr, url->pwd ); */ + if((mysql_real_connect(sql, url->addr, url->usr, url->pwd, + dbname, (unsigned int) url->port, NULL, 0 )) == NULL ) { + if( dbname ) PKI_Free ( dbname ); + db_close( sql ); + return( NULL ); + } + + if( dbname ) PKI_Free (dbname); + if( table ) PKI_Free (table); + + return( sql ); + +} + +int db_close ( MYSQL *sql ) { + + if( !sql ) return (PKI_ERR); + + mysql_close( sql ); + + return (PKI_OK); +} + + +#endif + +PKI_MEM_STACK *URL_get_data_mysql ( const char *url_s, ssize_t size ) +{ + PKI_MEM_STACK *ret = NULL; + URL *url = NULL; + + if( !url_s ) + { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return (NULL); + } + + if ((url = URL_new(url_s)) == NULL) + { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return NULL; + } + + if (url->proto != URI_PROTO_MYSQL) + { + PKI_log_debug("Wrong protocol for MySQL queries (%d)", URI_PROTO_MYSQL); + URL_free(url); + + return NULL; + } + + // Get the results + ret = URL_get_data_mysql_url( url, size ); + + // Free the URL + URL_free(url); + + // Return the results + return ret; +} + +PKI_MEM_STACK *URL_get_data_mysql_url ( const URL *url, ssize_t size ) { + +#ifdef HAVE_MYSQL + MYSQL_ROW row; + MYSQL * sql = NULL; + MYSQL_FIELD *fields = NULL; + MYSQL_RES *res = NULL; + + unsigned long *lengths = NULL; + long long n_rows = 0; + int n_fields = 0; + + PKI_MEM *tmp_mem = NULL; + PKI_MEM_STACK *sk = NULL; + + char * query = NULL; + + if( !url ) return (NULL); + + if((sql = db_connect ( url )) == NULL ) + { + return NULL; + } + + if ((query = parse_url_query(url)) == NULL) + { + PKI_log_err("Can not parse URL query"); + goto end; + } + else mysql_query(sql, query); + + /* Get the Data */ + if((res = mysql_store_result( sql )) == NULL) + { + PKI_log_err("Can not retrieve SQL data"); + goto end; + } + + if( ((n_rows = (long long) mysql_num_rows( res )) < 1 ) || + ((sk = PKI_STACK_MEM_new()) == NULL)) + { + PKI_log_err("No returned rows found"); + goto end; + } + + while((row = mysql_fetch_row(res)) != NULL ) + { + /* Count the number of fields retrieved */ + n_fields = (int) mysql_num_fields( res ); + lengths = mysql_fetch_lengths( res ); + fields = mysql_fetch_fields( res ); + if (!fields) + { + PKI_ERROR(PKI_ERR_GENERAL, "can not fetch query fields"); + break; + } + + if (n_fields > 0) + { + tmp_mem = PKI_MEM_new_null(); + if (size == 0 || (( size > 0 ) && ( lengths[0] < size))) + { + PKI_MEM_add(tmp_mem,row[0],lengths[0]); + + /* For now, let's only deal with one + field at the time */ + PKI_STACK_push( sk, tmp_mem ); + } + } + } + +end: + + if (query) PKI_Free (query); + db_close ( sql ); + + return ( sk ); + +#else + return ( NULL ); +#endif +} + +int URL_put_data_mysql ( const char *url_s, const PKI_MEM *data ) { + + int ret = 0; + URL *url = NULL; + + // Parameter checking + if( !url_s ) + { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return (PKI_ERR); + } + + // Allocates a new URL structure + if ((url = URL_new(url_s)) == NULL) + { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return PKI_ERR; + } + + // Checks the protocol to by MySQL + if (url->proto != URI_PROTO_MYSQL) + { + PKI_log_debug("Wrong protocol for MySQL queries (%d)", URI_PROTO_MYSQL); + URL_free(url); + + return PKI_ERR; + } + + // Gets the response + ret = URL_put_data_mysql_url( url, data ); + + // Frees the URL data structure + URL_free (url); + + return ret; +} + +int URL_put_data_mysql_url ( const URL *url, const PKI_MEM *data ) { + +#ifdef HAVE_MYSQL + MYSQL * sql = NULL; + + char * query = NULL; + + if( !url ) return (PKI_ERR); + + if((query = parse_url_put_query( url, data )) == NULL ) { + return( PKI_ERR ); + } + + if((sql = db_connect ( url )) == NULL ) { + PKI_Free( query ); + return(PKI_ERR); + } + + if(mysql_query(sql, query ) != 0 ) { + PKI_Free ( query ); + db_close( sql ); + + return( PKI_ERR ); + } + + PKI_Free (query); + db_close ( sql ); + + return ( PKI_OK ); + +#else + return ( PKI_ERR ); +#endif +} diff --git a/src/utils/net/pg.c b/src/utils/net/pg.c new file mode 100644 index 00000000..826a6ec7 --- /dev/null +++ b/src/utils/net/pg.c @@ -0,0 +1,410 @@ +/* src/net/pg.c */ +/* + * PostgreSQL URL Interface + * Copyright (c) 2007 by Massimiliano Pala and OpenCA Project + * OpenCA Licensed Code + */ + + +#include + +char *pg_parse_url_query ( const URL * url ) { + + char * ret = NULL; + char * table = NULL; + char * tmp_s = NULL; + char * tmp_s2 = NULL; + int where = 0; + int add_and = 0; + + char col[1024]; + char val[1024]; + char tmp[1024]; + + PKI_MEM *buf = NULL; + + if( !url || !url->path ) return( NULL ); + + tmp_s = url->path; + + while((tmp_s2 = strchr(tmp_s, '/')) != NULL ) { + tmp_s2++; + tmp_s = tmp_s2; + } + + if((table = parse_url_table ( url )) == NULL) { + return (NULL); + } + + if((buf = PKI_MEM_new_null()) == NULL ) { + return ( NULL ); + } + + snprintf( tmp, sizeof( tmp ), "SELECT %s from %s ", url->attrs, table ); + PKI_Free (table); + + PKI_MEM_add( buf, (const unsigned char *)tmp, strlen( tmp )); + + where = 0; + while( sscanf(tmp_s, "(%[^)=]=%[^)])", col, val) > 1 ) { + if( where == 0 ) { + /* Let's add the WHERE clause */ + PKI_MEM_add(buf, (const unsigned char *)"WHERE ", 6); + where = 1; + } + /* The tmp_s should point to the next token */ + tmp_s += strlen(col) + strlen(val) + 3; + + /* Control if we need to add the AND in the SQL statement */ + if( add_and == 1 ) { + PKI_MEM_add( buf, (const unsigned char *)" AND ", 5); + } + + PKI_MEM_add( buf, (const unsigned char *)col, strlen( col )); + PKI_MEM_add( buf, (const unsigned char *)"='", 2); + PKI_MEM_add( buf, (const unsigned char *)val, strlen( val )); + PKI_MEM_add( buf, (const unsigned char *)"' ", 2); + + /* This triggers the adding of AND on the next iteration */ + add_and = 1; + } + + if( (ret = PKI_Malloc (buf->size+1)) == NULL ) { + PKI_MEM_free ( buf ); + return( NULL ); + } + memcpy( ret, buf->data, buf->size ); + + PKI_MEM_free ( buf ); + return( ret ); +} + +char *pg_parse_url_put_query ( const URL * url, const PKI_MEM *data ) { + + char * ret = NULL; + char * table = NULL; + char * tmp_s = NULL; + char * tmp_s2 = NULL; + + int where = 0; + int add_and = 0; + + char col[1024]; + char val[1024]; + char tmp[1024]; + + // char buf[BUFF_MAX_SIZE]; + + PKI_MEM *buf = NULL; + + if( !url || !url->path ) return( NULL ); + + tmp_s = url->path; + + while((tmp_s2 = strchr(tmp_s, '/')) != NULL ) { + tmp_s2++; + tmp_s = tmp_s2; + } + + if((table = parse_url_table ( url )) == NULL) { + return (NULL); + } + + if((buf = PKI_MEM_new_null()) == NULL ) { + return ( NULL ); + } + + sprintf( tmp, "INSERT INTO %s (%s) VALUES ('", table, url->attrs ); + PKI_MEM_add( buf, (const unsigned char *)tmp, strlen( tmp )); + PKI_MEM_add( buf, data->data, data->size ); + PKI_MEM_add( buf, (const unsigned char *)"') ", 3); + + /* + base=strlen(buf); + for( i=0; i < data->size; i++ ) { + sprintf(buf + base + i, "%c", data->data[i]); + } + sprintf(buf+base+i,"') "); + */ + + where = 0; + while( (sscanf(tmp_s, "(%[^)=]=\"%[^)\"]\")", col, val) > 1) || + (sscanf(tmp_s, "(%[^)=]=%[^)])", col, val) > 1)) { + if( where == 0 ) { + /* It is actually an update, let's update! */ + snprintf( tmp, sizeof( tmp ), + "UPDATE %s SET %s='", table, url->attrs); + if( buf ) PKI_MEM_free ( buf ); + + buf = PKI_MEM_new_null(); + PKI_MEM_add( buf, (const unsigned char *)tmp, strlen( tmp )); + PKI_MEM_add( buf, data->data, data->size ); + PKI_MEM_add( buf, (const unsigned char *)"' WHERE ", 8); + + /* Let's add the WHERE clause */ + where = 1; + } + /* The tmp_s should point to the next token */ + tmp_s += strlen(col) + strlen(val) + 3; + + /* Control if we need to add the AND in the SQL statement */ + if( add_and == 1 ) { + PKI_MEM_add( buf, (const unsigned char *)" AND ", 5); + } + + PKI_MEM_add( buf, (const unsigned char *)col, strlen( col )); + PKI_MEM_add( buf, (const unsigned char *)"='", 2); + PKI_MEM_add( buf, (const unsigned char *)val, strlen( val )); + PKI_MEM_add( buf, (const unsigned char *)"' ", 2 ); + + /* This triggers the adding of AND on the next iteration */ + add_and = 1; + } + + PKI_Free (table); + + if( (ret = PKI_Malloc(buf->size) + 1) == NULL ) { + if( buf ) PKI_MEM_free ( buf ); + return( NULL ); + } + memcpy( ret, buf->data, buf->size ); + + PKI_MEM_free ( buf ); + + return( ret ); +} + + +char *pg_parse_url_table ( const URL * url ) { + char *tmp_s = NULL; + char *tmp_s2 = NULL; + char *ret = NULL; + char *dbname = NULL; + + size_t size = 0; + + if(!url || !url->path ) return (NULL); + + if((dbname = pg_parse_url_dbname( url )) == NULL ) { + return (NULL); + } + + tmp_s = url->path + strlen(dbname) + 1; + PKI_Free( dbname ); + + if((tmp_s2 = strchr( tmp_s, '/' )) == NULL ) { + size = strlen( tmp_s ); + } else { + size = (size_t) (tmp_s2 - tmp_s); + } + + if((ret = PKI_Malloc ( size + 1 )) == NULL ) { + return(NULL); + } + + memcpy(ret, tmp_s, size ); + ret[size] = '\x0'; + + return( ret ); +} + +char *pg_parse_url_dbname ( const URL *url ) { + + char *tmp_s = NULL; + char *ret = NULL; + size_t size = 0; + + if( !url || !url->path ) return (NULL); + + if((tmp_s = strchr( url->path, '/')) == NULL ) { + return (NULL); + } + + size = (size_t) (tmp_s - url->path); + if((ret = PKI_Malloc ( size + 1 )) == NULL ) { + return(NULL); + } + + memcpy(ret, url->path, size ); + ret[size] = '\x0'; + + return( ret ); +} + +#ifdef HAVE_PG + +PGconn *pg_db_connect ( const URL *url ) { + + PGconn *sql = NULL; + char * dbname = NULL; + + dbname = pg_parse_url_dbname ( url ); + + sql = PQsetdbLogin( url->addr, NULL, NULL, NULL, + dbname, url->usr, url->pwd ); + + if(PQstatus(sql) == CONNECTION_BAD) { + if( dbname ) PKI_Free (dbname); + pg_db_close( sql ); + } + + if( dbname ) PKI_Free (dbname); + + return( sql ); +} + +int pg_db_close ( PGconn *sql ) { + + if( !sql ) return 0; + + PQfinish( sql ); + + return (PKI_OK); +} + + +#endif + +PKI_MEM_STACK *URL_get_data_pg ( const char *url_s, ssize_t size ) { + URL *url = NULL; + + if( !url_s ) return (NULL); + + if(((url = URL_new( url_s )) == NULL) || + url->proto != URI_PROTO_PG ) { + return (NULL); + } + + return ( URL_get_data_pg_url( url, size )); +} + +PKI_MEM_STACK *URL_get_data_pg_url ( const URL *url, ssize_t size ) { + +#ifdef HAVE_PG + PGconn *sql; + PGresult *res; + + int n_rows = 0; + int i = 0; + int n_fields = 0; + + PKI_MEM *tmp_mem = NULL; + PKI_MEM_STACK *sk = NULL; + + char * query = NULL; + + if( !url ) return (NULL); + + query = pg_parse_url_query( url ); + + if((sql = pg_db_connect ( url )) == NULL ) { + PKI_Free( query ); + return(NULL); + } + + /* Get the Data */ + if(((res = PQexec( sql, query )) == NULL) || + (PQresultStatus( res ) != PGRES_COMMAND_OK )) { + + PQclear( res ); + PKI_Free( query ); + return(NULL); + } + + if( ((n_rows = PQntuples(res)) < 1 ) || + ((sk = PKI_STACK_MEM_new()) == NULL)) { + PKI_Free( query ); + return(NULL); + } + + /* Count the number of fields retrieved */ + n_fields = PQnfields( res ); + + for(i = 0; i < n_rows; i++ ) { + + if( n_fields > 0 ) { + tmp_mem = PKI_MEM_new_null(); + if( (size == 0 ) || + (( size > 0 ) && + ( PQgetlength(res, i, 0) < size)) ) { + + PKI_MEM_add(tmp_mem, + PQgetvalue ( res, i, 0 ), + (size_t) PQgetlength( res, i, 0 ) + ); + + /* For now, let's only deal with one + field at the time */ + PKI_STACK_push( sk, tmp_mem ); + } + } + + } + + PQclear( res ); + + PKI_Free (query); + pg_db_close ( sql ); + + return ( sk ); + +#else + return ( NULL ); +#endif +} + +int URL_put_data_pg ( const char *url_s, const PKI_MEM *data ) { + + URL *url = NULL; + int ret = 0; + + if( !url_s ) return (PKI_ERR); + + if(((url = URL_new( url_s )) == NULL) || + url->proto != URI_PROTO_PG ) { + return (PKI_ERR); + } + + ret = URL_put_data_pg_url( url, data ); + if( url ) URL_free ( url ); + + return ( ret ); +} + +int URL_put_data_pg_url ( const URL *url, const PKI_MEM *data ) { + +#ifdef HAVE_PG + PGconn * sql = NULL; + PGresult *res = NULL; + + int ret = PKI_OK; + char * query = NULL; + + if( !url ) return (PKI_ERR); + + if((query = pg_parse_url_put_query( url, data )) == NULL ) { + return( PKI_ERR ); + } + + if((sql = pg_db_connect ( url )) == NULL ) { + PKI_Free( query ); + return(PKI_ERR); + } + + /* Get the Data */ + if(((res = PQexec( sql, query )) == NULL) || + (PQresultStatus( res ) != PGRES_COMMAND_OK )) { + + // PQclear( res ); + ret = PKI_ERR; + } + + if( res ) PQclear( res ); + if( query ) PKI_Free (query); + + return ( ret ); + +#else + return ( PKI_ERR ); +#endif +} diff --git a/src/utils/net/pkcs11.c b/src/utils/net/pkcs11.c new file mode 100644 index 00000000..4ebb83af --- /dev/null +++ b/src/utils/net/pkcs11.c @@ -0,0 +1,334 @@ +/* src/net/pkcs11.c */ +/* + * LIBPKI - Easy PKI Library + * by Massimiliano Pala (madwolf@openca.org) + * OpenCA project 2007 + * + * Copyright (c) 2007 The OpenCA Project. All rights reserved. + * + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#ifdef HAVE_P11 + static PKCS11_CTX *ctx = NULL; +#endif /* HAVE_P11 */ + +char *pkcs11_parse_url_getval(const URL * url, + const char * keyword ) { + + char * ret = NULL; + char * tmp_s = NULL; + char * tmp_s2 = NULL; + + char *col = NULL; + char *val = NULL; + + if( !url || !url->path ) return( NULL ); + + tmp_s = url->path; + + while((tmp_s2 = strchr(tmp_s, '/')) != NULL ) { + tmp_s2++; + tmp_s = tmp_s2; + } + + if((col = PKI_Malloc( 1024 )) == NULL ) { + return( NULL ); + } + + if((val = PKI_Malloc( 1024 )) == NULL ) { + PKI_Free( col ); + return (NULL); + } + + while( sscanf(tmp_s, "(%[^=]=\"%[^\"])", col, val) > 1 ) { + + if( (strlen(col) == strlen(keyword)) && + (strncmp_nocase( col,keyword,(int)strlen(keyword)) ) == 0 ) { + ret = strdup( val ); + goto end; + } + + /* The tmp_s should point to the next token */ + tmp_s += strlen(col) + strlen(val) + 3; + } +end: + if( col ) PKI_Free ( col ); + if( val ) PKI_Free ( val ); + + return( ret ); +} + +PKI_MEM_STACK *URL_get_data_pkcs11(const char * url_s, + ssize_t size ) { + URL *url = NULL; + + if( !url_s ) return (NULL); + + if(((url = URL_new( url_s )) == NULL) || + url->proto != URI_PROTO_PKCS11 ) { + PKI_log_debug ("Not a PKCS11 URL"); + return (NULL); + } + + return URL_get_data_pkcs11_url(url, size); +} + +PKI_MEM_STACK *URL_get_data_pkcs11_url(const URL * url, + ssize_t size ) { + +#ifdef HAVE_P11 + + PKCS11_SLOT *slots = NULL; + PKCS11_TOKEN *tk = NULL; + + char *libfile = NULL; + int num = 0; + int i = 0; + + char * search_label = NULL; + char * search_id = NULL; + char * search_slot = NULL; + char * search_slotid = NULL; + + PKI_MEM *tmp_mem = NULL; + PKI_MEM_STACK *sk = NULL; + + if( !url ) return (NULL); + + if( ctx == NULL ) { + if((ctx = PKCS11_CTX_new ()) == NULL ) { + return(NULL); + } + + PKI_log_debug("Loading %s Library", url->addr ); + if(( i = PKCS11_CTX_load(ctx, url->addr)) != 0 ) { + PKI_log_err("Can not load library %s [err::%d]", url->addr, i); + // ERR_print_errors_fp( stderr ); + } + } + + if( PKCS11_enumerate_slots( ctx, &slots, &num ) == -1 ) { + PKI_log_err ("Can not enumerate slots"); + goto err; + }; + + if(( sk = PKI_STACK_MEM_new()) == NULL ) { + goto err; + } + + search_slot = pkcs11_parse_url_getval( url, "slot" ); + search_slotid = pkcs11_parse_url_getval( url, "slotid" ); + search_label = pkcs11_parse_url_getval( url, "label" ); + search_id = pkcs11_parse_url_getval( url, "id" ); + + if( search_slot ) + PKI_log_debug("PKCS#11::SEARCH::SLOT => %s\n", search_slot); + if( search_slotid ) + PKI_log_debug("PKCS#11::SEARCH::SLOTID => %s\n", search_slotid); + if( search_label ) + PKI_log_debug("PKCS#11::SEARCH::LABEL => %s\n", search_label); + if( search_id ) + PKI_log_debug("PKCS#11::SEARCH::ID => %s\n", search_id); + + for(i = 0; i < num; i++ ) { + + BIO *mem = NULL; + BUF_MEM *mem_buf = NULL; + + PKCS11_CERT *certs = NULL; + PKCS11_SLOT *p = NULL; + PKCS11_CERT *x = NULL; + + PKCS11_KEY *keyList = NULL; + PKCS11_KEY *key = NULL; + EVP_PKEY *evp_pkey = NULL; + + int n = 0; + int t = 0; + int n_objs = 0; + int p_ret = 0; + + p = &slots[i]; + + if((!p) || ((tk = p->token) == NULL) ) { + continue; + } + + if( (search_slot) && ( strncmp_nocase( search_slot, + tk->label, strlen(search_slot) == 0) )) { + continue; + } + + if( (search_slotid) && ( atoi(search_slotid) != i )) { + PKI_log_debug("PKCS11::SLOTID is %s (%d), curr is %d\n", + search_slotid, atoi(search_slotid), i); + continue; + } + + if( strncmp_nocase( url->attrs, "cert", 4 ) == 0) { + PKI_log_debug("PKCS11::CERT DATATYPE SELECTED!\n"); + if((mem = BIO_new(BIO_s_mem())) == NULL ) { + goto err; + } + + /* Get the list of certificates in the slot */ + p_ret = PKCS11_enumerate_certs( tk, &certs, &n_objs); + + for( n = 0; n < n_objs; n++ ) { + + /* Pointer to the current certificate */ + x = &certs[n]; + + PKI_log_debug("PKCS11::CERT label=%s\n", + x->label); + PKI_log_debug("PKCS11::CERT id="); + for( t = 0; t < x->id_len; t ++ ) { + printf("%c", x->id[t] ); + } printf("\n"); + + if( (search_label) && + (strncmp_nocase( search_label, x->label, + strlen( search_label)) != 0 )){ + PKI_log_debug("PKCS11::LABEL does not" + "match, SKIPPING!!!!\n"); + continue; + } + + if( search_id ) { + int stop = 0; + + for( t = 0; t < x->id_len; t ++ ) { + if( search_id[t] != x->id[t] ) { + stop = 1; + break; + } + } + + if( stop == 1 ) { + PKI_log_debug("PKCS#11::ID does not" + "match, SKIPPING!!!!\n"); + continue; + } + } + + /* Write the cert in PEM format to memory */ + p_ret = PEM_write_bio_X509( mem, x->x509 ); + + /* Get the pointer to the memory buffer */ + BIO_get_mem_ptr( mem, &mem_buf ); + + /* Push a PKI_MEM buffer on the stack */ + tmp_mem = PKI_MEM_new_null(); + PKI_MEM_add ( tmp_mem, mem_buf->data, + mem_buf->length); + PKI_STACK_push( sk, tmp_mem ); + } + + /* Free the temp memory buffer */ + if( mem ) BIO_free( mem ); + + } else if (strncmp_nocase( url->attrs, "key", 3) == 0 ) { + char *pin = NULL; + + PKI_log_debug("PKCS#11::KEY DATATYPE SELECTED!\n"); + + pin = pkcs11_parse_url_getval( url, "pin" ); + + if ( (tk->loginRequired == 1) && (pin != NULL ) ) { + p_ret = PKCS11_login ( p, 0, pin ); + PKI_log_debug("PKCS#11::LOGIN Result %d\n", + p_ret ); + } + + if((mem = BIO_new(BIO_s_mem())) == NULL ) { + goto err; + } + + p_ret = PKCS11_enumerate_keys ( tk, &keyList, &n_objs ); + + for( n = 0; n < n_objs; n++ ) { + key = &keyList[n]; + + PKI_log_debug("PKCS#11::KEY label=%s\n", key->label); + PKI_log_debug("PKCS#11::KEY id="); + for( t = 0; t < key->id_len; t ++ ) { + printf("%c", key->id[t] ); + } printf("\n"); + + if( (search_label) && + (strncmp_nocase( search_label, x->label, + strlen( search_label)) != 0 )){ + + PKI_log_debug("PKCS11::LABEL does not" + "match, SKIPPING!!!!\n"); + continue; + } + + if( search_id ) { + int stop = 0; + + for( t = 0; t < x->id_len; t ++ ) { + if( search_id[t] != x->id[t] ) { + stop = 1; + break; + } + } + + if( stop == 1 ) { + PKI_log_debug("PKCS#11::ID does not" + "match, SKIPPING!!!!\n"); + continue; + } + } + + /* Get Private Key in OpenSSL format */ + evp_pkey = PKCS11_get_private_key( key ); + + /* Write the cert in PEM format to memory */ + p_ret = PEM_write_bio_PUBKEY( mem, evp_pkey ); + + /* Get the pointer to the memory buffer */ + BIO_get_mem_ptr( mem, &mem_buf ); + + /* Push a PKI_MEM buffer on the stack */ + tmp_mem = PKI_MEM_new_null(); + PKI_MEM_add ( tmp_mem, mem_buf->data, + mem_buf->length); + PKI_STACK_push( sk, tmp_mem ); + } + + if( mem ) BIO_free ( mem ); + + } else { + PKI_log_debug("Selected Datatype Not Supported (%s)", url->attrs); + } + } + +err: + if( slots ) PKCS11_release_all_slots( ctx, slots, num ); + + if( libfile ) PKI_Free (libfile); + + if( search_slot ) PKI_Free ( search_slot ); + if( search_slotid ) PKI_Free ( search_slotid ); + if( search_label ) PKI_Free ( search_label ); + if( search_id ) PKI_Free ( search_id ); + + return ( sk ); + +#else + + PKI_log_debug("PKCS#11 Support not available in this build"); + return ( NULL ); + +#endif +} + diff --git a/src/utils/net/pki_socket.c b/src/utils/net/pki_socket.c new file mode 100644 index 00000000..f5dc3fa6 --- /dev/null +++ b/src/utils/net/pki_socket.c @@ -0,0 +1,352 @@ +/* + * LIBPKI - OpenSource PKI library + * by Massimiliano Pala (madwolf@openca.org) and OpenCA project + * + * Copyright (c) 2001-2007 The OpenCA Project. All rights reserved. + * + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +/*! \brief Allocates and Inizializes a new PKI_SOCKET */ +PKI_SOCKET *PKI_SOCKET_new () { + + PKI_SOCKET *sock = NULL; + + if(( sock = PKI_Malloc ( sizeof (PKI_SOCKET))) == NULL ) + { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return NULL; + } + + sock->type = PKI_SOCKET_TYPE_UNKNOWN; + sock->fd = -1; + sock->ssl = NULL; + sock->url = NULL; + + return sock; +} + +/*! \brief Creates a new PKI_SOCKET from an existing PKI_SSL */ + +PKI_SOCKET *PKI_SOCKET_new_ssl(PKI_SSL * ssl) { + PKI_SOCKET *sock = NULL; + + if ( !ssl ) return NULL; + + if(( sock = PKI_SOCKET_new ()) == NULL ) { + return NULL; + } + + PKI_SOCKET_set_ssl(sock, ssl); + + return sock; +} + + +/*! \brief Frees memory associated with a PKI_SOCKET data structure */ + +void PKI_SOCKET_free(PKI_SOCKET *sock) { + + if ( !sock ) return; + + if ( sock->ssl ) PKI_SSL_free ( sock->ssl ); + if ( sock->url ) URL_free ( sock->url ); + + PKI_Free ( sock ); + + return; +} + +/*! \brief Opens a connection to the passed url */ + +int PKI_SOCKET_open(PKI_SOCKET * sock, + const char * url_s, + int timeout ) { + + int ret = -1; + URL *url = NULL; + + if (!sock || !url_s ) return PKI_ERR; + + if ((url = URL_new ( url_s )) == NULL) + { + return PKI_ERR; + } + + ret = PKI_SOCKET_open_url(sock, url, timeout); + + URL_free(url); + + return ret; +} + +/*! \brief Opens a connection to the server identified by URL */ + +int PKI_SOCKET_open_url(PKI_SOCKET * sock, + const URL * url, + int timeout ) { + + int ret = -1; + + if ( !sock || !url ) return ( PKI_ERR ); + + if (sock->url != NULL) URL_free(sock->url); + sock->url = URL_new(URL_get_parsed(url)); + + if ( url->ssl == 1 ) + { + PKI_log_debug("Creating a SECURE connection (SSL/TLS)"); + ret = PKI_SOCKET_connect_ssl ( sock, url, timeout ); + } + else + { + PKI_log_debug("Creating a simple connection"); + ret = PKI_SOCKET_connect ( sock, url, timeout ); + } + + return ret; +} + +/*! \brief Opens a Connection to a URL via an already initialized PKI_SOCKET */ + +int PKI_SOCKET_connect(PKI_SOCKET * sock, + const URL * url, + int timeout ) { + + if ( !sock || !url ) return PKI_ERR; + + if (sock->url != NULL) URL_free(sock->url); + sock->url = URL_new(URL_get_parsed(url)); + + if((sock->fd = PKI_NET_open(url, timeout )) > 0 ) + { + sock->type = PKI_SOCKET_FD; + } + else + { + PKI_log_err ( "Can not connect to %s:%d (%s)", + url->addr, url->port, strerror (errno)); + return PKI_ERR; + } + + return PKI_OK; + +} + +/*! \brief Opens a Secure Connection to a URL via an already initialized PKI_SOCKET */ + +int PKI_SOCKET_connect_ssl(PKI_SOCKET * sock, + const URL * url, + int timeout ) { + + if ( !sock || !url ) return PKI_ERR; + + if (sock->url != NULL) URL_free(sock->url); + sock->url = URL_new(URL_get_parsed(url)); + + if(( sock->fd = PKI_NET_open ( url, timeout )) < 0 ) { + PKI_log_err("Can not create network connection to %s:%d", + url->addr, url->port ); + return PKI_ERR; + } + + if ( sock->ssl == NULL ) { + + // Allocates a new SSL object + if ((sock->ssl = PKI_SSL_new(NULL)) == NULL) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return PKI_ERR; + } + + // Let's allow for generic connections + PKI_SSL_set_verify(sock->ssl, PKI_SSL_VERIFY_NONE); + + } + + // Sets the name for SNI extension + PKI_SSL_set_host_name(sock->ssl, url->addr); + + if ( PKI_SSL_start_ssl ( sock->ssl, sock->fd ) == PKI_ERR ) + { + PKI_NET_close ( sock->fd ); + sock->fd = -1; + return PKI_ERR; + } + + sock->type = PKI_SOCKET_SSL; + + return PKI_OK; +} + +/*! \brief Closes a connected socket */ + +int PKI_SOCKET_close(PKI_SOCKET * sock) +{ + if (!sock) return PKI_ERR; + + switch ( sock->type ) + { + case PKI_SOCKET_FD: + PKI_NET_close ( sock->fd ); + break; + + case PKI_SOCKET_SSL: + if ( !sock->ssl ) return PKI_ERR; + PKI_SSL_close ( sock->ssl ); + break; + + default: + PKI_log_err("PKI SOCKET Close: type %d not supported", sock->type ); + break; + } + + if ( sock->url ) URL_free ( sock->url ); + + sock->url = NULL; + sock->type = PKI_SOCKET_TYPE_UNKNOWN; + + return PKI_OK; +} + +/*! \brief Sets an already connected PKI_SSL layer in an existing PKI_SOCKET */ + +int PKI_SOCKET_set_ssl(PKI_SOCKET *sock, PKI_SSL * ssl ) +{ + if ( !sock || !ssl ) return PKI_ERR; + + if ( sock->type == PKI_SOCKET_SSL && sock->ssl ) PKI_SSL_free ( sock->ssl ); + + sock->ssl = ssl; + + if (ssl->connected) + { + sock->type = PKI_SOCKET_SSL; + PKI_NET_close ( sock->fd ); + sock->fd = PKI_SSL_get_fd ( ssl ); + } + + return PKI_OK; +} + +/*! \brief Sets an already connected fd layer in an existing PKI_SOCKET */ + +int PKI_SOCKET_set_fd(PKI_SOCKET *sock, int fd ) { + + if ( !sock ) return PKI_ERR; + + sock->type = PKI_SOCKET_FD; + sock->fd = fd; + + if ( sock->ssl && sock->ssl->connected ) { + PKI_SSL_close ( sock->ssl ); + PKI_SSL_start_ssl ( sock->ssl, sock->fd ); + } + + return PKI_OK; +} + + +/*! \brief Returns the PKI_SSL layer (if present) */ + +PKI_SSL * PKI_SOCKET_get_ssl (const PKI_SOCKET *sock ) { + + if ( !sock ) return NULL; + + return sock->ssl; +} + +/*! \brief Returns the underlying file descriptor (if present) */ + +int PKI_SOCKET_get_fd (const PKI_SOCKET *sock ) { + + int ret = -1; + + if ( !sock ) return ( ret ); + + if((ret = PKI_SSL_get_fd ( sock->ssl )) < 0 ) { + ret = sock->fd; + } + + return ret; +} + +/*! \brief Starts an SSL/TLS session on a connected FD socket */ + +int PKI_SOCKET_start_ssl(PKI_SOCKET *sock ) { + + if( !sock ) return PKI_ERR; + + if ( !sock->ssl ) { + sock->ssl = PKI_SSL_new ( NULL ); + } + + if ( sock->ssl && sock->ssl->connected ) return PKI_ERR; + + return PKI_SSL_start_ssl ( sock->ssl, sock->fd ); + +} + +/*! \brief Reads n bytes from a connected socket */ + +ssize_t PKI_SOCKET_read (const PKI_SOCKET * sock, + const char * buf, + size_t n, + int timeout ) { + + if (!sock || !buf ) return -1; + + switch ( sock->type ) { + case PKI_SOCKET_FD: + return PKI_NET_read ( sock->fd, buf, n, timeout ); + break; + case PKI_SOCKET_SSL: + return (ssize_t) PKI_SSL_read ( sock->ssl, buf, (ssize_t) n ); + break; + default: + PKI_log_err ("PKI SOCKET READ: socket type %d not supported"); + return -1; + } + + return -1; +} + +/*! \brief Writes n bytes to a conected socket */ + +ssize_t PKI_SOCKET_write(const PKI_SOCKET * sock, + const char * buf, + size_t n ) { + + if (!sock || !buf ) return -1; + + switch ( sock->type ) { + case PKI_SOCKET_FD: + return PKI_NET_write ( sock->fd, buf, n ); + break; + case PKI_SOCKET_SSL: + return PKI_SSL_write ( sock->ssl, buf, (ssize_t) n ); + break; + default: + PKI_log_err ("PKI SOCKET WRITE: socket type %d not supported"); + return -1; + } + + return -1; +} + +/*! \brief Returns the URL used in PKI_SOCKET_open or PKI_SOCKET_open_url */ + +const URL *PKI_SOCKET_get_url(const PKI_SOCKET *sock) { + + if ( !sock ) return NULL; + + return sock->url; +} + + diff --git a/src/utils/net/sock.c b/src/utils/net/sock.c new file mode 100644 index 00000000..9b9ef714 --- /dev/null +++ b/src/utils/net/sock.c @@ -0,0 +1,631 @@ +/* Socket Wrapping functions */ +/* OpenCA libpki package + * Copyright (c) 2000-2009 by Massimiliano Pala and OpenCA Group + * All Rights Reserved + * + * =================================================================== + * Released under OpenCA LICENSE + */ + +#include + +#define LISTENQ 30 + +extern int h_errno; + +/* ---------------------------- Internal Functions ---------------------- */ + +int _Socket (int family, int type, int protocol) { + int n; + if ( (n = socket(family,type,protocol)) < 0) + PKI_log( PKI_LOG_ERR, "Can not Init Socket (%s)", + hstrerror(h_errno)); + return n; +} + +#pragma GCC diagnostic ignored "-Wconversion" +int _Listen (const char *hostname, int port, PKI_NET_SOCK_TYPE type) { + + int fd = 0; + int reuse_addr = 1; + int ret = 0; + + struct addrinfo *res, *rp; + struct addrinfo hints; + + // struct sockaddr_storage servaddr; + + char service[10]; + + /* create socket */ + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; + hints.ai_flags = AI_PASSIVE; + hints.ai_socktype = type; + hints.ai_canonname = NULL; + hints.ai_addr = NULL; + hints.ai_next = NULL; + + /* If we want a datagram listener, we switch to UDP */ + switch (hints.ai_socktype) + { + case PKI_NET_SOCK_DGRAM: + hints.ai_protocol = IPPROTO_UDP; + break; + + default: + hints.ai_protocol = 0; + } + + snprintf( service, sizeof(service)-1, "%d", port ); + + if((ret = getaddrinfo( hostname, service, &hints, &res)) != 0 ) { + PKI_log_err("Can not parse hostname (err: %d)", ret); + return ( -1 ); + } + + for ( rp = res; rp != NULL; rp = rp->ai_next ) { + if((fd = _Socket( rp->ai_family, rp->ai_socktype, + rp->ai_protocol)) == -1 ) { + continue; + } + + if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse_addr, + sizeof(reuse_addr)) == -1 ) { + // PKI_log( PKI_LOG_ERR, "Can not Set Socket Options [%s]", + // hstrerror(h_errno)); + close(fd); + continue; + } + + // Successfully Binded + break; + } + + if ( rp == NULL ) { + freeaddrinfo ( res ); + close ( fd ); + return ( -1 ); + } + + if (bind(fd, rp->ai_addr, rp->ai_addrlen) == -1 ) + { + PKI_log_err("Can not bind to %s:%d (%s)", hostname, port, + hstrerror(h_errno)); + close ( fd ); + freeaddrinfo ( res ); + return ( -1 ); + }; + + freeaddrinfo ( res ); + + /* If a DGRAM is used, no need to listen */ + if (type == PKI_NET_SOCK_DGRAM) return fd; + + /* Here we listen on the fd */ + if (listen(fd, LISTENQ) == -1) + { + PKI_log_err("Can not listen to fd (%s)", hstrerror(h_errno)); + close ( fd ); + return(-1); + } + + return ( fd ); + +} + +#ifndef LIBPKI_TARGET_OSX +# ifdef HAVE_GCC_PRAGMA_POP +# pragma GCC diagnostic pop +# endif +#endif + +ssize_t _Read (int fd, + const void * bufptr, + size_t nbytes) { + + ssize_t n; + +again: + if ((n = read(fd, (void *)bufptr, nbytes)) < 0) + { + if (INTERRUPTED_BY_SIGNAL) + { + goto again; + } + else + { + PKI_log(PKI_LOG_ERR, "Socket Read failed [%d:%s]", + h_errno, hstrerror(h_errno)); + } + } + return(n); +} + +ssize_t _Write (int fd, + const void * bufptr, + size_t nbytes) { + + ssize_t n; + +again: + if ((n = write(fd, (void *)bufptr, nbytes)) < 0) + { + if (INTERRUPTED_BY_SIGNAL) + { + goto again; + } + else + { + PKI_log_err( "Socket Write failed [%d:%s]!", h_errno, hstrerror(h_errno)); + } + } + return(n); +} + +int _Select (int maxfdp1, fd_set *readset, fd_set *writeset, + fd_set *exceptset, struct timeval *timeout) { + + int n; +again: + if ( (n = select (maxfdp1, readset, writeset, + exceptset, timeout)) < 0) { + if (INTERRUPTED_BY_SIGNAL) + goto again; + else + PKI_log( PKI_LOG_ERR, "Select failed!"); + } + return(n); +} + +int _Connect (int sockfd, const SA *srvaddr, socklen_t addrlen) +{ + if (connect(sockfd, srvaddr, addrlen) != 0) + { + PKI_log(PKI_LOG_ERR, "Socket Connect failed (%s)!", + hstrerror(h_errno)); + return(PKI_ERR); + } + return ( PKI_OK ); +} + + +int _Close (int fd) { + if (close(fd) != 0) { + PKI_log(PKI_LOG_ERR, "Socket Close failed (%s)!", + hstrerror(h_errno)); + return(0); + } + return( 1 ); +} + + +void _Shutdown (int fd, int howto) { + if (shutdown(fd,howto) != 0) + PKI_log(PKI_LOG_ERR, "Socket Shutdown failed (%s)!", + hstrerror(h_errno)); + + return; +} + +struct hostent *Gethostbyname (const char *hostname) { + + struct hostent *hp = NULL; + + if( !hostname ) return NULL; + if ((hp = gethostbyname(hostname)) == NULL) + PKI_log( PKI_LOG_ERR, "Socket gethostbyname() failed for " + "[%s]: %s", hostname, hstrerror(h_errno)); + return hp; +} + +#pragma GCC diagnostic ignored "-Wconversion" +int inet_connect (const URL *url) { + + int sockfd; + int ret = 0; + + struct addrinfo *res, *rp; + struct addrinfo hints; + + char service[10]; + + /* create socket */ + memset(&hints, 0, sizeof( struct addrinfo )); + hints.ai_family = AF_UNSPEC; + hints.ai_flags = AI_PASSIVE; + hints.ai_protocol = IPPROTO_TCP; + hints.ai_canonname = NULL; + hints.ai_addr = NULL; + hints.ai_next = NULL; + + snprintf( service, sizeof(service)-1, "%d", url->port ); + + if((ret = getaddrinfo( url->addr, service, &hints, &res)) != 0 ) { + PKI_log_err("Can not parse hostname (err: %d)", ret); + return ( -1 ); + } + + for ( rp = res; rp != NULL; rp = rp->ai_next ) { + if((sockfd = _Socket( rp->ai_family, rp->ai_socktype, + rp->ai_protocol)) == -1 ) { + continue; + } + break; + } + + if ( rp == NULL ) { + PKI_log_err ( "Can not create socket"); + freeaddrinfo ( res ); + return ( -1 ); + } + + /* try to connect */ + if(( ret = _Connect(sockfd, rp->ai_addr, rp->ai_addrlen )) == PKI_ERR ) { + PKI_log( PKI_LOG_ERR, "Socket _Connect failed (%s)", + hstrerror( h_errno )); + + _Close ( sockfd ); + freeaddrinfo ( res ); + return(-1); + } + + freeaddrinfo( res ); + + PKI_log_debug( "Connection Successful to %s:%d", + url->addr, url->port ); + + return ( sockfd ); +} + +#ifndef LIBPKI_TARGET_OSX +# ifdef HAVE_GCC_PRAGMA_POP +# pragma GCC diagnostic pop +# endif +#endif + + + +#pragma GCC diagnostic error "-Wconversion" +int inet_close ( int fd ) +{ + return _Close( fd ); +} + +#ifndef LIBPKI_TARGET_OSX +# ifdef HAVE_GCC_PRAGMA_POP +# pragma GCC diagnostic pop +# endif +#endif + +/* ----------------------------- Public Functions ----------------------- */ + +/*! \brief Returns a reference to a new socket (int) */ + +int PKI_NET_socket ( int family, int type, int protocol ) { + return _Socket( family, type, protocol ); +} + +/*! \brief Returns a reference to a listen socket */ +int PKI_NET_listen (const char *host, int port, PKI_NET_SOCK_TYPE type ) { + int sock = -1; + + sock = _Listen ( host, port, type ); + if ( sock < 0 ) + { + return PKI_ERR; + }; + + return sock; +} + +#pragma GCC diagnostic ignored "-Wsign-conversion" +/*! \brief Returns the connected socket as a result of an Accept */ +int PKI_NET_accept(int sock, int timeout ) { + + int n; + struct sockaddr addr; + socklen_t len; + + // Timeout Support Values + struct timeval time_out; + struct timeval *time_out_pnt = NULL; + fd_set readset; + int sel_ret; + + // Initialization + len=sizeof( struct sockaddr ); + + // Set the nonblocking status + if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) { + PKI_log_err("PKI_NET_accept()::Cannot set non-blocking " + "socket [%s]", hstrerror( h_errno)); + return -1; + } + + // Loop on the Accept + for (;;) { + + /* Add the socket to the read set */ + FD_ZERO( &readset ); + FD_SET ( sock, &readset); + + // We need to update the values every time as select can + // change them + if ( timeout <= 0 ) { + time_out_pnt = NULL; + } else { + time_out_pnt = &time_out; + time_out.tv_sec = timeout; + time_out.tv_usec = 0; + }; + + sel_ret = select(sock+1, &readset, NULL, NULL, time_out_pnt); + + if (sel_ret == -1 && errno == EINTR) { + char buf[512]; + if(strerror_r ( errno, buf, sizeof(buf)) == 0 ) { + PKI_log_debug("Select Recoverable [%s]", + buf); + } else { + PKI_log_debug("Select Recoverable"); + }; + continue; + } + + if( sel_ret < 0 ) { + PKI_log_debug("ERROR, Select %s", strerror(errno)); + return -1; + }; + + if( (timeout > 0 ) && ( sel_ret == 0 ) ) { + PKI_log_debug("ERROR, Socket connection t-out"); + return -1; + }; + + if (FD_ISSET (sock, &readset)) + { + n = accept(sock, &addr, &len); + + if ( n < 0) { + if (INTERRUPTED_BY_SIGNAL) { + continue; + }; + + PKI_log(PKI_LOG_ERR,"[%d:%ld:%d] Error while (ACCEPT) [%s:%s]", + n, h_errno, errno, hstrerror( h_errno ), + strerror(errno)); + } + break; + } + } + return(n); +} + +#ifndef LIBPKI_TARGET_OSX +# ifdef HAVE_GCC_PRAGMA_POP +# pragma GCC diagnostic pop +# endif +#endif + +/*! \brief Connects to an host and returns the connected socket */ +int PKI_NET_open(const URL * url, int timeout ) { + return inet_connect ( url ); +} + +/*! \brief Closes the connection to an open connection to an host */ +int PKI_NET_close ( int sock ) { + return inet_close ( sock ); +} + +/*! \brief Writes n bytes of data to a socket */ +ssize_t PKI_NET_write (int fd, const void *bufptr, size_t nbytes) { + return _Write( fd, bufptr, nbytes ); +} + +/*! \brief Reads n-bytes of data from a socket */ +#pragma GCC diagnostic ignored "-Wsign-conversion" +ssize_t PKI_NET_read (int fd, const void *bufptr, size_t nbytes, int timeout ) { + + ssize_t n = 0; + + // Timeout Support Values + struct timeval time_out; + struct timeval *time_out_pnt = NULL; + fd_set readset; + int sel_ret; + + if (fcntl( fd, F_SETFL, O_NONBLOCK) < 0) { + PKI_log_err("PKI_NET_accept()::Cannot set non-blocking " + "socket [%s]", hstrerror( h_errno)); + return -1; + } + + for ( ; ; ) { + /* Add the socket to the read set */ + FD_ZERO( &readset ); + FD_SET ( fd, &readset); + + // We need to update the values every time as select can + // change them + if ( timeout <= 0 ) { + time_out_pnt = NULL; + } else { + time_out_pnt = &time_out; + time_out.tv_sec = timeout; + time_out.tv_usec = 0; + }; + + sel_ret = select(fd+1, &readset, NULL, NULL, time_out_pnt); + + if (sel_ret == -1 && errno == EINTR) { + PKI_log_debug("ERROR, Select Recoverable [%s]", strerror(errno)); + continue; + } + + if( sel_ret < 0 ) { + PKI_log_debug("ERROR, Select %s", strerror(errno)); + return -1; + }; + + if( (timeout > 0 ) && (sel_ret == 0) ) { + // Timeout Condition, just return 0 + return 0; + } + + if (FD_ISSET (fd, &readset)) { + if((n = recv(fd, (void *)bufptr, nbytes, 0 )) == 0 ) { + // This only verifies in case of a closed connection + PKI_log_debug("ERROR: Connection closed by peer"); + return -1; + }; + + if (n < 0) { + if( errno == EWOULDBLOCK ) { + PKI_log_debug("Network error, EWOULDBLOCK"); + continue; + } + break; + } else { + //PKI_log_debug("Read %d bytes from socket", n); + }; + + break; + } + } + + return n; +} + +#ifndef LIBPKI_TARGET_OSX +# ifdef HAVE_GCC_PRAGMA_POP +# pragma GCC diagnostic pop +# endif +#endif + + +/*! \brief Returns data read from a socket */ +PKI_MEM *PKI_NET_get_data ( int fd, int timeout, size_t max_size ) { + + PKI_MEM *buf = NULL; + + char tmp_buff[BUFF_MAX_SIZE]; + ssize_t newsize = 0; + + if( fd < 1 ) { + PKI_log_err("Attempted to retrieve data from sock %d", fd ); + return NULL; + } + + /* get subject name from bio using recommended OpenSSL template */ + if((buf = PKI_MEM_new_null()) == NULL ) { + PKI_log_err( "Memory Failure" ); + return ( NULL ); + } + + while( (newsize = PKI_NET_read( fd, tmp_buff, sizeof(tmp_buff), + timeout )) != 0 ) { + + if( newsize < 0 ) { + PKI_log_err("Network Error: %s", strerror(errno)); + break; + } + + if( (max_size > 0) && + ((ssize_t)(buf->size) + newsize > max_size) ) { + newsize = (ssize_t) (max_size - buf->size); + PKI_MEM_add( buf, (const unsigned char *)tmp_buff, (size_t) newsize); + break; + }; + + PKI_MEM_add(buf, (const unsigned char *)tmp_buff, (size_t)newsize); + + }; + + if( buf->size <= 0 ) { + PKI_log_debug("WARNING::No NET data retrieved."); + + if( buf ) PKI_MEM_free ( buf ); + buf = NULL; + } + + return ( buf ); +} + +/*! \brief Gets a DGRAM packet */ +ssize_t PKI_NET_recvfrom (int fd, + const void * bufptr, + size_t nbytes, + const struct sockaddr_in * cli, + socklen_t cli_len) { + + ssize_t rv = 0; + struct sockaddr_in cli_addr; + socklen_t slen = sizeof(cli_addr); + + bzero(&cli_addr, sizeof(cli_addr)); + + if (!bufptr || nbytes <= 0) return 0; + + if (cli && cli_len > 0) + { + rv = recvfrom(fd, (char *)bufptr, nbytes, 0, (struct sockaddr *)cli, &cli_len); + PKI_log_debug("[UDP] Packet from %s:%d", + inet_ntoa(cli->sin_addr), ntohl(cli->sin_port)); + } + else + { + rv = recvfrom(fd, (char *)bufptr, nbytes, 0, (struct sockaddr *)&cli_addr, &slen); + PKI_log_debug("[UDP] Packet from %s:%d", + inet_ntoa(cli_addr.sin_addr), ntohl(cli_addr.sin_port)); + } + + if (rv == -1) + { + PKI_log_debug("[UDP] Error getting the packet!"); + return -1; + } + + return rv; +} + +/*!\brief Sends a datagram to a host */ +ssize_t PKI_NET_sendto(int sock, + const char * host, + int port, + const void * data, + size_t len) { + ssize_t ret = 0; + + // Check the input + if (!host || port < 0 || port > 65535) return -1; + + // Create a new datagram socket + if (sock < 0) + { + if ((sock = PKI_NET_socket(PF_INET, PKI_NET_SOCK_DGRAM, 0)) <= 0) + return -1; + } + + // Setup the Server socket + struct sockaddr_in serv; + socklen_t slen = sizeof(serv); + memset(&serv, 0, sizeof(struct sockaddr_in)); + serv.sin_family = AF_INET; + + // Set the destination + serv.sin_port = (in_port_t) htonl((uint32_t) port); + if (inet_aton(host, &serv.sin_addr) == -1) + { + PKI_log_err("ERROR: Can not convert destination address (%s)", host); + return -1; + } + + // Sends the data + ret = sendto(sock, data, len, 0, (struct sockaddr*) &serv, slen); + + // Check the return value + if (ret == -1) PKI_log_debug("ERROR: Can not send DGRAM packet (%d)", h_errno); + + return ret; +} diff --git a/src/utils/net/ssl.c b/src/utils/net/ssl.c new file mode 100644 index 00000000..bda2d3a2 --- /dev/null +++ b/src/utils/net/ssl.c @@ -0,0 +1,1270 @@ +/* OpenCA libpki package +* (c) 2000-2007 by Massimiliano Pala and OpenCA Group +* All Rights Reserved +* +* =================================================================== +* Released under OpenCA LICENSE +*/ + +#include + +#define BUFF_MAX_SIZE 2048 + +/* Static Function - used only internally */ +static int __ssl_find_trusted(X509_STORE_CTX *ctx, + PKI_X509_CERT_VALUE *x ) { + int i = 0; + int idx = 0; + int trusted_certs_num = 0; + + int ctx_err = X509_V_OK; + + int ret = PKI_ERR; + + SSL *ssl = NULL; + PKI_SSL *pki_ssl = NULL; + + PKI_X509_CERT *curr_cert = NULL; + + // Retrieves the store CTX context + if((ssl = X509_STORE_CTX_get_ex_data(ctx, + SSL_get_ex_data_X509_STORE_CTX_idx())) == 0 ) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Can not retrieve trust store context"); + return PKI_ERR; + } + + // Retrieves the SSL context extra data + if ((pki_ssl = SSL_get_ex_data(ssl, idx)) == 0 ) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Can not retrieve SSL/TLS context"); + return PKI_ERR; + } + + // Process current certificate + curr_cert = PKI_X509_new_dup_value(PKI_DATATYPE_X509_CERT, x, 0); + if (curr_cert == 0) return PKI_ERROR(PKI_ERR_MEMORY_ALLOC, 0); + + // Gets the number of trusted certificates + trusted_certs_num = PKI_STACK_X509_CERT_elements(pki_ssl->trusted_certs); + + // Check if a certificate is among the trusted ones + for (i = 0; i < trusted_certs_num; i++){ + + PKI_X509_CERT *issuer = NULL; + PKI_X509_CERT_VALUE *issuer_val = NULL; + + issuer = PKI_STACK_X509_CERT_get_num(pki_ssl->trusted_certs, i); + issuer_val = PKI_X509_get_value(issuer); + + // Checks if the peer certificate is the i-th trusted ones + if (X509_cmp(issuer_val, x) == 0) { + /* The certificate is present among the trusted ones */ + PKI_log_debug("Same Certificate Found in Chain!"); + ret = PKI_OK; + break; + } + + // Checks if the peer certificate was issued by the i-th trusted one + if((ctx_err = X509_check_issued(issuer_val, x)) == X509_V_OK ) { + /* The cert has been issued by a trusted one */ + PKI_log_debug("__ssl_find_trusted()-> Found Issuer"); + ret = PKI_OK; + break; + } + } + + if ( ret == PKI_OK ) X509_STORE_CTX_set_error(ctx, X509_V_OK); + // ctx->error = X509_V_OK; + + PKI_log_debug("__ssl_find_trusted()-> Return code is %d", ret ); + PKI_X509_free ( curr_cert ); + + return ret; +} + +static int __ssl_verify_cb ( int code, X509_STORE_CTX *ctx) { + + PKI_X509_CERT_VALUE *err_cert = NULL; + PKI_X509_CERT *x = NULL; + SSL *ssl = NULL; + PKI_SSL *pki_ssl = NULL; + PKI_STACK *sk = NULL; + + int err = 0; + int depth = 0; + int idx = 0; + int ret = 0; + + err_cert = X509_STORE_CTX_get_current_cert( ctx ); + err = X509_STORE_CTX_get_error( ctx ); + depth = X509_STORE_CTX_get_error_depth ( ctx ); + + // Gets the extra data from the SSL context + ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); + if (ssl == 0) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, 0); + return 0; + } + + // Gets the PKI extra data + pki_ssl = SSL_get_ex_data(ssl, idx); + if (pki_ssl == 0) PKI_DEBUG("Cannot retrieve the PKI_SSL context from SSL data"); + + if(( x = PKI_X509_new_dup_value(PKI_DATATYPE_X509_CERT, + err_cert, + NULL )) == NULL ) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, 0); + return 0; + } + + if ( 0 ) { + if ( PKI_X509_CERT_is_selfsigned ( x ) == PKI_ERR ) { + if ( (PKI_SSL_check_verify ( pki_ssl, + PKI_SSL_VERIFY_CRL) == PKI_OK ) || + (PKI_SSL_check_verify( pki_ssl, + PKI_SSL_VERIFY_CRL_REQUIRE ) == PKI_OK)) { + + // Check for PRQP support + if ( PKI_SSL_check_verify ( pki_ssl, + PKI_SSL_VERIFY_ENABLE_PRQP ) == PKI_OK ) { + // PKI_X509_CERT_VALUE *issVal = NULL; + // PKI_X509_CERT *caCert = NULL; + + sk = PKI_get_ca_service_sk( x, + "crlDistributionPoints", NULL); + } + + if ( sk == NULL ) { + if ( (sk = PKI_X509_CERT_get_cdp ( x )) == NULL ) { + PKI_log_debug ("NO CDP in cert %d", depth); + } + } + + if ( (!sk) && ( PKI_SSL_check_verify ( pki_ssl, + PKI_SSL_VERIFY_CRL_REQUIRE ) == PKI_OK) ) { + PKI_log_debug( "Required CRL check failed"); + X509_STORE_CTX_set_error(ctx, X509_V_ERR_UNABLE_TO_GET_CRL); + // ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL; + } else { + int i = 0; + + for ( i=0; i < PKI_STACK_elements ( sk ); i++ ) { + PKI_log_debug( "[%d] CDP num [%d] => " + "%s", depth, + PKI_STACK_get_num( sk, i )); + } + } + } + } + } + + // if (code == 1) ctx->error = X509_V_OK; + if (code == 1) X509_STORE_CTX_set_error(ctx, X509_V_OK); + + /* + if( 1 ) { + char *tmp = NULL; + + PKI_log_debug("[%d] SSL Verify (%d::%s)", + depth, X509_STORE_CTX_get_error( ctx ), + X509_verify_cert_error_string(err)); + + if((tmp = PKI_X509_CERT_get_parsed ( x, + PKI_X509_DATA_SUBJECT)) != NULL ){ + PKI_log_debug(" Subject = %s", tmp ); + PKI_Free ( tmp ); + } + + if ((tmp = PKI_X509_CERT_get_parsed ( x, + PKI_X509_DATA_ISSUER)) != NULL ) { + PKI_log_debug(" Issuer = %s", tmp); + PKI_Free ( tmp ); + } + + } + */ + + switch ( err ) { + /* Cert Validity */ + case X509_V_ERR_CERT_NOT_YET_VALID: + case X509_V_ERR_CERT_HAS_EXPIRED: + case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: + case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: + PKI_log_debug("Certificate Validity Error (%d::%s)", + depth, X509_verify_cert_error_string(err)); + break; + + /* Revocation Related */ + case X509_V_ERR_CERT_REVOKED: + PKI_log_debug("[%d] Certificate is Revoked", depth); + break; + + /* Certificate Availability */ + case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: + case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: + if (pki_ssl && pki_ssl->auth != 0 ) { + pki_ssl->verify_ok = PKI_ERR; + } + ret = 1; + break; + + /* CRL Related */ + case X509_V_ERR_UNABLE_TO_GET_CRL: + PKI_log_debug("[%d] Unable to get CRL", depth); + if (pki_ssl && PKI_SSL_check_verify(pki_ssl, + PKI_SSL_VERIFY_CRL ) == PKI_ERR ) { + ret = 1; + } + break; + + case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: + case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: + case X509_V_ERR_CRL_NOT_YET_VALID: + case X509_V_ERR_CRL_HAS_EXPIRED: + PKI_log_debug("[%d] CRL Validity Error", depth); + if (pki_ssl && PKI_SSL_check_verify(pki_ssl, + PKI_SSL_VERIFY_CRL) == PKI_ERR) { + ret = 1; + } + break; + +#ifdef X509_V_ERR_CRL_PATH_VALIDATION_ERROR + case X509_V_ERR_CRL_PATH_VALIDATION_ERROR: + PKI_log_debug("[%d] CRL Path Validation Error", depth); + break; +#endif + case X509_V_ERR_KEYUSAGE_NO_CRL_SIGN: + case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: + case X509_V_ERR_CRL_SIGNATURE_FAILURE: + PKI_log_debug("[%d] CRL Signature Error", depth); + break; + +#ifdef X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION + case X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION: + PKI_log_debug("[%d] CRL unhandled critical ext", depth); + break; +#endif + case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER: + PKI_log_debug("[%d] Unable to get CRL Issuer", depth); + break; + + /* Certificate Format */ + case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: + case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: + case X509_V_ERR_CERT_SIGNATURE_FAILURE: + case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: + PKI_log_debug("Certificate Signature Error (%d::%s)", + depth, X509_verify_cert_error_string(err)); + break; + + /* Library Specific */ + case X509_V_ERR_OUT_OF_MEM: + PKI_log_debug("Memory Error"); + break; + case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: + case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: + if ( pki_ssl && pki_ssl->flags & PKI_SSL_VERIFY_NO_SELFSIGNED) { + PKI_DEBUG("Self Signed Certificate in Chain [level %d]", depth ); + } else { + ret = 1; + } + break; + + /* Certificate Chain */ + case X509_V_ERR_INVALID_CA: + PKI_DEBUG("Invalid CA [%d::%s]", depth, X509_verify_cert_error_string(err)); + break; + + case X509_V_ERR_CERT_CHAIN_TOO_LONG: + case X509_V_ERR_PATH_LENGTH_EXCEEDED: + PKI_log_debug("Certificate Path Len Error [%d::%s]", + depth, X509_verify_cert_error_string(err)); + break; + + /* Extensions Related */ + case X509_V_ERR_INVALID_PURPOSE: + PKI_DEBUG("Invalid Purpose Error [%d::%s]", + depth, X509_verify_cert_error_string(err)); + break; + case X509_V_ERR_CERT_UNTRUSTED: + PKI_DEBUG("Certificate Not Trusted [%d::%s]", + depth, X509_verify_cert_error_string(err)); + if (pki_ssl && pki_ssl->auth != 0) { + PKI_DEBUG("Cert not trusted, Ignored"); + pki_ssl->verify_ok = PKI_ERR; + ret = 1; + }; + break; + + case X509_V_ERR_CERT_REJECTED: + PKI_log_debug("Certificate rejected [%d::%s]", + depth, X509_verify_cert_error_string(err)); + break; + case X509_V_ERR_SUBJECT_ISSUER_MISMATCH: + PKI_log_debug("Certificate Issuer Mismatch [%d::%s]", + depth, X509_verify_cert_error_string(err)); + break; + case X509_V_ERR_AKID_SKID_MISMATCH: + case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH: + PKI_log_debug("Certificate AKID/SKID Error [%d::%s]", + depth, X509_verify_cert_error_string(err)); + break; + case X509_V_ERR_KEYUSAGE_NO_CERTSIGN: +#ifdef X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION + case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION: +#endif + case X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE: +#ifdef X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE + case X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE: +#endif + case X509_V_ERR_INVALID_EXTENSION: + PKI_log_debug("Certificate Extension Error [%d::%s]", + depth, X509_verify_cert_error_string(err)); + break; + + case X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED: + case X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED: + PKI_log_debug("Proxy Certificate Error [%d::%s]", + depth, X509_verify_cert_error_string(err)); + break; + + case X509_V_ERR_INVALID_POLICY_EXTENSION: + case X509_V_ERR_NO_EXPLICIT_POLICY: + PKI_log_debug("Certificate Policy Error [%d::%s]", + depth, X509_verify_cert_error_string(err)); + break; + +#ifdef X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE + case X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: +#ifdef X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX + case X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: +#endif + PKI_log_debug("Certificate Constraint Error [%d::%s]", + depth, X509_verify_cert_error_string(err)); + break; +#endif + +#ifdef X509_V_ERR_UNSUPPORTED_NAME_SYNTAX + case X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: + PKI_log_debug("Certificate Name Error [%d::%s]", + depth, X509_verify_cert_error_string(err)); + break; +#endif + /* These are supported only in 0.9.9+ - when no + specific code is developed, let's just default */ + /* + case X509_V_ERR_DIFFERENT_CRL_SCOPE: + case X509_V_ERR_UNNESTED_RESOURCE: + case X509_V_ERR_PERMITTED_VIOLATION: + case X509_V_ERR_EXCLUDED_VIOLATION: + case X509_V_ERR_SUBTREE_MINMAX: + case X509_V_ERR_INVALID_NON_CA: + */ + case X509_V_OK: + /* No error */ + ret = 1; + break; + + default: + PKI_log_debug("General Error [%d:%s]", err, + X509_verify_cert_error_string(err)); + } + + // Only if we have the PKI_SSL structure available + // we can actually perform the extra operations + if (pki_ssl) { + + // Checks the flags we set for the SSL/TLS connection + if (pki_ssl->verify_flags == PKI_SSL_VERIFY_NONE) { + pki_ssl->auth = 0; + } + + /* Check if we don't really care about the authentication */ + if (pki_ssl->auth == 0 || ret == 1) ret = 1; + + /* We add the Cert to the peer_chain only if we have an "ok" return + * code to avoid duplicates */ + if (pki_ssl->peer_chain == 0) { + + // Generates an empty stack of certs + pki_ssl->peer_chain = PKI_STACK_X509_CERT_new(); + if (pki_ssl->peer_chain == 0) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, 0); + return 0; + } + } + + if (ret == 1) { + // We add the certificate only if it was successfully validated + // to avoid malformed, expired, etc. certificates + PKI_STACK_X509_CERT_push(pki_ssl->peer_chain, + PKI_X509_dup(x)); + } + + /* Check for the verify_ok --- it should be OK in depth 0. We use + * this variable to keep track if at least one cert in the chain is + * explicitly trusted */ + if (depth == 0 && + pki_ssl->auth != 0 && + pki_ssl->verify_ok != PKI_OK) { + + PKI_X509_CERT_STACK *sk_x = 0; + PKI_X509_CERT *sk_cert = 0; + + int k = 0; + int ok = PKI_ERR; + + sk_x = pki_ssl->peer_chain; + + // Certificate Details + fprintf(stderr, "\n ====== SERVER CERTIFICATE ==========\n"); + PKI_X509_CERT_put(x, PKI_DATA_FORMAT_TXT, "stderr", NULL, NULL, NULL); + fprintf(stderr, "\n\n"); + + if (sk_x != 0) for (k = 0; k < PKI_STACK_X509_CERT_elements(sk_x); k++) { + + // Gets the certificate from the stack + sk_cert = PKI_STACK_X509_CERT_get_num(sk_x, k); + + // Certificate Details + fprintf(stderr, "\n ====== PEER CHAIN CERTIFICATE - num: %d ==========\n", k); + PKI_X509_CERT_put(sk_cert, PKI_DATA_FORMAT_TXT, "stderr", NULL, NULL, NULL); + fprintf(stderr, "\n"); + + // Checks if we can find the certificate in the list of + // trusted certificates for the SSL/TLS connection + ok = __ssl_find_trusted(ctx, (X509 *) sk_cert->value); + + // If we have found the certificate, let's break + if (ok == PKI_OK) break; + } + + if ( ok == PKI_ERR ) { + /* No trusted certificate is present in the chain! */ + PKI_log_err("None of the peer chain certificates is " + "trusted"); + // ctx->error = X509_V_ERR_CERT_UNTRUSTED; + X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_UNTRUSTED); + ret = 0; + } else { + ret = 1; + } + } + } + + /* Free Allocated Memory for PKI_X509_CERT object */ + if (x) PKI_X509_CERT_free(x); + + return ret; +} + +static int __pki_ssl_init_ssl ( PKI_SSL *ssl ) { + + int ssl_verify_flags = 0; + + PKI_TOKEN *ssl_tk = NULL; + + if ( !ssl || !ssl->ssl_ctx ) return PKI_ERR; + + ssl->connected = 0; + + SSL_CTX_set_options(ssl->ssl_ctx,(long unsigned int)ssl->flags ); + + ssl_tk = ssl->tk; + + ssl_verify_flags = PKI_SSL_VERIFY_NONE; + + if( ssl->verify_flags & PKI_SSL_VERIFY_PEER ) { + ssl_verify_flags |= SSL_VERIFY_PEER | + SSL_VERIFY_CLIENT_ONCE; + }; + + if( ssl->verify_flags & PKI_SSL_VERIFY_PEER_REQUIRE ) { + ssl_verify_flags |= SSL_VERIFY_PEER | + SSL_VERIFY_FAIL_IF_NO_PEER_CERT | + SSL_VERIFY_CLIENT_ONCE; + } + + /* Load the Server/Client cert/key if auth is set */ + if ( ssl_tk && ssl_tk->cert && ssl_tk->keypair ) { + + PKI_X509_CERT_VALUE *x = NULL; + PKI_X509_KEYPAIR_VALUE * x_k = NULL; + + if((ssl_tk->cert != NULL ) && + (x = PKI_X509_get_value ( ssl_tk->cert )) != NULL ) + { + PKI_log_debug("Using Token Certificate for Peer Auth"); + + if (!SSL_CTX_use_certificate(ssl->ssl_ctx, x )) + { + PKI_log_err("Can not enable ssl auth (%s)", + ERR_error_string(ERR_get_error(),NULL)); + return PKI_ERR; + } + } + + x_k = PKI_X509_get_value ( ssl_tk->keypair ); + + if(!SSL_CTX_use_PrivateKey(ssl->ssl_ctx, x_k )) + { + PKI_log_err("ERROR::Can not enable ssl auth (%s)", + ERR_error_string(ERR_get_error(), NULL )); + + return PKI_ERR; + } + } + + /* Now sets the trusted certificates */ + if( ssl->trusted_certs || (ssl_tk && ssl_tk->trustedCerts)) + { + X509_STORE *store = NULL; + unsigned long vflags = 0; + + if ((store = SSL_CTX_get_cert_store(ssl->ssl_ctx)) == NULL) + { + PKI_log_debug("Crypto Lib Error (%d::%s)", ERR_get_error(), + ERR_error_string(ERR_get_error(), NULL)); + return PKI_ERR; + } + + //If we want CRL to be checked, enable this + if (ssl->flags & PKI_SSL_VERIFY_CRL) + vflags |= X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL; + + X509_STORE_set_flags( store, vflags ); + + // Adds the Token CA Cert to the Trusted Certs + if(ssl_tk && ssl_tk->cacert) X509_STORE_add_cert ( store, + PKI_X509_get_value(ssl_tk->cacert)); + + if ( ssl->trusted_certs ) { + int i = 0; + + for (i=0; i < PKI_STACK_X509_CERT_elements( + ssl->trusted_certs); i++) { + PKI_X509_CERT_VALUE *val = NULL; + PKI_X509_CERT *x = NULL; + + x = PKI_STACK_X509_CERT_get_num( + ssl->trusted_certs,i); + val = PKI_X509_get_value ( x ); + X509_STORE_add_cert ( store, val ); + } + } + + if ( ssl_tk && ssl_tk->trustedCerts ) { + int i = 0; + + for (i=0; i < PKI_STACK_X509_CERT_elements( + ssl_tk->trustedCerts); i++) { + PKI_X509_CERT_VALUE *val = NULL; + PKI_X509_CERT *x = NULL; + + x = PKI_STACK_X509_CERT_get_num( + ssl_tk->trustedCerts,i); + val = PKI_X509_get_value ( x ); + X509_STORE_add_cert ( store, val ); + } + } + } + + /* Clears the SSL_CTX chain certs */ + // SSL_CTX_clear_chain_certs(ssl->ssl_ctx); + SSL_CTX_clear_extra_chain_certs(ssl->ssl_ctx); + + /* Now sets the other (not-trusted) certificates */ + if ( ssl->other_certs ) { + int i = 0; + for (i = 0; i < PKI_STACK_X509_CERT_elements( + ssl->other_certs); i++) { + PKI_X509_CERT_VALUE *val = NULL; + PKI_X509_CERT *x = NULL; + + x = PKI_STACK_X509_CERT_get_num( + ssl->other_certs,i); + val = PKI_X509_get_value ( x ); + SSL_CTX_add_extra_chain_cert(ssl->ssl_ctx, val); + // SSL_CTX_add0_chain_cert(ssl->ssl_ctx, val); + } + } + + /* Now sets the other (not-trusted) certificates (from the ssl token, + * if any) */ + if ( ssl_tk && ssl_tk->otherCerts ) { + int i = 0; + for ( i = 0; i < PKI_STACK_X509_CERT_elements( + ssl_tk->otherCerts); i++) { + PKI_X509_CERT_VALUE *val = NULL; + PKI_X509_CERT *x = NULL; + + x = PKI_STACK_X509_CERT_get_num( + ssl_tk->otherCerts,i); + val = PKI_X509_get_value ( x ); + SSL_CTX_add_extra_chain_cert(ssl->ssl_ctx, val); + // SSL_CTX_add0_chain_cert(ssl->ssl_ctx, val); + } + } + + /* Set the Verify parameters for SSL */ + SSL_CTX_set_verify( ssl->ssl_ctx, ssl_verify_flags, __ssl_verify_cb ); + + /* If an old ref is present, let's remove it */ + if( ssl->ssl ) SSL_free ( ssl->ssl ); + + /* Generate a new SSL object */ + if((ssl->ssl = SSL_new(ssl->ssl_ctx)) == NULL ) { + PKI_log_debug("Can not create a new SSL object (%s:%d)", + __FILE__, __LINE__ ); + return PKI_ERR; + } + + if( ssl->servername ) { +#ifdef SSL_set_tlsext_host_name + if(!SSL_set_tlsext_host_name( ssl->ssl, ssl->servername )) { + PKI_log_err("ERROR::Can not set servername (%s)", + ERR_error_string(ERR_get_error(), NULL )); + return PKI_ERR; + } +#else + PKI_log_debug("Warning: TLS server name not supported by " + "installed crypto library"); +#endif + } + + return PKI_OK; +} + +int __pki_ssl_start_ssl ( PKI_SSL *ssl ) { + + int idx = -1; + int rv = -1; + + if (!ssl || !ssl->ssl ) + return PKI_ERROR(PKI_ERR_PARAM_NULL, 0); + + idx = SSL_get_ex_new_index(0, "pki_ssl index", NULL, NULL, NULL); + if((SSL_set_ex_data(ssl->ssl, idx, ssl)) == 0 ) { + return PKI_ERROR(PKI_ERR_MEMORY_ALLOC, 0); + } + + // Connect + if((rv = SSL_connect(ssl->ssl)) < 0 ) { + // Can not connect the SSL/TLS interface + return PKI_ERROR(PKI_ERR_NET_SSL_CONNECT, + ERR_error_string(ERR_get_error(), 0)); + } + + // Sets the connected bit + ssl->connected = 1; + + // Peer certificate processing + if (SSL_get_peer_certificate(ssl->ssl) != 0 && + SSL_get_verify_result(ssl->ssl) != X509_V_OK && + ssl->verify_ok != PKI_OK) { + + /* + PKI_log_err ("PEER VERIFY::SSL Verify Error [%d::%s]", + SSL_get_verify_result(ssl->ssl), + X509_verify_cert_error_string(SSL_get_verify_result(ssl->ssl))); + */ + + return PKI_ERROR(PKI_ERR_NET_SSL_VERIFY, 0); + } + + return PKI_OK; +} + +/*! \brief Sets the options for a new PKI_SSL object */ + +PKI_SSL * PKI_SSL_new (const PKI_SSL_ALGOR *algor) { + + PKI_SSL *ret = 0; + PKI_SSL_ALGOR *al2 = 0; + + SSL_library_init(); + + if ((ret = PKI_Malloc(sizeof( PKI_SSL ))) == 0) + { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, 0); + return (NULL); + } + + if (algor != 0) { + ret->algor = al2; + } else { + ret->algor = PKI_SSL_CLIENT_ALGOR_DEFAULT; + } + + if ((ret->ssl_ctx = SSL_CTX_new(ret->algor)) == 0) + { + PKI_log_debug("Can not create a new PKI_SSL object (%s)", + ERR_error_string(ERR_get_error(), NULL )); + goto err; + } + + // Enables CRL, OCSP, and PRQP (no REQUIRE) + PKI_SSL_set_verify(ret, PKI_SSL_VERIFY_NORMAL); + PKI_SSL_set_cipher(ret, PKI_SSL_CIPHERS_TLS1_2); + PKI_SSL_set_flags(ret, PKI_SSL_FLAGS_DEFAULT); + + ret->verify_ok = PKI_OK; + + return ret; +err: + + if( ret ) PKI_Free ( ret ); + return NULL; +} + +PKI_SSL *PKI_SSL_dup ( PKI_SSL *ssl ) { + + PKI_SSL *ret = NULL; + + if ( !ssl ) return NULL; + + if (( ret = PKI_SSL_new( ssl->algor )) == NULL ) { + return NULL; + } + + if ( ssl->trusted_certs ) { + int i = 0; + ret->trusted_certs = PKI_STACK_X509_CERT_new(); + for ( i = 0; i < PKI_STACK_X509_CERT_elements(ssl->trusted_certs); i++){ + PKI_STACK_X509_CERT_push ( ret->trusted_certs, + PKI_STACK_X509_CERT_get_num ( ssl->trusted_certs, i)); + } + } + + ret->verify_flags = ssl->verify_flags; + ret->verify_ok = ssl->verify_ok; + ret->flags = ssl->flags; + ret->tk = ssl->tk; + + return ret; +} + +/* --------------------------- Public Functions ------------------------ */ + +/*! \brief Sets the protocol for a new PKI_SSL object */ + +int PKI_SSL_set_algor(PKI_SSL *ssl, PKI_SSL_ALGOR *algor) { + + if( !ssl || !ssl->ssl_ctx || !algor ) + return PKI_ERROR(PKI_ERR_PARAM_NULL, 0); + + if(!SSL_CTX_set_ssl_version(ssl->ssl_ctx, algor)) + return PKI_ERROR(PKI_ERR_NET_SSL_SET_CIPHER, 0); + + return PKI_OK; +} + +/*! \brief Sets the SSL connection flags */ + +int PKI_SSL_set_flags ( PKI_SSL *ssl, PKI_SSL_FLAGS flags ) { + + if ( !ssl ) return PKI_ERROR(PKI_ERR_PARAM_NULL, 0); + + ssl->auth = (int) flags; + + return PKI_OK; +} + +/*! \brief Sets the Chiphers to be used */ + +int PKI_SSL_set_cipher ( PKI_SSL *ssl, char *cipher ) { + + // Input Checks + if ( ssl == 0 || ssl->ssl_ctx == 0 || cipher == 0) + return PKI_ERROR(PKI_ERR_PARAM_NULL, 0); + + if (ssl->cipher != 0) PKI_Free ( ssl->cipher ); + + ssl->cipher = strdup(cipher); + + if (!SSL_CTX_set_cipher_list ( ssl->ssl_ctx, cipher )) { + PKI_log_err("Can not set ciphers (%s)", + ERR_error_string(ERR_get_error(),NULL)); + return PKI_ERR; + } + + return PKI_OK; +} + +/*! \brief Sets the verify flags to be used when validating cert chain */ + +int PKI_SSL_set_verify ( PKI_SSL *ssl, PKI_SSL_VERIFY vflags ) { + + if ( !ssl ) return PKI_ERR; + + ssl->verify_flags = vflags; + + return PKI_OK; +} + +/*! \brief Checks if a verify flag has been set */ + +int PKI_SSL_check_verify(PKI_SSL *ssl, PKI_SSL_VERIFY flag) +{ + if (!ssl) { + return PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + } + + if (ssl->verify_flags & flag) return PKI_OK; + + return PKI_ERR; +} + +/*! \brief Sets the underlying socket descriptor */ + +int PKI_SSL_set_fd ( PKI_SSL *ssl, int fd ) { + + if ( !ssl || !ssl->ssl ) { + return PKI_ERROR(PKI_ERR_PARAM_NULL, 0); + } + + return SSL_set_fd ( ssl->ssl, fd ); +} + +/*! \brief Sets the SNI extension for the hostname */ + +int PKI_SSL_set_host_name ( PKI_SSL *ssl, const char * hostname ) { + + if ( !ssl ) { + return PKI_ERROR(PKI_ERR_PARAM_NULL, 0); + } + + // Free the name if one is already set + if (ssl->servername) PKI_Free (ssl->servername); + + // Sets the Servername to be used for SNI + ssl->servername = strdup(hostname); + + return 1; +} + +/*! \brief Returns the underlying socket descriptor */ + +int PKI_SSL_get_fd ( PKI_SSL *ssl ) { + + if ( !ssl || !ssl->ssl ) return -1; + + return SSL_get_fd ( ssl->ssl ); +} + +/*! \brief Initiates an SSL connection to a URL passed as a URL object */ +int PKI_SSL_connect_url(PKI_SSL *ssl, URL *url, int timeout) { + + int rv = PKI_OK; + int ssl_socket = -1; + + // Input checking + if (ssl == 0 || url == 0) { + return PKI_ERROR(PKI_ERR_PARAM_NULL, 0); + } + + if (( rv = __pki_ssl_init_ssl(ssl)) != PKI_OK) { + rv = PKI_ERROR(PKI_ERR_NET_SSL_INIT, 0); + goto err; + } + + /* Connect the socket first */ + if ((ssl_socket = PKI_NET_open(url, timeout)) < 0) { + /* Can not connect to the server */ + rv = PKI_ERROR(PKI_ERR_NET_OPEN, "[url = %s]", url->url_s); + goto err; + } + + // Starts the TLS/SSL protocol + return PKI_SSL_start_ssl(ssl, ssl_socket); + + /* + // Sets the FD for the socket + if (PKI_SSL_set_fd( ssl, ssl_socket ) != PKI_OK) { + rv PKI_ERROR(PKI_ERR_NET_SSL_SET_SOCKET, 0); + goto err; + } + + // Starts the SSL/TLS protocol + if ( __pki_ssl_start_ssl( ssl ) != PKI_OK) { + rv = PKI_ERROR(PKI_ERR_NET_SSL_START, 0); + goto err; + } + + // All Done, Ok. + return PKI_OK; + */ + +err: + if (ssl_socket > 0) close(ssl_socket); + ssl->connected = 0; + + return rv; +} + +/*! \brief Initiates an SSL connection over an already connected socket */ + +int PKI_SSL_start_ssl ( PKI_SSL *ssl, int fd ) { + + if (ssl == 0) return PKI_ERROR(PKI_ERR_PARAM_NULL, 0); + + if (fd <= 0) return PKI_ERROR(PKI_ERR_PARAM_TYPE, 0); + + if ( __pki_ssl_init_ssl ( ssl ) == PKI_ERR ) { + return PKI_ERROR(PKI_ERR_NET_SSL_INIT, 0); + } + + if (PKI_SSL_set_fd( ssl, fd ) != PKI_OK) { + return PKI_ERROR(PKI_ERR_NET_SSL_SET_SOCKET, 0); + } + + if ( __pki_ssl_start_ssl( ssl ) != PKI_OK) { + return PKI_ERROR(PKI_ERR_NET_SSL_START, 0); + } + + return PKI_OK; +} + +/*! \brief Initiates an SSL connection to a URL passed as a string */ + +int PKI_SSL_connect ( PKI_SSL *ssl, char *url_s, int timeout ) { + + URL *url = NULL; + int ret = PKI_OK; + + if ( !ssl || !url_s ) return PKI_ERR; + + if((url = URL_new ( url_s )) == NULL ) { + return PKI_ERR; + } + + if((ret = PKI_SSL_connect_url ( ssl, url, timeout )) == PKI_OK ) { + ssl->connected = 1; + } + + + URL_free ( url ); + + return ret; + +} + +/*! \brief Returns the Peer certificate used in a connected PKI_SSL */ + +struct pki_x509_st * PKI_SSL_get_peer_cert ( PKI_SSL *ssl ) { + PKI_X509_CERT_VALUE *x = NULL; + struct pki_x509_st * ret = NULL; + + if ( !ssl || !ssl->connected ) return PKI_ERR; + + if((x = SSL_get_peer_certificate ( ssl->ssl )) == NULL ) { + PKI_log_err("Can not get peer certificate (%s)", + ERR_error_string(ERR_get_error(), NULL)); + return NULL; + } + + if(( ret = PKI_X509_new_dup_value( PKI_DATATYPE_X509_CERT, + x, NULL )) == NULL ) { + PKI_log_debug("Memory Error"); + X509_free ( x ); + return NULL; + } + + return ret; + +} + +/*! \brief Returns the peer certificate chain as a new PKI_X509_CERT_STACK */ + +PKI_X509_CERT_STACK * PKI_SSL_get_peer_chain ( PKI_SSL *ssl ) { + + // PKI_X509_CERT_STACK *ret_sk = NULL; + // STACK_OF(X509) *sk = NULL; + // int i = 0; + + if ( !ssl || !ssl->connected ) return PKI_ERR; + + return ssl->peer_chain; + + /* + if(( sk = SSL_get_peer_cert_chain( ssl->ssl )) == NULL ) { + PKI_log_err("Can not retrieve peer cert chain from SSL (%s)", + ERR_error_string(ERR_get_error(),NULL)); + return NULL; + } + + if((ret_sk = PKI_STACK_X509_CERT_new()) == NULL ) { + PKI_log_err ("Memory Error"); + return NULL; + } + + for( i = 0; i < sk_X509_num( sk ); i++ ) { + PKI_X509_CERT_VALUE *x = NULL; + PKI_X509_CERT *cert = NULL; + + if((x = sk_X509_value( sk, i )) == NULL ) { + PKI_log_err ("Memory Error"); + PKI_STACK_X509_CERT_free_all ( ret_sk ); + return NULL; + } + + cert = PKI_X509_new_dup_value ( PKI_DATATYPE_X509_CERT, + x, NULL ); + PKI_STACK_X509_CERT_push ( ret_sk, cert ); + } + + return ret_sk; + */ +} + +/*! \brief Returns the extension value provided in Client Hello or NULL */ + +const char *PKI_SSL_get_servername ( PKI_SSL *ssl ) { + + if ( !ssl || !ssl->connected ) return NULL; + +#ifdef TLSEXT_NAMETYPE_host_name + return SSL_get_servername ( ssl->ssl, TLSEXT_NAMETYPE_host_name ); +#else + return NULL; +#endif +} + +/*! \brief Sets the PKI_TOKEN to be used for the SSL connection */ + +int PKI_SSL_set_token ( PKI_SSL *ssl, struct pki_token_st *tk ) { + + if( !ssl || !tk ) return PKI_ERR; + + if ( ssl->tk ) { + PKI_log_debug("WARNING: Setting a new token for PKI_SSL"); + } + + ssl->tk = tk; + + return PKI_OK; +} + +/*! \brief Sets the list of trusted certificates for SSL connections */ + +int PKI_SSL_set_trusted ( PKI_SSL *ssl, PKI_X509_CERT_STACK *sk ) { + + int i = 0; + + if ( !ssl || !sk ) { + PKI_log_err ( "Missing PKI_SSL or PKI_X509_CERT_STACK param!"); + return PKI_ERR; + } + + if ( ssl->trusted_certs ) { + PKI_log_debug("WARNING: Overriding already " + "present trusted certs in PKI_SSL"); + } else { + ssl->trusted_certs = PKI_STACK_X509_CERT_new(); + } + + for( i = 0; i < PKI_STACK_X509_CERT_elements (sk); i++ ) { + // PKI_log_debug("ADDING CERT #%d to trusted_certs", i ); + PKI_STACK_X509_CERT_push ( ssl->trusted_certs, + PKI_STACK_X509_CERT_get_num (sk,i)); + } + + return PKI_OK; +} + +/*! \brief Adds a certificate to the list of trusted ones for SSL connections */ + +int PKI_SSL_add_trusted ( PKI_SSL *ssl, PKI_X509_CERT *cert ) { + + // Input Check + if ( !ssl || !cert ) PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + + // Allocates a new list if not already present + if ((ssl->trusted_certs == NULL) && + (ssl->trusted_certs = PKI_STACK_X509_CERT_new()) == NULL) { + // Failure allocating memory + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + } + + // Adds the certificate to the list of trusted certs + PKI_STACK_X509_CERT_push ( ssl->trusted_certs, cert); + + // All Done + return PKI_OK; +} + +/*! \brief Sets the list of untrusted certificates for SSL connections */ + +int PKI_SSL_set_others ( PKI_SSL *ssl, PKI_X509_CERT_STACK *sk ) { + + int i = 0; + + if ( !ssl || !sk ) { + PKI_log_err ( "Missing PKI_SSL or PKI_X509_CERT_STACK param!"); + return PKI_ERR; + } + + if (ssl->other_certs == NULL) { + ssl->other_certs = PKI_STACK_X509_CERT_new(); + } + + for( i = 0; i < PKI_STACK_X509_CERT_elements (sk); i++ ) { + PKI_STACK_X509_CERT_push ( ssl->other_certs, + PKI_STACK_X509_CERT_get_num (sk,i)); + } + + return PKI_OK; +} + +/*! \brief Adds a certificate to the list of not-trusted ones for SSL connections */ + +int PKI_SSL_add_other ( PKI_SSL *ssl, PKI_X509_CERT *cert ) { + + // Input Check + if ( !ssl || !cert ) PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + + // Allocates a new list if not already present + if ((ssl->other_certs == NULL) && + (ssl->other_certs = PKI_STACK_X509_CERT_new()) == NULL) { + // Failure allocating memory + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + } + + // Adds the certificate to the list of non-trusted certs + PKI_STACK_X509_CERT_push(ssl->other_certs, cert); + + // All Done + return PKI_OK; +} + + +/*! \brief Closes an SSL connection */ + +int PKI_SSL_close ( PKI_SSL *ssl ) { + + if ( !ssl || !ssl->ssl ) return ( PKI_ERR ); + + if ( ssl->connected ) { + + // Close the SSL session + if (SSL_shutdown(ssl->ssl) == 0) { + SSL_shutdown(ssl->ssl); + } + + ssl->connected = 0; + } + + // Clear the SSL + SSL_clear(ssl->ssl); + + // Free the SSL structure + SSL_free ( ssl->ssl ); + ssl->ssl = NULL; // Safety + + // All Done + return PKI_OK; +} + +/*! \brief Frees memory associated with a PKI_SSL */ + +void PKI_SSL_free ( PKI_SSL *ssl ) { + + PKI_X509_CERT * cert = NULL; + + if (!ssl) return; + + if (ssl->ssl_ctx) { + SSL_CTX_set_ex_data ( ssl->ssl_ctx, 0, NULL ); + SSL_CTX_free(ssl->ssl_ctx); + ssl->ssl_ctx = NULL; + } + + if (ssl->ssl) { + SSL_set_ex_data ( ssl->ssl, 0, NULL ); + SSL_free ( ssl->ssl ); + } + + if (ssl->trusted_certs) { + while( (cert = PKI_STACK_X509_CERT_pop (ssl->trusted_certs)) + != NULL ) { + PKI_X509_CERT_free ( cert ); + } + + PKI_STACK_X509_CERT_free ( ssl->trusted_certs ); + } + + if (ssl->other_certs) { + while ((cert = PKI_STACK_X509_CERT_pop (ssl->other_certs)) + != NULL ) { + PKI_X509_CERT_free ( cert ); + } + PKI_STACK_X509_CERT_free ( ssl->other_certs ); + } + + if( ssl->peer_chain ) { + while((cert = PKI_STACK_X509_CERT_pop (ssl->peer_chain )) + != NULL ) { + PKI_X509_CERT_free ( cert ); + } + PKI_STACK_X509_CERT_free ( ssl->peer_chain ); + } + + + if (ssl->cipher) PKI_Free(ssl->cipher); + + if (ssl->servername) PKI_Free(ssl->servername); + + PKI_Free ( ssl ); + + return; +} + +/*! \brief Writes data to a connected PKI_SSL */ + +ssize_t PKI_SSL_write(const PKI_SSL * ssl, + const char * buf, + ssize_t size ) { + + ssize_t ret = 0; + + if (!ssl || !ssl->ssl || !ssl->connected || !buf || size <= 0) + { + if (!ssl || !ssl->ssl) PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + + if (!ssl->connected) PKI_log_debug("PKI_SSL not connected!"); + if (!buf) PKI_log_debug("PKI_SSL::Write::Empty Data"); + if (size <= 0) PKI_log_debug("PKI_SSL::Write::Size <=0 (%s)", size ); + + return -1; + } + + if((ret = SSL_write(ssl->ssl, buf, (int) size )) < 0) + { + PKI_log_err("SSL write error (%s)", + ERR_error_string(ERR_get_error(),NULL)); + } + + return ret; +} + +/*! \brief Reads data from a connected PKI_SSL */ + +ssize_t PKI_SSL_read(const PKI_SSL * ssl, + const char * buf, + ssize_t size) { + ssize_t ret = 0; + + if( !ssl || !ssl->ssl || !ssl->connected || !buf || size <= 0) + { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return -1; + } + + if ((ret = SSL_read((SSL *)ssl->ssl, (char *)buf, (int) size )) < 0) + { + PKI_log_err("SSL read error (%s)", + ERR_error_string(ERR_get_error(),NULL)); + } + + return ret; +} + diff --git a/src/utils/net/url.c b/src/utils/net/url.c new file mode 100644 index 00000000..d3ece05b --- /dev/null +++ b/src/utils/net/url.c @@ -0,0 +1,1570 @@ +/* + * OpenCA Project + * by Massimiliano Pala (madwolf@openca.org) + * OpenCA project 1999-2008 + * + * Copyright (c) 1999-2008 The OpenCA Project. All rights reserved. + * + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#define BUFF_MAX_SIZE 2048 + +/*! \brief Returns a PKI_MEM_STACK object filled from a file descriptor + * + * This function returns a PKI_MEM_STACK object (actually filled with only + * one object in the stack), with the data retrieved from the URL specified + * as input. This function will accept only URL with URI_PROTOCOL_FD as + * its protocol. + */ + +typedef struct uri_protocol { + int num; + char *string; +} URI_PROTOCOL; + +URI_PROTOCOL proto_list[] = { + { URI_PROTO_FILE, "file" }, + { URI_PROTO_LDAP, "ldap" }, + { URI_PROTO_HTTP, "http" }, + { URI_PROTO_HTTPS, "https" }, + { URI_PROTO_FTP, "ftp" }, + { URI_PROTO_ID, "id" }, + { URI_PROTO_FD, "fd" }, + { URI_PROTO_MYSQL, "mysql" }, + { URI_PROTO_PG, "pg"}, + { URI_PROTO_PKCS11, "pkcs11" }, + { URI_PROTO_SOCK, "sock" }, + { URI_PROTO_SOCK, "dns" }, + { 0, NULL } +}; + +/* This is required because of strange behavior of htons() and (int) + * conversion - when treating warning as errors, it would block the + * compilation */ +#pragma GCC diagnostic ignored "-Wconversion" +char * URL_get_local_addr ( void ) { + struct sockaddr_in addr; + struct sockaddr_in sa; + socklen_t sa_len; + + char * ret = NULL; + + int s = socket(AF_INET, SOCK_DGRAM, 0); + + + memset(&addr, 0, sizeof(struct sockaddr_in)); + addr.sin_family = AF_INET; + inet_aton("128.0.0.1", &addr.sin_addr); + + addr.sin_port = htons(80); + + if((connect(s, (struct sockaddr *) &addr, sizeof(addr))) != 0 ) { + return(NULL); + } + + sa_len = sizeof(sa); + if((getsockname( s, (struct sockaddr *) &sa, &sa_len)) != 0 ) { + return ( NULL ); + } + + ret = strdup( inet_ntoa(sa.sin_addr) ); + + return ( ret ); +} +#pragma GCC diagnostic warning "-Wconversion" + +const char *URL_proto_to_string ( URI_PROTO proto ) { + + URI_PROTOCOL *pnt = NULL; + + pnt = &proto_list[0]; + while ( pnt != NULL ) { + if( pnt->num == proto ) { + break; + } + pnt++; + } + + if (pnt == NULL ) { + return ( NULL ); + } + + return ( (const char * ) pnt->string ); +} + +PKI_MEM_STACK *URL_get_data_fd(const URL *url, ssize_t size ) { + + PKI_MEM_STACK * ret = NULL; + PKI_MEM * obj = NULL; + + ssize_t file_size = 0; + // ssize_t max_size = 0; + + unsigned char * buff = NULL; + ssize_t buff_size = 0; + + int fd = 1; + + if (!url || url->port < 0) + { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return ( NULL ); + } + + fd = url->port; + + // if( size == 0 ) max_size = LONG_MAX - 1; + + if((ret = PKI_STACK_MEM_new()) == NULL) + { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return( NULL ); + } + + if ((obj = PKI_MEM_new_null()) == NULL) + { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + PKI_STACK_MEM_free(ret); + return NULL; + } + + if ((buff = PKI_Malloc(BUFF_MAX_SIZE)) == NULL) + { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + PKI_STACK_MEM_free(ret); + PKI_MEM_free (obj); + return NULL; + } + + do { + buff_size = _Read(fd, buff, BUFF_MAX_SIZE); + + if (buff_size > 0 ) + { + if ((size > 0) && (file_size + buff_size > size)) + { + buff_size = size - file_size; + PKI_MEM_add( obj, buff, (size_t) buff_size ); + break; + } + else + { + PKI_MEM_add( obj, buff, (size_t) buff_size ); + file_size += buff_size; + } + } + } while ( buff_size > 0 ); + + PKI_STACK_MEM_push( ret, obj ); + + /* Now we free the buff */ + if( buff ) PKI_Free ( buff ); + + return( ret ); +} + +/*! \brief Returns a PKI_MEM_STACK object filled from a file + * + * This function returns a PKI_MEM_STACK object (actually filled with only + * one object in the stack), with the data retrieved from the URL specified + * as input. This function will accept only URL with URI_PROTOCOL_FILE as + * its protocol. + */ +extern int errno; +PKI_MEM_STACK *URL_get_data_file(const URL *url, ssize_t size ) { + + PKI_MEM_STACK * ret = NULL; + PKI_MEM * obj = NULL; + off_t file_size = 0; + int fd = 0; + + if( !url ) return (NULL); + if( url->proto != URI_PROTO_FILE ) return (NULL); + + if((fd = open( url->addr, O_RDONLY)) == -1 ) { + PKI_log_err_simple("Cannot Open Resource (%s): %s", + url->addr, strerror(errno)); + return (NULL); + } + + if( size == 0 ) size = LONG_MAX - 1; + + if((ret = PKI_STACK_MEM_new()) == NULL ) { + return( NULL ); + } + if((obj = PKI_MEM_new_null()) == NULL ) { + PKI_STACK_MEM_free(ret); + return ( NULL ); + } + + lseek( fd, 0, SEEK_END); + file_size = lseek( fd, 0, SEEK_CUR); + + if( file_size > size ) file_size = size; + + lseek( fd, 0, SEEK_SET); + + PKI_MEM_grow( obj, (size_t) file_size ); + if((read( fd, obj->data, (size_t) file_size)) == -1 ) { + /* Error ?!?!? */ + PKI_MEM_free( obj ); + PKI_STACK_MEM_free ( ret ); + ret = NULL; + } else { + obj->size = (size_t) file_size; + } + close( fd ); + + PKI_STACK_MEM_push( ret, obj ); + + return( ret ); +} + +/*! + * \brief Returns a PKI_MEM_STACK filled with the data from the URL string + * + * Returns a PKI_MEM_STACK object filled with the data retrieved from + * the URL that is passed as input. This is the most general function + * provided by LibPKI that allows to retrieve an object from many different + * sources. + * + * In case of failure NULL is returned. + */ + +PKI_MEM_STACK *URL_get_data(const char * url_s, + int timeout, + ssize_t size, + PKI_SSL * ssl ) { + + URL *url = NULL; + PKI_MEM_STACK *ret = NULL; + + if (!url_s) return NULL; + if ((url = URL_new(url_s)) == NULL) return NULL; + + ret = URL_get_data_url(url, timeout, size, ssl); + + if (url) URL_free(url); + + return ret; +} + +/*! + * \brief Returns a PKI_MEM_STACK filled with data from the passed URL object + * + * Returns a PKI_MEM_STACK object filled with the data retrieved from + * the URL that is passed as input. This function is very similar to the + * URL_get_data (). Use this function when you already have the URL object + * of your target data. + * + * In case of failure NULL is returned. + * + * Currently supported protocols are: URI_PROTO_FD, URI_PROTO_FILE, + * URI_PROTO_HTTP, URI_PROTO_LDAP, URI_PROTO_MYSQL, URI_PROTO_PG, + * URI_PROTO_PKCS11, URI_PROTO_ID. + */ + +PKI_MEM_STACK *URL_get_data_url(const URL * url, + int timeout, + ssize_t size, + PKI_SSL * ssl ) { + + PKI_MEM_STACK * ret = NULL; + + if( !url ) { + PKI_ERROR(PKI_ERR_PARAM_NULL, "Missing URL parameter"); + return NULL; + } + + switch( url->proto ) { + case URI_PROTO_FD: + ret = URL_get_data_fd( url, size ); + break; + + case URI_PROTO_FILE: + ret = URL_get_data_file( url, size ); + break; + + case URI_PROTO_HTTP: + case URI_PROTO_HTTPS: + PKI_HTTP_GET_data_url(url, timeout, (size_t) size, + &ret, ssl); + break; +#ifdef HAVE_LDAP + case URI_PROTO_LDAP: + ret = URL_get_data_ldap_url( url, timeout, size ); + break; +#endif +#ifdef HAVE_MYSQL + case URI_PROTO_MYSQL: + ret = URL_get_data_mysql_url( url, size ); + break; +#endif +#ifdef HAVE_PG + case URI_PROTO_PG: + ret = URL_get_data_pg_url( url, size ); + break; +#endif +#ifdef HAVE_LIBRESOLV + case URI_PROTO_DNS: + ret = URL_get_data_dns_url( url, size ); + break; +#endif + case URI_PROTO_PKCS11: + ret = URL_get_data_pkcs11_url( url, size ); + break; + + case URI_PROTO_ID: + case URI_PROTO_FTP: + default: + PKI_ERROR(PKI_ERR_URI_UNSUPPORTED, NULL); + break; + } + + // Report the Error, if any. + if (!ret) PKI_DEBUG("Cannot retrieve data from (%s)", url->url_s); + + return ( ret ); +} + +/*! + * \brief Returns a PKI_MEM_STACK filled with data from a PKI_SOCKET + * + * Returns a PKI_MEM_STACK object filled with the data retrieved from + * a connected PKI_SOCKET. This function is very similar to the + * URL_get_data (). Use this function when you already have the URL object + * of your target data. + * + * In case of failure NULL is returned. + * + * Currently supported protocols are: URI_PROTO_FD, URI_PROTO_FILE, + * URI_PROTO_HTTP, URI_PROTO_LDAP, URI_PROTO_MYSQL, URI_PROTO_PG, + * URI_PROTO_PKCS11, URI_PROTO_ID. + */ + +PKI_MEM_STACK * URL_get_data_socket(const PKI_SOCKET * sock, + int timeout, + ssize_t size) { + + PKI_MEM_STACK * ret = NULL; + + if (size < 0) size = 0; + + if( !sock || !sock->url ) return NULL; + + switch( sock->url->proto ) { + case URI_PROTO_FD: + // ret = URL_get_data_fd( url, size ); + break; + case URI_PROTO_FILE: + // ret = URL_get_data_file( url, size ); + break; + case URI_PROTO_HTTP: + case URI_PROTO_HTTPS: + PKI_HTTP_GET_data_socket( sock, timeout, (size_t) size, + &ret ); + break; +#ifdef HAVE_LDAP + case URI_PROTO_LDAP: + // ret = URL_get_data_ldap_url( url, timeout, size ); + break; +#endif +#ifdef HAVE_MYSQL + case URI_PROTO_MYSQL: + // ret = URL_get_data_mysql_url( url, size ); + break; +#endif +#ifdef HAVE_PG + case URI_PROTO_PG: + // ret = URL_get_data_pg_url( url, size ); + break; +#endif + case URI_PROTO_PKCS11: + // ret = URL_get_data_pkcs11_url( url, size ); + break; + case URI_PROTO_ID: + case URI_PROTO_FTP: + case URI_PROTO_DNS: + default: + PKI_ERROR(PKI_ERR_URI_UNSUPPORTED, NULL); + ret = NULL; + break; + } + + return ( ret ); +} + +/*! \brief Sends/Writes a PKI_MEM object into a URL passed as a string + * + * This function sends (or writes) the content of a PKI_MEM object into + * a specific URL that is passed as a string. For a list of valid URL + * protocols, please refer to the URL_new() function. + * + * In case of failure PKI_ERR is returned, otherwise PKI_OK is. + * + * Currently supported protocols are: URI_PROTO_FD, URI_PROTO_FILE, + * URI_PROTO_MYSQL, URI_PROTO_PG. + */ + +int URL_put_data(const char * url_s, + const PKI_MEM * data, + const char * contType, + PKI_MEM_STACK ** ret_sk, + int timeout, + ssize_t max_size, + PKI_SSL * ssl ) { + + URL *url = NULL; + int ret = 0; + + if (!url_s || !data) + return PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + + if ((url = URL_new(url_s)) == NULL) + return PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + + ret = URL_put_data_url(url, data, contType, ret_sk, + timeout, max_size, ssl ); + + if (url) URL_free(url); + + return ret; +} + +int URL_put_data_raw(const char * url_s, + const unsigned char * data, + const size_t size, + const char * contType, + PKI_MEM_STACK ** ret_sk, + int timeout, + ssize_t max_size, + PKI_SSL * ssl ) { + + int ret = 0; + PKI_MEM * mem_data = NULL; + + if (!url_s || !data || !size) + return PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + + if ((mem_data = PKI_MEM_new_null()) == NULL) + return PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + + mem_data->data = (unsigned char *)data; + mem_data->size = size; + + ret = URL_put_data(url_s, + mem_data, + contType, + ret_sk, + timeout, + max_size, + ssl); + + mem_data->data = NULL; + mem_data->size = 0; + + PKI_MEM_free(mem_data); + + return ret; + +} + +int URL_put_data_fd (const URL * url, + const PKI_MEM * data ) { + + int fd = 0; + + if( !url || !data || url->port < 1 ) return ( PKI_ERR ); + + fd = url->port; + + if(_Write( fd, data->data, data->size ) < 0 ) { + PKI_ERROR(PKI_ERR_GENERAL, strerror(errno)); + return ( PKI_ERR ); + } + + return ( PKI_OK ); +} + +int URL_put_data_file(const URL * url, + const PKI_MEM * data) { + + int fd = 0; + + if( !url || !data || !url->addr ) return ( PKI_ERR ); + + if(( fd = open( url->addr, O_RDWR|O_CREAT|O_TRUNC, + S_IRUSR|S_IWUSR )) == -1 ) { + return ( PKI_ERR ); + } + + if(_Write( fd, data->data, data->size ) < 0 ) { + close (fd); + return ( PKI_ERR ); + } + + close ( fd ); + + return ( PKI_OK ); + +} + +int URL_put_data_url(const URL * url, + const PKI_MEM * data, + const char * contType, + PKI_MEM_STACK ** ret_sk, + int timeout, + ssize_t max_size, + PKI_SSL * ssl) { + + int ret = PKI_OK; + + if (max_size < 0) max_size = 0; + + if( !url || !data ) { + return ( PKI_ERR ); + } + + switch( url->proto ) { + case URI_PROTO_FD: + ret = URL_put_data_fd( url, data ); + break; + case URI_PROTO_FILE: + ret = URL_put_data_file( url, data ); + break; + case URI_PROTO_HTTP: + case URI_PROTO_HTTPS: + ret = PKI_HTTP_POST_data_url (url, (char *) data->data, + (size_t) data->size, contType, timeout, + (size_t) max_size, ret_sk, ssl ); + break; + // case URI_PROTO_LDAP: + // ret = URL_put_data_ldap_url( url ); + // break; +#ifdef HAVE_MYSQL + case URI_PROTO_MYSQL: + ret = URL_put_data_mysql_url( url, data ); + break; +#endif +#ifdef HAVE_PG + case URI_PROTO_PG: + ret = URL_put_data_pg_url( url, data ); + break; +#endif + // case URI_PROTO_PKCS11: + // ret = URL_put_data_pkcs11_url( url, size ); + // break; + case URI_PROTO_FTP: + case URI_PROTO_DNS: + default: + return PKI_ERROR(PKI_ERR_URI_UNSUPPORTED, NULL); + break; + } + + return ( ret ); +} + + +int URL_put_data_socket(const PKI_SOCKET * sock, + const PKI_MEM * data, + const char * contType, + PKI_MEM_STACK ** ret_sk, + int timeout, + ssize_t max_size) { + + int ret = PKI_OK; + + if (max_size < 0) max_size = 0; + + if( !sock || !sock->url ) { + return ( PKI_ERR ); + } + + switch( sock->url->proto ) { + case URI_PROTO_FD: + // ret = URL_put_data_fd( url, data ); + break; + case URI_PROTO_FILE: + // ret = URL_put_data_file( url, data ); + break; + case URI_PROTO_HTTP: + case URI_PROTO_HTTPS: + ret = PKI_HTTP_POST_data_socket(sock, + (char *) data->data, data->size, + contType, timeout, (size_t) max_size, ret_sk); + break; + // case URI_PROTO_LDAP: + // ret = URL_put_data_ldap_url( url ); + // break; +#ifdef HAVE_MYSQL + case URI_PROTO_MYSQL: + // ret = URL_put_data_mysql_url( url, data ); + break; +#endif +#ifdef HAVE_PG + case URI_PROTO_PG: + // ret = URL_put_data_pg_url( url, data ); + break; +#endif + // case URI_PROTO_PKCS11: + // ret = URL_put_data_pkcs11_url( url, size ); + // break; + case URI_PROTO_FTP: + case URI_PROTO_DNS: + default: + ret = PKI_ERR; + break; + } + + return ( ret ); +} + +/*! + * \brief Returns the text representation of a URL + */ + +const char *URL_get_parsed(const URL *url) +{ + if (!url || !url->url_s) return NULL; + + return url->url_s; +} + + +/* !\brief Returns a URL data structure from the input string + * + * This function parses the string passed as input and generates a new URL + * object. In case of an error in parsing the URL a NULL pointer is returned. + * + * Currently supported protocols are: fd:// (URI_PROTO_FD), + * file:// (URI_PROTO_FILE), http:// (URI_PROTO_HTTP), ldap:// (URI_PROTO_LDAP), + * mysql:// (URI_PROTO_MYSQL), pg:// (URI_PROTO_PG), mysql:// (URI_PROTO_MYSQL), + * pkcs11:// (URI_PROTO_PKCS11), dns://(URI_PROTO_DNS), socket://(URI_PROTO_SOCKET) + */ + +URL *URL_new(const char * url_s ) { + + URL *ret = NULL; + char *tmp_s = NULL; + char *tmp_s2 = NULL; + char *tmp_s3 = NULL; + char *tmp_s4 = NULL; + + size_t len = 0; + + ret = (URL *) PKI_Malloc ( sizeof( URL )); + if(ret == 0) + { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + goto err; + } + memset( ret, 0, sizeof(URL) ); + + // If no URL is passed, we assume stdin was meant + if (url_s == NULL) { + + // If no URL is passed, let's use stdin as the source + if ((ret->url_s = strdup("stdin")) == NULL) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return NULL; + } + + } else { + + size_t len = strlen(url_s); + // Size of the URL string + + // Allocates the memory for copying the URL + if ((ret->url_s = (char *) PKI_Malloc(len + 1)) == NULL) + goto err; + + // Copy the name in the URL itself + memcpy(ret->url_s, url_s, len); + + } + + if (strncmp_nocase(ret->url_s, "stdin", 5) == 0) + { + ret->proto = URI_PROTO_FD; + ret->addr = strdup("stdin"); + ret->port = fileno(stdin); + ret->object_num = 0; + } + else if (strncmp_nocase(ret->url_s, "stdout", 6) == 0) + { + ret->proto = URI_PROTO_FD; + ret->addr = strdup("stdout"); + ret->port = fileno(stdout); + ret->object_num = 0; + } + else if (strncmp_nocase(ret->url_s, "stderr", 6) == 0) + { + ret->proto = URI_PROTO_FD; + ret->addr = strdup("stderr"); + ret->port = fileno(stderr); + ret->object_num = 0; + } + else if( strncmp("ldap://", ret->url_s, 6 ) == 0) + { + ret->proto = URI_PROTO_LDAP; + ret->port = DEFAULT_LDAP_PORT; + + tmp_s = &ret->url_s[7]; + + if((tmp_s3 = strchr(tmp_s, '@')) != NULL ) { + tmp_s4 = strchr(tmp_s, '/'); + if( tmp_s4 && tmp_s3 < tmp_s4 ) { + tmp_s2 = strchr( tmp_s, ':' ); + + if ( !tmp_s2 || (tmp_s3 < tmp_s2)) + { + PKI_ERROR(PKI_ERR_URI_PARSE, NULL); + // return NULL; + goto err; + } + len = (size_t) ( tmp_s2 - tmp_s ); + ret->usr = (char *) malloc (len+1); + memset( ret->usr, 0, len+1); + strncpy( ret->usr, tmp_s, len); + ret->usr[len] = '\x0'; + + tmp_s = tmp_s2+1; + tmp_s2 = strchr( tmp_s,'@'); + + len = (size_t) ( tmp_s2 - tmp_s ); + ret->pwd = (char *) malloc (len+1); + memset( ret->pwd, 0, len+1); + strncpy( ret->pwd, tmp_s, len); + ret->pwd[len] = '\x0'; + + tmp_s = tmp_s2+1; + } + } + + // IPv6 Hex Address Parsing + if( (*tmp_s == '[') && + ((tmp_s2 = strchr( tmp_s, ']' )) != NULL )) { + + len = (size_t) ( tmp_s2 - tmp_s ); + ret->addr = ( char *) malloc ( len ); + memset ( ret->addr, 0, len ); + + strncpy( ret->addr, tmp_s + 1, len-1 ); + ret->addr[len-1] = '\x0'; + + tmp_s = tmp_s2 + 1; + if ( *tmp_s == ':' ) { + ret->port = atoi ( tmp_s + 1 ); + } + + if( (tmp_s2 = strchr( tmp_s, '/' )) != NULL ) { + tmp_s = tmp_s2; + } else { + tmp_s = &ret->url_s[7]; + } + } else if( strchr( tmp_s, ':' )) { + tmp_s2 = strchr(tmp_s,':'); + + len = (size_t) ( tmp_s2 - tmp_s ); + ret->addr = (char *) malloc (len+1); + memset( ret->addr, 0, len+1 ); + + memcpy( ret->addr, tmp_s, len); + ret->addr[len] = '\x0'; + + tmp_s = tmp_s2+1; + ret->port = atoi( tmp_s ); + if( ret->port == 0 ) { + /* Error in parsing the port number! */ + // URL_free ( ret ); + PKI_ERROR(PKI_ERR_URI_PARSE, NULL); + // return(NULL); + goto err; + } + + if( (tmp_s2 = strchr( tmp_s, '/' )) != NULL ) { + tmp_s = tmp_s2; + } else { + tmp_s = &ret->url_s[7]; + } + } + + if( (tmp_s2 = strchr( tmp_s, '/' )) != NULL ) { + char *tmp_attrs = NULL; + tmp_s2++; + + if((tmp_attrs = strchr( tmp_s, '?' )) != NULL) { + len = strlen( tmp_attrs ); + ret->attrs = (char *) malloc ( len ); + memset( ret->attrs, 0, len ); + memcpy( ret->attrs, tmp_attrs + 1, len); + len = (size_t) ( tmp_attrs - tmp_s2 ); + + ret->path = (char *) malloc ( len +1); + memset( ret->path, 0, len +1); + memcpy( ret->path, tmp_s2, len); + + if( !ret->addr ) { + len = (size_t) (tmp_s2 - tmp_s - 1); + ret->addr = (char *) malloc (len+1); + memset( ret->addr, 0, len+1); + memcpy( ret->addr, tmp_s, len); + ret->addr[len] = '\x0'; + } + } else { + if( !ret->addr ) { + len = (size_t) ( tmp_s2 - tmp_s ); + ret->addr = (char *) malloc (len+1); + memset( ret->addr, 0, len+1); + memcpy( ret->addr, tmp_s, len); + ret->addr[len] = '\x0'; + } + + tmp_s = tmp_s2; + ret->path = strdup( tmp_s ); + } + } else { + if( !ret->addr ) + ret->addr = strdup( tmp_s ); + ret->path = strdup("/"); + } + + } + else if (strncmp("mysql://", ret->url_s, 8) == 0) + { + ret->proto = URI_PROTO_MYSQL; + ret->port = DEFAULT_MYSQL_PORT; + + tmp_s = &ret->url_s[8]; + + if((tmp_s3 = strchr(tmp_s, '@')) != NULL ) { + tmp_s4 = strchr(tmp_s, '/'); + if( tmp_s4 && tmp_s3 < tmp_s4 ) { + tmp_s2 = strchr( tmp_s, ':' ); + + if( !tmp_s2 || (tmp_s3 < tmp_s2)) { + PKI_ERROR(PKI_ERR_URI_PARSE, NULL); + // return (NULL); + goto err; + } + len = (size_t) ( tmp_s2 - tmp_s ); + ret->usr = (char *) malloc (len+1); + memset( ret->usr, 0, len+1); + memcpy( ret->usr, tmp_s, len); + ret->usr[len] = '\x0'; + + tmp_s = tmp_s2+1; + tmp_s2 = strchr( tmp_s,'@'); + + len = (size_t) ( tmp_s2 - tmp_s ); + ret->pwd = (char *) malloc (len+1); + memset( ret->pwd, 0, len+1); + memcpy( ret->pwd, tmp_s, len); + ret->pwd[len] = '\x0'; + + tmp_s = tmp_s2+1; + } + } + + // IPv6 Hex Address Parsing + if( (*tmp_s == '[') && + ((tmp_s2 = strchr( tmp_s, ']' )) != NULL )) { + + len = (size_t) ( tmp_s2 - tmp_s ); + ret->addr = ( char *) malloc ( len ); + memset ( ret->addr, 0, len ); + + memcpy( ret->addr, tmp_s + 1, len-1 ); + ret->addr[len-1] = '\x0'; + + tmp_s = tmp_s2 + 1; + if ( *tmp_s == ':' ) { + ret->port = atoi ( tmp_s + 1 ); + } + + if( (tmp_s2 = strchr( tmp_s, '/' )) != NULL ) { + tmp_s = tmp_s2; + } else { + tmp_s = &ret->url_s[7]; + } + } else if( strchr( tmp_s, ':' )) { + tmp_s2 = strchr(tmp_s,':'); + + len = (size_t) ( tmp_s2 - tmp_s ); + ret->addr = (char *) malloc (len+1); + memset( ret->addr, 0, len+1 ); + + memcpy( ret->addr, tmp_s, len); + ret->addr[len] = '\x0'; + + tmp_s = tmp_s2+1; + ret->port = atoi( tmp_s ); + if( ret->port == 0 ) { + /* Error in parsing the port number! */ + // URL_free ( ret ); + PKI_ERROR(PKI_ERR_URI_PARSE, NULL); + // return(NULL); + goto err; + } + + if( (tmp_s2 = strchr( tmp_s, '/' )) != NULL ) { + tmp_s = tmp_s2; + } else { + tmp_s = &ret->url_s[7]; + } + } + + if( (tmp_s2 = strchr( tmp_s, '/' )) != NULL ) { + char *tmp_attrs = NULL; + tmp_s2++; + + if((tmp_attrs = strchr( tmp_s, '?' )) != NULL) { + len = strlen( tmp_attrs ); + ret->attrs = (char *) malloc ( len ); + memset( ret->attrs, 0, len ); + memcpy( ret->attrs, tmp_attrs + 1, len); + + len = (size_t) (tmp_attrs - tmp_s2); + ret->path = (char *) PKI_Malloc(len+1); + memcpy(ret->path, tmp_s2, len); + ret->path[len] = 0; // Safety + + if( !ret->addr ) + { + len = (size_t) (tmp_s2 - tmp_s - 1); + ret->addr = (char *) PKI_Malloc (len+1); + memcpy(ret->addr, tmp_s, len); + ret->addr[len] = '\x0'; + } + } + else + { + if(!ret->addr) + { + len = (size_t) (tmp_s2 - tmp_s - 1); + ret->addr = (char *) PKI_Malloc (len+1); + memcpy(ret->addr, tmp_s, len); + ret->addr[len] = '\x0'; + } + + tmp_s = tmp_s2; + ret->path = strdup( tmp_s ); + } + } + else if( !ret->addr ) + { + ret->addr = strdup( tmp_s ); + ret->path = strdup("/"); + } + } + else if( strncmp("pg://", ret->url_s, 5 ) == 0) + { + ret->proto = URI_PROTO_PG; + ret->port = DEFAULT_PG_PORT; + + tmp_s = &ret->url_s[5]; + + if((tmp_s3 = strchr(tmp_s, '@')) != NULL ) { + tmp_s4 = strchr(tmp_s, '/'); + if( tmp_s4 && tmp_s3 < tmp_s4 ) { + tmp_s2 = strchr( tmp_s, ':' ); + + if( !tmp_s2 || (tmp_s3 < tmp_s2)) { + PKI_ERROR(PKI_ERR_URI_PARSE, NULL); + // return (NULL); + goto err; + } + len = (size_t) ( tmp_s2 - tmp_s ); + ret->usr = (char *) malloc (len+1); + memset( ret->usr, 0, len+1); + memcpy( ret->usr, tmp_s, len); + ret->usr[len] = '\x0'; + + tmp_s = tmp_s2+1; + tmp_s2 = strchr( tmp_s,'@'); + + len = (size_t) ( tmp_s2 - tmp_s ); + ret->pwd = (char *) malloc (len+1); + memset( ret->pwd, 0, len+1); + memcpy( ret->pwd, tmp_s, len); + ret->pwd[len] = '\x0'; + + tmp_s = tmp_s2+1; + } + } + + // IPv6 Hex Address Parsing + if( (*tmp_s == '[') && + ((tmp_s2 = strchr( tmp_s, ']' )) != NULL )) { + + len = (size_t) ( tmp_s2 - tmp_s ); + ret->addr = ( char *) malloc ( len ); + memset ( ret->addr, 0, len ); + + memcpy( ret->addr, tmp_s + 1, len-1 ); + ret->addr[len-1] = '\x0'; + + tmp_s = tmp_s2 + 1; + if ( *tmp_s == ':' ) { + ret->port = atoi ( tmp_s + 1 ); + } + + if( (tmp_s2 = strchr( tmp_s, '/' )) != NULL ) { + tmp_s = tmp_s2; + } else { + tmp_s = &ret->url_s[7]; + } + } else if( strchr( tmp_s, ':' )) { + tmp_s2 = strchr(tmp_s,':'); + + len = (size_t) ( tmp_s2 - tmp_s ); + ret->addr = (char *) malloc (len+1); + memset( ret->addr, 0, len+1 ); + + memcpy( ret->addr, tmp_s, len); + ret->addr[len] = '\x0'; + + tmp_s = tmp_s2+1; + ret->port = atoi( tmp_s ); + if( ret->port == 0 ) { + /* Error in parsing the port number! */ + // URL_free ( ret ); + PKI_ERROR(PKI_ERR_URI_PARSE, NULL); + // return(NULL); + goto err; + } + + if( (tmp_s2 = strchr( tmp_s, '/' )) != NULL ) { + tmp_s = tmp_s2; + } else { + tmp_s = &ret->url_s[7]; + } + } + + if( (tmp_s2 = strchr( tmp_s, '/' )) != NULL ) { + char *tmp_attrs = NULL; + tmp_s2++; + + if((tmp_attrs = strchr( tmp_s, '?' )) != NULL) { + len = strlen( tmp_attrs ); + ret->attrs = (char *) malloc ( len ); + memset( ret->attrs, 0, len ); + memcpy( ret->attrs, tmp_attrs + 1, len); + + len = (size_t) (tmp_attrs - tmp_s2); + ret->path = (char *) malloc ( len ); + memset( ret->path, 0, len); + memcpy( ret->path, tmp_s2, len - 1); + + if( !ret->addr ) { + len = (size_t) (tmp_s2 - tmp_s - 1); + ret->addr = (char *) malloc (len+1); + memset( ret->addr, 0, len+1); + memcpy( ret->addr, tmp_s, len); + ret->addr[len] = '\x0'; + } + } else { + if( !ret->addr ) { + len = (size_t) (tmp_s2 - tmp_s); + ret->addr = (char *) malloc (len+1); + memset( ret->addr, 0, len+1); + memcpy( ret->addr, tmp_s, len); + ret->addr[len] = '\x0'; + } + + tmp_s = tmp_s2; + ret->path = strdup( tmp_s ); + } + } else { + if( !ret->addr ) + ret->addr = strdup( tmp_s ); + ret->path = strdup("/"); + } + } + else if (strncmp( "file://", ret->url_s, 6 ) == 0) + { + char *tmp_s = NULL; + char *tmp_s2 = NULL; + + ret->port = -1; + ret->proto = URI_PROTO_FILE; + + tmp_s = &ret->url_s[7]; + len = strlen(tmp_s); + + if( len > 0 ) { + if((tmp_s2 = strstr(tmp_s, "#" )) != NULL ) { + *tmp_s2 = 0x0; + tmp_s2++; + if( tmp_s2 ) { + ret->object_num = atoi( tmp_s2 ); + } + len = strlen( tmp_s ); + } + ret->addr = (char *) malloc ( len + 1 ); + memset( ret->addr, 0, len + 1 ); + memcpy( ret->addr, tmp_s, len ); + ret->addr[len] = 0; + } else { + ret->addr = strdup(""); + } + + } + else if (strncmp( "fd://", ret->url_s, 5 ) == 0) + { + char *tmp_s = NULL; + char *tmp_s2 = NULL; + + ret->port = 0; + ret->proto = URI_PROTO_FD; + ret->object_num = 0; + + tmp_s = &ret->url_s[5]; + len = strlen( tmp_s ); + + if( len > 0 ) { + if((tmp_s2 = strstr(tmp_s, "#" )) != NULL ) { + *tmp_s2 = 0x0; + tmp_s2++; + if( tmp_s2 ) { + ret->object_num = atoi( tmp_s2 ); + } + len = strlen( tmp_s ); + } + + ret->addr = (char *) malloc ( len + 1 ); + memset( ret->addr, 0, len + 1 ); + memcpy( ret->addr, tmp_s, len ); + ret->addr[len] = 0; + ret->port = atoi( ret->addr ); + } else { + ret->addr = strdup("0"); + } + + } + else if (strncmp( "id://", ret->url_s, 5 ) == 0) + { + char *tmp_s = NULL; + char *tmp_s2 = NULL; + + ret->port = -1; + ret->proto = URI_PROTO_ID; + + tmp_s = &ret->url_s[5]; + len = strlen( tmp_s ); + + if(( tmp_s2 = strstr(tmp_s, "/" )) != NULL ) { + + if((len = (size_t)(tmp_s2 - tmp_s)) > 0 ) { + ret->addr = PKI_Malloc( len + 1); + memcpy( ret->addr, tmp_s, len ); + ret->addr[len] = 0; + } else { + ret->addr = strdup(""); + }; + + tmp_s = tmp_s2 + 1; + + if((tmp_s2 = strstr(tmp_s, "#" )) != NULL ) { + *tmp_s2 = 0x0; + tmp_s2++; + if( tmp_s2 ) { + ret->object_num = atoi( tmp_s2 ); + } + } + + if((len = strlen( tmp_s )) > 0 ) { + ret->path = PKI_Malloc( len ); + memcpy(ret->path, tmp_s, len); + ret->path[len] = 0; + } + } else { + len = strlen(tmp_s); + + if( len > 0 ) { + if((tmp_s2 = strstr(tmp_s, "#" )) != NULL ) { + *tmp_s2 = 0x0; + tmp_s2++; + if( tmp_s2 ) { + ret->object_num = atoi(tmp_s2); + } + len = strlen( tmp_s ); + } + + ret->addr = PKI_Malloc( len + 1 ); + memcpy( ret->addr, tmp_s, len ); + ret->addr[len] = 0; + } else { + ret->addr = strdup(""); + } + } + } + else if( strncmp("http://", ret->url_s, 7 ) == 0) + { + ret->proto = URI_PROTO_HTTP; + ret->port = DEFAULT_HTTP_PORT; + tmp_s = &ret->url_s[7]; + + if((tmp_s3 = strchr(tmp_s, '@')) != NULL ) { + tmp_s4 = strchr(tmp_s, '/'); + if( tmp_s4 && tmp_s3 < tmp_s4 ) { + tmp_s2 = strchr( tmp_s, ':' ); + + if( !tmp_s2 || (tmp_s3 < tmp_s2)) { + PKI_ERROR(PKI_ERR_URI_PARSE, NULL); + // return NULL; + goto err; + } + len = (size_t) ( tmp_s2 - tmp_s ); + ret->usr = (char *) malloc (len+1); + memset( ret->usr, 0, len+1); + + memcpy( ret->usr, tmp_s, len); + ret->usr[len] = '\x0'; + + tmp_s = tmp_s2+1; + tmp_s2 = strchr( tmp_s,'@'); + + len = (size_t) ( tmp_s2 - tmp_s ); + ret->pwd = (char *) malloc (len+1); + memset( ret->pwd, 0, len+1); + memcpy( ret->pwd, tmp_s, len); + ret->pwd[len] = '\x0'; + + tmp_s = tmp_s2+1; + + } + } + + // IPv6 Hex Address Parsing + if( (*tmp_s == '[') && + ((tmp_s2 = strchr( tmp_s, ']' )) != NULL )) { + + len = (size_t) ( tmp_s2 - tmp_s ); + ret->addr = ( char *) malloc ( len ); + memset ( ret->addr, 0, len ); + + memcpy( ret->addr, tmp_s + 1, len-1 ); + ret->addr[len-1] = '\x0'; + + tmp_s = tmp_s2 + 1; + if ( *tmp_s == ':' ) { + ret->port = atoi ( tmp_s + 1 ); + } + + if( (tmp_s2 = strchr( tmp_s, '/' )) != NULL ) { + tmp_s = tmp_s2; + } else { + tmp_s = &ret->url_s[7]; + } + + } else if( strchr( tmp_s, ':' )) { + tmp_s2 = strchr(tmp_s,':'); + + len = (size_t) ( tmp_s2 - tmp_s ); + ret->addr = (char *) malloc (len+1); + memset( ret->addr, 0, len+1 ); + + memcpy( ret->addr, tmp_s, len); + ret->addr[len] = '\x0'; + + tmp_s = tmp_s2+1; + ret->port = atoi( tmp_s ); + if( (tmp_s2 = strchr( tmp_s, '/' )) != NULL ) { + tmp_s = tmp_s2; + } else { + tmp_s = &ret->url_s[7]; + } + } + + if( strchr( tmp_s, '/' )) { + + tmp_s2 = strchr(tmp_s,'/'); + + if( !ret->addr ) { + len = (size_t) ( tmp_s2 - tmp_s ); + ret->addr = (char *) malloc (len+1); + memset( ret->addr, 0, len+1); + memcpy( ret->addr, tmp_s, len); + ret->addr[len] = '\x0'; + } + + tmp_s = tmp_s2; + ret->path = strdup( tmp_s ); + } else { + if( !ret->addr ) + ret->addr = strdup( tmp_s ); + ret->path = strdup("/"); + } + } + else if( strncmp("https://", ret->url_s, 8 ) == 0) + { + ret->proto = URI_PROTO_HTTPS; + ret->port = DEFAULT_HTTPS_PORT; + ret->ssl = 1; + tmp_s = &ret->url_s[8]; + + if((tmp_s3 = strchr(tmp_s, '@')) != NULL ) { + tmp_s4 = strchr(tmp_s, '/'); + if( tmp_s4 && tmp_s3 < tmp_s4 ) { + tmp_s2 = strchr( tmp_s, ':' ); + + if( !tmp_s2 || (tmp_s3 < tmp_s2)) { + PKI_ERROR(PKI_ERR_URI_PARSE, NULL); + // return NULL; + goto err; + } + len = (size_t) ( tmp_s2 - tmp_s ); + ret->usr = (char *) malloc (len+1); + memset( ret->usr, 0, len+1); + + memcpy( ret->usr, tmp_s, len); + ret->usr[len] = '\x0'; + + tmp_s = tmp_s2+1; + tmp_s2 = strchr( tmp_s,'@'); + + len = (size_t) ( tmp_s2 - tmp_s ); + ret->pwd = (char *) malloc (len+1); + memset( ret->pwd, 0, len+1); + memcpy( ret->pwd, tmp_s, len); + ret->pwd[len] = '\x0'; + + tmp_s = tmp_s2+1; + + } + } + + // IPv6 Hex Address Parsing + if( (*tmp_s == '[') && + ((tmp_s2 = strchr( tmp_s, ']' )) != NULL )) { + + len = (size_t) ( tmp_s2 - tmp_s ); + ret->addr = ( char *) malloc ( len ); + memset ( ret->addr, 0, len ); + + strncpy( ret->addr, tmp_s + 1, len-1 ); + ret->addr[len-1] = '\x0'; + + tmp_s = tmp_s2 + 1; + if ( *tmp_s == ':' ) { + ret->port = atoi ( tmp_s + 1 ); + } + + if( (tmp_s2 = strchr( tmp_s, '/' )) != NULL ) { + tmp_s = tmp_s2; + } else { + tmp_s = &ret->url_s[7]; + } + } else if( strchr( tmp_s, ':' )) { + tmp_s2 = strchr(tmp_s,':'); + + len = (size_t) ( tmp_s2 - tmp_s ); + ret->addr = (char *) malloc (len+1); + memset( ret->addr, 0, len+1 ); + + memcpy( ret->addr, tmp_s, len); + ret->addr[len] = '\x0'; + + tmp_s = tmp_s2+1; + ret->port = atoi( tmp_s ); + if( (tmp_s2 = strchr( tmp_s, '/' )) != NULL ) { + tmp_s = tmp_s2; + } else { + tmp_s = &ret->url_s[7]; + } + } + + if( strchr( tmp_s, '/' )) { + + tmp_s2 = strchr(tmp_s,'/'); + + if( !ret->addr ) { + len = (size_t) ( tmp_s2 - tmp_s ); + ret->addr = (char *) malloc (len+1); + memset( ret->addr, 0, len+1); + memcpy( ret->addr, tmp_s, len); + ret->addr[len] = '\x0'; + } + + tmp_s = tmp_s2; + ret->path = strdup( tmp_s ); + } else { + if( !ret->addr ) + ret->addr = strdup( tmp_s ); + ret->path = strdup("/"); + } + } + else if( strncmp("pkcs11://", ret->url_s, 8 ) == 0) + { + ret->proto = URI_PROTO_PKCS11; + ret->port = DEFAULT_PKCS11_PORT; + + tmp_s = &ret->url_s[9]; + + if(( tmp_s3 = strstr(tmp_s, "/(" )) != NULL ) { + + len = (size_t) (tmp_s3 - tmp_s); + ret->addr = PKI_Malloc( len + 1); + memcpy( ret->addr, tmp_s, len ); + tmp_s = tmp_s3 + 1; + + if(( tmp_s3 = strchr( tmp_s, '?' )) != NULL ) { + len = (size_t) (tmp_s3 - tmp_s); + ret->path = PKI_Malloc( len + 1); + memcpy( ret->path, tmp_s, len ); + + tmp_s = tmp_s3 + 1; + len = strlen( tmp_s ); + ret->attrs = PKI_Malloc ( len + 1); + memcpy( ret->attrs, tmp_s, len ); + } else { + len = strlen( tmp_s ); + ret->path = PKI_Malloc( len + 1 ); + memcpy( ret->path, tmp_s, len ); + ret->attrs = strdup( "data" ); + } + + } else if(( tmp_s3 = strchr( tmp_s, '?')) != NULL ) { + + len = (size_t) (tmp_s3 - tmp_s); + ret->addr = PKI_Malloc( len + 1 ); + memcpy( ret->addr, tmp_s, len ); + tmp_s = tmp_s3 + 1; + + ret->attrs = strdup( tmp_s ); + } else { + ret->addr = strdup( tmp_s ); + ret->attrs = strdup( "data" ); + ret->path = strdup( "" ); + } + + if ((ret->addr) && (ret->addr[strlen(ret->addr)-1] == '/') ) { + ret->addr[strlen(ret->addr)-1] = '\x0'; + } + + } + else if( strncmp("socket://", ret->url_s, 9 ) == 0) + { + tmp_s = &ret->url_s[9]; + + if( strchr( tmp_s, ':' )) { + + tmp_s2 = strchr(tmp_s,':'); + + len = (size_t) ( tmp_s2 - tmp_s ); + ret->addr = (char *) malloc (len+1); + memset( ret->addr, 0, len+1 ); + + memcpy( ret->addr, tmp_s, len); + ret->addr[len] = '\x0'; + + tmp_s = tmp_s2+1; + ret->port = atoi( tmp_s ); + } else { + ret->port = -1; + + ret->addr = (char *) malloc ( BUFF_MAX_SIZE ); + memset( ret->addr, 0, BUFF_MAX_SIZE ); + memcpy( ret->addr, ret->url_s, BUFF_MAX_SIZE); + ret->addr[BUFF_MAX_SIZE] = 0; + } + + ret->proto = URI_PROTO_SOCK; + } + else if( strncmp("dns://", ret->url_s, 6 ) == 0) + { + ret->proto = URI_PROTO_DNS; + ret->port = DEFAULT_DNS_PORT; + ret->path = NULL; + + tmp_s = &ret->url_s[6]; + + if (strchr(tmp_s,'?')) + { + tmp_s2 = strchr(tmp_s, '?'); + len = (size_t) (tmp_s2 - tmp_s); + ret->addr = (char *) malloc (len+1); + memset(ret->addr, 0, len+1); + + memcpy(ret->addr, tmp_s, len); + ret->addr[len] = '\x0'; + + tmp_s = tmp_s2+1; + + if ((len = strlen(tmp_s)) > 0) + { + ret->attrs = (char *) malloc (len+1); + memcpy(ret->attrs, tmp_s, len); + ret->attrs[len] = '\x0'; + } + else ret->attrs = strdup("A"); + } + else + { + ret->attrs = strdup("A"); + ret->addr = (char *) malloc (BUFF_MAX_SIZE); + memset(ret->addr, 0, BUFF_MAX_SIZE); + memcpy(ret->addr, ret->url_s, BUFF_MAX_SIZE); + ret->addr[BUFF_MAX_SIZE] = 0; + } + } + else + { + // No protocol specified, we assume file:// or sock:// + size_t len = 0; + + ret->port = -1; + ret->proto = URI_PROTO_FILE; + + if (ret->url_s) + { + len = strlen(ret->url_s); + + ret->addr = (char *) PKI_Malloc( len+1 ); + memcpy(ret->addr, ret->url_s, len); + ret->addr[len] = 0; + } + else + { + PKI_ERROR(PKI_ERR_URI_PARSE, NULL); + + // return NULL; + goto err; + } + } + + return ret; + +err: + + if (ret) URL_free(ret); + + return NULL; +} + +/*! \brief Releases the Memory associated to a URL data structure */ + +void URL_free(URL *url) { + + if (!url ) return; + + if (url->url_s) PKI_ZFree_str (url->url_s); + if (url->addr) PKI_ZFree_str (url->addr); + if (url->usr) PKI_ZFree_str (url->usr); + if (url->pwd) PKI_ZFree_str (url->pwd); + if (url->attrs) PKI_ZFree_str (url->attrs); + if (url->path) PKI_ZFree_str (url->path); + + if (url) PKI_ZFree (url, sizeof(URL)); + + return; +} diff --git a/src/utils/pki_config.c b/src/utils/pki_config.c new file mode 100644 index 00000000..fa0a7427 --- /dev/null +++ b/src/utils/pki_config.c @@ -0,0 +1,1091 @@ +/* Config management for libpki */ + +#include + +#include +#include +#include + +/* Static function, to be used only internally */ +static char * _xml_search_namespace_add ( char *search ); + +static char *def_conf_dirs[] = { + PKI_DEFAULT_CONF_DIR, + LIBPKI_PATH_SEPARATOR "etc" LIBPKI_PATH_SEPARATOR "libpki", + NULL +}; + +#define PKI_DEF_CONF_DIRS_SIZE 2 +#define LIBXML_MIN_VERSION 20600 +#define LIBXML_212_VERSION 21200 + +#if LIBXML_VERSION < LIBXML_MIN_VERSION +#define xmlErrorPtr void * +#endif + +/* +#if LIBXML_VERSION >= LIBXML_MIN_VERSION +#define logXmlMessages(a,b) PKI_DEBUG("XML I/O Error: %s", b) +#else +#define logXmlMessages(a,b) PKI_DEBUG("XML I/O Error", b) +#endif +*/ + +#if LIBXML_VERSION >= LIBXML_212_VERSION +void logXmlMessages( void *userData, const xmlError *error ) { +#else +void logXmlMessages( void *userData, xmlErrorPtr error ) { +#endif +#if LIBXML_VERSION >= LIBXML_MIN_VERSION + PKI_log_err( "XML I/O Error: %s", error->message); +#else + PKI_log_err( "XML I/O Error"); +#endif + return; +} + +static char * _xml_search_namespace_add ( char *search ) { + + char *my_search = NULL; + char *my_arg = NULL; + char *ret = NULL; + + int r = 0; + int i = 0; + + size_t my_search_len = 0; + + // int strSize = -1; + + /* Let's alloc enough memory for the arguments, maybe this is + too much, but for the moment, let's keep it big */ + my_arg = PKI_Malloc ( BUFF_MAX_SIZE ); + my_search = PKI_Malloc ( BUFF_MAX_SIZE ); + + if (!my_arg || !my_search) { + if (my_arg) PKI_Free(my_arg); + if (my_search) PKI_Free(my_search); + return NULL; + } + + /* Now let's take care about setting the appropriate namespace + if it is not passed, already */ + i = 0; + while( search[i] == LIBPKI_PATH_SEPARATOR_CHAR ) { + i++; + strncat(my_search, LIBPKI_PATH_SEPARATOR, BUFF_MAX_SIZE ); + } + + while ((i < strlen( search )) && + (sscanf( search + i, "%[^" LIBPKI_PATH_SEPARATOR "]%n", my_arg, &r ) > 0 )) { + + i = i + r; + + my_search_len = strlen(my_search); + if (strchr( my_arg, ':' ) == NULL) { + strncat(my_search, PKI_NAMESPACE_PREFIX ":", BUFF_MAX_SIZE - my_search_len); + my_search_len = strlen(my_search); + } + + strncat(my_search, my_arg, BUFF_MAX_SIZE - my_search_len); + + while (search[i] == LIBPKI_PATH_SEPARATOR_CHAR) { + i++; + my_search_len = strlen(my_search); + strncat(my_search, LIBPKI_PATH_SEPARATOR, BUFF_MAX_SIZE - my_search_len); + } + } + PKI_Free(my_arg); + + // Duplicates only the good parts + ret = strdup(my_search); + + PKI_Free(my_search); + return(ret); +} + +/*! \brief Loads a PKI_CONFIG object (XML config file) */ + +PKI_CONFIG * PKI_CONFIG_load(const char *urlPath) +{ + FILE *file = NULL; + PKI_CONFIG *doc = NULL; + URL *url = NULL; + xmlParserCtxt *parserCtxt = NULL; + + LIBXML_TEST_VERSION + + if (urlPath) url = URL_new( urlPath ); + else return ( NULL ); + + // Let's check the URL was parsed correctly + if( !url || !url->addr ) return(PKI_ERR); + + if ((file = fopen(url->addr, "r")) == NULL) + { + URL_free(url); + return PKI_ERR; + } + fclose(file); + + if ((parserCtxt = xmlNewParserCtxt()) == NULL ) + { + URL_free( url ); + return(PKI_ERR); + } + +#if LIBXML_VERSION > LIBXML_MIN_VERSION + xmlSetStructuredErrorFunc( parserCtxt, logXmlMessages ); +#endif + + /* Do not Keep Blank Nodes */ + xmlKeepBlanksDefault(0); + + /*parse the file and get the DOM */ +#if LIBXML_VERSION > LIBXML_MIN_VERSION + doc = (PKI_CONFIG *) xmlCtxtReadFile(parserCtxt, url->addr, NULL, + XML_PARSE_RECOVER | XML_PARSE_NOERROR | XML_PARSE_NOWARNING | + XML_PARSE_NOENT ); +#else + doc = (PKI_CONFIG *) xmlCtxtReadFile(parserCtxt, url->addr, NULL, 0); +#endif + + // xmlClearParserCtxt ( parserCtxt ); + xmlFreeParserCtxt ( parserCtxt ); + URL_free(url); + + return( doc ); +} + +void PKI_CONFIG_free_void ( void * doc ) +{ + PKI_CONFIG *my_doc = NULL; + + my_doc = (PKI_CONFIG *) doc; + PKI_CONFIG_free( my_doc); + + return; +} + +/*! \brief Frees the memory associated with a PKI_CONFIG object */ + +int PKI_CONFIG_free ( PKI_CONFIG * doc ) { + if( !doc ) return (PKI_OK); + + xmlFreeDoc( doc ); + + /* + *Free the global variables that may + *have been allocated by the parser. + */ + //xmlCleanupParser(); + + return( PKI_OK ); +} + +/*! \brief Gets the root element of a PKI_CONFIG document */ + +PKI_CONFIG_ELEMENT * PKI_CONFIG_get_root ( PKI_CONFIG *doc ) { + + if ( !doc ) return ( NULL ); + + return ( xmlDocGetRootElement( doc )); +} + +/*! \brief Loads an OID file and creates internal OIDs */ + +PKI_CONFIG * PKI_CONFIG_OID_load(const char *oidFile ) { + + PKI_OID *oid = NULL; + PKI_CONFIG *doc = NULL; + PKI_CONFIG_ELEMENT *curr = NULL; + PKI_CONFIG_ELEMENT_STACK *sk = NULL; + + int size = 0; + int i = 0; + + if ( !oidFile ) return NULL; + + if((doc = PKI_CONFIG_load ( oidFile)) == NULL ) { + PKI_log_err ("Can not open OID file %s", oidFile ); + return (NULL); + }; + + if (( sk = PKI_CONFIG_get_element_stack ( doc, + (char *) "/objectIdentifiers/oid" )) == NULL ) { + // PKI_DEBUG("[WARNING] no OID found in %s", oidFile ); + return NULL; + } + size = PKI_STACK_CONFIG_ELEMENT_elements ( sk ); + + for( i = 0; i < size; i++ ) { + curr = PKI_STACK_CONFIG_ELEMENT_get_num ( sk, i ); + + if( curr && curr->type == XML_ELEMENT_NODE ) { + xmlChar *name = NULL; + xmlChar *descr = NULL; + xmlChar *val = NULL; + + name = xmlGetProp( curr, (xmlChar *) "name" ); + descr = xmlGetProp( curr, (xmlChar *) "description" ); + val = xmlNodeListGetString(doc, curr->xmlChildrenNode, 1); + + PKI_DEBUG("[OID load] Creating OID (%s, %s, %s)", + name, descr, val ); + + oid = PKI_OID_new ( (char *) val, (char *) name, + (char *) descr); + + if( descr ) xmlFree ( descr ); + if( name ) xmlFree ( name ); + if( val ) xmlFree ( val ); + + if( oid == NULL ) { + PKI_DEBUG("Failed Creating OID (%s, %s, %s)", + name, descr, val ); + } + } + } + + return (doc); +} + +/*! \brief Searches for a specific OID inside a PKI_CONFIG object */ + +PKI_OID * PKI_CONFIG_OID_search(const PKI_CONFIG *doc, const char *searchName ) { + + PKI_OID *oid = NULL; + PKI_CONFIG_ELEMENT *curr = NULL; + PKI_CONFIG_ELEMENT_STACK *sk = NULL; + + xmlChar oidSearchBuff[BUFF_MAX_SIZE]; + + int size = 0; + int i = 0; + + if( !doc || !searchName ) return (NULL); + + if((oid = PKI_OID_get( searchName )) != NULL ) { + return ( oid ); + } + + snprintf( (char *) oidSearchBuff, BUFF_MAX_SIZE, + "/objectIdentifiers/oid[@name=\"%s\"]", searchName ); + + if ((sk = PKI_CONFIG_get_element_stack(doc, + (const char *)oidSearchBuff )) == NULL ) { + return NULL; + } + + size = PKI_STACK_CONFIG_ELEMENT_elements ( sk ); + + for( i = 0; i < size; i++ ) { + curr = PKI_STACK_CONFIG_ELEMENT_get_num ( sk, i ); + + if( curr && curr->type == XML_ELEMENT_NODE ) { + xmlChar *name = NULL; + xmlChar *descr = NULL; + xmlChar *val = NULL; + + name = xmlGetProp( curr, (xmlChar *) "name" ); + descr = xmlGetProp( curr, (xmlChar *) "description" ); + val = xmlNodeListGetString((PKI_CONFIG *)doc, + curr->xmlChildrenNode, 1); + + oid = PKI_OID_new ( (char *) val, (char *) name, + (char *) descr); + + if( descr ) xmlFree ( descr ); + if( name ) xmlFree ( name ); + if( val ) xmlFree ( val ); + + if( oid != NULL ) { + PKI_DEBUG("Failed Creating OID (%s, %s, %s)", + name, descr, val ); + continue; + } + } + } + + return (oid); +} + +/*! \brief Returns a stack of values for the selected search path */ + +PKI_STACK * PKI_CONFIG_get_stack_value(const PKI_CONFIG *doc, const char *search ) { + + PKI_CONFIG_ELEMENT_STACK *sk = NULL; + PKI_STACK *ret = NULL; + PKI_CONFIG_ELEMENT *curr = NULL; + + int size = -1; + char *val = NULL; + + if ((sk = PKI_CONFIG_get_element_stack((PKI_CONFIG *)doc, search)) == NULL ) { + return NULL; + } + + if((size = PKI_STACK_CONFIG_ELEMENT_elements ( sk )) <= 0 ) { + return NULL; + } + + ret = PKI_STACK_new( NULL ); + + while ((curr = PKI_STACK_CONFIG_ELEMENT_pop ( sk )) != NULL ) { + if( curr && curr->type == XML_ELEMENT_NODE ) { + if((val = PKI_CONFIG_get_element_value ( curr )) != NULL ) { + PKI_STACK_push ( ret, strdup (val) ); + } + } + } + + PKI_STACK_free_all ( sk ); + + return ret; +} + + +/*! \brief Returns the first value found via the provided search path */ + +char * PKI_CONFIG_get_value(const PKI_CONFIG *doc, const char *search ) { + + PKI_CONFIG_ELEMENT *curr = NULL; + + if (( curr = PKI_CONFIG_get_element ( doc, search, -1 )) == NULL ) { + return NULL; + } + + return PKI_CONFIG_get_element_value ( curr ); +} + +/*! \brief Returns the value of the named attribute in the searched item */ + +char * PKI_CONFIG_get_attribute_value(const PKI_CONFIG *doc, + const char *search, + const char *attr_name ) { + + PKI_CONFIG_ELEMENT *el = NULL; + char * ret = NULL; + + if( !doc || !search || !attr_name ) { + return ( NULL ); + } + + if((el = PKI_CONFIG_get_element ( doc, search, -1 )) == NULL ) { + return ( NULL ); + }; + + ret = (char * ) xmlGetProp( el, BAD_CAST attr_name ); + + return ( ret ); +} + +/*! \brief Returns the number of items identified by the search path */ + +int PKI_CONFIG_get_elements_num(const PKI_CONFIG *doc, const char *search ) { + + PKI_STACK *sk = NULL; + int ret = -1; + PKI_CONFIG_ELEMENT *pnt = NULL; + + if((sk = PKI_CONFIG_get_element_stack((PKI_CONFIG *)doc, search )) == NULL ) { + return -1; + } + + ret = PKI_STACK_elements ( sk ); + + while((pnt = PKI_STACK_pop ( sk)) != NULL ) { + // Nothing, we do not want to free the node's memory! + } + + PKI_STACK_free ( sk ); + + return ret; +} + +/*! \brief Returns the n-th PKI_CONFIG_ELEMENT identified by the search path */ + +PKI_CONFIG_ELEMENT * PKI_CONFIG_get_element(const PKI_CONFIG * doc, + const char * search, + int num ) { + + PKI_CONFIG_ELEMENT_STACK *sk = NULL; + // Stack of Elements from the Search + + PKI_CONFIG_ELEMENT *ret = NULL; + // Return Value + + PKI_CONFIG_ELEMENT *tmp_el = NULL; + // Temporary reference used to free + // the nodes from the returned stack + + // Some input checks + if (!doc || !search) return NULL; + + // Checks if the search returns any element(s) + if ((sk = PKI_CONFIG_get_element_stack((PKI_CONFIG *)doc, search)) == NULL) { + PKI_DEBUG("Element Not Found [Search: %s, Position: %d]", search, num); + return NULL; + } + + // Use the magic 'negative' values as setting for the last + // element in the stack + if ( num < 0 ) num = PKI_STACK_CONFIG_ELEMENT_elements ( sk ) - 1; + + // Gets the right element + if ((ret = PKI_STACK_CONFIG_ELEMENT_get_num(sk, num)) == NULL) { + PKI_DEBUG("Can not get element number %d from the search [Search: %s]", + num, search); + } + + // Free all remaining parts of the stack + while ((tmp_el = PKI_STACK_CONFIG_ELEMENT_pop(sk)) != NULL) { + // Nothing to do - the elements are xmlNode and + // the memory would be freed with xmlFreeNode function, + // however, it is our understanding that the passed + // nodes are just references and do not need to be + // freed by the calling function + // + // Not Needed: xmlFreeNode(tmp_el); + } + + // Free all the remaining memory + PKI_STACK_CONFIG_ELEMENT_free_all(sk); + + // All Done. + return ret; +} + +/*! \brief Returns the stack of elements identified by the search path */ + +PKI_CONFIG_ELEMENT_STACK * PKI_CONFIG_get_element_stack(const PKI_CONFIG * doc, + const char * search ) { + + xmlXPathContext *xpathCtx = NULL; + xmlXPathObject *xpathObj = NULL; + xmlNodeSet *nodes = NULL; + + PKI_CONFIG_ELEMENT_STACK *ret = NULL; + + int size = 0; + int i = 0; + + char *my_search = NULL; + + if( !doc || !search ) return (NULL); + + xpathCtx = xmlXPathNewContext((PKI_CONFIG *)doc); + if(xpathCtx == NULL) { + PKI_log_err("Unable to create new XPath context [Search: %s]", + search); + return NULL; + } + + xmlXPathRegisterNs(xpathCtx, (xmlChar *) PKI_NAMESPACE_PREFIX, + (xmlChar *) PKI_NAMESPACE_HREF); + + my_search = _xml_search_namespace_add((char *)search); + + xpathObj = xmlXPathEvalExpression( (xmlChar *) my_search, xpathCtx); + if( xpathObj == NULL ) { + xmlXPathFreeContext(xpathCtx); + PKI_Free ( my_search ); + return(NULL); + } + + nodes = xpathObj->nodesetval; + if( nodes ) { + size = nodes->nodeNr; + } else { + size = -1; + } + + if( size > 0 ) { + ret = PKI_STACK_CONFIG_ELEMENT_new(); + + /* recursively copy the node */ + for( i = size-1; i >= 0; i-- ) { + if( nodes->nodeTab[i]->type != XML_ELEMENT_NODE ) + continue; + // curr = xmlCopyNode( nodes->nodeTab[i], 1); + PKI_STACK_CONFIG_ELEMENT_push( ret, nodes->nodeTab[i] ); + } + } + + xmlXPathFreeObject(xpathObj); + xmlXPathFreeContext(xpathCtx); + + PKI_Free ( my_search ); + + return (ret); +} + +/*! \brief Returns the value of a PKI_CONFIG_ELEMENT */ + +char * PKI_CONFIG_get_element_value (PKI_CONFIG_ELEMENT *e) +{ + char *val = NULL; + char *ret = NULL; + + if (!e) + { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return NULL; + } + + val = (char *)xmlNodeGetContent ( e ); + + if (val) + { + if(strchr(val, '$')) ret = get_env_string( val ); + else ret = strdup(val); + + xmlFree(val); + } + + return ret; +} + +/*! \brief Returns the name of a PKI_CONFIG_ELEMENT */ + +char * PKI_CONFIG_get_element_name (PKI_CONFIG_ELEMENT *e) +{ + if (!e) + { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return (NULL); + } + + return( (char *) e->name ); +} + +/*! \brief Returns the child of a PKI_CONFIG_ELEMENT */ + +PKI_CONFIG_ELEMENT * PKI_CONFIG_get_element_child (PKI_CONFIG_ELEMENT *e) +{ + PKI_CONFIG_ELEMENT *ret = NULL; + + if(!e) + { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return (NULL); + } + + if(!e->children) return NULL; + else ret = e->children; + + while (ret && ret->type != XML_ELEMENT_NODE) + { + ret = ret->next; + } + + return( ret ); +} + +/*! \brief Returns the next PKI_CONFIG_ELEMENT */ + +PKI_CONFIG_ELEMENT * PKI_CONFIG_get_element_next ( PKI_CONFIG_ELEMENT *e) +{ + PKI_CONFIG_ELEMENT *ret = NULL; + + if (!e) + { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return NULL; + } + + if (!e->next) return (NULL); + + ret = e->next; + while (ret && ret->type != XML_ELEMENT_NODE) + { + ret = ret->next; + } + + return( ret ); +} + +/*! \brief Returns the previous PKI_CONFIG_ELEMENT */ + +PKI_CONFIG_ELEMENT * PKI_CONFIG_get_element_prev ( PKI_CONFIG_ELEMENT *e) +{ + PKI_CONFIG_ELEMENT *ret = NULL; + + if(!e) + { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return (NULL); + } + + if (!e->prev) return NULL; + + ret = e->prev; + while (ret && ret->type != XML_ELEMENT_NODE) + { + ret = ret->prev; + } + + return (PKI_CONFIG_ELEMENT *) e->prev; +} + +/*! \brief Returns the stack of a PKI_CONFIG_ELEMENT's children */ + +PKI_CONFIG_ELEMENT_STACK * PKI_CONFIG_get_element_children(PKI_CONFIG_ELEMENT *e) +{ + PKI_CONFIG_ELEMENT_STACK *ret = NULL; + PKI_CONFIG_ELEMENT *curr = NULL; + + if (!e) + { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return (NULL); + } + + if ((curr = e->children) == NULL) return NULL; + + if ((ret = PKI_STACK_CONFIG_ELEMENT_new()) == NULL) return NULL; + + while (curr) + { + if( curr->type != XML_ELEMENT_NODE ) continue; + + PKI_STACK_CONFIG_ELEMENT_push( ret, curr ); + curr = curr->next; + } + + return( ret ); +} + +/*! + * \brief Returns a pointer to the filename of the configuration file that + contains the configuration named 'name'. + */ + +char * PKI_CONFIG_find(const char *dir, const char *name ) +{ + struct dirent *dd = NULL; + DIR *dirp = NULL; + URL *url = NULL; + + int found = 0; + char *ret = NULL; + + /* Check input */ + if( !dir || !name ) + { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return (PKI_ERR); + } + + if ((url = URL_new(dir)) == NULL) + { + PKI_DEBUG("Dir [%s] is not a valid URI", dir ); + return (PKI_ERR); + } + + if (url->proto != URI_PROTO_FILE) + { + PKI_DEBUG("URL is not a file, skipping!", dir ); + return (PKI_ERR); + } + + if ((dirp = opendir(url->addr)) == NULL) + { + PKI_DEBUG("Can not open directory [%s]", url->addr ); + return (PKI_ERR); + } + else + { + while(( dd = readdir( dirp )) != NULL ) + { + long len; + char *filename = NULL; + + filename = dd->d_name; + len = (long) strlen( filename ); + + PKI_DEBUG("Processing file [%s]", filename ); + + if (len < 4 || strcmp(".xml", filename +len-4) != 0) + { + PKI_DEBUG("Skipping %s", filename ); + continue; + } + else + { + char fullpath[BUFF_MAX_SIZE]; + size_t fullsize = 0; + + PKI_CONFIG *tmp_cfg = NULL; + char *tmp_name = NULL; + + snprintf(fullpath, BUFF_MAX_SIZE, + "%s/%s", url->addr, filename ); + + PKI_DEBUG("Opening File %s", fullpath ); + + // Check the allowed size + fullsize = strlen(url->addr) + strlen( filename ) + 1; + if (fullsize > BUFF_MAX_SIZE) continue; + + if ((tmp_cfg = PKI_CONFIG_load(fullpath)) == NULL) + { + PKI_DEBUG("Can not load %s", fullpath ); + continue; + } + + PKI_DEBUG("Getting Name Param... "); + tmp_name = PKI_CONFIG_get_value(tmp_cfg, "/*/name"); + PKI_CONFIG_free(tmp_cfg); + + if (tmp_name != NULL) + { + PKI_DEBUG("Got Name::%s", tmp_name); + if (strcmp_nocase(tmp_name, name) == 0) + { + PKI_Free(tmp_name); + tmp_name = NULL; // Safety + + found = 1; + ret = strdup(fullpath); + PKI_DEBUG("File successfully loaded %s", fullpath ); + break; + } + PKI_Free(tmp_name); + tmp_name = NULL; // Safety + } + else PKI_DEBUG("No Name found!"); + } + } + closedir( dirp ); + } + + // Let's free the URL memory + if (url) URL_free(url); + + // If found, let's return it + if (found == 1) return ret; + + // If not found, we return NULL + return NULL; +} + +/*! + * \brief Returns a pointer to the filename of the configuration file that + contains the configuration named 'name'. + */ + +char * PKI_CONFIG_find_all(const char *dir, + const char *name, + const char *subdir) { + + PKI_STACK *dir_list = NULL; + char * dir_name = NULL; + char * ret = NULL; + + int i = 0; + + // Checks the input + if (!name ) + { + PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); + return NULL; + } + + // Get the list of entries for the directory + if ((dir_list = PKI_CONFIG_get_search_paths(dir)) == NULL) return NULL; + + // Some debugging + PKI_DEBUG( "GOT SEARCH PATHS => %d", PKI_STACK_elements( dir_list )); + + // Go throught the different elements of the directory and search them + for ( i=0; i < PKI_STACK_elements( dir_list ); i++ ) + { + char buff[BUFF_MAX_SIZE]; + + dir_name = PKI_STACK_get_num(dir_list, i); + + if (subdir != NULL) snprintf(buff, sizeof(buff), "%s/%s", dir_name, subdir); + else snprintf(buff, sizeof(buff), "%s", dir_name ); + + // Debugging + PKI_DEBUG("SEARCHING FOR %s in dir %s", name, buff ); + + if ((ret = PKI_CONFIG_find(buff, name)) != NULL) + { + PKI_DEBUG("FOUND => %s [%s]", name, buff ); + break; + } + } + + // Free all the contents + if (dir_list) PKI_STACK_free_all(dir_list); + + // Let's return the results + return ret; +} + +/*! + * \brief Returns a stack of all configuration files found in the passed + * directory. + */ + +PKI_CONFIG_STACK * PKI_CONFIG_load_dir(const char *dir, + PKI_CONFIG_STACK *sk ) { + + struct dirent *dd = NULL; + DIR *dirp = NULL; + URL *url = NULL; + + int found = 0; + PKI_CONFIG_STACK *ret = NULL; + + /* Check input */ + if( !dir ) { + return (NULL); + } + + if(( url = URL_new ( dir )) == NULL ) { + PKI_DEBUG( "Dir not valid for config (%s)", dir ); + return ( NULL ); + } + + if( url->proto != URI_PROTO_FILE ) { + PKI_DEBUG( "Dir not valid for config (%s)", dir ); + return (NULL); + } + + if((dirp = opendir( url->addr )) == NULL ) { + PKI_log_err("Can not open dir %s!\n", url->addr ); + return (NULL); + } else { + + if( !sk ) { + if((ret = PKI_STACK_CONFIG_new()) == NULL ) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return NULL; + } + + } else { + ret = sk; + } + + while(( dd = readdir( dirp )) != NULL ) { + long len; + char *filename = NULL; + + filename = dd->d_name; + len = (long) strlen( filename ); + + if( (len < 4) || (strcmp( ".xml", filename +len -4 ))) { + PKI_DEBUG( "Skipping file %s", filename); + continue; + } else { + + char fullpath[BUFF_MAX_SIZE]; + size_t fullsize = 0; + + PKI_CONFIG *tmp_cfg = NULL; + + PKI_DEBUG( "Loading file %s" LIBPKI_PATH_SEPARATOR "%s", + url->addr, filename ); + + snprintf(fullpath, BUFF_MAX_SIZE, + "%s" LIBPKI_PATH_SEPARATOR "%s", url->addr, filename ); + + if ((fullsize = strlen(url->addr) + strlen(filename) + 1) > BUFF_MAX_SIZE) { + continue; + } + + if((tmp_cfg = PKI_CONFIG_load(fullpath)) == NULL) { + continue; + } + + PKI_DEBUG( "Loaded %s file", fullpath ); + PKI_STACK_CONFIG_push( ret, tmp_cfg ); + found = 1; + } + } + closedir( dirp ); + } + if( url ) URL_free (url); + + if( found == 1 ) { + return (ret); + } else { + PKI_STACK_CONFIG_free( ret ); + PKI_DEBUG("PKI_CONFIG_load_dir() Failed!\n" ); + return ( NULL ); + } +} + +/*! + * \brief Returns a stack of all configurations files found in the passed + * directory plush the default search paths + */ + +PKI_CONFIG_STACK *PKI_CONFIG_load_all(const char * dir ) { + + PKI_STACK *dir_list = NULL; + PKI_CONFIG_STACK *sk = NULL; + char *name = NULL; + + if((dir_list = PKI_CONFIG_get_search_paths ( dir )) == NULL ) { + return ( NULL ); + } + + while( (name = PKI_STACK_pop ( dir_list )) != NULL ) { + PKI_CONFIG_load_dir ( name, sk ); + PKI_Free ( name ); + } + + return ( sk ); +} + +/*! \brief Returns a PKI_STACK of directories (useful to search in default + dirs for config files */ + +PKI_STACK *PKI_CONFIG_get_search_paths(const char *dir ) { + + char *homedir = NULL; + char buff[BUFF_MAX_SIZE]; + + PKI_STACK *list = NULL; + int i = 0; + + // PKI_DEBUG("get_search_paths() start"); + + if((list = PKI_STACK_new_null()) == NULL ) { + return ( NULL ); + } + + /* If passed as an argument, dir is the first dir in the search path */ + if( dir ) { + PKI_STACK_push( list, strdup(dir) ); + return list; + } + + /* Check for the HOME environment variable */ + if(( homedir = getenv("HOME")) != NULL ) { + memset(buff, '\x0', sizeof( buff )); + snprintf( buff, sizeof( buff), "%s" + LIBPKI_PATH_SEPARATOR ".libpki", homedir ); + + /* Adds the user's home directory to the search path */ + PKI_STACK_push ( list, strdup( buff ) ); + }; + + /* Adds all the 'default' libpki config directories */ + for( i = 0 ; i < PKI_DEF_CONF_DIRS_SIZE; i++ ) { + PKI_STACK_push ( list, strdup(def_conf_dirs[i]) ); + } + + // PKI_DEBUG("get_search_paths()::Entries in list %d", + // PKI_STACK_elements ( list )); + + // PKI_DEBUG("get_search_paths()::ENDING"); + return ( list ); +} + + +/*! \brief Create a new Node for a PKI_X509_PROFILE */ + +PKI_CONFIG_ELEMENT *PKI_CONFIG_ELEMENT_new(const char *name, + const char *value ) { + + PKI_CONFIG_ELEMENT *ret = NULL; + // xmlNsPtr ns = NULL; + + if( !name ) return ( NULL ); + + if((ret = xmlNewNode( NULL, BAD_CAST name )) == NULL ) { + return ( NULL ); + } + + // ns = xmlNewNs ( ret, PKI_NAMESPACE_PREFIX, NULL ); + + if( value ) { + xmlAddChild( ret, xmlNewText ( BAD_CAST value )); + } + + return ( ret ); + +} + +/*! \brief Adds an attribute to an existing profile element */ +int PKI_CONFIG_ELEMENT_add_attribute(PKI_CONFIG * doc, + PKI_CONFIG_ELEMENT * node, + const char * name, + const char * value ) { + + if( (node == NULL) || ( name == NULL )) { + return ( PKI_ERR ); + } + + // snprintf(buf, sizeof(buf), "%s", PKI_NAMESPACE_PREFIX, name ); + xmlNewProp( node, BAD_CAST name, BAD_CAST value ); + + // if( doc ) _pki_update_config ( &doc ); + + return ( PKI_OK ); +} + +PKI_CONFIG_ELEMENT *PKI_CONFIG_add_node ( PKI_CONFIG *doc, + char *parent, char *name, char *value ) { + + + PKI_CONFIG_ELEMENT *p_node = NULL; + + if((p_node = PKI_CONFIG_get_element( doc, parent, -1 )) == NULL ) { + PKI_log_err("Can not find Parent node (%s) [Adding: %s]", + parent, name); + return NULL; + } + + return PKI_CONFIG_ELEMENT_add_child ( doc, p_node, name, value ); +} + +/*! \brief Add a child element to an existing node */ + +PKI_CONFIG_ELEMENT *PKI_CONFIG_ELEMENT_add_child(PKI_CONFIG * doc, + PKI_CONFIG_ELEMENT * node, + const char * name, + const char * value) { + + PKI_CONFIG_ELEMENT *ret = NULL; + + // PKI_DEBUG ( "add_child():: name=%s, value=%s", name, value ); + + if(!node || !name ) return NULL; + + // snprintf(buf, sizeof(buf), "%s:%s", PKI_NAMESPACE_PREFIX, name ); + // ns = xmlNewNs ( node, NULL, PKI_NAMESPACE_PREFIX); + + // PKI_DEBUG ( "add_child():: New Name::%s", name); + + if((ret = xmlNewTextChild( node, NULL, BAD_CAST name, BAD_CAST value )) + == NULL ) { + // PKI_DEBUG("add_child()::Failed!"); + } + + + // xmlFreeNs ( ns ); + + // if(doc) _pki_update_config( &doc ); + + return ( ret ); +} + +/*! \brief Add a child element to an existing node */ + +PKI_CONFIG_ELEMENT *PKI_CONFIG_ELEMENT_add_child_el ( PKI_CONFIG * doc, + PKI_CONFIG_ELEMENT *node, PKI_CONFIG_ELEMENT *el) { + + if(!node || !el ) return ( PKI_ERR ); + + xmlAddChild( node, el ); + + // if ( doc ) _pki_update_config ( &doc ); + + return ( el ); +} diff --git a/src/utils/pki_cred.c b/src/utils/pki_cred.c new file mode 100644 index 00000000..0009815d --- /dev/null +++ b/src/utils/pki_cred.c @@ -0,0 +1,136 @@ +/* src/pki_cred.c */ + +#include + +/*! + * \brief Allocates a new PKI_CRED structure + * + * Allocates memory for a new PKI_CRED structure. The returned data + * structure contains a copy (strdup) of the passed user and pwd + * strings. + * + * The function returns a pointer to a PKI_CRED structure in case + * of success, otherwise it returns NULL. + */ + +PKI_CRED *PKI_CRED_new ( const char * const user, const char * const pwd ) { + + PKI_CRED * cred = NULL; + + if ((cred = PKI_CRED_new_null()) == NULL ) + return ( NULL ); + + memset(cred, 0, sizeof(PKI_CRED)); + + if (user) cred->username = strdup( user ); + if (pwd) cred->password = strdup( pwd ); + + return ( cred ); +} + +/*! + * \brief Allocates a new PKI_CRED structure + * + * Allocates memory for a new PKI_CRED structure. The returned data + * structure is already zeroized. + * + * The function returns a pointer to a PKI_CRED structure in case + * of success, otherwise it returns NULL. + */ + +PKI_CRED *PKI_CRED_new_null ( void ) { + + PKI_CRED *c = NULL; + + c = (PKI_CRED *) PKI_Malloc (sizeof(PKI_CRED)); + + return (c); +} + +/*! + * \brief Free a PKI_CRED memory region + * + * This function frees a PKI_CRED data structure. The internal data + * is also freed (no need to free the internal structures before + * calling this function. + * + * No value is returned (void). + */ + +void PKI_CRED_free( PKI_CRED *cred ) { + + if( !cred ) return; + + if( cred->password != NULL ) { + PKI_ZFree_str ( (char *) cred->password ); + } + + if( cred->username != NULL ) { + PKI_ZFree_str ( (char *) cred->username ); + } + + if( cred->prompt_info != NULL ) { + PKI_ZFree_str ( (char *) cred->prompt_info ); + } + + if( cred->ssl != NULL ) { + PKI_SSL_free((PKI_SSL *)cred->ssl); + } + + PKI_Free( cred ); + + return; +} + +/*! \brief Duplicates a PKI_CRED data structure */ + +PKI_CRED *PKI_CRED_dup ( const PKI_CRED * const cred ) { + + PKI_CRED *ret = NULL; + + if (!cred ) return ( NULL ); + + if (( ret = PKI_CRED_new_null()) == NULL ) return NULL; + + if( cred->password != NULL ) { + ret->password = strdup ( cred->password ); + } + + if( cred->username != NULL ) { + ret->username = strdup ( cred->username ); + } + + if( cred->prompt_info != NULL ) { + ret->prompt_info = strdup ( cred->prompt_info ); + } + + if( cred->ssl != NULL ) { + PKI_log_debug("WARNING: Cred's PKI_SSL will not duplicate!"); + } + + return ( ret ); +} + +/*! \brief Sets the SSL configuration for Creds */ + +int PKI_CRED_set_ssl(PKI_CRED *cred, struct pki_ssl_t * const ssl) { + + if (!cred || !ssl) return PKI_ERR; + + if (cred->ssl) { + PKI_log_debug( "Warning: overriding existing CRED SSL"); + } + + cred->ssl = ssl; + + return PKI_OK; +} + +/*! \brief Gets the pointer to the PKI_SSL structure inside a CRED */ + +const struct pki_ssl_t * PKI_CRED_get_ssl(const PKI_CRED * const cred) { + + if (!cred || !cred->ssl) return NULL; + + return cred->ssl; +} diff --git a/src/utils/pki_err.c b/src/utils/pki_err.c new file mode 100644 index 00000000..84049364 --- /dev/null +++ b/src/utils/pki_err.c @@ -0,0 +1,246 @@ +/* PKI ERR Management Functions */ + +#include + +#ifndef _LIBPKI_ERR_H +#include +#endif + +// Local Definition for __libpki_errors_st[] +typedef struct pki_err_st { + PKI_ERR_CODE code; + char * descr; +} PKI_ERR_ST; + +/* We define the actual object of strings only if we are compiling + * the pki_err.c file where __LIBPKI_ERR__ is defined */ + +const PKI_ERR_ST __libpki_errors_st[] = { + // General Errors + { PKI_ERR_UNKNOWN, "Unknown Error" }, + { PKI_ERR_GENERAL, "General Error" }, + { PKI_ERR_NOT_IMPLEMENTED, "Not Implemented" }, + { PKI_ERR_MEMORY_ALLOC, "Memory Allocation Error" }, + { PKI_ERR_OBJECT_CREATE, "Object Creation Error" }, + { PKI_ERR_OBJECT_TYPE_UNKNOWN, "OID Unknown" }, + { PKI_ERR_POINTER_NULL, "Null Memory Pointer" }, + { PKI_ERR_PARAM_NULL, "Null Parameter" }, + { PKI_ERR_PARAM_TYPE, "Wrong Paramenter Type" }, + { PKI_ERR_CALLBACK_NULL, "Missing or Null Callback" }, + { PKI_ERR_PKI_FORMAT_UNKNOW, "Unknow PKI Format" }, + { PKI_ERR_DATA_FORMAT_UNKNOWN, "Unknown Data Format" }, + { PKI_ERR_DATA_ASN1_ENCODING, "Error while encoding value in ASN1/DER" }, + // PKI MEM Errors + { PKI_ERR_MEM_, "" }, + // PKI DIGEST Errors + { PKI_ERR_DIGEST_TYPE_UNKNOWN, "Digest Type Unknown" }, + { PKI_ERR_DIGEST_VALUE_NULL, "Digest Value not available" }, + // PKI ALGOR Errors + { PKI_ERR_ALGOR_UNKNOWN, "Unknown Algorithm" }, + { PKI_ERR_ALGOR_SET, "Cannot set the Algorithm data" }, + { PKI_ERR_ALGOR_GET, "Cannot get the algorithm data" }, + { PKI_ERR_ALGOR_ADD, "Cannot add a new algorithm" }, + { PKI_ERR_ALGOR_PKEY_METHOD_NEW, "Error while allocating a new public key algorithm" }, + { PKI_ERR_ALGOR_PKEY_METHOD_ADD, "Error while adding a new public key algorithm" }, + { PKI_ERR_ALGOR_PKEY_METHOD_UNKNOWN, "Public key algorithm not supported" }, + { PKI_ERR_ALGOR_PKEY_ASN1_METHOD_NEW, "Error while allocating a new ASN1 method for a public key algorithm" }, + { PKI_ERR_ALGOR_PKEY_ASN1_METHOD_ADD, "Error while allocating a new ASN1 method for a public key algorithm" }, + { PKI_ERR_ALGOR_PKEY_ASN1_METHOD_UNKNOWN, "Cannot add a new ASN1 method for a public key algorithm" }, + { PKI_ERR_ALGOR_COMPOSITE_EXPLICIT_WRONG_COMPONENT, "Wrong algorithm sequence for explicit composite key" }, + // URI Related Operations + { PKI_ERR_URI_UNSUPPORTED, "Unsupported URI Schema" }, + { PKI_ERR_URI_GENERAL, "URI General Error" }, + { PKI_ERR_URI_PARSE, "URI parsing Error" }, + { PKI_ERR_URI_OPEN, "File Open Error" }, + { PKI_ERR_URI_CLOSE, "File Close Error" }, + { PKI_ERR_URI_READ, "File Read Error" }, + { PKI_ERR_URI_WRITE, "File Write Error" }, + { PKI_ERR_URI_DNS, "DNS Error" }, + { PKI_ERR_URI_SSL, "SSL Connection Error" }, + { PKI_ERR_URI_SSL_TRUST, "Untrusted SSL Connection Error" }, + /* HSM Related */ + { PKI_ERR_HSM_INIT, "Can not init HSM" }, + { PKI_ERR_HSM_LOGIN, "Can not login in HSM" }, + { PKI_ERR_HSM_SET_ALGOR, "Error while chosing algorithm in HSM" }, + { PKI_ERR_HSM_SET_SLOT, "Error while setting HSM slot to use" }, + { PKI_ERR_HSM_KEYPAIR_LOAD, "Can not load HSM key" }, + { PKI_ERR_HSM_KEYPAIR_STORE, "Can not store Key to HSM" }, + { PKI_ERR_HSM_KEYPAIR_IMPORT, "Can not import Key to HSM" }, + { PKI_ERR_HSM_KEYPAIR_EXPORT, "Can not export Key from HSM" }, + { PKI_ERR_HSM_KEYPAIR_GENERATE, "Can create new key material in HSM" }, + { PKI_ERR_HSM_SCHEME_UNSUPPORTED, "Unsupported crypto algorithm" }, + { PKI_ERR_HSM_POINTER_NULL, "Missing (null) HSM Pointer" }, + { PKI_ERR_HSM_PKCS11_LIB_POINTER_NULL, "Missing (null) PKCS#11 Library Pointer" }, + { PKI_ERR_HSM_, "" }, + /* Configuration Related */ + { PKI_ERR_CONFIG_MISSING, "Can not find Configuration file" }, + { PKI_ERR_CONFIG_LOAD, "Error while loading configuration data" }, + { PKI_ERR_CONFIG_SAVE, "Error while storing configuration data" }, + { PKI_ERR_CONFIG_, "" }, + /* Profile Related */ + { PKI_ERR_X509_PROFILE_, "" }, + /* Token Related */ + { PKI_ERR_TOKEN_INIT, "Can not initialize Token" }, + { PKI_ERR_TOKEN_LOGIN, "Error while logging into token" }, + { PKI_ERR_TOKEN_KEYPAIR_LOAD, "Can not load Token Key" }, + { PKI_ERR_TOKEN_CERT_LOAD, "Can not load Token certificate" }, + { PKI_ERR_TOKEN_CACERT_LOAD, "Can not load Token CA certificate" }, + { PKI_ERR_TOKEN_OTHERCERTS_LOAD, "Can not load Token other certificates" }, + { PKI_ERR_TOKEN_TRUSTEDCERTS_LOAD, "Can not load Token trusted certificates" }, + { PKI_ERR_TOKEN_SET_CRED, "Can not set Token credentials" }, + { PKI_ERR_TOKEN_USE_SLOT, "Error while setting Token's Slot" }, + { PKI_ERR_TOKEN_PROFILE_LOAD, "Can not load Token's Profile" }, + { PKI_ERR_TOKEN_SET_ALGOR, "Error while setting Token's Algorithm" }, + { PKI_ERR_TOKEN_GET_ALGOR, "Error while retrieving Token's Algorithm" }, + { PKI_ERR_TOKEN_, "" }, + /* Key Operations */ + { PKI_ERR_X509_KEYPAIR_SIZE, "Key Size Error" }, + { PKI_ERR_X509_KEYPAIR_SIZE_SHORT, "Key Size smaller than allowed minimum" }, + { PKI_ERR_X509_KEYPAIR_SIZE_LONG, "Key Size longer than supported maximum" }, + { PKI_ERR_X509_KEYPAIR_GENERATION, "Can not create new key material" }, + { PKI_ERR_X509_KEYPAIR_, "" }, + /* Certificate Operations */ + { PKI_ERR_X509_CERT_CREATE, "Can not create a certificate object" }, + { PKI_ERR_X509_CERT_CREATE_SUBJECT, "Can not create a suitable certificate Subject" }, + { PKI_ERR_X509_CERT_CREATE_VERSION, "Can not set certificate version" }, + { PKI_ERR_X509_CERT_CREATE_NOTBEFORE, "Can not set certificate notBefore field" }, + { PKI_ERR_X509_CERT_CREATE_NOTAFTER, "Can not set certificate notAfter field" }, + { PKI_ERR_X509_CERT_CREATE_ISSUER, "Can not set certificate Issuer field" }, + { PKI_ERR_X509_CERT_CREATE_SERIAL, "Can not set certificate Serial field" }, + { PKI_ERR_X509_CERT_CREATE_EXT, "Can not create certificate extension" }, + { PKI_ERR_X509_CERT_VERIFY_, "Cannot verify the certificate" }, + { PKI_ERR_X509_CERT_, "" }, + /* Request Operations */ + { PKI_ERR_X509_REQ_CREATE, "Can not create a request object" }, + { PKI_ERR_X509_REQ_CREATE_SUBJECT, "Can not create a suitable request Subject" }, + { PKI_ERR_X509_REQ_CREATE_VERSION, "Can not set request version" }, + { PKI_ERR_X509_REQ_CREATE_NOTBEFORE, "Can not set request notBefore field" }, + { PKI_ERR_X509_REQ_CREATE_NOTAFTER, "Can not set request notAfter field" }, + { PKI_ERR_X509_REQ_CREATE_PUBKEY, "Can not set request PublicKey field" }, + { PKI_ERR_X509_REQ_CREATE_ALGORITHM, "Can not set request Algorithm" }, + { PKI_ERR_X509_REQ_, "" }, + /* CRL Errors */ + { PKI_ERR_X509_CRL_EXTENSION, "Can not set the requested extension in CRL." }, + { PKI_ERR_X509_CRL_, "" }, + // PKI X509 PKCS7 ERRORS + { PKI_ERR_X509_PKCS7_TYPE_UNKNOWN, "Unknown PKCS#7 Type" }, + { PKI_ERR_X509_PKCS7_SIGNER_INFO_NULL, "Missing SignerInfo Structure" }, + { PKI_ERR_X509_PKCS7_CIPHER, "Cipher not supported" }, + { PKI_ERR_X509_PKCS7_, "" }, + // PKI X509 CMS ERRORS + { PKI_ERR_X509_CMS_TYPE_UNKNOWN, "Unknown CMS Type" }, + { PKI_ERR_X509_CMS_SIGNER_INFO_NULL, "Missign SignerInfo Structure" }, + { PKI_ERR_X509_CMS_CIPHER, "Cipher not supported" }, + { PKI_ERR_X509_CMS_RECIPIENT_INFO_NULL, "Missing RecipientInfo Structure"}, + { PKI_ERR_X509_CMS_DATA_INIT, "Cannot initialize data stream" }, + { PKI_ERR_X509_CMS_DATA_READ, "Cannot read from the data stream" }, + { PKI_ERR_X509_CMS_DATA_WRITE, "Cannot write to the data stream" }, + { PKI_ERR_X509_CMS_DATA_FINALIZE, "Cannot finalize the data stream" }, + { PKI_ERR_X509_CMS_WRONG_TYPE, "CMS is not of the right type" }, + { PKI_ERR_X509_CMS_SIGNER_ADD, "Cannot add the signer to the CMS." }, + { PKI_ERR_X509_CMS_SIGNER_GET, "Cannot retrieve the signer from the CMS." }, + { PKI_ERR_X509_CMS_RECIPIENT_ADD, "Cannot add the recipient to the CMS." }, + { PKI_ERR_X509_CMS_RECIPIENT_GET, "Cannot retrieve the recipient from the CMS." }, + { PKI_ERR_X509_CMS_SET_DETACHED, "Cannot set the detached status for the CMS."}, + { PKI_ERR_X509_CMS_, "" }, + // Generic PKI_X509_AUX_DATA Errors + { PKI_ERR_X509_AUX_DATA_MEMORY_FREE_CB_NULL, "Missing AUX Data free callback function" }, + { PKI_ERR_X509_AUX_DATA_MEMORY_DUP_CB_NULL, "Missing AUX Data duplicate callback function" }, + { PKI_ERR_X509_AUX_DATA_, "" }, + /* OCSP Ops */ + { PKI_ERR_OCSP_RESP_ENCODE, "Can not encode OCSP response" }, + { PKI_ERR_OCSP_RESP_DECODE, "Can not decode OCSP response" }, + { PKI_ERR_OCSP_RESP_SIGN, "Can not sign OCSP response" }, + { PKI_ERR_OCSP_REQ_ENCODE, "Can not encode OCSP request" }, + { PKI_ERR_OCSP_REQ_DECODE, "Can not decode OCSP request" }, + { PKI_ERR_OCSP_REQ_SIGN, "Can not sign OCSP request" }, + { PKI_ERR_OCSP_NONCE_COPY, "Can not copy NONCE from request" }, + { PKI_ERR_OCSP_, "" }, + /* PRQP Ops */ + { PKI_ERR_PRQP_, "" }, + /* PKI Message Operations */ + { PKI_ERR_MSG_, "" }, + /* Enrollment Protocol Related */ + { PKI_ERR_ENROLL_, "" }, + /* Signatures Related Errors */ + { PKI_ERR_SIGNATURE_CREATE, "Can not create signature" }, + { PKI_ERR_SIGNATURE_CREATE_CALLBACK, "Error while creating signature in callback" }, + { PKI_ERR_SIGNATURE_VERIFY, "Error while verifying the signature" }, + { PKI_ERR_SIGNATURE_, "" }, + /* Network Related Errors */ + { PKI_ERR_NET_OPEN, "Can not open socket connection" }, + { PKI_ERR_NET_, "" }, + /* SSL/TLS Related Errors */ + { PKI_ERR_NET_SSL_NOT_SUPPORTED , "Not supported by SSL/TLS" }, + { PKI_ERR_NET_SSL_NO_CIPHER , "No valid cipher (algorithm)" }, + { PKI_ERR_NET_SSL_VERIFY , "TLS/SSL certificate verify error" }, + { PKI_ERR_NET_SSL_SET_SOCKET , "Can not set the socket FD for SSL/TLS" }, + { PKI_ERR_NET_SSL_SET_CIPHER , "Can not set the selected ciphers list" }, + { PKI_ERR_NET_SSL_SET_FLAGS , "Can not set the selected flags for SSL/TLS" }, + { PKI_ERR_NET_SSL_INIT , "Can not init the SSL/TLS protocol" }, + { PKI_ERR_NET_SSL_START , "Can not start the SSL/TLS protocol" }, + { PKI_ERR_NET_SSL_CONNECT , "Can not connect via SSL/TLS protocol" }, + { PKI_ERR_NET_SSL_PEER_CERTIFICATE , "Can not process peer certificate" }, + { PKI_ERR_NET_SSL_ , "" }, + // SCEP Related Errors + { PKI_ERR_EST_ATTRIBUTE_UNKNOWN , "Unknown Attribute Type for EST" }, + { PKI_ERR_EST_ , "" }, + // SCEP Related Errors + { PKI_ERR_SCEP_ATTRIBUTE_UNKNOWN , "Unknown Attribute Type for SCEP" }, + { PKI_ERR_SCEP_ , "" }, + // CMP Related Errors + { PKI_ERR_CMP_ATTRIBUTE_UNKNOWN , "Unknown Attribute Type for CMP" }, + { PKI_ERR_CMP_ , "" }, + /* List Boundary */ + { 0, 0 } +}; + +static const int __libpki_err_size = sizeof ( __libpki_errors_st ) / sizeof ( PKI_ERR_ST ); + +/* Pointer to the Error Stack */ +PKI_STACK *pki_err_stack = NULL; + +/*! + * \brief Set and logs library errors + */ +#pragma GCC diagnostic ignored "-Wuninitialized" +int __pki_error ( const char *file, int line, int err, const char *info, ... ) { + + int i, found; + PKI_ERR_ST *curr = NULL; + char fmt[2048]; + + va_list ap; + + found = -1; + for ( i = 0; i < __libpki_err_size ; i++ ) + { + curr = (PKI_ERR_ST *) &__libpki_errors_st[i]; + + if ( ( curr ) && ( curr->code == err ) ) + { + found = i; + if ( !curr->descr ) break; + + if ( info == NULL ) { + snprintf(fmt, sizeof(fmt), "[%s:%d] %s (%d):", file, line, curr->descr, curr->code); + PKI_log_err_simple(fmt, NULL); + } else { + snprintf(fmt, sizeof(fmt), "[%s:%d] %s (%d): %s", file, line, curr->descr, curr->code, info ); + PKI_log_err_simple( fmt, ap); + } + + break; + } + } + + if ( found < 0 ) err = PKI_ERR_UNKNOWN; + + return ( PKI_ERR ); +} + +#ifndef LIBPKI_TARGET_OSX +# ifdef HAVE_GCC_PRAGMA_POP +# pragma GCC diagnostic pop +# endif +#endif diff --git a/src/utils/pki_init.c b/src/utils/pki_init.c new file mode 100644 index 00000000..70c12e4c --- /dev/null +++ b/src/utils/pki_init.c @@ -0,0 +1,640 @@ +/* Initialization functions */ + +#include + +#ifndef _LIBPKI_FEATURES_H +#include +#endif + +#ifndef _LIBPKI_OID_DEFS_H +#include +#endif + +#ifdef ENABLE_OQS +# include +#endif + +#ifdef ENABLE_COMPOSITE +# include +#endif + +#if OPENSSL_VERSION_NUMBER > 0x3000000fL +#include +#endif + +#ifndef _LIBPKI_ERR_H +#include +#endif + +#ifdef ENABLE_COMPOSITE + +# ifndef _LIBPKI_COMPOSITE_PKEY_METH_H +# include +# endif + +#endif // ENABLE_COMPOSITE + +#ifdef ENABLE_COMBINED + +# ifndef OPENSSL_COMBINED_PKEY_METH_H +# include +# endif + +#ifndef OPENSSL_COMBINED_ASN1_METH_H +#include +#endif + +#endif // ENABLE_COMBINED + +const long LIBPKI_OS_DETAILS = LIBPKI_OS_CLASS | + LIBPKI_OS_BITS | LIBPKI_OS_VENDOR; + +#include +#include + +// Global Vars +static int _libpki_init = 0; +static int _libpki_fips_mode = 0; + +// Composite Methods +extern EVP_PKEY_ASN1_METHOD composite_asn1_meth; +extern EVP_PKEY_METHOD composite_pkey_meth; + +#if OPENSSL_VERSION_NUMBER < 0x00908000L +int NID_proxyCertInfo = -1; +#endif + +#if OPENSSL_VERSION_NUMBER > 0x30000000L +OSSL_PROVIDER * ossl_providers[4] = { + NULL, // OSSL_PROVIDER_load(OSSL_LIB_CTX_new(), "default"), + NULL, // OSSL_PROVIDER_load(OSSL_LIB_CTX_new(), "legacy"), + NULL, // OSSL_PROVIDER_load(OSSL_LIB_CTX_new(), "oqsprovider"), + NULL +}; +#endif + +// OpenSSL Library Context +#if OPENSSL_VERSION_NUMBER > 0x30000000L +static OSSL_LIB_CTX * _ossl_lib_ctx = NULL; +#endif + + +// ================================ +// MACRO for Algorithm Registration +// ================================ + +#ifdef ENABLE_COMBINED +static int _init_combined() { + + int combined_id = -1; + + // Let's create the Initial OID for Composite Crypto + // Retrieves the COMBINED id + int combined_id = OBJ_txt2nid(OPENCA_ALG_PKEY_ALT_OID); + + // Assigns the generated IDs + EVP_PKEY_asn1_meth_set_id(&composite_asn1_meth, combined_id); + + // We Need to initialize the ASN1 conversion method + // https://www.openssl.org/docs/man1.1.1/man3/EVP_PKEY_ASN1_METHOD.html + if (!EVP_PKEY_asn1_add0(&combined_asn1_meth)) return 0; + + // We also Need to initialize the PKEY method for the algorithm + // https://www.openssl.org/docs/man1.1.1/man3/EVP_PKEY_METHOD.html + if (!EVP_PKEY_meth_add0(&combined_pkey_meth)) return 0; + + // All Done, Success. + return 1; +} +#endif + +/*! + * \brief Initialize libpki internal structures. + */ +int PKI_init_all( void ) { + + // Initialize OpenSSL so that it adds all + // the needed algor and digest + if( _libpki_init == 0 ) { + + // Enables Logging/Debugging during init + PKI_log_init (PKI_LOG_TYPE_STDERR, PKI_LOG_INFO, + NULL, + PKI_LOG_FLAGS_ENABLE_DEBUG, + NULL ); + + // OpenSSL init + X509V3_add_standard_extensions(); + OpenSSL_add_all_algorithms(); + OpenSSL_add_all_digests(); + OpenSSL_add_all_ciphers(); + + // Pthread Initialization + OpenSSL_pthread_init(); + + // Initializes the SSL layer + SSL_library_init(); + +#if OPENSSL_VERSION_NUMBER < 0x30000000 + ERR_load_ERR_strings(); + ERR_load_crypto_strings(); +#endif + + // Parser for Config files + xmlInitParser(); + + // Initializes the OID layer + PKI_X509_OID_init(); + + // PKI Discovery Services + PRQP_init_all_services(); + + // SCEP Init + PKI_X509_SCEP_init(); + +#if OPENSSL_VERSION_NUMBER >= 0x3000000fL + // Initializes the OQS Provider layer + PKI_init_providers(); +#endif + +#ifdef ENABLE_OQS + // Post-Quantum Crypto Implementation + PKI_PQC_init(); +#endif +#ifdef ENABLE_COMPOSITE + // Generic Composite Crypto (both AND and OR) + PKI_COMPOSITE_init(); + // // Explicit Composite Crypto + PKI_EXPLICIT_COMPOSITE_init(); +#endif +#ifdef ENABLE_COMBINED + // Multikey Crypto (multi-keys OR) + _init_combined(); +#endif + } + + /* Enable Proxy Certificates Support */ + PKI_set_env( "OPENSSL_ALLOW_PROXY", "1"); + + /* Set the initialization bit */ + _libpki_init = 1; + + /* Check Application and LibPKI coherence */ + if ((LIBPKI_OS_CLASS | LIBPKI_OS_BITS | LIBPKI_OS_VENDOR ) != + LIBPKI_OS_DETAILS ) { + PKI_log_err ("WARNING::LibPKI and Application OS details are " + "different [%d/%d]", LIBPKI_OS_DETAILS, + LIBPKI_OS_CLASS | LIBPKI_OS_BITS | + LIBPKI_OS_VENDOR); + } + +#ifdef HAVE_MYSQL + /* MySQL Initialization */ + /* see http://dev.mysql.com/doc/refman/5.0/en/mysql-library-init.html */ + if (mysql_library_init(0, NULL, NULL) != 0) + { + /* Let's just log the error - is this a FATAL error ? For now.. no. */ + PKI_log_err("Cound not initialize MySQL library!"); + } +#endif + + /* If FIPS mode is available, let's enforce it by default */ + /* + if (!PKI_set_fips_mode(1)) + { + int err_code = HSM_get_errno(NULL); + PKI_log_err("ERROR: %d while setting Fips Mode: %s", err_code, + HSM_get_errdesc(err_code, NULL)); + } + */ + + return ( PKI_OK ); +} + +/*! + * \brief Finalization libpki internal structures. + */ + +void PKI_final_all( void ) +{ + if ( _libpki_init != 0) + { + xmlCleanupParser(); + ERR_free_strings(); + EVP_cleanup(); + OpenSSL_pthread_cleanup(); + OBJ_cleanup(); + EVP_cleanup(); + CRYPTO_cleanup_all_ex_data(); + PKI_cleanup_providers(); +#if HAVE_MYSQL + mysql_library_end(); +#endif + } +} + + +/* + * \!brief Sets the underlying crypto library into FIPS mode. Returns 0 in case of failure. + */ +int PKI_set_fips_mode(int k) +{ + // Now let's set the fips mode in the default HSM, if we can not set it, then + // there is no chance we can operate in FIPS mode - let's report the error. + // Otherwise, let's use the _libpki_fips_mode variable to keep track of the + // intended mode for correctly initializing new HSMs + if (HSM_set_fips_mode(NULL, k) == PKI_ERR) + { + PKI_ERROR(PKI_ERR_GENERAL, "Can not set the default (software) HSM in FIPS mode!"); + + _libpki_fips_mode = 0; + return PKI_ERR; + } + + // Set the internal variable to '1' to indicate that the underlying crypto + // provided is to operate in FIPS mode only + _libpki_fips_mode = 1; + + return PKI_OK; +} + +/* + * !\brief Returns true (!0) if libpki is to enforce FIPS mode in HSMs + */ +int PKI_is_fips_mode() +{ + // Checks if the _libpki_fips_mode is set. If this is the case, check that the + // default crypto provider is also in FIPS mode, if not, let's report that we + // are not in fips mode (PKI_ERR). + // + // If the _libpki_fips_mode is set, instead, check also the default provider + // so that we get a direct reply from the crypto provider + if (_libpki_fips_mode != 0) return HSM_is_fips_mode(NULL); + + return PKI_ERR; +} + +/*! \brief Returns the status of the library (check for initialization) */ + +int PKI_get_init_status ( void ) { + + if( _libpki_init == 0 ) { + return PKI_STATUS_NOT_INIT; + } + + return PKI_STATUS_INIT; +} + +/* \brief Returns a stack of the names of all the available tokens */ + +PKI_STACK * PKI_list_all_tokens ( char *dir ) { + + char *name = NULL; + + PKI_STACK *dir_list = NULL; + PKI_STACK *list = NULL; + int i = 0; + + if((dir_list = PKI_CONFIG_get_search_paths( dir )) == NULL ) { + return ( NULL ); + } + + if((list = PKI_STACK_new_null()) == NULL ) { + return ( NULL ); + } + + for ( i=0; i proto != URI_PROTO_FILE ) { + if( url ) URL_free (url ); + return (NULL); + } + + if( !list ) { + if((ret = PKI_STACK_new_null()) == NULL ) { + if( url ) URL_free (url ); + return( NULL ); + } + } else { + ret = list; + } + + token_dir_size = strlen(url->addr) + 1 + + strlen( PKI_DEFAULT_TOKEN_DIR ) + 1; + + token_dir = PKI_Malloc ( token_dir_size ); + snprintf( token_dir, token_dir_size, "%s/%s", + url->addr, PKI_DEFAULT_TOKEN_DIR ); + + PKI_log_debug("PKI_list_all_tokens_dir()::Opening dir %s", token_dir); + + if((dirp = opendir( token_dir )) == NULL ) { + + snprintf( token_dir, token_dir_size, "%s", url->addr ); + + PKI_log_debug("PKI_list_all_tokens_dir()::Opening dir %s", token_dir); + if((dirp = opendir( token_dir)) == NULL ) { + if( url ) URL_free (url ); + if( token_dir ) PKI_Free ( token_dir ); + return ( ret ); + } + } + + while(( dd = readdir( dirp )) != NULL ) { + long len; + char *filename = NULL; + PKI_TOKEN *tk = NULL; + + filename = dd->d_name; + len = (long) strlen( filename ); + + if( (len < 4) || (strcmp( ".xml", filename +len -4 ))) { + continue; + } else { + char fullpath[BUFF_MAX_SIZE]; + size_t fullsize = 0; + + PKI_CONFIG *tmp_cfg = NULL; + char *tmp_name = NULL; + + snprintf(fullpath, BUFF_MAX_SIZE, + "%s/%s", token_dir, filename ); + + if((fullsize = strlen(token_dir) + + strlen( filename ) + 1) > + BUFF_MAX_SIZE) { + continue; + } + + if((tmp_cfg = PKI_CONFIG_load( fullpath )) == + NULL ) { + continue; + } + + if((tmp_name = PKI_CONFIG_get_value( tmp_cfg, + "/*/name")) != NULL) { + + if((tk = PKI_TOKEN_new_null()) != NULL ) { + if((PKI_TOKEN_init( tk, token_dir, tmp_name )) != PKI_ERR ) { + PKI_STACK_push( list, strdup(tmp_name)); + } + PKI_TOKEN_free( tk ); + } + } + + } + } + closedir( dirp ); + + if( url ) URL_free (url); + if( token_dir ) PKI_Free ( token_dir ); + + return ( ret ); +} + + +/* \brief Returns a stack of all the available PKI_TOKENS */ + +PKI_TOKEN_STACK *PKI_get_all_tokens ( char *dir ) { + char *name = NULL; + + PKI_STACK *dir_list = NULL; + PKI_TOKEN_STACK *list = NULL; + int i = 0; + + if((dir_list = PKI_CONFIG_get_search_paths( dir )) == NULL ) { + return ( NULL ); + } + + if ((list = PKI_STACK_TOKEN_new()) == NULL) { + return ( NULL ); + } + + for ( i=0; i proto != URI_PROTO_FILE ) { + if( url ) URL_free (url ); + return (NULL); + } + + if( !list ) { + if((ret = PKI_STACK_TOKEN_new()) == NULL ) { + if( url ) URL_free (url ); + return( NULL ); + } + } else { + ret = list; + } + + token_dir_size = strlen(url->addr) + 1 + + strlen( PKI_DEFAULT_TOKEN_DIR ) + 1; + + token_dir = PKI_Malloc ( token_dir_size ); + snprintf( token_dir, token_dir_size, "%s/%s", + url->addr, PKI_DEFAULT_TOKEN_DIR ); + + PKI_log_debug("PKI_list_all_tokens_dir()::Opening dir %s", token_dir); + + if((dirp = opendir( token_dir )) == NULL ) { + + snprintf( token_dir, token_dir_size, "%s", url->addr ); + + PKI_log_debug("PKI_list_all_tokens_dir()::Opening dir %s", token_dir); + if((dirp = opendir( token_dir)) == NULL ) { + if( url ) URL_free (url ); + if( token_dir ) PKI_Free ( token_dir ); + return ( ret ); + } + } + + while(( dd = readdir( dirp )) != NULL ) { + long len; + char *filename = NULL; + PKI_TOKEN *tk = NULL; + + filename = dd->d_name; + len = (long) strlen( filename ); + + if( (len < 4) || (strcmp( ".xml", filename +len -4 ))) { + continue; + } else { + char fullpath[BUFF_MAX_SIZE]; + size_t fullsize = 0; + + PKI_CONFIG *tmp_cfg = NULL; + char *tmp_name = NULL; + + snprintf(fullpath, BUFF_MAX_SIZE, + "%s/%s", token_dir, filename ); + + if((fullsize = strlen(token_dir) + + strlen( filename ) + 1) > + BUFF_MAX_SIZE) { + continue; + } + + if((tmp_cfg = PKI_CONFIG_load( fullpath )) == + NULL ) { + continue; + } + + if((tmp_name = PKI_CONFIG_get_value( tmp_cfg, + "/*/name")) != NULL) { + + if((tk = PKI_TOKEN_new_null()) != NULL ) { + if((PKI_TOKEN_init( tk, dir, tmp_name )) != PKI_ERR ) { + PKI_STACK_TOKEN_push( list, tk); + } else { + PKI_TOKEN_free( tk ); + } + } + } + + } + } + closedir( dirp ); + + if( url ) URL_free (url); + if( token_dir ) PKI_Free ( token_dir ); + + return ( ret ); +} + +/*! \brief Returns a stack of all the available Identities */ +PKI_ID_INFO_STACK * PKI_list_all_id ( void ) { + PKI_log_debug("%s:%d::Sorry, code still missing!",__FILE__,__LINE__); + return ( NULL ); +} + +int PKI_init_providers(void) { + +#if OPENSSL_VERSION_NUMBER > 0x3000000fL + + OSSL_PROVIDER* provider = NULL; + // Internal pointer + + OSSL_LIB_CTX * lib_ctx = PKI_init_get_ossl_library_ctx(); + // OpenSSL Library Context + + // Loads the Default Provider + if (ossl_providers[0] == NULL) { + provider = OSSL_PROVIDER_load(lib_ctx, "default"); + if (provider == NULL) { + fprintf(stderr, "Failed to load Default provider\n"); + return 0; + } + } + + // Loads the Legacy Provider + if (ossl_providers[1] == NULL) { + provider = OSSL_PROVIDER_load(lib_ctx, "legacy"); + if (provider == NULL) { + fprintf(stderr, "Failed to load Default provider\n"); + return 0; + } + } + +#ifdef ENABLE_OQSPROV + + // Loads the OQS Provider + if (ossl_providers[2] == NULL) { + provider = OSSL_PROVIDER_load(lib_ctx, "oqsprovider"); + if (provider == NULL) { + fprintf(stderr, "Failed to load Default provider\n"); + return 0; + } + } + +#endif // End of ENABLE_OQSPROV +#endif // End of OPENSSL_VERSION_NUMBER > 0x3000000fL + + // All Done + return 1; +} + +int PKI_cleanup_providers(void) { + +#if OPENSSL_VERSION_NUMBER > 0x3000000fL + + // Unloads all the providers + for (int i = 0; ossl_providers[i] != NULL; i++) { + OSSL_PROVIDER_unload(ossl_providers[i]); + } + +#endif // End of OPENSSL_VERSION_NUMBER > 0x3000000fL + + // All Done + return 1; +} + +#if OPENSSL_VERSION_NUMBER > 0x3000000fL +OSSL_LIB_CTX * PKI_init_get_ossl_library_ctx() { + if (_ossl_lib_ctx == NULL) { + _ossl_lib_ctx = OSSL_LIB_CTX_new(); + } + if (!_ossl_lib_ctx) { + PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); + return NULL; + } + return _ossl_lib_ctx; +} +#else +void * PKI_init_get_ossl_library_ctx() { + PKI_DEBUG("Function not implemented for OpenSSL < 3.0.0"); + return NULL; +} +#endif \ No newline at end of file diff --git a/src/utils/pki_log.c b/src/utils/pki_log.c new file mode 100644 index 00000000..324bfca2 --- /dev/null +++ b/src/utils/pki_log.c @@ -0,0 +1,581 @@ +/* OpenCA libpki package +* (c) 2000-2007 by Massimiliano Pala and OpenCA Group +* All Rights Reserved +* +* =================================================================== +* Released under OpenCA LICENSE +*/ + +#include +#include + +#include + +#pragma GCC diagnostic ignored "-Wunused-function" + +/* Log Configuration Mutex */ +static pthread_mutex_t log_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t log_cond; + +/* Log resource usage Mutex */ +static pthread_mutex_t log_res_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t log_res_cond; + +/* Local function prototypes */ +static int _pki_syslog_init( PKI_LOG *l ); +static int _pki_stdout_init( PKI_LOG *l ); +static int _pki_stderr_init( PKI_LOG *l ); +static int _pki_file_init( PKI_LOG *l ); + +static void _pki_syslog_add( int, const char *fmt, va_list ap ); +static void _pki_stdout_add( int, const char *fmt, va_list ap ); +static void _pki_stderr_add( int, const char *fmt, va_list ap ); +static void _pki_file_add( int, const char *fmt, va_list ap ); + +static int _pki_syslog_finalize( PKI_LOG *l ); +static int _pki_stdout_finalize( PKI_LOG *l ); +static int _pki_stderr_finalize( PKI_LOG *l ); +static int _pki_file_finalize( PKI_LOG *l ); + +static int _pki_syslog_entry_sign( PKI_LOG *l, char *entry ); +static int _pki_stdout_entry_sign( PKI_LOG *l, char *entry ); +static int _pki_file_entry_sign( PKI_LOG *l, char *entry ); + +/* Log Static Variable */ +static PKI_LOG _log_st = { + /* Keep track if the LOG subsystem has undergone initialization */ + 0, + + /* Type of PKI_LOG - PKI_LOG_TYPE */ + PKI_LOG_TYPE_SYSLOG, + + /* Identifier of the resource */ + NULL, + + /* Log Level - one of PKI_LOG_LEVEL */ + PKI_LOG_ERR, + + /* Enable Debuging Infos in the Log */ + 0, + + /* PKI_TOKEN - if present it enables Signed Logging */ + NULL, + + /* Init Callback Pointer */ + NULL, + + /* Add Callback Pointer */ + NULL, + + /* Finalize Callback Pointer */ + NULL, + + /* Sign Callback Pointer */ + NULL, +}; + +/*! + * \brief Initialize the log subsystem +*/ + +int PKI_log_init ( PKI_LOG_TYPE type, PKI_LOG_LEVEL level, char *resource, + PKI_LOG_FLAGS flags, PKI_TOKEN *tk ) { + + int ret = PKI_OK; + + /* We should acquire both the log and log_res mutex to + prevent bad programmers to mess with threads and logging */ + pthread_mutex_lock( &log_res_mutex ); + pthread_mutex_lock( &log_mutex ); + + _log_st.type = type; + _log_st.level = level; + + if( _log_st.resource != NULL ) { + PKI_Free( _log_st.resource ); + _log_st.resource = NULL; + } + + if( resource ) { + _log_st.resource = strdup( resource ); + } else { + _log_st.resource = NULL; + } + + _log_st.flags = flags; + + /* Check consistency between the token and the signature flag */ + if( tk ) { + _log_st.tk = tk; + + /* It does not make sense not enabling the signature + when passing the token! */ + if( ! (flags & PKI_LOG_FLAGS_ENABLE_SIGNATURE )) { + PKI_log_err ( "Token configured for logs but no " + "signature flag set in init!"); + ret = PKI_ERR; + goto err; + } + } else { + /* Again, no sense enabling signatures without passing + the token! */ + if( flags & PKI_LOG_FLAGS_ENABLE_SIGNATURE ) { + PKI_log_err ( "Log signing enabled but no token is " + "configured for signing logs in init!"); + ret = PKI_ERR; + goto err; + } + } + + /* Let's use different functions for different log types */ + switch ( type ) { + + case PKI_LOG_TYPE_SYSLOG: { + _log_st.init = _pki_syslog_init; + _log_st.add = _pki_syslog_add; + _log_st.finalize = _pki_syslog_finalize; + _log_st.entry_sign = _pki_syslog_entry_sign; + } break; + + case PKI_LOG_TYPE_STDOUT: { + _log_st.init = _pki_stdout_init; + _log_st.add = _pki_stdout_add; + _log_st.finalize = _pki_stdout_finalize; + _log_st.entry_sign = NULL; + } break; + + case PKI_LOG_TYPE_STDERR: { + _log_st.init = _pki_stderr_init; + _log_st.add = _pki_stderr_add; + _log_st.finalize = _pki_stderr_finalize; + _log_st.entry_sign = NULL; + } break; + + case PKI_LOG_TYPE_FILE: { + _log_st.init = _pki_file_init; + _log_st.add = _pki_file_add; + _log_st.finalize = _pki_file_finalize; + _log_st.entry_sign = NULL; + } break; + + case PKI_LOG_TYPE_FILE_XML: + default: { + ret = PKI_ERR; + goto err; + } + } + + if ( _log_st.init ) { + ret = _log_st.init( & _log_st ); + } + +err: + pthread_cond_signal ( &log_cond ); + pthread_mutex_unlock( &log_mutex ); + + pthread_cond_signal ( &log_res_cond ); + pthread_mutex_unlock( &log_res_mutex ); + + return (ret); +} + +/*! + * \brief Finalize the log subsystem + */ + +int PKI_log_end( void ) +{ + int ret = PKI_OK; + + /* We should acquire both the log and log_res mutex */ + pthread_mutex_lock( &log_res_mutex ); + + /* Let's wait for the log_mutex */ + pthread_mutex_lock( &log_mutex ); + + if ( _log_st.finalize) + ret = _log_st.finalize ( & _log_st ); + else + ret = PKI_OK; + + _log_st.level = PKI_LOG_NONE; + _log_st.flags = PKI_LOG_FLAGS_NONE; + _log_st.init = NULL; + _log_st.add = NULL; + _log_st.finalize = NULL; + _log_st.entry_sign = NULL; + + pthread_cond_signal ( &log_cond ); + pthread_mutex_unlock( &log_mutex ); + + pthread_cond_signal ( &log_res_cond ); + pthread_mutex_unlock( &log_res_mutex ); + + return ret; +} + +/*! \brief Add an entry in the log */ + +void PKI_log( int level, const char *fmt, ... ) { + + va_list ap; + + if( (_log_st.add) && ((level == PKI_LOG_ALWAYS) || + ((level > PKI_LOG_NONE) && (level <= _log_st.level))) ) { + + pthread_mutex_lock( &log_res_mutex ); + va_start (ap, fmt); + _log_st.add( level, fmt, ap ); + va_end (ap); + + pthread_mutex_unlock( &log_res_mutex ); + pthread_cond_signal ( &log_res_cond ); + } + + return; +} + +/*! \brief Add an entry in the Debug log */ + +void PKI_log_debug_simple( const char *fmt, ... ) { + + va_list ap; + unsigned int rv = 0; + + if((rv = _log_st.flags & PKI_LOG_FLAGS_ENABLE_DEBUG) == 0 ) { + return; + } + + pthread_mutex_lock( &log_res_mutex ); + + va_start (ap, fmt); + if( _log_st.add ) _log_st.add ( PKI_LOG_INFO, fmt, ap ); + va_end (ap); + + pthread_mutex_unlock( &log_res_mutex ); + pthread_cond_signal ( &log_res_cond ); + + return; +} + +/*! \brief Add an entry in the Debug log */ + +void PKI_log_err_simple( const char *fmt, ... ) { + + va_list ap; + + pthread_mutex_lock( &log_res_mutex ); + + va_start (ap, fmt); + if( _log_st.add ) _log_st.add ( PKI_LOG_ERR, fmt, ap ); + va_end (ap); + + pthread_mutex_unlock( &log_res_mutex ); + pthread_cond_signal ( &log_res_cond ); + + return; +} + +/* ===================== Init Callbacks Functions ===================== */ + +static int _pki_syslog_init( PKI_LOG *l ) { + + int ret = PKI_OK; + + openlog( l->resource, LOG_PID, LOG_USER ); + + if( !l ) return ( PKI_ERR ); + + return ( ret ); +} + +static int _pki_stdout_init( PKI_LOG *l ) { + + int ret = PKI_OK; + + if( !l ) return ( PKI_ERR ); + + /* Actually not much to do here... */ + + return ( ret ); +} + +static int _pki_stderr_init( PKI_LOG *l ) { + + int ret = PKI_OK; + + if( !l ) return ( PKI_ERR ); + + /* Actually not much to do here... */ + + return ( ret ); +} + +static int _pki_file_init( PKI_LOG *l ) { + + int ret = PKI_OK; + int fd = 0; + + if( !l ) return ( PKI_ERR ); + + if( !l->resource ) return ( PKI_ERR ); + + if(( fd = open( l->resource, O_RDWR | O_APPEND | O_CREAT, + S_IRUSR | S_IWUSR )) == -1 ) { + /* Error! */ + return( PKI_ERR ); + } + + close ( fd ); + + return ( ret ); +} + +/* ===================== LogAdd Callbacks Functions ===================== */ + +/* Internal Usage Only! */ + +static char *_get_info_string( int level ) { + + char *info = NULL; + + switch ( level ) { + case PKI_LOG_MSG: + info = "MSG"; + break; + case PKI_LOG_ERR: + info = "ERROR"; + break; + case PKI_LOG_WARNING: + info = "WARNING"; + break; + case PKI_LOG_NOTICE: + info = "NOTICE"; + break; + case PKI_LOG_INFO: + info = "INFO"; + break; + case PKI_LOG_DEBUG: + info = "DEBUG"; + break; + default: + info = "GENERAL"; + } + + return( info ); +} + +static char * _pki_get_time_s( void ) { + + struct timespec now; + // Current Time + + const size_t time_s_size = 50; + // Time String Size + + char * time_s = PKI_Malloc(time_s_size); + // Time String + + // Get the current time + if (clock_gettime(CLOCK_MONOTONIC, &now) >= 0) { + + long millisec = 0; + // Milliseconds + + millisec = now.tv_nsec / 1000; + strftime(time_s, time_s_size, "%Y-%m-%d %H:%M:%S", localtime(&now.tv_sec)); + strncat(time_s, ".", time_s_size - strlen(time_s) - 1); + snprintf(time_s + strlen(time_s), time_s_size - strlen(time_s) - 1, + "%ld", millisec); + + } else { + + PKI_TIME *now = PKI_TIME_new(0); + // Current GMT Time + + char * now_s = PKI_TIME_get_parsed(now); + // Text Representation of the now time + + // Let's make sure we have some text to write + if (now_s == NULL) now_s = strdup("