mkreq.c 3.9 KB

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