bio_ssl.cc 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /*
  2. * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the OpenSSL license (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. #include <openssl/ssl.h>
  10. #include <openssl/bio.h>
  11. static SSL *get_ssl(BIO *bio) {
  12. return reinterpret_cast<SSL *>(bio->ptr);
  13. }
  14. static int ssl_read(BIO *bio, char *out, int outl) {
  15. SSL *ssl = get_ssl(bio);
  16. if (ssl == NULL) {
  17. return 0;
  18. }
  19. BIO_clear_retry_flags(bio);
  20. const int ret = SSL_read(ssl, out, outl);
  21. switch (SSL_get_error(ssl, ret)) {
  22. case SSL_ERROR_WANT_READ:
  23. BIO_set_retry_read(bio);
  24. break;
  25. case SSL_ERROR_WANT_WRITE:
  26. BIO_set_retry_write(bio);
  27. break;
  28. case SSL_ERROR_WANT_ACCEPT:
  29. BIO_set_retry_special(bio);
  30. bio->retry_reason = BIO_RR_ACCEPT;
  31. break;
  32. case SSL_ERROR_WANT_CONNECT:
  33. BIO_set_retry_special(bio);
  34. bio->retry_reason = BIO_RR_CONNECT;
  35. break;
  36. case SSL_ERROR_NONE:
  37. case SSL_ERROR_SYSCALL:
  38. case SSL_ERROR_SSL:
  39. case SSL_ERROR_ZERO_RETURN:
  40. default:
  41. break;
  42. }
  43. return ret;
  44. }
  45. static int ssl_write(BIO *bio, const char *out, int outl) {
  46. SSL *ssl = get_ssl(bio);
  47. if (ssl == NULL) {
  48. return 0;
  49. }
  50. BIO_clear_retry_flags(bio);
  51. const int ret = SSL_write(ssl, out, outl);
  52. switch (SSL_get_error(ssl, ret)) {
  53. case SSL_ERROR_WANT_WRITE:
  54. BIO_set_retry_write(bio);
  55. break;
  56. case SSL_ERROR_WANT_READ:
  57. BIO_set_retry_read(bio);
  58. break;
  59. case SSL_ERROR_WANT_CONNECT:
  60. BIO_set_retry_special(bio);
  61. bio->retry_reason = BIO_RR_CONNECT;
  62. break;
  63. case SSL_ERROR_NONE:
  64. case SSL_ERROR_SYSCALL:
  65. case SSL_ERROR_SSL:
  66. default:
  67. break;
  68. }
  69. return ret;
  70. }
  71. static long ssl_ctrl(BIO *bio, int cmd, long num, void *ptr) {
  72. SSL *ssl = get_ssl(bio);
  73. if (ssl == NULL && cmd != BIO_C_SET_SSL) {
  74. return 0;
  75. }
  76. switch (cmd) {
  77. case BIO_C_SET_SSL:
  78. bio->shutdown = num;
  79. bio->ptr = ptr;
  80. bio->init = 1;
  81. return 1;
  82. case BIO_CTRL_GET_CLOSE:
  83. return bio->shutdown;
  84. case BIO_CTRL_SET_CLOSE:
  85. bio->shutdown = num;
  86. return 1;
  87. case BIO_CTRL_WPENDING:
  88. return BIO_ctrl(SSL_get_wbio(ssl), cmd, num, ptr);
  89. case BIO_CTRL_PENDING:
  90. return SSL_pending(ssl);
  91. case BIO_CTRL_FLUSH: {
  92. BIO_clear_retry_flags(bio);
  93. long ret = BIO_ctrl(SSL_get_wbio(ssl), cmd, num, ptr);
  94. BIO_copy_next_retry(bio);
  95. return ret;
  96. }
  97. case BIO_CTRL_PUSH:
  98. case BIO_CTRL_POP:
  99. case BIO_CTRL_DUP:
  100. return -1;
  101. default:
  102. return BIO_ctrl(SSL_get_rbio(ssl), cmd, num, ptr);
  103. }
  104. }
  105. static int ssl_new(BIO *bio) {
  106. return 1;
  107. }
  108. static int ssl_free(BIO *bio) {
  109. SSL *ssl = get_ssl(bio);
  110. if (ssl == NULL) {
  111. return 1;
  112. }
  113. SSL_shutdown(ssl);
  114. if (bio->shutdown) {
  115. SSL_free(ssl);
  116. }
  117. return 1;
  118. }
  119. static long ssl_callback_ctrl(BIO *bio, int cmd, bio_info_cb fp) {
  120. SSL *ssl = get_ssl(bio);
  121. if (ssl == NULL) {
  122. return 0;
  123. }
  124. switch (cmd) {
  125. case BIO_CTRL_SET_CALLBACK:
  126. return -1;
  127. default:
  128. return BIO_callback_ctrl(SSL_get_rbio(ssl), cmd, fp);
  129. }
  130. }
  131. static const BIO_METHOD ssl_method = {
  132. BIO_TYPE_SSL, "SSL", ssl_write, ssl_read, NULL,
  133. NULL, ssl_ctrl, ssl_new, ssl_free, ssl_callback_ctrl,
  134. };
  135. const BIO_METHOD *BIO_f_ssl(void) { return &ssl_method; }
  136. long BIO_set_ssl(BIO *bio, SSL *ssl, int take_owership) {
  137. return BIO_ctrl(bio, BIO_C_SET_SSL, take_owership, ssl);
  138. }