mkreq.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /* Certificate request creation. Demonstrates some request related
  2. * operations.
  3. */
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <openssl/pem.h>
  7. #include <openssl/conf.h>
  8. #include <openssl/x509v3.h>
  9. #ifndef OPENSSL_NO_ENGINE
  10. #include <openssl/engine.h>
  11. #endif
  12. int mkreq(X509_REQ **x509p, EVP_PKEY **pkeyp, int bits, int serial, int days);
  13. int add_ext(STACK_OF(X509_REQUEST) *sk, int nid, char *value);
  14. int main(int argc, char **argv)
  15. {
  16. BIO *bio_err;
  17. X509_REQ *req=NULL;
  18. EVP_PKEY *pkey=NULL;
  19. CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
  20. bio_err=BIO_new_fp(stderr, BIO_NOCLOSE);
  21. mkreq(&req,&pkey,512,0,365);
  22. RSA_print_fp(stdout,pkey->pkey.rsa,0);
  23. X509_REQ_print_fp(stdout,req);
  24. PEM_write_X509_REQ(stdout,req);
  25. X509_REQ_free(req);
  26. EVP_PKEY_free(pkey);
  27. #ifndef OPENSSL_NO_ENGINE
  28. ENGINE_cleanup();
  29. #endif
  30. CRYPTO_cleanup_all_ex_data();
  31. CRYPTO_mem_leaks(bio_err);
  32. BIO_free(bio_err);
  33. return(0);
  34. }
  35. static void callback(int p, int n, void *arg)
  36. {
  37. char c='B';
  38. if (p == 0) c='.';
  39. if (p == 1) c='+';
  40. if (p == 2) c='*';
  41. if (p == 3) c='\n';
  42. fputc(c,stderr);
  43. }
  44. int mkreq(X509_REQ **req, EVP_PKEY **pkeyp, int bits, int serial, int days)
  45. {
  46. X509_REQ *x;
  47. EVP_PKEY *pk;
  48. RSA *rsa;
  49. X509_NAME *name=NULL;
  50. STACK_OF(X509_EXTENSION) *exts = NULL;
  51. if ((pk=EVP_PKEY_new()) == NULL)
  52. goto err;
  53. if ((x=X509_REQ_new()) == NULL)
  54. goto err;
  55. rsa=RSA_generate_key(bits,RSA_F4,callback,NULL);
  56. if (!EVP_PKEY_assign_RSA(pk,rsa))
  57. goto err;
  58. rsa=NULL;
  59. X509_REQ_set_pubkey(x,pk);
  60. name=X509_REQ_get_subject_name(x);
  61. /* This function creates and adds the entry, working out the
  62. * correct string type and performing checks on its length.
  63. * Normally we'd check the return value for errors...
  64. */
  65. X509_NAME_add_entry_by_txt(name,"C",
  66. MBSTRING_ASC, "UK", -1, -1, 0);
  67. X509_NAME_add_entry_by_txt(name,"CN",
  68. MBSTRING_ASC, "OpenSSL Group", -1, -1, 0);
  69. #ifdef REQUEST_EXTENSIONS
  70. /* Certificate requests can contain extensions, which can be used
  71. * to indicate the extensions the requestor would like added to
  72. * their certificate. CAs might ignore them however or even choke
  73. * if they are present.
  74. */
  75. /* For request extensions they are all packed in a single attribute.
  76. * We save them in a STACK and add them all at once later...
  77. */
  78. exts = sk_X509_EXTENSION_new_null();
  79. /* Standard extenions */
  80. add_ext(exts, NID_key_usage, "critical,digitalSignature,keyEncipherment");
  81. /* This is a typical use for request extensions: requesting a value for
  82. * subject alternative name.
  83. */
  84. add_ext(exts, NID_subject_alt_name, "email:steve@openssl.org");
  85. /* Some Netscape specific extensions */
  86. add_ext(exts, NID_netscape_cert_type, "client,email");
  87. #ifdef CUSTOM_EXT
  88. /* Maybe even add our own extension based on existing */
  89. {
  90. int nid;
  91. nid = OBJ_create("1.2.3.4", "MyAlias", "My Test Alias Extension");
  92. X509V3_EXT_add_alias(nid, NID_netscape_comment);
  93. add_ext(x, nid, "example comment alias");
  94. }
  95. #endif
  96. /* Now we've created the extensions we add them to the request */
  97. X509_REQ_add_extensions(x, exts);
  98. sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
  99. #endif
  100. if (!X509_REQ_sign(x,pk,EVP_sha1()))
  101. goto err;
  102. *req=x;
  103. *pkeyp=pk;
  104. return(1);
  105. err:
  106. return(0);
  107. }
  108. /* Add extension using V3 code: we can set the config file as NULL
  109. * because we wont reference any other sections.
  110. */
  111. int add_ext(STACK_OF(X509_REQUEST) *sk, int nid, char *value)
  112. {
  113. X509_EXTENSION *ex;
  114. ex = X509V3_EXT_conf_nid(NULL, NULL, nid, value);
  115. if (!ex)
  116. return 0;
  117. sk_X509_EXTENSION_push(sk, ex);
  118. return 1;
  119. }