spkigen.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /* NOCW */
  2. /*-
  3. * demos/spkigen.c
  4. * 18-Mar-1997 - eay - A quick hack :-)
  5. * version 1.1, it would probably help to save or load the
  6. * private key :-)
  7. */
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <openssl/err.h>
  11. #include <openssl/asn1.h>
  12. #include <openssl/objects.h>
  13. #include <openssl/evp.h>
  14. #include <openssl/x509.h>
  15. #include <openssl/pem.h>
  16. /*
  17. * The following two don't exist in SSLeay but they are in here as examples
  18. */
  19. #define PEM_write_SPKI(fp,x) \
  20. PEM_ASN1_write((int (*)())i2d_NETSCAPE_SPKI,"SPKI",fp,\
  21. (char *)x,NULL,NULL,0,NULL)
  22. int SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey);
  23. /* These are defined in the next version of SSLeay */
  24. int EVP_PKEY_assign(EVP_PKEY *pkey, int type, char *key);
  25. #define RSA_F4 0x10001
  26. #define EVP_PKEY_assign_RSA(pkey,rsa) EVP_PKEY_assign((pkey),EVP_PKEY_RSA,\
  27. (char *)(rsa))
  28. int main(argc, argv)
  29. int argc;
  30. char *argv[];
  31. {
  32. RSA *rsa = NULL;
  33. NETSCAPE_SPKI *spki = NULL;
  34. EVP_PKEY *pkey = NULL;
  35. char buf[128];
  36. int ok = 0, i;
  37. FILE *fp;
  38. pkey = EVP_PKEY_new();
  39. if (argc < 2) {
  40. /*
  41. * Generate an RSA key, the random state should have been seeded with
  42. * lots of calls to RAND_seed(....)
  43. */
  44. fprintf(stderr, "generating RSA key, could take some time...\n");
  45. if ((rsa = RSA_generate_key(512, RSA_F4, NULL)) == NULL)
  46. goto err;
  47. } else {
  48. if ((fp = fopen(argv[1], "r")) == NULL) {
  49. perror(argv[1]);
  50. goto err;
  51. }
  52. if ((rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL)) == NULL)
  53. goto err;
  54. fclose(fp);
  55. }
  56. if (!EVP_PKEY_assign_RSA(pkey, rsa))
  57. goto err;
  58. rsa = NULL;
  59. /* lets make the spki and set the public key and challenge */
  60. if ((spki = NETSCAPE_SPKI_new()) == NULL)
  61. goto err;
  62. if (!SPKI_set_pubkey(spki, pkey))
  63. goto err;
  64. fprintf(stderr, "please enter challenge string:");
  65. fflush(stderr);
  66. buf[0] = '\0';
  67. fgets(buf, sizeof(buf), stdin);
  68. i = strlen(buf);
  69. if (i > 0)
  70. buf[--i] = '\0';
  71. if (!ASN1_STRING_set((ASN1_STRING *)spki->spkac->challenge, buf, i))
  72. goto err;
  73. if (!NETSCAPE_SPKI_sign(spki, pkey, EVP_md5()))
  74. goto err;
  75. PEM_write_SPKI(stdout, spki);
  76. if (argc < 2)
  77. PEM_write_RSAPrivateKey(stdout, pkey->pkey.rsa, NULL, NULL, 0, NULL);
  78. ok = 1;
  79. err:
  80. if (!ok) {
  81. fprintf(stderr, "something bad happened....");
  82. ERR_print_errors_fp(stderr);
  83. }
  84. NETSCAPE_SPKI_free(spki);
  85. EVP_PKEY_free(pkey);
  86. exit(!ok);
  87. }
  88. /* This function is in the next version of SSLeay */
  89. int EVP_PKEY_assign(pkey, type, key)
  90. EVP_PKEY *pkey;
  91. int type;
  92. char *key;
  93. {
  94. if (pkey == NULL)
  95. return (0);
  96. if (pkey->pkey.ptr != NULL) {
  97. if (pkey->type == EVP_PKEY_RSA)
  98. RSA_free(pkey->pkey.rsa);
  99. /* else memory leak */
  100. }
  101. pkey->type = type;
  102. pkey->pkey.ptr = key;
  103. return (1);
  104. }
  105. /*
  106. * While I have a X509_set_pubkey() and X509_REQ_set_pubkey(),
  107. * SPKI_set_pubkey() does not currently exist so here is a version of it. The
  108. * next SSLeay release will probably have X509_set_pubkey(),
  109. * X509_REQ_set_pubkey() and NETSCAPE_SPKI_set_pubkey() as macros calling the
  110. * same function
  111. */
  112. int SPKI_set_pubkey(x, pkey)
  113. NETSCAPE_SPKI *x;
  114. EVP_PKEY *pkey;
  115. {
  116. int ok = 0;
  117. X509_PUBKEY *pk;
  118. X509_ALGOR *a;
  119. ASN1_OBJECT *o;
  120. unsigned char *s, *p;
  121. int i;
  122. if (x == NULL)
  123. return (0);
  124. if ((pk = X509_PUBKEY_new()) == NULL)
  125. goto err;
  126. a = pk->algor;
  127. /* set the algorithm id */
  128. if ((o = OBJ_nid2obj(pkey->type)) == NULL)
  129. goto err;
  130. ASN1_OBJECT_free(a->algorithm);
  131. a->algorithm = o;
  132. /* Set the parameter list */
  133. if ((a->parameter == NULL) || (a->parameter->type != V_ASN1_NULL)) {
  134. ASN1_TYPE_free(a->parameter);
  135. a->parameter = ASN1_TYPE_new();
  136. a->parameter->type = V_ASN1_NULL;
  137. }
  138. i = i2d_PublicKey(pkey, NULL);
  139. if ((s = (unsigned char *)malloc(i + 1)) == NULL)
  140. goto err;
  141. p = s;
  142. i2d_PublicKey(pkey, &p);
  143. if (!ASN1_BIT_STRING_set(pk->public_key, s, i))
  144. goto err;
  145. free(s);
  146. X509_PUBKEY_free(x->spkac->pubkey);
  147. x->spkac->pubkey = pk;
  148. pk = NULL;
  149. ok = 1;
  150. err:
  151. if (pk != NULL)
  152. X509_PUBKEY_free(pk);
  153. return (ok);
  154. }