Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1235993
  • 博文数量: 389
  • 博客积分: 2874
  • 博客等级: 少校
  • 技术积分: 3577
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-24 10:34
文章分类

全部博文(389)

文章存档

2020年(2)

2018年(39)

2017年(27)

2016年(3)

2015年(55)

2014年(92)

2013年(54)

2012年(53)

2011年(64)

分类: C/C++

2018-07-04 15:40:32

重点是mkcert函数

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <openssl/ssl.h>
  3. #include <openssl/err.h>
  4. #include <openssl/pem.h>
  5. #include <openssl/conf.h>
  6. #include <openssl/x509v3.h>

  7. #include <openssl/bn.h>
  8. #include <openssl/evp.h>
  9. #include <openssl/asn1.h>
  10. #include <openssl/x509.h>
  11. #include <openssl/objects.h>
  12. #include <openssl/buffer.h>

  13. #ifndef OPENSSL_NO_ENGINE
  14. #include <openssl/engine.h>
  15. #endif

  16. void die_most_horribly_from_openssl_error (const char *func)
  17. {
  18.     /* This is the OpenSSL function that prints the contents of the
  19.      * error stack to the specified file handle. */
  20.     BIO *mem = BIO_new(BIO_s_mem());
  21.     ERR_print_errors(mem);

  22.     BUF_MEM *pp;
  23.     BIO_get_mem_ptr(mem, &pp);
  24.     printf("%s ERROR %s", func, pp->data);

  25.     BIO_free(mem);
  26.     exit (EXIT_FAILURE);
  27. }

  28. static void callback(int p, int n, void *arg)
  29. {
  30.     char c = 'B';

  31.     if (p == 0) c = '.';
  32.     if (p == 1) c = '+';
  33.     if (p == 2) c = '*';
  34.     if (p == 3) c = '\n';
  35.     fputc(c, stderr);
  36. }

  37. /*
  38.  * pkeyp: cert's public key
  39.  * sign_privkeyp: sign private key
  40.  * issuer_name: issuer name,use for cert chain,if self sign,this is null,else ca's name
  41.  * cn : cert's subject cn entry
  42.  * days:
  43.  */
  44. int mkcert(X509 **x509p, EVP_PKEY **pkeyp, EVP_PKEY **sign_privkeyp, X509_NAME *issuer_name, const char* cn,int bits, int serial, int days)
  45. {
  46.     X509 *x;
  47.     EVP_PKEY *pk;
  48.     X509_NAME *name = NULL;

  49.     if ((pkeyp == NULL) || (*pkeyp == NULL))
  50.     {
  51.         if ((pk = EVP_PKEY_new()) == NULL)
  52.         {
  53.             abort();
  54.             return(0);
  55.         }
  56.     }
  57.     else
  58.         pk = *pkeyp;

  59.     if ((x509p == NULL) || (*x509p == NULL))
  60.     {
  61.         if ((x = X509_new()) == NULL)
  62.             goto err;
  63.     }
  64.     else
  65.         x = *x509p;

  66.     X509_set_version(x, 2);
  67.     ASN1_INTEGER_set(X509_get_serialNumber(x), serial);
  68.     X509_gmtime_adj(X509_get_notBefore(x), 0);
  69.     X509_gmtime_adj(X509_get_notAfter(x), (long)60 * 60 * 24 * days);
  70.     X509_set_pubkey(x, pk);

  71.     name = X509_get_subject_name(x);
  72.     

  73.     /* This function creates and adds the entry, working out the
  74.      * correct string type and performing checks on its length.
  75.      * Normally we'd check the return value for errors...
  76.      */
  77.     X509_NAME_add_entry_by_txt(name, "C",
  78.                                MBSTRING_ASC, "UK", -1, -1, 0);
  79.     X509_NAME_add_entry_by_txt(name, "CN",
  80.                                MBSTRING_ASC, cn, -1, -1, 0);

  81.     /* Its self signed so set the issuer name to be the same as the
  82.      * subject.
  83.      */
  84.     if (!issuer_name)
  85.         X509_set_issuer_name(x, name);
  86.     else
  87.         X509_set_issuer_name(x, issuer_name);

  88.     /* Add various extensions: standard extensions */
  89.     add_ext(x, NID_basic_constraints, "critical,CA:TRUE");
  90.     add_ext(x, NID_key_usage, "critical,keyCertSign,cRLSign");

  91.     add_ext(x, NID_subject_key_identifier, "hash");

  92.     /* Some Netscape specific extensions */
  93.     add_ext(x, NID_netscape_cert_type, "sslCA");

  94.     add_ext(x, NID_netscape_comment, "example comment extension");


  95. #ifdef CUSTOM_EXT
  96.     /* Maybe even add our own extension based on existing */
  97.     {
  98.         int nid;
  99.         nid = OBJ_create("1.2.3.4", "MyAlias", "My Test Alias Extension");
  100.         X509V3_EXT_add_alias(nid, NID_netscape_comment);
  101.         add_ext(x, nid, "example comment alias");
  102.     }
  103. #endif

  104.     if (!X509_sign(x, *sign_privkeyp, EVP_sha1()))
  105.         goto err;

  106.     *x509p = x;
  107.     *pkeyp = pk;
  108.     return(1);
  109. err:
  110.     return(0);
  111. }

  112. /* Add extension using V3 code: we can set the config file as NULL
  113.  * because we wont reference any other sections.
  114.  */

  115. int add_ext(X509 *cert, int nid, char *value)
  116. {
  117.     X509_EXTENSION *ex;
  118.     X509V3_CTX ctx;
  119.     /* This sets the 'context' of the extensions. */
  120.     /* No configuration database */
  121.     X509V3_set_ctx_nodb(&ctx);
  122.     /* Issuer and subject certs: both the target since it is self signed,
  123.      * no request and no CRL
  124.      */
  125.     X509V3_set_ctx(&ctx, cert, cert, NULL, NULL, 0);
  126.     ex = X509V3_EXT_conf_nid(NULL, &ctx, nid, value);
  127.     if (!ex)
  128.         return 0;

  129.     X509_add_ext(cert, ex, -1);
  130.     X509_EXTENSION_free(ex);
  131.     return 1;
  132. }

  133. int main()
  134. {
  135.     OpenSSL_add_all_ciphers();
  136.     OpenSSL_add_all_digests();
  137.     ERR_load_crypto_strings();

  138.     SSL_CTX *ctx = SSL_CTX_new (SSLv23_server_method ());
  139.     SSL_CTX_set_options (ctx,
  140.                          SSL_OP_SINGLE_DH_USE |
  141.                          SSL_OP_SINGLE_ECDH_USE |
  142.                          SSL_OP_NO_SSLv2);

  143.     /* Cheesily pick an elliptic curve to use with elliptic curve ciphersuites.
  144.     * We just hardcode a single curve which is reasonably decent.
  145.     * See http://www.mail-archive.com/openssl-dev@openssl.org/msg30957.html */
  146.     EC_KEY *ecdh = EC_KEY_new_by_curve_name (NID_sm2p256v1);
  147.     if (! ecdh)
  148.         die_most_horribly_from_openssl_error ("EC_KEY_new_by_curve_name");

  149.     //PEM_write_bio_ECPrivateKey(BIO *bp, EC_KEY *x, const EVP_CIPHER *enc,
  150.     // unsigned char *kstr, int klen, pem_password_cb *cb, void *u);
  151.     //ec_key_simple_generate_key(ecdh);
  152.     EC_KEY_generate_key(ecdh);

  153.     BIO *bio_out = BIO_new_file("SM2_private.pem", "w");

  154.     PEM_write_bio_ECPrivateKey(bio_out, ecdh, NULL, NULL, 0, NULL, NULL);

  155.     BIO_free(bio_out);

  156.     //----------------make self sign cert---------------
  157.     EVP_PKEY *evk = EVP_PKEY_new();
  158.     EVP_PKEY_set1_EC_KEY(evk, ecdh);
  159.     X509 *x509 = NULL;

  160.     mkcert(&x509, &evk, &evk,0,"Openssl Group", 256, 2345, 3650);
  161.     BIO *bio_x = BIO_new_file("cert.pem", "w");
  162.     PEM_write_bio_X509(bio_x, x509);

  163.     BIO_free(bio_x);

  164.     EVP_PKEY_free(evk);
  165.     //-----------------make server cert ----------------------
  166.     evk = EVP_PKEY_new(); //ca key
  167.     EVP_PKEY_set1_EC_KEY(evk, ecdh);

  168.     EC_KEY *ec_server = EC_KEY_new_by_curve_name (NID_sm2p256v1);
  169.     if (! ec_server)
  170.         die_most_horribly_from_openssl_error ("EC_KEY_new_by_curve_name");

  171.     EC_KEY_generate_key(ec_server);
  172.     bio_out = BIO_new_file("server.pem", "w");

  173.     PEM_write_bio_ECPrivateKey(bio_out, ec_server, NULL, NULL, 0, NULL, NULL);
  174.     BIO_free(bio_out);

  175.     //
  176.     EVP_PKEY *evserv = EVP_PKEY_new();
  177.     EVP_PKEY_set1_EC_KEY(evserv, ec_server);

  178.     X509 *serv_x509 = NULL;
  179.     X509_NAME *is_name = X509_get_subject_name(x509);

  180.     mkcert(&serv_x509,&evserv , &evk,is_name,"gd.com", 256, 2345, 3650);
  181.     BIO *bio_s = BIO_new_file("server-cert.pem", "w");
  182.     PEM_write_bio_X509(bio_s, serv_x509);

  183.     BIO_free(bio_s);
  184.     EVP_PKEY_free(evserv);
  185.     EC_KEY_free(ec_server);
  186.     EVP_PKEY_free(evk);
  187.     //----------------

  188.     EC_KEY_free(ecdh);
  189.     SSL_CTX_free(ctx);
  190.     return 0;
  191. }
参考github上的代码。
阅读(3814) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~