00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 #include <stdio.h>
00113 #include <stdlib.h>
00114 #define USE_SOCKETS
00115 #define NON_MAIN
00116 #include "apps.h"
00117 #undef NON_MAIN
00118 #undef USE_SOCKETS
00119 #include <openssl/err.h>
00120 #include <openssl/x509.h>
00121 #include <openssl/ssl.h>
00122 #include "s_apps.h"
00123
00124 int verify_depth=0;
00125 int verify_error=X509_V_OK;
00126
00127 int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx)
00128 {
00129 char buf[256];
00130 X509 *err_cert;
00131 int err,depth;
00132
00133 err_cert=X509_STORE_CTX_get_current_cert(ctx);
00134 err= X509_STORE_CTX_get_error(ctx);
00135 depth= X509_STORE_CTX_get_error_depth(ctx);
00136
00137 X509_NAME_oneline(X509_get_subject_name(err_cert),buf,sizeof buf);
00138 BIO_printf(bio_err,"depth=%d %s\n",depth,buf);
00139 if (!ok)
00140 {
00141 BIO_printf(bio_err,"verify error:num=%d:%s\n",err,
00142 X509_verify_cert_error_string(err));
00143 if (verify_depth >= depth)
00144 {
00145 ok=1;
00146 verify_error=X509_V_OK;
00147 }
00148 else
00149 {
00150 ok=0;
00151 verify_error=X509_V_ERR_CERT_CHAIN_TOO_LONG;
00152 }
00153 }
00154 switch (ctx->error)
00155 {
00156 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
00157 X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert),buf,sizeof buf);
00158 BIO_printf(bio_err,"issuer= %s\n",buf);
00159 break;
00160 case X509_V_ERR_CERT_NOT_YET_VALID:
00161 case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
00162 BIO_printf(bio_err,"notBefore=");
00163 ASN1_TIME_print(bio_err,X509_get_notBefore(ctx->current_cert));
00164 BIO_printf(bio_err,"\n");
00165 break;
00166 case X509_V_ERR_CERT_HAS_EXPIRED:
00167 case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
00168 BIO_printf(bio_err,"notAfter=");
00169 ASN1_TIME_print(bio_err,X509_get_notAfter(ctx->current_cert));
00170 BIO_printf(bio_err,"\n");
00171 break;
00172 }
00173 BIO_printf(bio_err,"verify return:%d\n",ok);
00174 return(ok);
00175 }
00176
00177 int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file)
00178 {
00179 if (cert_file != NULL)
00180 {
00181
00182
00183
00184
00185
00186 if (SSL_CTX_use_certificate_file(ctx,cert_file,
00187 SSL_FILETYPE_PEM) <= 0)
00188 {
00189 BIO_printf(bio_err,"unable to get certificate from '%s'\n",cert_file);
00190 ERR_print_errors(bio_err);
00191 return(0);
00192 }
00193 if (key_file == NULL) key_file=cert_file;
00194 if (SSL_CTX_use_PrivateKey_file(ctx,key_file,
00195 SSL_FILETYPE_PEM) <= 0)
00196 {
00197 BIO_printf(bio_err,"unable to get private key from '%s'\n",key_file);
00198 ERR_print_errors(bio_err);
00199 return(0);
00200 }
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223 if (!SSL_CTX_check_private_key(ctx))
00224 {
00225 BIO_printf(bio_err,"Private key does not match the certificate public key\n");
00226 return(0);
00227 }
00228 }
00229 return(1);
00230 }
00231
00232 int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key)
00233 {
00234 if (cert == NULL)
00235 return 1;
00236 if (SSL_CTX_use_certificate(ctx,cert) <= 0)
00237 {
00238 BIO_printf(bio_err,"error setting certificate\n");
00239 ERR_print_errors(bio_err);
00240 return 0;
00241 }
00242 if (SSL_CTX_use_PrivateKey(ctx,key) <= 0)
00243 {
00244 BIO_printf(bio_err,"error setting private key\n");
00245 ERR_print_errors(bio_err);
00246 return 0;
00247 }
00248
00249
00250
00251
00252 if (!SSL_CTX_check_private_key(ctx))
00253 {
00254 BIO_printf(bio_err,"Private key does not match the certificate public key\n");
00255 return 0;
00256 }
00257 return 1;
00258 }
00259
00260 long MS_CALLBACK bio_dump_callback(BIO *bio, int cmd, const char *argp,
00261 int argi, long argl, long ret)
00262 {
00263 BIO *out;
00264
00265 out=(BIO *)BIO_get_callback_arg(bio);
00266 if (out == NULL) return(ret);
00267
00268 if (cmd == (BIO_CB_READ|BIO_CB_RETURN))
00269 {
00270 BIO_printf(out,"read from %p [%p] (%d bytes => %ld (0x%lX))\n",
00271 (void *)bio,argp,argi,ret,ret);
00272 BIO_dump(out,argp,(int)ret);
00273 return(ret);
00274 }
00275 else if (cmd == (BIO_CB_WRITE|BIO_CB_RETURN))
00276 {
00277 BIO_printf(out,"write to %p [%p] (%d bytes => %ld (0x%lX))\n",
00278 (void *)bio,argp,argi,ret,ret);
00279 BIO_dump(out,argp,(int)ret);
00280 }
00281 return(ret);
00282 }
00283
00284 void MS_CALLBACK apps_ssl_info_callback(const SSL *s, int where, int ret)
00285 {
00286 const char *str;
00287 int w;
00288
00289 w=where& ~SSL_ST_MASK;
00290
00291 if (w & SSL_ST_CONNECT) str="SSL_connect";
00292 else if (w & SSL_ST_ACCEPT) str="SSL_accept";
00293 else str="undefined";
00294
00295 if (where & SSL_CB_LOOP)
00296 {
00297 BIO_printf(bio_err,"%s:%s\n",str,SSL_state_string_long(s));
00298 }
00299 else if (where & SSL_CB_ALERT)
00300 {
00301 str=(where & SSL_CB_READ)?"read":"write";
00302 BIO_printf(bio_err,"SSL3 alert %s:%s:%s\n",
00303 str,
00304 SSL_alert_type_string_long(ret),
00305 SSL_alert_desc_string_long(ret));
00306 }
00307 else if (where & SSL_CB_EXIT)
00308 {
00309 if (ret == 0)
00310 BIO_printf(bio_err,"%s:failed in %s\n",
00311 str,SSL_state_string_long(s));
00312 else if (ret < 0)
00313 {
00314 BIO_printf(bio_err,"%s:error in %s\n",
00315 str,SSL_state_string_long(s));
00316 }
00317 }
00318 }
00319
00320
00321 void MS_CALLBACK msg_cb(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
00322 {
00323 BIO *bio = arg;
00324 const char *str_write_p, *str_version, *str_content_type = "", *str_details1 = "", *str_details2= "";
00325
00326 str_write_p = write_p ? ">>>" : "<<<";
00327
00328 switch (version)
00329 {
00330 case SSL2_VERSION:
00331 str_version = "SSL 2.0";
00332 break;
00333 case SSL3_VERSION:
00334 str_version = "SSL 3.0 ";
00335 break;
00336 case TLS1_VERSION:
00337 str_version = "TLS 1.0 ";
00338 break;
00339 default:
00340 str_version = "???";
00341 }
00342
00343 if (version == SSL2_VERSION)
00344 {
00345 str_details1 = "???";
00346
00347 if (len > 0)
00348 {
00349 switch (((const unsigned char*)buf)[0])
00350 {
00351 case 0:
00352 str_details1 = ", ERROR:";
00353 str_details2 = " ???";
00354 if (len >= 3)
00355 {
00356 unsigned err = (((const unsigned char*)buf)[1]<<8) + ((const unsigned char*)buf)[2];
00357
00358 switch (err)
00359 {
00360 case 0x0001:
00361 str_details2 = " NO-CIPHER-ERROR";
00362 break;
00363 case 0x0002:
00364 str_details2 = " NO-CERTIFICATE-ERROR";
00365 break;
00366 case 0x0004:
00367 str_details2 = " BAD-CERTIFICATE-ERROR";
00368 break;
00369 case 0x0006:
00370 str_details2 = " UNSUPPORTED-CERTIFICATE-TYPE-ERROR";
00371 break;
00372 }
00373 }
00374
00375 break;
00376 case 1:
00377 str_details1 = ", CLIENT-HELLO";
00378 break;
00379 case 2:
00380 str_details1 = ", CLIENT-MASTER-KEY";
00381 break;
00382 case 3:
00383 str_details1 = ", CLIENT-FINISHED";
00384 break;
00385 case 4:
00386 str_details1 = ", SERVER-HELLO";
00387 break;
00388 case 5:
00389 str_details1 = ", SERVER-VERIFY";
00390 break;
00391 case 6:
00392 str_details1 = ", SERVER-FINISHED";
00393 break;
00394 case 7:
00395 str_details1 = ", REQUEST-CERTIFICATE";
00396 break;
00397 case 8:
00398 str_details1 = ", CLIENT-CERTIFICATE";
00399 break;
00400 }
00401 }
00402 }
00403
00404 if (version == SSL3_VERSION || version == TLS1_VERSION)
00405 {
00406 switch (content_type)
00407 {
00408 case 20:
00409 str_content_type = "ChangeCipherSpec";
00410 break;
00411 case 21:
00412 str_content_type = "Alert";
00413 break;
00414 case 22:
00415 str_content_type = "Handshake";
00416 break;
00417 }
00418
00419 if (content_type == 21)
00420 {
00421 str_details1 = ", ???";
00422
00423 if (len == 2)
00424 {
00425 switch (((const unsigned char*)buf)[0])
00426 {
00427 case 1:
00428 str_details1 = ", warning";
00429 break;
00430 case 2:
00431 str_details1 = ", fatal";
00432 break;
00433 }
00434
00435 str_details2 = " ???";
00436 switch (((const unsigned char*)buf)[1])
00437 {
00438 case 0:
00439 str_details2 = " close_notify";
00440 break;
00441 case 10:
00442 str_details2 = " unexpected_message";
00443 break;
00444 case 20:
00445 str_details2 = " bad_record_mac";
00446 break;
00447 case 21:
00448 str_details2 = " decryption_failed";
00449 break;
00450 case 22:
00451 str_details2 = " record_overflow";
00452 break;
00453 case 30:
00454 str_details2 = " decompression_failure";
00455 break;
00456 case 40:
00457 str_details2 = " handshake_failure";
00458 break;
00459 case 42:
00460 str_details2 = " bad_certificate";
00461 break;
00462 case 43:
00463 str_details2 = " unsupported_certificate";
00464 break;
00465 case 44:
00466 str_details2 = " certificate_revoked";
00467 break;
00468 case 45:
00469 str_details2 = " certificate_expired";
00470 break;
00471 case 46:
00472 str_details2 = " certificate_unknown";
00473 break;
00474 case 47:
00475 str_details2 = " illegal_parameter";
00476 break;
00477 case 48:
00478 str_details2 = " unknown_ca";
00479 break;
00480 case 49:
00481 str_details2 = " access_denied";
00482 break;
00483 case 50:
00484 str_details2 = " decode_error";
00485 break;
00486 case 51:
00487 str_details2 = " decrypt_error";
00488 break;
00489 case 60:
00490 str_details2 = " export_restriction";
00491 break;
00492 case 70:
00493 str_details2 = " protocol_version";
00494 break;
00495 case 71:
00496 str_details2 = " insufficient_security";
00497 break;
00498 case 80:
00499 str_details2 = " internal_error";
00500 break;
00501 case 90:
00502 str_details2 = " user_canceled";
00503 break;
00504 case 100:
00505 str_details2 = " no_renegotiation";
00506 break;
00507 }
00508 }
00509 }
00510
00511 if (content_type == 22)
00512 {
00513 str_details1 = "???";
00514
00515 if (len > 0)
00516 {
00517 switch (((const unsigned char*)buf)[0])
00518 {
00519 case 0:
00520 str_details1 = ", HelloRequest";
00521 break;
00522 case 1:
00523 str_details1 = ", ClientHello";
00524 break;
00525 case 2:
00526 str_details1 = ", ServerHello";
00527 break;
00528 case 11:
00529 str_details1 = ", Certificate";
00530 break;
00531 case 12:
00532 str_details1 = ", ServerKeyExchange";
00533 break;
00534 case 13:
00535 str_details1 = ", CertificateRequest";
00536 break;
00537 case 14:
00538 str_details1 = ", ServerHelloDone";
00539 break;
00540 case 15:
00541 str_details1 = ", CertificateVerify";
00542 break;
00543 case 16:
00544 str_details1 = ", ClientKeyExchange";
00545 break;
00546 case 20:
00547 str_details1 = ", Finished";
00548 break;
00549 }
00550 }
00551 }
00552 }
00553
00554 BIO_printf(bio, "%s %s%s [length %04lx]%s%s\n", str_write_p, str_version, str_content_type, (unsigned long)len, str_details1, str_details2);
00555
00556 if (len > 0)
00557 {
00558 size_t num, i;
00559
00560 BIO_printf(bio, " ");
00561 num = len;
00562 #if 0
00563 if (num > 16)
00564 num = 16;
00565 #endif
00566 for (i = 0; i < num; i++)
00567 {
00568 if (i % 16 == 0 && i > 0)
00569 BIO_printf(bio, "\n ");
00570 BIO_printf(bio, " %02x", ((const unsigned char*)buf)[i]);
00571 }
00572 if (i < len)
00573 BIO_printf(bio, " ...");
00574 BIO_printf(bio, "\n");
00575 }
00576 BIO_flush(bio);
00577 }