s_cb.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. /* apps/s_cb.c - callback functions used by s_client, s_server, and s_time */
  2. /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  3. * All rights reserved.
  4. *
  5. * This package is an SSL implementation written
  6. * by Eric Young (eay@cryptsoft.com).
  7. * The implementation was written so as to conform with Netscapes SSL.
  8. *
  9. * This library is free for commercial and non-commercial use as long as
  10. * the following conditions are aheared to. The following conditions
  11. * apply to all code found in this distribution, be it the RC4, RSA,
  12. * lhash, DES, etc., code; not just the SSL code. The SSL documentation
  13. * included with this distribution is covered by the same copyright terms
  14. * except that the holder is Tim Hudson (tjh@cryptsoft.com).
  15. *
  16. * Copyright remains Eric Young's, and as such any Copyright notices in
  17. * the code are not to be removed.
  18. * If this package is used in a product, Eric Young should be given attribution
  19. * as the author of the parts of the library used.
  20. * This can be in the form of a textual message at program startup or
  21. * in documentation (online or textual) provided with the package.
  22. *
  23. * Redistribution and use in source and binary forms, with or without
  24. * modification, are permitted provided that the following conditions
  25. * are met:
  26. * 1. Redistributions of source code must retain the copyright
  27. * notice, this list of conditions and the following disclaimer.
  28. * 2. Redistributions in binary form must reproduce the above copyright
  29. * notice, this list of conditions and the following disclaimer in the
  30. * documentation and/or other materials provided with the distribution.
  31. * 3. All advertising materials mentioning features or use of this software
  32. * must display the following acknowledgement:
  33. * "This product includes cryptographic software written by
  34. * Eric Young (eay@cryptsoft.com)"
  35. * The word 'cryptographic' can be left out if the rouines from the library
  36. * being used are not cryptographic related :-).
  37. * 4. If you include any Windows specific code (or a derivative thereof) from
  38. * the apps directory (application code) you must include an acknowledgement:
  39. * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
  40. *
  41. * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
  42. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  43. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  44. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  45. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  46. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  47. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  48. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  49. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  50. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  51. * SUCH DAMAGE.
  52. *
  53. * The licence and distribution terms for any publically available version or
  54. * derivative of this code cannot be changed. i.e. this code cannot simply be
  55. * copied and put under another distribution licence
  56. * [including the GNU Public Licence.]
  57. */
  58. #include <stdio.h>
  59. #include <stdlib.h>
  60. #define USE_SOCKETS
  61. #define NON_MAIN
  62. #include "apps.h"
  63. #undef NON_MAIN
  64. #undef USE_SOCKETS
  65. #include <openssl/err.h>
  66. #include <openssl/x509.h>
  67. #include <openssl/ssl.h>
  68. #include "s_apps.h"
  69. int verify_depth=0;
  70. int verify_error=X509_V_OK;
  71. int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx)
  72. {
  73. char buf[256];
  74. X509 *err_cert;
  75. int err,depth;
  76. err_cert=X509_STORE_CTX_get_current_cert(ctx);
  77. err= X509_STORE_CTX_get_error(ctx);
  78. depth= X509_STORE_CTX_get_error_depth(ctx);
  79. X509_NAME_oneline(X509_get_subject_name(err_cert),buf,256);
  80. BIO_printf(bio_err,"depth=%d %s\n",depth,buf);
  81. if (!ok)
  82. {
  83. BIO_printf(bio_err,"verify error:num=%d:%s\n",err,
  84. X509_verify_cert_error_string(err));
  85. if (verify_depth >= depth)
  86. {
  87. ok=1;
  88. verify_error=X509_V_OK;
  89. }
  90. else
  91. {
  92. ok=0;
  93. verify_error=X509_V_ERR_CERT_CHAIN_TOO_LONG;
  94. }
  95. }
  96. switch (ctx->error)
  97. {
  98. case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
  99. X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert),buf,256);
  100. BIO_printf(bio_err,"issuer= %s\n",buf);
  101. break;
  102. case X509_V_ERR_CERT_NOT_YET_VALID:
  103. case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
  104. BIO_printf(bio_err,"notBefore=");
  105. ASN1_TIME_print(bio_err,X509_get_notBefore(ctx->current_cert));
  106. BIO_printf(bio_err,"\n");
  107. break;
  108. case X509_V_ERR_CERT_HAS_EXPIRED:
  109. case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
  110. BIO_printf(bio_err,"notAfter=");
  111. ASN1_TIME_print(bio_err,X509_get_notAfter(ctx->current_cert));
  112. BIO_printf(bio_err,"\n");
  113. break;
  114. }
  115. BIO_printf(bio_err,"verify return:%d\n",ok);
  116. return(ok);
  117. }
  118. int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file)
  119. {
  120. if (cert_file != NULL)
  121. {
  122. /*
  123. SSL *ssl;
  124. X509 *x509;
  125. */
  126. if (SSL_CTX_use_certificate_file(ctx,cert_file,
  127. SSL_FILETYPE_PEM) <= 0)
  128. {
  129. BIO_printf(bio_err,"unable to get certificate from '%s'\n",cert_file);
  130. ERR_print_errors(bio_err);
  131. return(0);
  132. }
  133. if (key_file == NULL) key_file=cert_file;
  134. if (SSL_CTX_use_PrivateKey_file(ctx,key_file,
  135. SSL_FILETYPE_PEM) <= 0)
  136. {
  137. BIO_printf(bio_err,"unable to get private key from '%s'\n",key_file);
  138. ERR_print_errors(bio_err);
  139. return(0);
  140. }
  141. /*
  142. In theory this is no longer needed
  143. ssl=SSL_new(ctx);
  144. x509=SSL_get_certificate(ssl);
  145. if (x509 != NULL) {
  146. EVP_PKEY *pktmp;
  147. pktmp = X509_get_pubkey(x509);
  148. EVP_PKEY_copy_parameters(pktmp,
  149. SSL_get_privatekey(ssl));
  150. EVP_PKEY_free(pktmp);
  151. }
  152. SSL_free(ssl);
  153. */
  154. /* If we are using DSA, we can copy the parameters from
  155. * the private key */
  156. /* Now we know that a key and cert have been set against
  157. * the SSL context */
  158. if (!SSL_CTX_check_private_key(ctx))
  159. {
  160. BIO_printf(bio_err,"Private key does not match the certificate public key\n");
  161. return(0);
  162. }
  163. }
  164. return(1);
  165. }
  166. long MS_CALLBACK bio_dump_cb(BIO *bio, int cmd, const char *argp, int argi,
  167. long argl, long ret)
  168. {
  169. BIO *out;
  170. out=(BIO *)BIO_get_callback_arg(bio);
  171. if (out == NULL) return(ret);
  172. if (cmd == (BIO_CB_READ|BIO_CB_RETURN))
  173. {
  174. BIO_printf(out,"read from %08X [%08lX] (%d bytes => %ld (0x%X))\n",
  175. bio,argp,argi,ret,ret);
  176. BIO_dump(out,argp,(int)ret);
  177. return(ret);
  178. }
  179. else if (cmd == (BIO_CB_WRITE|BIO_CB_RETURN))
  180. {
  181. BIO_printf(out,"write to %08X [%08lX] (%d bytes => %ld (0x%X))\n",
  182. bio,argp,argi,ret,ret);
  183. BIO_dump(out,argp,(int)ret);
  184. }
  185. return(ret);
  186. }
  187. void MS_CALLBACK apps_ssl_info_callback(SSL *s, int where, int ret)
  188. {
  189. char *str;
  190. int w;
  191. w=where& ~SSL_ST_MASK;
  192. if (w & SSL_ST_CONNECT) str="SSL_connect";
  193. else if (w & SSL_ST_ACCEPT) str="SSL_accept";
  194. else str="undefined";
  195. if (where & SSL_CB_LOOP)
  196. {
  197. BIO_printf(bio_err,"%s:%s\n",str,SSL_state_string_long(s));
  198. }
  199. else if (where & SSL_CB_ALERT)
  200. {
  201. str=(where & SSL_CB_READ)?"read":"write";
  202. BIO_printf(bio_err,"SSL3 alert %s:%s:%s\n",
  203. str,
  204. SSL_alert_type_string_long(ret),
  205. SSL_alert_desc_string_long(ret));
  206. }
  207. else if (where & SSL_CB_EXIT)
  208. {
  209. if (ret == 0)
  210. BIO_printf(bio_err,"%s:failed in %s\n",
  211. str,SSL_state_string_long(s));
  212. else if (ret < 0)
  213. {
  214. BIO_printf(bio_err,"%s:error in %s\n",
  215. str,SSL_state_string_long(s));
  216. }
  217. }
  218. }