xp_ssl.c 76 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708
  1. /*
  2. +----------------------------------------------------------------------+
  3. | Copyright (c) The PHP Group |
  4. +----------------------------------------------------------------------+
  5. | This source file is subject to version 3.01 of the PHP license, |
  6. | that is bundled with this package in the file LICENSE, and is |
  7. | available through the world-wide-web at the following url: |
  8. | https://www.php.net/license/3_01.txt |
  9. | If you did not receive a copy of the PHP license and are unable to |
  10. | obtain it through the world-wide-web, please send a note to |
  11. | license@php.net so we can mail you a copy immediately. |
  12. +----------------------------------------------------------------------+
  13. | Authors: Wez Furlong <wez@thebrainroom.com> |
  14. | Daniel Lowrey <rdlowrey@php.net> |
  15. | Chris Wright <daverandom@php.net> |
  16. | Jakub Zelenka <bukka@php.net> |
  17. +----------------------------------------------------------------------+
  18. */
  19. #ifdef HAVE_CONFIG_H
  20. #include "config.h"
  21. #endif
  22. #include "php.h"
  23. #include "ext/standard/file.h"
  24. #include "ext/standard/url.h"
  25. #include "streams/php_streams_int.h"
  26. #include "zend_smart_str.h"
  27. #include "php_openssl.h"
  28. #include "php_network.h"
  29. #include <openssl/ssl.h>
  30. #include <openssl/rsa.h>
  31. #include <openssl/x509.h>
  32. #include <openssl/x509v3.h>
  33. #include <openssl/err.h>
  34. #include <openssl/bn.h>
  35. #include <openssl/dh.h>
  36. #ifdef PHP_WIN32
  37. #include "win32/winutil.h"
  38. #include "win32/time.h"
  39. #include <Wincrypt.h>
  40. /* These are from Wincrypt.h, they conflict with OpenSSL */
  41. #undef X509_NAME
  42. #undef X509_CERT_PAIR
  43. #undef X509_EXTENSIONS
  44. #endif
  45. /* Flags for determining allowed stream crypto methods */
  46. #define STREAM_CRYPTO_IS_CLIENT (1<<0)
  47. #define STREAM_CRYPTO_METHOD_SSLv2 (1<<1)
  48. #define STREAM_CRYPTO_METHOD_SSLv3 (1<<2)
  49. #define STREAM_CRYPTO_METHOD_TLSv1_0 (1<<3)
  50. #define STREAM_CRYPTO_METHOD_TLSv1_1 (1<<4)
  51. #define STREAM_CRYPTO_METHOD_TLSv1_2 (1<<5)
  52. #define STREAM_CRYPTO_METHOD_TLSv1_3 (1<<6)
  53. #ifndef OPENSSL_NO_TLS1_METHOD
  54. #define HAVE_TLS1 1
  55. #endif
  56. #ifndef OPENSSL_NO_TLS1_1_METHOD
  57. #define HAVE_TLS11 1
  58. #endif
  59. #ifndef OPENSSL_NO_TLS1_2_METHOD
  60. #define HAVE_TLS12 1
  61. #endif
  62. #if OPENSSL_VERSION_NUMBER >= 0x10101000 && !defined(OPENSSL_NO_TLS1_3)
  63. #define HAVE_TLS13 1
  64. #endif
  65. #ifndef OPENSSL_NO_ECDH
  66. #define HAVE_ECDH 1
  67. #endif
  68. #ifndef OPENSSL_NO_TLSEXT
  69. #define HAVE_TLS_SNI 1
  70. #define HAVE_TLS_ALPN 1
  71. #endif
  72. #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
  73. #define HAVE_SEC_LEVEL 1
  74. #endif
  75. #ifndef OPENSSL_NO_SSL3
  76. #define HAVE_SSL3 1
  77. #define PHP_OPENSSL_MIN_PROTO_VERSION STREAM_CRYPTO_METHOD_SSLv3
  78. #else
  79. #define PHP_OPENSSL_MIN_PROTO_VERSION STREAM_CRYPTO_METHOD_TLSv1_0
  80. #endif
  81. #ifdef HAVE_TLS13
  82. #define PHP_OPENSSL_MAX_PROTO_VERSION STREAM_CRYPTO_METHOD_TLSv1_3
  83. #else
  84. #define PHP_OPENSSL_MAX_PROTO_VERSION STREAM_CRYPTO_METHOD_TLSv1_2
  85. #endif
  86. /* Simplify ssl context option retrieval */
  87. #define GET_VER_OPT(name) \
  88. (PHP_STREAM_CONTEXT(stream) && (val = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), "ssl", name)) != NULL)
  89. #define GET_VER_OPT_STRING(name, str) \
  90. if (GET_VER_OPT(name)) { \
  91. if (try_convert_to_string(val)) str = Z_STRVAL_P(val); \
  92. }
  93. #define GET_VER_OPT_LONG(name, num) \
  94. if (GET_VER_OPT(name)) { num = zval_get_long(val); }
  95. /* Used for peer verification in windows */
  96. #define PHP_X509_NAME_ENTRY_TO_UTF8(ne, i, out) \
  97. ASN1_STRING_to_UTF8(&out, X509_NAME_ENTRY_get_data(X509_NAME_get_entry(ne, i)))
  98. #if PHP_OPENSSL_API_VERSION < 0x10100
  99. static RSA *php_openssl_tmp_rsa_cb(SSL *s, int is_export, int keylength);
  100. #endif
  101. extern php_stream* php_openssl_get_stream_from_ssl_handle(const SSL *ssl);
  102. extern zend_string* php_openssl_x509_fingerprint(X509 *peer, const char *method, bool raw);
  103. extern int php_openssl_get_ssl_stream_data_index(void);
  104. static struct timeval php_openssl_subtract_timeval(struct timeval a, struct timeval b);
  105. static int php_openssl_compare_timeval(struct timeval a, struct timeval b);
  106. static ssize_t php_openssl_sockop_io(int read, php_stream *stream, char *buf, size_t count);
  107. const php_stream_ops php_openssl_socket_ops;
  108. /* Certificate contexts used for server-side SNI selection */
  109. typedef struct _php_openssl_sni_cert_t {
  110. char *name;
  111. SSL_CTX *ctx;
  112. } php_openssl_sni_cert_t;
  113. /* Provides leaky bucket handhsake renegotiation rate-limiting */
  114. typedef struct _php_openssl_handshake_bucket_t {
  115. zend_long prev_handshake;
  116. zend_long limit;
  117. zend_long window;
  118. float tokens;
  119. unsigned should_close;
  120. } php_openssl_handshake_bucket_t;
  121. #ifdef HAVE_TLS_ALPN
  122. /* Holds the available server ALPN protocols for negotiation */
  123. typedef struct _php_openssl_alpn_ctx_t {
  124. unsigned char *data;
  125. unsigned short len;
  126. } php_openssl_alpn_ctx;
  127. #endif
  128. /* This implementation is very closely tied to the that of the native
  129. * sockets implemented in the core.
  130. * Don't try this technique in other extensions!
  131. * */
  132. typedef struct _php_openssl_netstream_data_t {
  133. php_netstream_data_t s;
  134. SSL *ssl_handle;
  135. SSL_CTX *ctx;
  136. struct timeval connect_timeout;
  137. int enable_on_connect;
  138. int is_client;
  139. int ssl_active;
  140. php_stream_xport_crypt_method_t method;
  141. php_openssl_handshake_bucket_t *reneg;
  142. php_openssl_sni_cert_t *sni_certs;
  143. unsigned sni_cert_count;
  144. #ifdef HAVE_TLS_ALPN
  145. php_openssl_alpn_ctx alpn_ctx;
  146. #endif
  147. char *url_name;
  148. unsigned state_set:1;
  149. unsigned _spare:31;
  150. } php_openssl_netstream_data_t;
  151. /* it doesn't matter that we do some hash traversal here, since it is done only
  152. * in an error condition arising from a network connection problem */
  153. static int php_openssl_is_http_stream_talking_to_iis(php_stream *stream) /* {{{ */
  154. {
  155. if (Z_TYPE(stream->wrapperdata) == IS_ARRAY &&
  156. stream->wrapper &&
  157. strcasecmp(stream->wrapper->wops->label, "HTTP") == 0
  158. ) {
  159. /* the wrapperdata is an array zval containing the headers */
  160. zval *tmp;
  161. #define SERVER_MICROSOFT_IIS "Server: Microsoft-IIS"
  162. #define SERVER_GOOGLE "Server: GFE/"
  163. ZEND_HASH_FOREACH_VAL(Z_ARRVAL(stream->wrapperdata), tmp) {
  164. if (zend_string_equals_literal_ci(Z_STR_P(tmp), SERVER_MICROSOFT_IIS)) {
  165. return 1;
  166. } else if (zend_string_equals_literal_ci(Z_STR_P(tmp), SERVER_GOOGLE)) {
  167. return 1;
  168. }
  169. } ZEND_HASH_FOREACH_END();
  170. }
  171. return 0;
  172. }
  173. /* }}} */
  174. static int php_openssl_handle_ssl_error(php_stream *stream, int nr_bytes, bool is_init) /* {{{ */
  175. {
  176. php_openssl_netstream_data_t *sslsock = (php_openssl_netstream_data_t*)stream->abstract;
  177. int err = SSL_get_error(sslsock->ssl_handle, nr_bytes);
  178. char esbuf[512];
  179. smart_str ebuf = {0};
  180. unsigned long ecode;
  181. int retry = 1;
  182. switch(err) {
  183. case SSL_ERROR_ZERO_RETURN:
  184. /* SSL terminated (but socket may still be active) */
  185. retry = 0;
  186. break;
  187. case SSL_ERROR_WANT_READ:
  188. case SSL_ERROR_WANT_WRITE:
  189. /* re-negotiation, or perhaps the SSL layer needs more
  190. * packets: retry in next iteration */
  191. errno = EAGAIN;
  192. retry = is_init ? 1 : sslsock->s.is_blocked;
  193. break;
  194. case SSL_ERROR_SYSCALL:
  195. if (ERR_peek_error() == 0) {
  196. if (nr_bytes == 0) {
  197. if (!php_openssl_is_http_stream_talking_to_iis(stream) && ERR_get_error() != 0) {
  198. php_error_docref(NULL, E_WARNING, "SSL: fatal protocol error");
  199. }
  200. SSL_set_shutdown(sslsock->ssl_handle, SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
  201. stream->eof = 1;
  202. retry = 0;
  203. } else {
  204. char *estr = php_socket_strerror(php_socket_errno(), NULL, 0);
  205. php_error_docref(NULL, E_WARNING,
  206. "SSL: %s", estr);
  207. efree(estr);
  208. retry = 0;
  209. }
  210. break;
  211. }
  212. ZEND_FALLTHROUGH;
  213. default:
  214. /* some other error */
  215. ecode = ERR_get_error();
  216. switch (ERR_GET_REASON(ecode)) {
  217. case SSL_R_NO_SHARED_CIPHER:
  218. php_error_docref(NULL, E_WARNING,
  219. "SSL_R_NO_SHARED_CIPHER: no suitable shared cipher could be used. "
  220. "This could be because the server is missing an SSL certificate "
  221. "(local_cert context option)");
  222. retry = 0;
  223. break;
  224. default:
  225. do {
  226. /* NULL is automatically added */
  227. ERR_error_string_n(ecode, esbuf, sizeof(esbuf));
  228. if (ebuf.s) {
  229. smart_str_appendc(&ebuf, '\n');
  230. }
  231. smart_str_appends(&ebuf, esbuf);
  232. } while ((ecode = ERR_get_error()) != 0);
  233. smart_str_0(&ebuf);
  234. php_error_docref(NULL, E_WARNING,
  235. "SSL operation failed with code %d. %s%s",
  236. err,
  237. ebuf.s ? "OpenSSL Error messages:\n" : "",
  238. ebuf.s ? ZSTR_VAL(ebuf.s) : "");
  239. if (ebuf.s) {
  240. smart_str_free(&ebuf);
  241. }
  242. }
  243. retry = 0;
  244. errno = 0;
  245. }
  246. return retry;
  247. }
  248. /* }}} */
  249. static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) /* {{{ */
  250. {
  251. php_stream *stream;
  252. SSL *ssl;
  253. int err, depth, ret;
  254. zval *val;
  255. zend_ulong allowed_depth = OPENSSL_DEFAULT_STREAM_VERIFY_DEPTH;
  256. ret = preverify_ok;
  257. /* determine the status for the current cert */
  258. err = X509_STORE_CTX_get_error(ctx);
  259. depth = X509_STORE_CTX_get_error_depth(ctx);
  260. /* conjure the stream & context to use */
  261. ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
  262. stream = (php_stream*)SSL_get_ex_data(ssl, php_openssl_get_ssl_stream_data_index());
  263. /* if allow_self_signed is set, make sure that verification succeeds */
  264. if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT &&
  265. GET_VER_OPT("allow_self_signed") &&
  266. zend_is_true(val)
  267. ) {
  268. ret = 1;
  269. }
  270. /* check the depth */
  271. GET_VER_OPT_LONG("verify_depth", allowed_depth);
  272. if ((zend_ulong)depth > allowed_depth) {
  273. ret = 0;
  274. X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_CHAIN_TOO_LONG);
  275. }
  276. return ret;
  277. }
  278. /* }}} */
  279. static int php_openssl_x509_fingerprint_cmp(X509 *peer, const char *method, const char *expected)
  280. {
  281. zend_string *fingerprint;
  282. int result = -1;
  283. fingerprint = php_openssl_x509_fingerprint(peer, method, 0);
  284. if (fingerprint) {
  285. result = strcasecmp(expected, ZSTR_VAL(fingerprint));
  286. zend_string_release_ex(fingerprint, 0);
  287. }
  288. return result;
  289. }
  290. static bool php_openssl_x509_fingerprint_match(X509 *peer, zval *val)
  291. {
  292. if (Z_TYPE_P(val) == IS_STRING) {
  293. const char *method = NULL;
  294. switch (Z_STRLEN_P(val)) {
  295. case 32:
  296. method = "md5";
  297. break;
  298. case 40:
  299. method = "sha1";
  300. break;
  301. }
  302. return method && php_openssl_x509_fingerprint_cmp(peer, method, Z_STRVAL_P(val)) == 0;
  303. } else if (Z_TYPE_P(val) == IS_ARRAY) {
  304. zval *current;
  305. zend_string *key;
  306. if (!zend_hash_num_elements(Z_ARRVAL_P(val))) {
  307. php_error_docref(NULL, E_WARNING, "Invalid peer_fingerprint array; [algo => fingerprint] form required");
  308. return 0;
  309. }
  310. ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(val), key, current) {
  311. if (key == NULL || Z_TYPE_P(current) != IS_STRING) {
  312. php_error_docref(NULL, E_WARNING, "Invalid peer_fingerprint array; [algo => fingerprint] form required");
  313. return 0;
  314. }
  315. if (php_openssl_x509_fingerprint_cmp(peer, ZSTR_VAL(key), Z_STRVAL_P(current)) != 0) {
  316. return 0;
  317. }
  318. } ZEND_HASH_FOREACH_END();
  319. return 1;
  320. } else {
  321. php_error_docref(NULL, E_WARNING,
  322. "Invalid peer_fingerprint value; fingerprint string or array of the form [algo => fingerprint] required");
  323. }
  324. return 0;
  325. }
  326. static bool php_openssl_matches_wildcard_name(const char *subjectname, const char *certname) /* {{{ */
  327. {
  328. char *wildcard = NULL;
  329. ptrdiff_t prefix_len;
  330. size_t suffix_len, subject_len;
  331. if (strcasecmp(subjectname, certname) == 0) {
  332. return 1;
  333. }
  334. /* wildcard, if present, must only be present in the left-most component */
  335. if (!(wildcard = strchr(certname, '*')) || memchr(certname, '.', wildcard - certname)) {
  336. return 0;
  337. }
  338. /* 1) prefix, if not empty, must match subject */
  339. prefix_len = wildcard - certname;
  340. if (prefix_len && strncasecmp(subjectname, certname, prefix_len) != 0) {
  341. return 0;
  342. }
  343. suffix_len = strlen(wildcard + 1);
  344. subject_len = strlen(subjectname);
  345. if (suffix_len <= subject_len) {
  346. /* 2) suffix must match
  347. * 3) no . between prefix and suffix
  348. **/
  349. return strcasecmp(wildcard + 1, subjectname + subject_len - suffix_len) == 0 &&
  350. memchr(subjectname + prefix_len, '.', subject_len - suffix_len - prefix_len) == NULL;
  351. }
  352. return 0;
  353. }
  354. /* }}} */
  355. static bool php_openssl_matches_san_list(X509 *peer, const char *subject_name) /* {{{ */
  356. {
  357. int i, len;
  358. unsigned char *cert_name = NULL;
  359. char ipbuffer[64];
  360. GENERAL_NAMES *alt_names = X509_get_ext_d2i(peer, NID_subject_alt_name, 0, 0);
  361. int alt_name_count = sk_GENERAL_NAME_num(alt_names);
  362. for (i = 0; i < alt_name_count; i++) {
  363. GENERAL_NAME *san = sk_GENERAL_NAME_value(alt_names, i);
  364. if (san->type == GEN_DNS) {
  365. ASN1_STRING_to_UTF8(&cert_name, san->d.dNSName);
  366. if ((size_t)ASN1_STRING_length(san->d.dNSName) != strlen((const char*)cert_name)) {
  367. OPENSSL_free(cert_name);
  368. /* prevent null-byte poisoning*/
  369. continue;
  370. }
  371. /* accommodate valid FQDN entries ending in "." */
  372. len = strlen((const char*)cert_name);
  373. if (len && strcmp((const char *)&cert_name[len-1], ".") == 0) {
  374. cert_name[len-1] = '\0';
  375. }
  376. if (php_openssl_matches_wildcard_name(subject_name, (const char *)cert_name)) {
  377. OPENSSL_free(cert_name);
  378. sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
  379. return 1;
  380. }
  381. OPENSSL_free(cert_name);
  382. } else if (san->type == GEN_IPADD) {
  383. if (san->d.iPAddress->length == 4) {
  384. sprintf(ipbuffer, "%d.%d.%d.%d",
  385. san->d.iPAddress->data[0],
  386. san->d.iPAddress->data[1],
  387. san->d.iPAddress->data[2],
  388. san->d.iPAddress->data[3]
  389. );
  390. if (strcasecmp(subject_name, (const char*)ipbuffer) == 0) {
  391. sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
  392. return 1;
  393. }
  394. }
  395. /* No, we aren't bothering to check IPv6 addresses. Why?
  396. * Because IP SAN names are officially deprecated and are
  397. * not allowed by CAs starting in 2015. Deal with it.
  398. */
  399. }
  400. }
  401. sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
  402. return 0;
  403. }
  404. /* }}} */
  405. static bool php_openssl_matches_common_name(X509 *peer, const char *subject_name) /* {{{ */
  406. {
  407. char buf[1024];
  408. X509_NAME *cert_name;
  409. bool is_match = 0;
  410. int cert_name_len;
  411. cert_name = X509_get_subject_name(peer);
  412. cert_name_len = X509_NAME_get_text_by_NID(cert_name, NID_commonName, buf, sizeof(buf));
  413. if (cert_name_len == -1) {
  414. php_error_docref(NULL, E_WARNING, "Unable to locate peer certificate CN");
  415. } else if ((size_t)cert_name_len != strlen(buf)) {
  416. php_error_docref(NULL, E_WARNING, "Peer certificate CN=`%.*s' is malformed", cert_name_len, buf);
  417. } else if (php_openssl_matches_wildcard_name(subject_name, buf)) {
  418. is_match = 1;
  419. } else {
  420. php_error_docref(NULL, E_WARNING,
  421. "Peer certificate CN=`%.*s' did not match expected CN=`%s'",
  422. cert_name_len, buf, subject_name);
  423. }
  424. return is_match;
  425. }
  426. /* }}} */
  427. static int php_openssl_apply_peer_verification_policy(SSL *ssl, X509 *peer, php_stream *stream) /* {{{ */
  428. {
  429. zval *val = NULL;
  430. zval *peer_fingerprint;
  431. char *peer_name = NULL;
  432. int err,
  433. must_verify_peer,
  434. must_verify_peer_name,
  435. must_verify_fingerprint;
  436. php_openssl_netstream_data_t *sslsock = (php_openssl_netstream_data_t*)stream->abstract;
  437. must_verify_peer = GET_VER_OPT("verify_peer")
  438. ? zend_is_true(val)
  439. : sslsock->is_client;
  440. must_verify_peer_name = GET_VER_OPT("verify_peer_name")
  441. ? zend_is_true(val)
  442. : sslsock->is_client;
  443. must_verify_fingerprint = GET_VER_OPT("peer_fingerprint");
  444. peer_fingerprint = val;
  445. if ((must_verify_peer || must_verify_peer_name || must_verify_fingerprint) && peer == NULL) {
  446. php_error_docref(NULL, E_WARNING, "Could not get peer certificate");
  447. return FAILURE;
  448. }
  449. /* Verify the peer against using CA file/path settings */
  450. if (must_verify_peer) {
  451. err = SSL_get_verify_result(ssl);
  452. switch (err) {
  453. case X509_V_OK:
  454. /* fine */
  455. break;
  456. case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
  457. if (GET_VER_OPT("allow_self_signed") && zend_is_true(val)) {
  458. /* allowed */
  459. break;
  460. }
  461. /* not allowed, so fall through */
  462. ZEND_FALLTHROUGH;
  463. default:
  464. php_error_docref(NULL, E_WARNING,
  465. "Could not verify peer: code:%d %s",
  466. err,
  467. X509_verify_cert_error_string(err)
  468. );
  469. return FAILURE;
  470. }
  471. }
  472. /* If a peer_fingerprint match is required this trumps peer and peer_name verification */
  473. if (must_verify_fingerprint) {
  474. if (Z_TYPE_P(peer_fingerprint) == IS_STRING || Z_TYPE_P(peer_fingerprint) == IS_ARRAY) {
  475. if (!php_openssl_x509_fingerprint_match(peer, peer_fingerprint)) {
  476. php_error_docref(NULL, E_WARNING,
  477. "peer_fingerprint match failure"
  478. );
  479. return FAILURE;
  480. }
  481. } else {
  482. php_error_docref(NULL, E_WARNING,
  483. "Expected peer fingerprint must be a string or an array"
  484. );
  485. return FAILURE;
  486. }
  487. }
  488. /* verify the host name presented in the peer certificate */
  489. if (must_verify_peer_name) {
  490. GET_VER_OPT_STRING("peer_name", peer_name);
  491. /* If no peer name was specified we use the autodetected url name in client environments */
  492. if (peer_name == NULL && sslsock->is_client) {
  493. peer_name = sslsock->url_name;
  494. }
  495. if (peer_name) {
  496. if (php_openssl_matches_san_list(peer, peer_name)) {
  497. return SUCCESS;
  498. } else if (php_openssl_matches_common_name(peer, peer_name)) {
  499. return SUCCESS;
  500. } else {
  501. return FAILURE;
  502. }
  503. } else {
  504. return FAILURE;
  505. }
  506. }
  507. return SUCCESS;
  508. }
  509. /* }}} */
  510. static int php_openssl_passwd_callback(char *buf, int num, int verify, void *data) /* {{{ */
  511. {
  512. php_stream *stream = (php_stream *)data;
  513. zval *val = NULL;
  514. char *passphrase = NULL;
  515. /* TODO: could expand this to make a callback into PHP user-space */
  516. GET_VER_OPT_STRING("passphrase", passphrase);
  517. if (passphrase) {
  518. if (Z_STRLEN_P(val) < (size_t)num - 1) {
  519. memcpy(buf, Z_STRVAL_P(val), Z_STRLEN_P(val)+1);
  520. return (int)Z_STRLEN_P(val);
  521. }
  522. }
  523. return 0;
  524. }
  525. /* }}} */
  526. #ifdef PHP_WIN32
  527. #define RETURN_CERT_VERIFY_FAILURE(code) X509_STORE_CTX_set_error(x509_store_ctx, code); return 0;
  528. static int php_openssl_win_cert_verify_callback(X509_STORE_CTX *x509_store_ctx, void *arg) /* {{{ */
  529. {
  530. PCCERT_CONTEXT cert_ctx = NULL;
  531. PCCERT_CHAIN_CONTEXT cert_chain_ctx = NULL;
  532. #if OPENSSL_VERSION_NUMBER < 0x10100000L
  533. X509 *cert = x509_store_ctx->cert;
  534. #else
  535. X509 *cert = X509_STORE_CTX_get0_cert(x509_store_ctx);
  536. #endif
  537. php_stream *stream;
  538. php_openssl_netstream_data_t *sslsock;
  539. zval *val;
  540. bool is_self_signed = 0;
  541. stream = (php_stream*)arg;
  542. sslsock = (php_openssl_netstream_data_t*)stream->abstract;
  543. { /* First convert the x509 struct back to a DER encoded buffer and let Windows decode it into a form it can work with */
  544. unsigned char *der_buf = NULL;
  545. int der_len;
  546. der_len = i2d_X509(cert, &der_buf);
  547. if (der_len < 0) {
  548. unsigned long err_code, e;
  549. char err_buf[512];
  550. while ((e = ERR_get_error()) != 0) {
  551. err_code = e;
  552. }
  553. php_error_docref(NULL, E_WARNING, "Error encoding X509 certificate: %d: %s", err_code, ERR_error_string(err_code, err_buf));
  554. RETURN_CERT_VERIFY_FAILURE(SSL_R_CERTIFICATE_VERIFY_FAILED);
  555. }
  556. cert_ctx = CertCreateCertificateContext(X509_ASN_ENCODING, der_buf, der_len);
  557. OPENSSL_free(der_buf);
  558. if (cert_ctx == NULL) {
  559. char *err = php_win_err();
  560. php_error_docref(NULL, E_WARNING, "Error creating certificate context: %s", err);
  561. php_win_err_free(err);
  562. RETURN_CERT_VERIFY_FAILURE(SSL_R_CERTIFICATE_VERIFY_FAILED);
  563. }
  564. }
  565. { /* Next fetch the relevant cert chain from the store */
  566. CERT_ENHKEY_USAGE enhkey_usage = {0};
  567. CERT_USAGE_MATCH cert_usage = {0};
  568. CERT_CHAIN_PARA chain_params = {sizeof(CERT_CHAIN_PARA)};
  569. LPSTR usages[] = {szOID_PKIX_KP_SERVER_AUTH, szOID_SERVER_GATED_CRYPTO, szOID_SGC_NETSCAPE};
  570. DWORD chain_flags = 0;
  571. unsigned long allowed_depth = OPENSSL_DEFAULT_STREAM_VERIFY_DEPTH;
  572. unsigned int i;
  573. enhkey_usage.cUsageIdentifier = 3;
  574. enhkey_usage.rgpszUsageIdentifier = usages;
  575. cert_usage.dwType = USAGE_MATCH_TYPE_OR;
  576. cert_usage.Usage = enhkey_usage;
  577. chain_params.RequestedUsage = cert_usage;
  578. chain_flags = CERT_CHAIN_CACHE_END_CERT | CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT;
  579. if (!CertGetCertificateChain(NULL, cert_ctx, NULL, NULL, &chain_params, chain_flags, NULL, &cert_chain_ctx)) {
  580. char *err = php_win_err();
  581. php_error_docref(NULL, E_WARNING, "Error getting certificate chain: %s", err);
  582. php_win_err_free(err);
  583. CertFreeCertificateContext(cert_ctx);
  584. RETURN_CERT_VERIFY_FAILURE(SSL_R_CERTIFICATE_VERIFY_FAILED);
  585. }
  586. /* check if the cert is self-signed */
  587. if (cert_chain_ctx->cChain > 0 && cert_chain_ctx->rgpChain[0]->cElement > 0
  588. && (cert_chain_ctx->rgpChain[0]->rgpElement[0]->TrustStatus.dwInfoStatus & CERT_TRUST_IS_SELF_SIGNED) != 0) {
  589. is_self_signed = 1;
  590. }
  591. /* check the depth */
  592. GET_VER_OPT_LONG("verify_depth", allowed_depth);
  593. for (i = 0; i < cert_chain_ctx->cChain; i++) {
  594. if (cert_chain_ctx->rgpChain[i]->cElement > allowed_depth) {
  595. CertFreeCertificateChain(cert_chain_ctx);
  596. CertFreeCertificateContext(cert_ctx);
  597. RETURN_CERT_VERIFY_FAILURE(X509_V_ERR_CERT_CHAIN_TOO_LONG);
  598. }
  599. }
  600. }
  601. { /* Then verify it against a policy */
  602. SSL_EXTRA_CERT_CHAIN_POLICY_PARA ssl_policy_params = {sizeof(SSL_EXTRA_CERT_CHAIN_POLICY_PARA)};
  603. CERT_CHAIN_POLICY_PARA chain_policy_params = {sizeof(CERT_CHAIN_POLICY_PARA)};
  604. CERT_CHAIN_POLICY_STATUS chain_policy_status = {sizeof(CERT_CHAIN_POLICY_STATUS)};
  605. LPWSTR server_name = NULL;
  606. BOOL verify_result;
  607. ssl_policy_params.dwAuthType = (sslsock->is_client) ? AUTHTYPE_SERVER : AUTHTYPE_CLIENT;
  608. /* we validate the name ourselves using the peer_name
  609. ctx option, so no need to use a server name here */
  610. ssl_policy_params.pwszServerName = NULL;
  611. chain_policy_params.pvExtraPolicyPara = &ssl_policy_params;
  612. verify_result = CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_SSL, cert_chain_ctx, &chain_policy_params, &chain_policy_status);
  613. CertFreeCertificateChain(cert_chain_ctx);
  614. CertFreeCertificateContext(cert_ctx);
  615. if (!verify_result) {
  616. char *err = php_win_err();
  617. php_error_docref(NULL, E_WARNING, "Error verifying certificate chain policy: %s", err);
  618. php_win_err_free(err);
  619. RETURN_CERT_VERIFY_FAILURE(SSL_R_CERTIFICATE_VERIFY_FAILED);
  620. }
  621. if (chain_policy_status.dwError != 0) {
  622. /* The chain does not match the policy */
  623. if (is_self_signed && chain_policy_status.dwError == CERT_E_UNTRUSTEDROOT
  624. && GET_VER_OPT("allow_self_signed") && zend_is_true(val)) {
  625. /* allow self-signed certs */
  626. X509_STORE_CTX_set_error(x509_store_ctx, X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT);
  627. } else {
  628. RETURN_CERT_VERIFY_FAILURE(SSL_R_CERTIFICATE_VERIFY_FAILED);
  629. }
  630. }
  631. }
  632. return 1;
  633. }
  634. /* }}} */
  635. #endif
  636. static long php_openssl_load_stream_cafile(X509_STORE *cert_store, const char *cafile) /* {{{ */
  637. {
  638. php_stream *stream;
  639. X509 *cert;
  640. BIO *buffer;
  641. int buffer_active = 0;
  642. char *line = NULL;
  643. size_t line_len;
  644. long certs_added = 0;
  645. stream = php_stream_open_wrapper(cafile, "rb", 0, NULL);
  646. if (stream == NULL) {
  647. php_error(E_WARNING, "failed loading cafile stream: `%s'", cafile);
  648. return 0;
  649. } else if (stream->wrapper->is_url) {
  650. php_stream_close(stream);
  651. php_error(E_WARNING, "remote cafile streams are disabled for security purposes");
  652. return 0;
  653. }
  654. cert_start: {
  655. line = php_stream_get_line(stream, NULL, 0, &line_len);
  656. if (line == NULL) {
  657. goto stream_complete;
  658. } else if (!strcmp(line, "-----BEGIN CERTIFICATE-----\n") ||
  659. !strcmp(line, "-----BEGIN CERTIFICATE-----\r\n")
  660. ) {
  661. buffer = BIO_new(BIO_s_mem());
  662. buffer_active = 1;
  663. goto cert_line;
  664. } else {
  665. efree(line);
  666. goto cert_start;
  667. }
  668. }
  669. cert_line: {
  670. BIO_puts(buffer, line);
  671. efree(line);
  672. line = php_stream_get_line(stream, NULL, 0, &line_len);
  673. if (line == NULL) {
  674. goto stream_complete;
  675. } else if (!strcmp(line, "-----END CERTIFICATE-----") ||
  676. !strcmp(line, "-----END CERTIFICATE-----\n") ||
  677. !strcmp(line, "-----END CERTIFICATE-----\r\n")
  678. ) {
  679. goto add_cert;
  680. } else {
  681. goto cert_line;
  682. }
  683. }
  684. add_cert: {
  685. BIO_puts(buffer, line);
  686. efree(line);
  687. cert = PEM_read_bio_X509(buffer, NULL, 0, NULL);
  688. BIO_free(buffer);
  689. buffer_active = 0;
  690. if (cert && X509_STORE_add_cert(cert_store, cert)) {
  691. ++certs_added;
  692. X509_free(cert);
  693. }
  694. goto cert_start;
  695. }
  696. stream_complete: {
  697. php_stream_close(stream);
  698. if (buffer_active == 1) {
  699. BIO_free(buffer);
  700. }
  701. }
  702. if (certs_added == 0) {
  703. php_error(E_WARNING, "no valid certs found cafile stream: `%s'", cafile);
  704. }
  705. return certs_added;
  706. }
  707. /* }}} */
  708. static int php_openssl_enable_peer_verification(SSL_CTX *ctx, php_stream *stream) /* {{{ */
  709. {
  710. zval *val = NULL;
  711. char *cafile = NULL;
  712. char *capath = NULL;
  713. php_openssl_netstream_data_t *sslsock = (php_openssl_netstream_data_t*)stream->abstract;
  714. GET_VER_OPT_STRING("cafile", cafile);
  715. GET_VER_OPT_STRING("capath", capath);
  716. if (cafile == NULL) {
  717. cafile = zend_ini_string("openssl.cafile", sizeof("openssl.cafile")-1, 0);
  718. cafile = strlen(cafile) ? cafile : NULL;
  719. } else if (!sslsock->is_client) {
  720. /* Servers need to load and assign CA names from the cafile */
  721. STACK_OF(X509_NAME) *cert_names = SSL_load_client_CA_file(cafile);
  722. if (cert_names != NULL) {
  723. SSL_CTX_set_client_CA_list(ctx, cert_names);
  724. } else {
  725. php_error(E_WARNING, "SSL: failed loading CA names from cafile");
  726. return FAILURE;
  727. }
  728. }
  729. if (capath == NULL) {
  730. capath = zend_ini_string("openssl.capath", sizeof("openssl.capath")-1, 0);
  731. capath = strlen(capath) ? capath : NULL;
  732. }
  733. if (cafile || capath) {
  734. if (!SSL_CTX_load_verify_locations(ctx, cafile, capath)) {
  735. ERR_clear_error();
  736. if (cafile && !php_openssl_load_stream_cafile(SSL_CTX_get_cert_store(ctx), cafile)) {
  737. return FAILURE;
  738. }
  739. }
  740. } else {
  741. #ifdef PHP_WIN32
  742. SSL_CTX_set_cert_verify_callback(ctx, php_openssl_win_cert_verify_callback, (void *)stream);
  743. #else
  744. if (sslsock->is_client && !SSL_CTX_set_default_verify_paths(ctx)) {
  745. php_error_docref(NULL, E_WARNING,
  746. "Unable to set default verify locations and no CA settings specified");
  747. return FAILURE;
  748. }
  749. #endif
  750. }
  751. SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, verify_callback);
  752. return SUCCESS;
  753. }
  754. /* }}} */
  755. static void php_openssl_disable_peer_verification(SSL_CTX *ctx, php_stream *stream) /* {{{ */
  756. {
  757. SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
  758. }
  759. /* }}} */
  760. static int php_openssl_set_local_cert(SSL_CTX *ctx, php_stream *stream) /* {{{ */
  761. {
  762. zval *val = NULL;
  763. char *certfile = NULL;
  764. GET_VER_OPT_STRING("local_cert", certfile);
  765. if (certfile) {
  766. char resolved_path_buff[MAXPATHLEN];
  767. const char *private_key = NULL;
  768. if (VCWD_REALPATH(certfile, resolved_path_buff)) {
  769. /* a certificate to use for authentication */
  770. if (SSL_CTX_use_certificate_chain_file(ctx, resolved_path_buff) != 1) {
  771. php_error_docref(NULL, E_WARNING,
  772. "Unable to set local cert chain file `%s'; Check that your cafile/capath "
  773. "settings include details of your certificate and its issuer",
  774. certfile);
  775. return FAILURE;
  776. }
  777. GET_VER_OPT_STRING("local_pk", private_key);
  778. if (private_key) {
  779. char resolved_path_buff_pk[MAXPATHLEN];
  780. if (VCWD_REALPATH(private_key, resolved_path_buff_pk)) {
  781. if (SSL_CTX_use_PrivateKey_file(ctx, resolved_path_buff_pk, SSL_FILETYPE_PEM) != 1) {
  782. php_error_docref(NULL, E_WARNING, "Unable to set private key file `%s'", resolved_path_buff_pk);
  783. return FAILURE;
  784. }
  785. }
  786. } else {
  787. if (SSL_CTX_use_PrivateKey_file(ctx, resolved_path_buff, SSL_FILETYPE_PEM) != 1) {
  788. php_error_docref(NULL, E_WARNING, "Unable to set private key file `%s'", resolved_path_buff);
  789. return FAILURE;
  790. }
  791. }
  792. if (!SSL_CTX_check_private_key(ctx)) {
  793. php_error_docref(NULL, E_WARNING, "Private key does not match certificate!");
  794. }
  795. }
  796. }
  797. return SUCCESS;
  798. }
  799. /* }}} */
  800. #if PHP_OPENSSL_API_VERSION < 0x10100
  801. static int php_openssl_get_crypto_method_ctx_flags(int method_flags) /* {{{ */
  802. {
  803. int ssl_ctx_options = SSL_OP_ALL;
  804. #ifdef SSL_OP_NO_SSLv2
  805. ssl_ctx_options |= SSL_OP_NO_SSLv2;
  806. #endif
  807. #ifdef HAVE_SSL3
  808. if (!(method_flags & STREAM_CRYPTO_METHOD_SSLv3)) {
  809. ssl_ctx_options |= SSL_OP_NO_SSLv3;
  810. }
  811. #endif
  812. #ifdef HAVE_TLS1
  813. if (!(method_flags & STREAM_CRYPTO_METHOD_TLSv1_0)) {
  814. ssl_ctx_options |= SSL_OP_NO_TLSv1;
  815. }
  816. #endif
  817. #ifdef HAVE_TLS11
  818. if (!(method_flags & STREAM_CRYPTO_METHOD_TLSv1_1)) {
  819. ssl_ctx_options |= SSL_OP_NO_TLSv1_1;
  820. }
  821. #endif
  822. #ifdef HAVE_TLS12
  823. if (!(method_flags & STREAM_CRYPTO_METHOD_TLSv1_2)) {
  824. ssl_ctx_options |= SSL_OP_NO_TLSv1_2;
  825. }
  826. #endif
  827. #ifdef HAVE_TLS13
  828. if (!(method_flags & STREAM_CRYPTO_METHOD_TLSv1_3)) {
  829. ssl_ctx_options |= SSL_OP_NO_TLSv1_3;
  830. }
  831. #endif
  832. return ssl_ctx_options;
  833. }
  834. /* }}} */
  835. #endif
  836. static inline int php_openssl_get_min_proto_version_flag(int flags) /* {{{ */
  837. {
  838. int ver;
  839. for (ver = PHP_OPENSSL_MIN_PROTO_VERSION; ver <= PHP_OPENSSL_MAX_PROTO_VERSION; ver <<= 1) {
  840. if (flags & ver) {
  841. return ver;
  842. }
  843. }
  844. return PHP_OPENSSL_MAX_PROTO_VERSION;
  845. }
  846. /* }}} */
  847. static inline int php_openssl_get_max_proto_version_flag(int flags) /* {{{ */
  848. {
  849. int ver;
  850. for (ver = PHP_OPENSSL_MAX_PROTO_VERSION; ver >= PHP_OPENSSL_MIN_PROTO_VERSION; ver >>= 1) {
  851. if (flags & ver) {
  852. return ver;
  853. }
  854. }
  855. return STREAM_CRYPTO_METHOD_TLSv1_3;
  856. }
  857. /* }}} */
  858. #if PHP_OPENSSL_API_VERSION >= 0x10100
  859. static inline int php_openssl_map_proto_version(int flag) /* {{{ */
  860. {
  861. switch (flag) {
  862. #ifdef HAVE_TLS13
  863. case STREAM_CRYPTO_METHOD_TLSv1_3:
  864. return TLS1_3_VERSION;
  865. #endif
  866. case STREAM_CRYPTO_METHOD_TLSv1_2:
  867. return TLS1_2_VERSION;
  868. case STREAM_CRYPTO_METHOD_TLSv1_1:
  869. return TLS1_1_VERSION;
  870. case STREAM_CRYPTO_METHOD_TLSv1_0:
  871. return TLS1_VERSION;
  872. #ifdef HAVE_SSL3
  873. case STREAM_CRYPTO_METHOD_SSLv3:
  874. return SSL3_VERSION;
  875. #endif
  876. default:
  877. return TLS1_2_VERSION;
  878. }
  879. }
  880. /* }}} */
  881. static int php_openssl_get_min_proto_version(int flags) /* {{{ */
  882. {
  883. return php_openssl_map_proto_version(php_openssl_get_min_proto_version_flag(flags));
  884. }
  885. /* }}} */
  886. static int php_openssl_get_max_proto_version(int flags) /* {{{ */
  887. {
  888. return php_openssl_map_proto_version(php_openssl_get_max_proto_version_flag(flags));
  889. }
  890. /* }}} */
  891. #endif
  892. static int php_openssl_get_proto_version_flags(int flags, int min, int max) /* {{{ */
  893. {
  894. int ver;
  895. if (!min) {
  896. min = php_openssl_get_min_proto_version_flag(flags);
  897. }
  898. if (!max) {
  899. max = php_openssl_get_max_proto_version_flag(flags);
  900. }
  901. for (ver = PHP_OPENSSL_MIN_PROTO_VERSION; ver <= PHP_OPENSSL_MAX_PROTO_VERSION; ver <<= 1) {
  902. if (ver >= min && ver <= max) {
  903. if (!(flags & ver)) {
  904. flags |= ver;
  905. }
  906. } else if (flags & ver) {
  907. flags &= ~ver;
  908. }
  909. }
  910. return flags;
  911. }
  912. /* }}} */
  913. static void php_openssl_limit_handshake_reneg(const SSL *ssl) /* {{{ */
  914. {
  915. php_stream *stream;
  916. php_openssl_netstream_data_t *sslsock;
  917. struct timeval now;
  918. zend_long elapsed_time;
  919. stream = php_openssl_get_stream_from_ssl_handle(ssl);
  920. sslsock = (php_openssl_netstream_data_t*)stream->abstract;
  921. gettimeofday(&now, NULL);
  922. /* The initial handshake is never rate-limited */
  923. if (sslsock->reneg->prev_handshake == 0) {
  924. sslsock->reneg->prev_handshake = now.tv_sec;
  925. return;
  926. }
  927. elapsed_time = (now.tv_sec - sslsock->reneg->prev_handshake);
  928. sslsock->reneg->prev_handshake = now.tv_sec;
  929. sslsock->reneg->tokens -= (elapsed_time * (sslsock->reneg->limit / sslsock->reneg->window));
  930. if (sslsock->reneg->tokens < 0) {
  931. sslsock->reneg->tokens = 0;
  932. }
  933. ++sslsock->reneg->tokens;
  934. /* The token level exceeds our allowed limit */
  935. if (sslsock->reneg->tokens > sslsock->reneg->limit) {
  936. zval *val;
  937. sslsock->reneg->should_close = 1;
  938. if (PHP_STREAM_CONTEXT(stream) && (val = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream),
  939. "ssl", "reneg_limit_callback")) != NULL
  940. ) {
  941. zval param, retval;
  942. php_stream_to_zval(stream, &param);
  943. /* Closing the stream inside this callback would segfault! */
  944. stream->flags |= PHP_STREAM_FLAG_NO_FCLOSE;
  945. if (FAILURE == call_user_function(NULL, NULL, val, &retval, 1, &param)) {
  946. php_error(E_WARNING, "SSL: failed invoking reneg limit notification callback");
  947. }
  948. stream->flags ^= PHP_STREAM_FLAG_NO_FCLOSE;
  949. /* If the reneg_limit_callback returned true don't auto-close */
  950. if (Z_TYPE(retval) == IS_TRUE) {
  951. sslsock->reneg->should_close = 0;
  952. }
  953. zval_ptr_dtor(&retval);
  954. } else {
  955. php_error_docref(NULL, E_WARNING,
  956. "SSL: client-initiated handshake rate limit exceeded by peer");
  957. }
  958. }
  959. }
  960. /* }}} */
  961. static void php_openssl_info_callback(const SSL *ssl, int where, int ret) /* {{{ */
  962. {
  963. /* Rate-limit client-initiated handshake renegotiation to prevent DoS */
  964. if (where & SSL_CB_HANDSHAKE_START) {
  965. php_openssl_limit_handshake_reneg(ssl);
  966. }
  967. }
  968. /* }}} */
  969. static void php_openssl_init_server_reneg_limit(php_stream *stream, php_openssl_netstream_data_t *sslsock) /* {{{ */
  970. {
  971. zval *val;
  972. zend_long limit = OPENSSL_DEFAULT_RENEG_LIMIT;
  973. zend_long window = OPENSSL_DEFAULT_RENEG_WINDOW;
  974. if (PHP_STREAM_CONTEXT(stream) &&
  975. NULL != (val = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), "ssl", "reneg_limit"))
  976. ) {
  977. limit = zval_get_long(val);
  978. }
  979. /* No renegotiation rate-limiting */
  980. if (limit < 0) {
  981. return;
  982. }
  983. if (PHP_STREAM_CONTEXT(stream) &&
  984. NULL != (val = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), "ssl", "reneg_window"))
  985. ) {
  986. window = zval_get_long(val);
  987. }
  988. sslsock->reneg = (void*)pemalloc(sizeof(php_openssl_handshake_bucket_t),
  989. php_stream_is_persistent(stream)
  990. );
  991. sslsock->reneg->limit = limit;
  992. sslsock->reneg->window = window;
  993. sslsock->reneg->prev_handshake = 0;
  994. sslsock->reneg->tokens = 0;
  995. sslsock->reneg->should_close = 0;
  996. SSL_set_info_callback(sslsock->ssl_handle, php_openssl_info_callback);
  997. }
  998. /* }}} */
  999. #if PHP_OPENSSL_API_VERSION < 0x10100
  1000. static RSA *php_openssl_tmp_rsa_cb(SSL *s, int is_export, int keylength)
  1001. {
  1002. BIGNUM *bn = NULL;
  1003. static RSA *rsa_tmp = NULL;
  1004. if (!rsa_tmp && ((bn = BN_new()) == NULL)) {
  1005. php_error_docref(NULL, E_WARNING, "allocation error generating RSA key");
  1006. }
  1007. if (!rsa_tmp && bn) {
  1008. if (!BN_set_word(bn, RSA_F4) || ((rsa_tmp = RSA_new()) == NULL) ||
  1009. !RSA_generate_key_ex(rsa_tmp, keylength, bn, NULL)) {
  1010. if (rsa_tmp) {
  1011. RSA_free(rsa_tmp);
  1012. }
  1013. rsa_tmp = NULL;
  1014. }
  1015. BN_free(bn);
  1016. }
  1017. return (rsa_tmp);
  1018. }
  1019. #endif
  1020. static int php_openssl_set_server_dh_param(php_stream * stream, SSL_CTX *ctx) /* {{{ */
  1021. {
  1022. zval *zdhpath = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), "ssl", "dh_param");
  1023. if (zdhpath == NULL) {
  1024. #if 0
  1025. /* Coming in OpenSSL 1.1 ... eventually we'll want to enable this
  1026. * in the absence of an explicit dh_param.
  1027. */
  1028. SSL_CTX_set_dh_auto(ctx, 1);
  1029. #endif
  1030. return SUCCESS;
  1031. }
  1032. if (!try_convert_to_string(zdhpath)) {
  1033. return FAILURE;
  1034. }
  1035. BIO *bio = BIO_new_file(Z_STRVAL_P(zdhpath), PHP_OPENSSL_BIO_MODE_R(PKCS7_BINARY));
  1036. if (bio == NULL) {
  1037. php_error_docref(NULL, E_WARNING, "Invalid dh_param");
  1038. return FAILURE;
  1039. }
  1040. #if PHP_OPENSSL_API_VERSION >= 0x30000
  1041. EVP_PKEY *pkey = PEM_read_bio_Parameters(bio, NULL);
  1042. BIO_free(bio);
  1043. if (pkey == NULL) {
  1044. php_error_docref(NULL, E_WARNING, "Failed reading DH params");
  1045. return FAILURE;
  1046. }
  1047. if (SSL_CTX_set0_tmp_dh_pkey(ctx, pkey) < 0) {
  1048. php_error_docref(NULL, E_WARNING, "Failed assigning DH params");
  1049. EVP_PKEY_free(pkey);
  1050. return FAILURE;
  1051. }
  1052. #else
  1053. DH *dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
  1054. BIO_free(bio);
  1055. if (dh == NULL) {
  1056. php_error_docref(NULL, E_WARNING, "Failed reading DH params");
  1057. return FAILURE;
  1058. }
  1059. if (SSL_CTX_set_tmp_dh(ctx, dh) < 0) {
  1060. php_error_docref(NULL, E_WARNING, "Failed assigning DH params");
  1061. DH_free(dh);
  1062. return FAILURE;
  1063. }
  1064. DH_free(dh);
  1065. #endif
  1066. return SUCCESS;
  1067. }
  1068. /* }}} */
  1069. #if defined(HAVE_ECDH) && PHP_OPENSSL_API_VERSION < 0x10100
  1070. static int php_openssl_set_server_ecdh_curve(php_stream *stream, SSL_CTX *ctx) /* {{{ */
  1071. {
  1072. zval *zvcurve;
  1073. int curve_nid;
  1074. EC_KEY *ecdh;
  1075. zvcurve = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), "ssl", "ecdh_curve");
  1076. if (zvcurve == NULL) {
  1077. SSL_CTX_set_ecdh_auto(ctx, 1);
  1078. return SUCCESS;
  1079. } else {
  1080. if (!try_convert_to_string(zvcurve)) {
  1081. return FAILURE;
  1082. }
  1083. curve_nid = OBJ_sn2nid(Z_STRVAL_P(zvcurve));
  1084. if (curve_nid == NID_undef) {
  1085. php_error_docref(NULL, E_WARNING, "Invalid ecdh_curve specified");
  1086. return FAILURE;
  1087. }
  1088. }
  1089. ecdh = EC_KEY_new_by_curve_name(curve_nid);
  1090. if (ecdh == NULL) {
  1091. php_error_docref(NULL, E_WARNING, "Failed generating ECDH curve");
  1092. return FAILURE;
  1093. }
  1094. SSL_CTX_set_tmp_ecdh(ctx, ecdh);
  1095. EC_KEY_free(ecdh);
  1096. return SUCCESS;
  1097. }
  1098. /* }}} */
  1099. #endif
  1100. static int php_openssl_set_server_specific_opts(php_stream *stream, SSL_CTX *ctx) /* {{{ */
  1101. {
  1102. zval *zv;
  1103. long ssl_ctx_options = SSL_CTX_get_options(ctx);
  1104. #if defined(HAVE_ECDH) && PHP_OPENSSL_API_VERSION < 0x10100
  1105. if (php_openssl_set_server_ecdh_curve(stream, ctx) == FAILURE) {
  1106. return FAILURE;
  1107. }
  1108. #endif
  1109. #if PHP_OPENSSL_API_VERSION < 0x10100
  1110. SSL_CTX_set_tmp_rsa_callback(ctx, php_openssl_tmp_rsa_cb);
  1111. #endif
  1112. /* We now use php_openssl_tmp_rsa_cb to generate a key of appropriate size whenever necessary */
  1113. if (php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), "ssl", "rsa_key_size") != NULL) {
  1114. php_error_docref(NULL, E_WARNING, "rsa_key_size context option has been removed");
  1115. }
  1116. php_openssl_set_server_dh_param(stream, ctx);
  1117. zv = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), "ssl", "single_dh_use");
  1118. if (zv == NULL || zend_is_true(zv)) {
  1119. ssl_ctx_options |= SSL_OP_SINGLE_DH_USE;
  1120. }
  1121. zv = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), "ssl", "honor_cipher_order");
  1122. if (zv == NULL || zend_is_true(zv)) {
  1123. ssl_ctx_options |= SSL_OP_CIPHER_SERVER_PREFERENCE;
  1124. }
  1125. SSL_CTX_set_options(ctx, ssl_ctx_options);
  1126. return SUCCESS;
  1127. }
  1128. /* }}} */
  1129. #ifdef HAVE_TLS_SNI
  1130. static int php_openssl_server_sni_callback(SSL *ssl_handle, int *al, void *arg) /* {{{ */
  1131. {
  1132. php_stream *stream;
  1133. php_openssl_netstream_data_t *sslsock;
  1134. unsigned i;
  1135. const char *server_name;
  1136. server_name = SSL_get_servername(ssl_handle, TLSEXT_NAMETYPE_host_name);
  1137. if (!server_name) {
  1138. return SSL_TLSEXT_ERR_NOACK;
  1139. }
  1140. stream = (php_stream*)SSL_get_ex_data(ssl_handle, php_openssl_get_ssl_stream_data_index());
  1141. sslsock = (php_openssl_netstream_data_t*)stream->abstract;
  1142. if (!(sslsock->sni_cert_count && sslsock->sni_certs)) {
  1143. return SSL_TLSEXT_ERR_NOACK;
  1144. }
  1145. for (i=0; i < sslsock->sni_cert_count; i++) {
  1146. if (php_openssl_matches_wildcard_name(server_name, sslsock->sni_certs[i].name)) {
  1147. SSL_set_SSL_CTX(ssl_handle, sslsock->sni_certs[i].ctx);
  1148. return SSL_TLSEXT_ERR_OK;
  1149. }
  1150. }
  1151. return SSL_TLSEXT_ERR_NOACK;
  1152. }
  1153. /* }}} */
  1154. static SSL_CTX *php_openssl_create_sni_server_ctx(char *cert_path, char *key_path) /* {{{ */
  1155. {
  1156. /* The hello method is not inherited by SSL structs when assigning a new context
  1157. * inside the SNI callback, so the just use SSLv23 */
  1158. SSL_CTX *ctx = SSL_CTX_new(SSLv23_server_method());
  1159. if (SSL_CTX_use_certificate_chain_file(ctx, cert_path) != 1) {
  1160. php_error_docref(NULL, E_WARNING,
  1161. "Failed setting local cert chain file `%s'; " \
  1162. "check that your cafile/capath settings include " \
  1163. "details of your certificate and its issuer",
  1164. cert_path
  1165. );
  1166. SSL_CTX_free(ctx);
  1167. return NULL;
  1168. } else if (SSL_CTX_use_PrivateKey_file(ctx, key_path, SSL_FILETYPE_PEM) != 1) {
  1169. php_error_docref(NULL, E_WARNING,
  1170. "Failed setting private key from file `%s'",
  1171. key_path
  1172. );
  1173. SSL_CTX_free(ctx);
  1174. return NULL;
  1175. }
  1176. return ctx;
  1177. }
  1178. /* }}} */
  1179. static int php_openssl_enable_server_sni(php_stream *stream, php_openssl_netstream_data_t *sslsock) /* {{{ */
  1180. {
  1181. zval *val;
  1182. zval *current;
  1183. zend_string *key;
  1184. zend_ulong key_index;
  1185. int i = 0;
  1186. char resolved_path_buff[MAXPATHLEN];
  1187. SSL_CTX *ctx;
  1188. /* If the stream ctx disables SNI we're finished here */
  1189. if (GET_VER_OPT("SNI_enabled") && !zend_is_true(val)) {
  1190. return SUCCESS;
  1191. }
  1192. /* If no SNI cert array is specified we're finished here */
  1193. if (!GET_VER_OPT("SNI_server_certs")) {
  1194. return SUCCESS;
  1195. }
  1196. if (Z_TYPE_P(val) != IS_ARRAY) {
  1197. php_error_docref(NULL, E_WARNING,
  1198. "SNI_server_certs requires an array mapping host names to cert paths"
  1199. );
  1200. return FAILURE;
  1201. }
  1202. sslsock->sni_cert_count = zend_hash_num_elements(Z_ARRVAL_P(val));
  1203. if (sslsock->sni_cert_count == 0) {
  1204. php_error_docref(NULL, E_WARNING,
  1205. "SNI_server_certs host cert array must not be empty"
  1206. );
  1207. return FAILURE;
  1208. }
  1209. sslsock->sni_certs = (php_openssl_sni_cert_t*)safe_pemalloc(sslsock->sni_cert_count,
  1210. sizeof(php_openssl_sni_cert_t), 0, php_stream_is_persistent(stream)
  1211. );
  1212. memset(sslsock->sni_certs, 0, sslsock->sni_cert_count * sizeof(php_openssl_sni_cert_t));
  1213. ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(val), key_index, key, current) {
  1214. (void) key_index;
  1215. if (!key) {
  1216. php_error_docref(NULL, E_WARNING,
  1217. "SNI_server_certs array requires string host name keys"
  1218. );
  1219. return FAILURE;
  1220. }
  1221. if (Z_TYPE_P(current) == IS_ARRAY) {
  1222. zval *local_pk, *local_cert;
  1223. zend_string *local_pk_str, *local_cert_str;
  1224. char resolved_cert_path_buff[MAXPATHLEN], resolved_pk_path_buff[MAXPATHLEN];
  1225. local_cert = zend_hash_str_find(Z_ARRVAL_P(current), "local_cert", sizeof("local_cert")-1);
  1226. if (local_cert == NULL) {
  1227. php_error_docref(NULL, E_WARNING,
  1228. "local_cert not present in the array"
  1229. );
  1230. return FAILURE;
  1231. }
  1232. local_cert_str = zval_try_get_string(local_cert);
  1233. if (UNEXPECTED(!local_cert_str)) {
  1234. return FAILURE;
  1235. }
  1236. if (!VCWD_REALPATH(ZSTR_VAL(local_cert_str), resolved_cert_path_buff)) {
  1237. php_error_docref(NULL, E_WARNING,
  1238. "Failed setting local cert chain file `%s'; file not found",
  1239. ZSTR_VAL(local_cert_str)
  1240. );
  1241. zend_string_release(local_cert_str);
  1242. return FAILURE;
  1243. }
  1244. zend_string_release(local_cert_str);
  1245. local_pk = zend_hash_str_find(Z_ARRVAL_P(current), "local_pk", sizeof("local_pk")-1);
  1246. if (local_pk == NULL) {
  1247. php_error_docref(NULL, E_WARNING,
  1248. "local_pk not present in the array"
  1249. );
  1250. return FAILURE;
  1251. }
  1252. local_pk_str = zval_try_get_string(local_pk);
  1253. if (UNEXPECTED(!local_pk_str)) {
  1254. return FAILURE;
  1255. }
  1256. if (!VCWD_REALPATH(ZSTR_VAL(local_pk_str), resolved_pk_path_buff)) {
  1257. php_error_docref(NULL, E_WARNING,
  1258. "Failed setting local private key file `%s'; file not found",
  1259. ZSTR_VAL(local_pk_str)
  1260. );
  1261. zend_string_release(local_pk_str);
  1262. return FAILURE;
  1263. }
  1264. zend_string_release(local_pk_str);
  1265. ctx = php_openssl_create_sni_server_ctx(resolved_cert_path_buff, resolved_pk_path_buff);
  1266. } else if (VCWD_REALPATH(Z_STRVAL_P(current), resolved_path_buff)) {
  1267. ctx = php_openssl_create_sni_server_ctx(resolved_path_buff, resolved_path_buff);
  1268. } else {
  1269. php_error_docref(NULL, E_WARNING,
  1270. "Failed setting local cert chain file `%s'; file not found",
  1271. Z_STRVAL_P(current)
  1272. );
  1273. return FAILURE;
  1274. }
  1275. if (ctx == NULL) {
  1276. return FAILURE;
  1277. }
  1278. sslsock->sni_certs[i].name = pestrdup(ZSTR_VAL(key), php_stream_is_persistent(stream));
  1279. sslsock->sni_certs[i].ctx = ctx;
  1280. ++i;
  1281. } ZEND_HASH_FOREACH_END();
  1282. SSL_CTX_set_tlsext_servername_callback(sslsock->ctx, php_openssl_server_sni_callback);
  1283. return SUCCESS;
  1284. }
  1285. /* }}} */
  1286. static void php_openssl_enable_client_sni(php_stream *stream, php_openssl_netstream_data_t *sslsock) /* {{{ */
  1287. {
  1288. zval *val;
  1289. char *sni_server_name;
  1290. /* If SNI is explicitly disabled we're finished here */
  1291. if (GET_VER_OPT("SNI_enabled") && !zend_is_true(val)) {
  1292. return;
  1293. }
  1294. sni_server_name = sslsock->url_name;
  1295. GET_VER_OPT_STRING("peer_name", sni_server_name);
  1296. if (sni_server_name) {
  1297. SSL_set_tlsext_host_name(sslsock->ssl_handle, sni_server_name);
  1298. }
  1299. }
  1300. /* }}} */
  1301. #endif
  1302. #ifdef HAVE_TLS_ALPN
  1303. /**
  1304. * Parses a comma-separated list of strings into a string suitable for SSL_CTX_set_next_protos_advertised
  1305. * outlen: (output) set to the length of the resulting buffer on success.
  1306. * err: (maybe NULL) on failure, an error message line is written to this BIO.
  1307. * in: a NULL terminated string like "abc,def,ghi"
  1308. *
  1309. * returns: an emalloced buffer or NULL on failure.
  1310. */
  1311. static unsigned char *php_openssl_alpn_protos_parse(unsigned short *outlen, const char *in) /* {{{ */
  1312. {
  1313. size_t len;
  1314. unsigned char *out;
  1315. size_t i, start = 0;
  1316. len = strlen(in);
  1317. if (len >= 65535) {
  1318. return NULL;
  1319. }
  1320. out = emalloc(strlen(in) + 1);
  1321. for (i = 0; i <= len; ++i) {
  1322. if (i == len || in[i] == ',') {
  1323. if (i - start > 255) {
  1324. efree(out);
  1325. return NULL;
  1326. }
  1327. out[start] = i - start;
  1328. start = i + 1;
  1329. } else {
  1330. out[i + 1] = in[i];
  1331. }
  1332. }
  1333. *outlen = len + 1;
  1334. return out;
  1335. }
  1336. /* }}} */
  1337. static int php_openssl_server_alpn_callback(SSL *ssl_handle,
  1338. const unsigned char **out, unsigned char *outlen,
  1339. const unsigned char *in, unsigned int inlen, void *arg) /* {{{ */
  1340. {
  1341. php_openssl_netstream_data_t *sslsock = arg;
  1342. if (SSL_select_next_proto((unsigned char **)out, outlen, sslsock->alpn_ctx.data, sslsock->alpn_ctx.len, in, inlen) != OPENSSL_NPN_NEGOTIATED) {
  1343. return SSL_TLSEXT_ERR_NOACK;
  1344. }
  1345. return SSL_TLSEXT_ERR_OK;
  1346. }
  1347. /* }}} */
  1348. #endif
  1349. int php_openssl_setup_crypto(php_stream *stream,
  1350. php_openssl_netstream_data_t *sslsock,
  1351. php_stream_xport_crypto_param *cparam) /* {{{ */
  1352. {
  1353. const SSL_METHOD *method;
  1354. int ssl_ctx_options;
  1355. int method_flags;
  1356. zend_long min_version = 0;
  1357. zend_long max_version = 0;
  1358. char *cipherlist = NULL;
  1359. char *alpn_protocols = NULL;
  1360. zval *val;
  1361. if (sslsock->ssl_handle) {
  1362. if (sslsock->s.is_blocked) {
  1363. php_error_docref(NULL, E_WARNING, "SSL/TLS already set-up for this stream");
  1364. return FAILURE;
  1365. } else {
  1366. return SUCCESS;
  1367. }
  1368. }
  1369. ERR_clear_error();
  1370. /* We need to do slightly different things based on client/server method
  1371. * so lets remember which method was selected */
  1372. sslsock->is_client = cparam->inputs.method & STREAM_CRYPTO_IS_CLIENT;
  1373. method_flags = ((cparam->inputs.method >> 1) << 1);
  1374. method = sslsock->is_client ? SSLv23_client_method() : SSLv23_server_method();
  1375. sslsock->ctx = SSL_CTX_new(method);
  1376. GET_VER_OPT_LONG("min_proto_version", min_version);
  1377. GET_VER_OPT_LONG("max_proto_version", max_version);
  1378. method_flags = php_openssl_get_proto_version_flags(method_flags, min_version, max_version);
  1379. #if PHP_OPENSSL_API_VERSION < 0x10100
  1380. ssl_ctx_options = php_openssl_get_crypto_method_ctx_flags(method_flags);
  1381. #else
  1382. ssl_ctx_options = SSL_OP_ALL;
  1383. #endif
  1384. if (sslsock->ctx == NULL) {
  1385. php_error_docref(NULL, E_WARNING, "SSL context creation failure");
  1386. return FAILURE;
  1387. }
  1388. if (GET_VER_OPT("no_ticket") && zend_is_true(val)) {
  1389. ssl_ctx_options |= SSL_OP_NO_TICKET;
  1390. }
  1391. ssl_ctx_options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
  1392. #ifdef SSL_OP_IGNORE_UNEXPECTED_EOF
  1393. /* Only for OpenSSL 3+ to keep OpenSSL 1.1.1 behavior */
  1394. ssl_ctx_options |= SSL_OP_IGNORE_UNEXPECTED_EOF;
  1395. #endif
  1396. if (!GET_VER_OPT("disable_compression") || zend_is_true(val)) {
  1397. ssl_ctx_options |= SSL_OP_NO_COMPRESSION;
  1398. }
  1399. if (GET_VER_OPT("verify_peer") && !zend_is_true(val)) {
  1400. php_openssl_disable_peer_verification(sslsock->ctx, stream);
  1401. } else if (FAILURE == php_openssl_enable_peer_verification(sslsock->ctx, stream)) {
  1402. return FAILURE;
  1403. }
  1404. /* callback for the passphrase (for localcert) */
  1405. if (GET_VER_OPT("passphrase")) {
  1406. SSL_CTX_set_default_passwd_cb_userdata(sslsock->ctx, stream);
  1407. SSL_CTX_set_default_passwd_cb(sslsock->ctx, php_openssl_passwd_callback);
  1408. }
  1409. GET_VER_OPT_STRING("ciphers", cipherlist);
  1410. #ifndef USE_OPENSSL_SYSTEM_CIPHERS
  1411. if (!cipherlist) {
  1412. cipherlist = OPENSSL_DEFAULT_STREAM_CIPHERS;
  1413. }
  1414. #endif
  1415. if (cipherlist) {
  1416. if (SSL_CTX_set_cipher_list(sslsock->ctx, cipherlist) != 1) {
  1417. return FAILURE;
  1418. }
  1419. }
  1420. if (GET_VER_OPT("security_level")) {
  1421. zend_long lval = zval_get_long(val);
  1422. if (lval < 0 || lval > 5) {
  1423. php_error_docref(NULL, E_WARNING, "Security level must be between 0 and 5");
  1424. }
  1425. #ifdef HAVE_SEC_LEVEL
  1426. SSL_CTX_set_security_level(sslsock->ctx, lval);
  1427. #endif
  1428. }
  1429. GET_VER_OPT_STRING("alpn_protocols", alpn_protocols);
  1430. if (alpn_protocols) {
  1431. #ifdef HAVE_TLS_ALPN
  1432. {
  1433. unsigned short alpn_len;
  1434. unsigned char *alpn = php_openssl_alpn_protos_parse(&alpn_len, alpn_protocols);
  1435. if (alpn == NULL) {
  1436. php_error_docref(NULL, E_WARNING, "Failed parsing comma-separated TLS ALPN protocol string");
  1437. SSL_CTX_free(sslsock->ctx);
  1438. sslsock->ctx = NULL;
  1439. return FAILURE;
  1440. }
  1441. if (sslsock->is_client) {
  1442. SSL_CTX_set_alpn_protos(sslsock->ctx, alpn, alpn_len);
  1443. } else {
  1444. sslsock->alpn_ctx.data = (unsigned char *) pestrndup((const char*)alpn, alpn_len, php_stream_is_persistent(stream));
  1445. sslsock->alpn_ctx.len = alpn_len;
  1446. SSL_CTX_set_alpn_select_cb(sslsock->ctx, php_openssl_server_alpn_callback, sslsock);
  1447. }
  1448. efree(alpn);
  1449. }
  1450. #else
  1451. php_error_docref(NULL, E_WARNING,
  1452. "alpn_protocols support is not compiled into the OpenSSL library against which PHP is linked");
  1453. #endif
  1454. }
  1455. if (FAILURE == php_openssl_set_local_cert(sslsock->ctx, stream)) {
  1456. return FAILURE;
  1457. }
  1458. SSL_CTX_set_options(sslsock->ctx, ssl_ctx_options);
  1459. #if PHP_OPENSSL_API_VERSION >= 0x10100
  1460. SSL_CTX_set_min_proto_version(sslsock->ctx, php_openssl_get_min_proto_version(method_flags));
  1461. SSL_CTX_set_max_proto_version(sslsock->ctx, php_openssl_get_max_proto_version(method_flags));
  1462. #endif
  1463. if (sslsock->is_client == 0 &&
  1464. PHP_STREAM_CONTEXT(stream) &&
  1465. FAILURE == php_openssl_set_server_specific_opts(stream, sslsock->ctx)
  1466. ) {
  1467. return FAILURE;
  1468. }
  1469. sslsock->ssl_handle = SSL_new(sslsock->ctx);
  1470. if (sslsock->ssl_handle == NULL) {
  1471. php_error_docref(NULL, E_WARNING, "SSL handle creation failure");
  1472. SSL_CTX_free(sslsock->ctx);
  1473. sslsock->ctx = NULL;
  1474. #ifdef HAVE_TLS_ALPN
  1475. if (sslsock->alpn_ctx.data) {
  1476. pefree(sslsock->alpn_ctx.data, php_stream_is_persistent(stream));
  1477. sslsock->alpn_ctx.data = NULL;
  1478. }
  1479. #endif
  1480. return FAILURE;
  1481. } else {
  1482. SSL_set_ex_data(sslsock->ssl_handle, php_openssl_get_ssl_stream_data_index(), stream);
  1483. }
  1484. if (!SSL_set_fd(sslsock->ssl_handle, sslsock->s.socket)) {
  1485. php_openssl_handle_ssl_error(stream, 0, 1);
  1486. }
  1487. #ifdef HAVE_TLS_SNI
  1488. /* Enable server-side SNI */
  1489. if (!sslsock->is_client && php_openssl_enable_server_sni(stream, sslsock) == FAILURE) {
  1490. return FAILURE;
  1491. }
  1492. #endif
  1493. /* Enable server-side handshake renegotiation rate-limiting */
  1494. if (!sslsock->is_client) {
  1495. php_openssl_init_server_reneg_limit(stream, sslsock);
  1496. }
  1497. #ifdef SSL_MODE_RELEASE_BUFFERS
  1498. SSL_set_mode(sslsock->ssl_handle, SSL_get_mode(sslsock->ssl_handle) | SSL_MODE_RELEASE_BUFFERS);
  1499. #endif
  1500. if (cparam->inputs.session) {
  1501. if (cparam->inputs.session->ops != &php_openssl_socket_ops) {
  1502. php_error_docref(NULL, E_WARNING, "Supplied session stream must be an SSL enabled stream");
  1503. } else if (((php_openssl_netstream_data_t*)cparam->inputs.session->abstract)->ssl_handle == NULL) {
  1504. php_error_docref(NULL, E_WARNING, "Supplied SSL session stream is not initialized");
  1505. } else {
  1506. SSL_copy_session_id(sslsock->ssl_handle, ((php_openssl_netstream_data_t*)cparam->inputs.session->abstract)->ssl_handle);
  1507. }
  1508. }
  1509. return SUCCESS;
  1510. }
  1511. /* }}} */
  1512. static int php_openssl_capture_peer_certs(php_stream *stream,
  1513. php_openssl_netstream_data_t *sslsock, X509 *peer_cert) /* {{{ */
  1514. {
  1515. zval *val, zcert;
  1516. php_openssl_certificate_object *cert_object;
  1517. int cert_captured = 0;
  1518. if (NULL != (val = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream),
  1519. "ssl", "capture_peer_cert")) &&
  1520. zend_is_true(val)
  1521. ) {
  1522. object_init_ex(&zcert, php_openssl_certificate_ce);
  1523. cert_object = Z_OPENSSL_CERTIFICATE_P(&zcert);
  1524. cert_object->x509 = peer_cert;
  1525. php_stream_context_set_option(PHP_STREAM_CONTEXT(stream), "ssl", "peer_certificate", &zcert);
  1526. zval_ptr_dtor(&zcert);
  1527. cert_captured = 1;
  1528. }
  1529. if (NULL != (val = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream),
  1530. "ssl", "capture_peer_cert_chain")) &&
  1531. zend_is_true(val)
  1532. ) {
  1533. zval arr;
  1534. STACK_OF(X509) *chain;
  1535. chain = SSL_get_peer_cert_chain(sslsock->ssl_handle);
  1536. if (chain && sk_X509_num(chain) > 0) {
  1537. int i;
  1538. array_init(&arr);
  1539. for (i = 0; i < sk_X509_num(chain); i++) {
  1540. X509 *mycert = X509_dup(sk_X509_value(chain, i));
  1541. object_init_ex(&zcert, php_openssl_certificate_ce);
  1542. cert_object = Z_OPENSSL_CERTIFICATE_P(&zcert);
  1543. cert_object->x509 = mycert;
  1544. add_next_index_zval(&arr, &zcert);
  1545. }
  1546. } else {
  1547. ZVAL_NULL(&arr);
  1548. }
  1549. php_stream_context_set_option(PHP_STREAM_CONTEXT(stream), "ssl", "peer_certificate_chain", &arr);
  1550. zval_ptr_dtor(&arr);
  1551. }
  1552. return cert_captured;
  1553. }
  1554. /* }}} */
  1555. static int php_openssl_enable_crypto(php_stream *stream,
  1556. php_openssl_netstream_data_t *sslsock,
  1557. php_stream_xport_crypto_param *cparam) /* {{{ */
  1558. {
  1559. int n;
  1560. int retry = 1;
  1561. int cert_captured = 0;
  1562. X509 *peer_cert;
  1563. if (cparam->inputs.activate && !sslsock->ssl_active) {
  1564. struct timeval start_time, *timeout;
  1565. int blocked = sslsock->s.is_blocked, has_timeout = 0;
  1566. #ifdef HAVE_TLS_SNI
  1567. if (sslsock->is_client) {
  1568. php_openssl_enable_client_sni(stream, sslsock);
  1569. }
  1570. #endif
  1571. if (!sslsock->state_set) {
  1572. if (sslsock->is_client) {
  1573. SSL_set_connect_state(sslsock->ssl_handle);
  1574. } else {
  1575. SSL_set_accept_state(sslsock->ssl_handle);
  1576. }
  1577. sslsock->state_set = 1;
  1578. }
  1579. if (SUCCESS == php_set_sock_blocking(sslsock->s.socket, 0)) {
  1580. sslsock->s.is_blocked = 0;
  1581. /* The following mode are added only if we are able to change socket
  1582. * to non blocking mode which is also used for read and write */
  1583. SSL_set_mode(
  1584. sslsock->ssl_handle,
  1585. (
  1586. SSL_get_mode(sslsock->ssl_handle) |
  1587. SSL_MODE_ENABLE_PARTIAL_WRITE |
  1588. SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER
  1589. )
  1590. );
  1591. }
  1592. timeout = sslsock->is_client ? &sslsock->connect_timeout : &sslsock->s.timeout;
  1593. has_timeout = !sslsock->s.is_blocked && (timeout->tv_sec > 0 || (timeout->tv_sec == 0 && timeout->tv_usec));
  1594. /* gettimeofday is not monotonic; using it here is not strictly correct */
  1595. if (has_timeout) {
  1596. gettimeofday(&start_time, NULL);
  1597. }
  1598. do {
  1599. struct timeval cur_time, elapsed_time;
  1600. ERR_clear_error();
  1601. if (sslsock->is_client) {
  1602. n = SSL_connect(sslsock->ssl_handle);
  1603. } else {
  1604. n = SSL_accept(sslsock->ssl_handle);
  1605. }
  1606. if (has_timeout) {
  1607. gettimeofday(&cur_time, NULL);
  1608. elapsed_time = php_openssl_subtract_timeval(cur_time, start_time);
  1609. if (php_openssl_compare_timeval( elapsed_time, *timeout) > 0) {
  1610. php_error_docref(NULL, E_WARNING, "SSL: Handshake timed out");
  1611. return -1;
  1612. }
  1613. }
  1614. if (n <= 0) {
  1615. /* in case of SSL_ERROR_WANT_READ/WRITE, do not retry in non-blocking mode */
  1616. retry = php_openssl_handle_ssl_error(stream, n, blocked);
  1617. if (retry) {
  1618. /* wait until something interesting happens in the socket. It may be a
  1619. * timeout. Also consider the unlikely of possibility of a write block */
  1620. int err = SSL_get_error(sslsock->ssl_handle, n);
  1621. struct timeval left_time;
  1622. if (has_timeout) {
  1623. left_time = php_openssl_subtract_timeval(*timeout, elapsed_time);
  1624. }
  1625. php_pollfd_for(sslsock->s.socket, (err == SSL_ERROR_WANT_READ) ?
  1626. (POLLIN|POLLPRI) : POLLOUT, has_timeout ? &left_time : NULL);
  1627. }
  1628. } else {
  1629. retry = 0;
  1630. }
  1631. } while (retry);
  1632. if (sslsock->s.is_blocked != blocked && SUCCESS == php_set_sock_blocking(sslsock->s.socket, blocked)) {
  1633. sslsock->s.is_blocked = blocked;
  1634. }
  1635. if (n == 1) {
  1636. peer_cert = SSL_get_peer_certificate(sslsock->ssl_handle);
  1637. if (peer_cert && PHP_STREAM_CONTEXT(stream)) {
  1638. cert_captured = php_openssl_capture_peer_certs(stream, sslsock, peer_cert);
  1639. }
  1640. if (FAILURE == php_openssl_apply_peer_verification_policy(sslsock->ssl_handle, peer_cert, stream)) {
  1641. SSL_shutdown(sslsock->ssl_handle);
  1642. n = -1;
  1643. } else {
  1644. sslsock->ssl_active = 1;
  1645. }
  1646. } else if (errno == EAGAIN) {
  1647. n = 0;
  1648. } else {
  1649. n = -1;
  1650. /* We want to capture the peer cert even if verification fails*/
  1651. peer_cert = SSL_get_peer_certificate(sslsock->ssl_handle);
  1652. if (peer_cert && PHP_STREAM_CONTEXT(stream)) {
  1653. cert_captured = php_openssl_capture_peer_certs(stream, sslsock, peer_cert);
  1654. }
  1655. }
  1656. if (n && peer_cert && cert_captured == 0) {
  1657. X509_free(peer_cert);
  1658. }
  1659. return n;
  1660. } else if (!cparam->inputs.activate && sslsock->ssl_active) {
  1661. /* deactivate - common for server/client */
  1662. SSL_shutdown(sslsock->ssl_handle);
  1663. sslsock->ssl_active = 0;
  1664. }
  1665. return -1;
  1666. }
  1667. /* }}} */
  1668. static ssize_t php_openssl_sockop_read(php_stream *stream, char *buf, size_t count) /* {{{ */
  1669. {
  1670. return php_openssl_sockop_io( 1, stream, buf, count );
  1671. }
  1672. /* }}} */
  1673. static ssize_t php_openssl_sockop_write(php_stream *stream, const char *buf, size_t count) /* {{{ */
  1674. {
  1675. return php_openssl_sockop_io( 0, stream, (char*)buf, count );
  1676. }
  1677. /* }}} */
  1678. /**
  1679. * Factored out common functionality (blocking, timeout, loop management) for read and write.
  1680. * Perform IO (read or write) to an SSL socket. If we have a timeout, we switch to non-blocking mode
  1681. * for the duration of the operation, using select to do our waits. If we time out, or we have an error
  1682. * report that back to PHP
  1683. */
  1684. static ssize_t php_openssl_sockop_io(int read, php_stream *stream, char *buf, size_t count) /* {{{ */
  1685. {
  1686. php_openssl_netstream_data_t *sslsock = (php_openssl_netstream_data_t*)stream->abstract;
  1687. /* Only do this if SSL is active. */
  1688. if (sslsock->ssl_active) {
  1689. int retry = 1;
  1690. struct timeval start_time;
  1691. struct timeval *timeout = NULL;
  1692. int began_blocked = sslsock->s.is_blocked;
  1693. int has_timeout = 0;
  1694. int nr_bytes = 0;
  1695. /* prevent overflow in openssl */
  1696. if (count > INT_MAX) {
  1697. count = INT_MAX;
  1698. }
  1699. /* never use a timeout with non-blocking sockets */
  1700. if (began_blocked) {
  1701. timeout = &sslsock->s.timeout;
  1702. }
  1703. if (timeout && php_set_sock_blocking(sslsock->s.socket, 0) == SUCCESS) {
  1704. sslsock->s.is_blocked = 0;
  1705. }
  1706. if (!sslsock->s.is_blocked && timeout && (timeout->tv_sec > 0 || (timeout->tv_sec == 0 && timeout->tv_usec))) {
  1707. has_timeout = 1;
  1708. /* gettimeofday is not monotonic; using it here is not strictly correct */
  1709. gettimeofday(&start_time, NULL);
  1710. }
  1711. /* Main IO loop. */
  1712. do {
  1713. struct timeval cur_time, elapsed_time, left_time;
  1714. /* If we have a timeout to check, figure out how much time has elapsed since we started. */
  1715. if (has_timeout) {
  1716. gettimeofday(&cur_time, NULL);
  1717. /* Determine how much time we've taken so far. */
  1718. elapsed_time = php_openssl_subtract_timeval(cur_time, start_time);
  1719. /* and return an error if we've taken too long. */
  1720. if (php_openssl_compare_timeval(elapsed_time, *timeout) > 0 ) {
  1721. /* If the socket was originally blocking, set it back. */
  1722. if (began_blocked) {
  1723. php_set_sock_blocking(sslsock->s.socket, 1);
  1724. sslsock->s.is_blocked = 1;
  1725. }
  1726. sslsock->s.timeout_event = 1;
  1727. return -1;
  1728. }
  1729. }
  1730. /* Now, do the IO operation. Don't block if we can't complete... */
  1731. ERR_clear_error();
  1732. if (read) {
  1733. nr_bytes = SSL_read(sslsock->ssl_handle, buf, (int)count);
  1734. if (sslsock->reneg && sslsock->reneg->should_close) {
  1735. /* renegotiation rate limiting triggered */
  1736. php_stream_xport_shutdown(stream, (stream_shutdown_t)SHUT_RDWR);
  1737. nr_bytes = 0;
  1738. stream->eof = 1;
  1739. break;
  1740. }
  1741. } else {
  1742. nr_bytes = SSL_write(sslsock->ssl_handle, buf, (int)count);
  1743. }
  1744. /* Now, how much time until we time out? */
  1745. if (has_timeout) {
  1746. left_time = php_openssl_subtract_timeval( *timeout, elapsed_time );
  1747. }
  1748. /* If we didn't do anything on the last loop (or an error) check to see if we should retry or exit. */
  1749. if (nr_bytes <= 0) {
  1750. /* Get the error code from SSL, and check to see if it's an error or not. */
  1751. int err = SSL_get_error(sslsock->ssl_handle, nr_bytes );
  1752. retry = php_openssl_handle_ssl_error(stream, nr_bytes, 0);
  1753. /* If we get this (the above doesn't check) then we'll retry as well. */
  1754. if (errno == EAGAIN && err == SSL_ERROR_WANT_READ && read) {
  1755. retry = 1;
  1756. }
  1757. if (errno == EAGAIN && err == SSL_ERROR_WANT_WRITE && read == 0) {
  1758. retry = 1;
  1759. }
  1760. /* Also, on reads, we may get this condition on an EOF. We should check properly. */
  1761. if (read) {
  1762. stream->eof = (retry == 0 && errno != EAGAIN && !SSL_pending(sslsock->ssl_handle));
  1763. }
  1764. /* Don't loop indefinitely in non-blocking mode if no data is available */
  1765. if (began_blocked == 0) {
  1766. break;
  1767. }
  1768. /* Now, if we have to wait some time, and we're supposed to be blocking, wait for the socket to become
  1769. * available. Now, php_pollfd_for uses select to wait up to our time_left value only...
  1770. */
  1771. if (retry) {
  1772. if (read) {
  1773. php_pollfd_for(sslsock->s.socket, (err == SSL_ERROR_WANT_WRITE) ?
  1774. (POLLOUT|POLLPRI) : (POLLIN|POLLPRI), has_timeout ? &left_time : NULL);
  1775. } else {
  1776. php_pollfd_for(sslsock->s.socket, (err == SSL_ERROR_WANT_READ) ?
  1777. (POLLIN|POLLPRI) : (POLLOUT|POLLPRI), has_timeout ? &left_time : NULL);
  1778. }
  1779. }
  1780. } else {
  1781. /* Else, if we got bytes back, check for possible errors. */
  1782. int err = SSL_get_error(sslsock->ssl_handle, nr_bytes);
  1783. /* If we didn't get any error, then let's return it to PHP. */
  1784. if (err == SSL_ERROR_NONE) {
  1785. break;
  1786. }
  1787. /* Otherwise, we need to wait again (up to time_left or we get an error) */
  1788. if (began_blocked) {
  1789. if (read) {
  1790. php_pollfd_for(sslsock->s.socket, (err == SSL_ERROR_WANT_WRITE) ?
  1791. (POLLOUT|POLLPRI) : (POLLIN|POLLPRI), has_timeout ? &left_time : NULL);
  1792. } else {
  1793. php_pollfd_for(sslsock->s.socket, (err == SSL_ERROR_WANT_READ) ?
  1794. (POLLIN|POLLPRI) : (POLLOUT|POLLPRI), has_timeout ? &left_time : NULL);
  1795. }
  1796. }
  1797. }
  1798. /* Finally, we keep going until we got data, and an SSL_ERROR_NONE, unless we had an error. */
  1799. } while (retry);
  1800. /* Tell PHP if we read / wrote bytes. */
  1801. if (nr_bytes > 0) {
  1802. php_stream_notify_progress_increment(PHP_STREAM_CONTEXT(stream), nr_bytes, 0);
  1803. }
  1804. /* And if we were originally supposed to be blocking, let's reset the socket to that. */
  1805. if (began_blocked && php_set_sock_blocking(sslsock->s.socket, 1) == SUCCESS) {
  1806. sslsock->s.is_blocked = 1;
  1807. }
  1808. return 0 > nr_bytes ? 0 : nr_bytes;
  1809. } else {
  1810. size_t nr_bytes = 0;
  1811. /* This block is if we had no timeout... We will just sit and wait forever on the IO operation. */
  1812. if (read) {
  1813. nr_bytes = php_stream_socket_ops.read(stream, buf, count);
  1814. } else {
  1815. nr_bytes = php_stream_socket_ops.write(stream, buf, count);
  1816. }
  1817. return nr_bytes;
  1818. }
  1819. }
  1820. /* }}} */
  1821. static struct timeval php_openssl_subtract_timeval(struct timeval a, struct timeval b) /* {{{ */
  1822. {
  1823. struct timeval difference;
  1824. difference.tv_sec = a.tv_sec - b.tv_sec;
  1825. difference.tv_usec = a.tv_usec - b.tv_usec;
  1826. if (a.tv_usec < b.tv_usec) {
  1827. difference.tv_sec -= 1L;
  1828. difference.tv_usec += 1000000L;
  1829. }
  1830. return difference;
  1831. }
  1832. /* }}} */
  1833. static int php_openssl_compare_timeval( struct timeval a, struct timeval b )
  1834. {
  1835. if (a.tv_sec > b.tv_sec || (a.tv_sec == b.tv_sec && a.tv_usec > b.tv_usec) ) {
  1836. return 1;
  1837. } else if( a.tv_sec == b.tv_sec && a.tv_usec == b.tv_usec ) {
  1838. return 0;
  1839. } else {
  1840. return -1;
  1841. }
  1842. }
  1843. static int php_openssl_sockop_close(php_stream *stream, int close_handle) /* {{{ */
  1844. {
  1845. php_openssl_netstream_data_t *sslsock = (php_openssl_netstream_data_t*)stream->abstract;
  1846. #ifdef PHP_WIN32
  1847. int n;
  1848. #endif
  1849. unsigned i;
  1850. if (close_handle) {
  1851. if (sslsock->ssl_active) {
  1852. SSL_shutdown(sslsock->ssl_handle);
  1853. sslsock->ssl_active = 0;
  1854. }
  1855. if (sslsock->ssl_handle) {
  1856. SSL_free(sslsock->ssl_handle);
  1857. sslsock->ssl_handle = NULL;
  1858. }
  1859. if (sslsock->ctx) {
  1860. SSL_CTX_free(sslsock->ctx);
  1861. sslsock->ctx = NULL;
  1862. }
  1863. #ifdef HAVE_TLS_ALPN
  1864. if (sslsock->alpn_ctx.data) {
  1865. pefree(sslsock->alpn_ctx.data, php_stream_is_persistent(stream));
  1866. }
  1867. #endif
  1868. #ifdef PHP_WIN32
  1869. if (sslsock->s.socket == -1)
  1870. sslsock->s.socket = SOCK_ERR;
  1871. #endif
  1872. if (sslsock->s.socket != SOCK_ERR) {
  1873. #ifdef PHP_WIN32
  1874. /* prevent more data from coming in */
  1875. shutdown(sslsock->s.socket, SHUT_RD);
  1876. /* try to make sure that the OS sends all data before we close the connection.
  1877. * Essentially, we are waiting for the socket to become writeable, which means
  1878. * that all pending data has been sent.
  1879. * We use a small timeout which should encourage the OS to send the data,
  1880. * but at the same time avoid hanging indefinitely.
  1881. * */
  1882. do {
  1883. n = php_pollfd_for_ms(sslsock->s.socket, POLLOUT, 500);
  1884. } while (n == -1 && php_socket_errno() == EINTR);
  1885. #endif
  1886. closesocket(sslsock->s.socket);
  1887. sslsock->s.socket = SOCK_ERR;
  1888. }
  1889. }
  1890. if (sslsock->sni_certs) {
  1891. for (i = 0; i < sslsock->sni_cert_count; i++) {
  1892. if (sslsock->sni_certs[i].ctx) {
  1893. SSL_CTX_free(sslsock->sni_certs[i].ctx);
  1894. pefree(sslsock->sni_certs[i].name, php_stream_is_persistent(stream));
  1895. }
  1896. }
  1897. pefree(sslsock->sni_certs, php_stream_is_persistent(stream));
  1898. sslsock->sni_certs = NULL;
  1899. }
  1900. if (sslsock->url_name) {
  1901. pefree(sslsock->url_name, php_stream_is_persistent(stream));
  1902. }
  1903. if (sslsock->reneg) {
  1904. pefree(sslsock->reneg, php_stream_is_persistent(stream));
  1905. }
  1906. pefree(sslsock, php_stream_is_persistent(stream));
  1907. return 0;
  1908. }
  1909. /* }}} */
  1910. static int php_openssl_sockop_flush(php_stream *stream) /* {{{ */
  1911. {
  1912. return php_stream_socket_ops.flush(stream);
  1913. }
  1914. /* }}} */
  1915. static int php_openssl_sockop_stat(php_stream *stream, php_stream_statbuf *ssb) /* {{{ */
  1916. {
  1917. return php_stream_socket_ops.stat(stream, ssb);
  1918. }
  1919. /* }}} */
  1920. static inline int php_openssl_tcp_sockop_accept(php_stream *stream, php_openssl_netstream_data_t *sock,
  1921. php_stream_xport_param *xparam STREAMS_DC) /* {{{ */
  1922. {
  1923. int clisock;
  1924. bool nodelay = 0;
  1925. zval *tmpzval = NULL;
  1926. xparam->outputs.client = NULL;
  1927. if (PHP_STREAM_CONTEXT(stream) &&
  1928. (tmpzval = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), "socket", "tcp_nodelay")) != NULL &&
  1929. zend_is_true(tmpzval)) {
  1930. nodelay = 1;
  1931. }
  1932. clisock = php_network_accept_incoming(sock->s.socket,
  1933. xparam->want_textaddr ? &xparam->outputs.textaddr : NULL,
  1934. xparam->want_addr ? &xparam->outputs.addr : NULL,
  1935. xparam->want_addr ? &xparam->outputs.addrlen : NULL,
  1936. xparam->inputs.timeout,
  1937. xparam->want_errortext ? &xparam->outputs.error_text : NULL,
  1938. &xparam->outputs.error_code,
  1939. nodelay);
  1940. if (clisock >= 0) {
  1941. php_openssl_netstream_data_t *clisockdata = (php_openssl_netstream_data_t*) emalloc(sizeof(*clisockdata));
  1942. /* copy underlying tcp fields */
  1943. memset(clisockdata, 0, sizeof(*clisockdata));
  1944. memcpy(clisockdata, sock, sizeof(clisockdata->s));
  1945. clisockdata->s.socket = clisock;
  1946. #ifdef __linux__
  1947. /* O_NONBLOCK is not inherited on Linux */
  1948. clisockdata->s.is_blocked = 1;
  1949. #endif
  1950. xparam->outputs.client = php_stream_alloc_rel(stream->ops, clisockdata, NULL, "r+");
  1951. if (xparam->outputs.client) {
  1952. xparam->outputs.client->ctx = stream->ctx;
  1953. if (stream->ctx) {
  1954. GC_ADDREF(stream->ctx);
  1955. }
  1956. }
  1957. if (xparam->outputs.client && sock->enable_on_connect) {
  1958. /* remove the client bit */
  1959. if (sock->method & STREAM_CRYPTO_IS_CLIENT) {
  1960. sock->method = ((sock->method >> 1) << 1);
  1961. }
  1962. clisockdata->method = sock->method;
  1963. if (php_stream_xport_crypto_setup(xparam->outputs.client, clisockdata->method,
  1964. NULL) < 0 || php_stream_xport_crypto_enable(
  1965. xparam->outputs.client, 1) < 0) {
  1966. php_error_docref(NULL, E_WARNING, "Failed to enable crypto");
  1967. php_stream_close(xparam->outputs.client);
  1968. xparam->outputs.client = NULL;
  1969. xparam->outputs.returncode = -1;
  1970. }
  1971. }
  1972. }
  1973. return xparam->outputs.client == NULL ? -1 : 0;
  1974. }
  1975. /* }}} */
  1976. static int php_openssl_sockop_set_option(php_stream *stream, int option, int value, void *ptrparam) /* {{{ */
  1977. {
  1978. php_openssl_netstream_data_t *sslsock = (php_openssl_netstream_data_t*)stream->abstract;
  1979. php_stream_xport_crypto_param *cparam = (php_stream_xport_crypto_param *)ptrparam;
  1980. php_stream_xport_param *xparam = (php_stream_xport_param *)ptrparam;
  1981. switch (option) {
  1982. case PHP_STREAM_OPTION_META_DATA_API:
  1983. if (sslsock->ssl_active) {
  1984. zval tmp;
  1985. char *proto_str;
  1986. const SSL_CIPHER *cipher;
  1987. array_init(&tmp);
  1988. switch (SSL_version(sslsock->ssl_handle)) {
  1989. #ifdef HAVE_TLS13
  1990. case TLS1_3_VERSION: proto_str = "TLSv1.3"; break;
  1991. #endif
  1992. #ifdef HAVE_TLS12
  1993. case TLS1_2_VERSION: proto_str = "TLSv1.2"; break;
  1994. #endif
  1995. #ifdef HAVE_TLS11
  1996. case TLS1_1_VERSION: proto_str = "TLSv1.1"; break;
  1997. #endif
  1998. case TLS1_VERSION: proto_str = "TLSv1"; break;
  1999. #ifdef HAVE_SSL3
  2000. case SSL3_VERSION: proto_str = "SSLv3"; break;
  2001. #endif
  2002. default: proto_str = "UNKNOWN";
  2003. }
  2004. cipher = SSL_get_current_cipher(sslsock->ssl_handle);
  2005. add_assoc_string(&tmp, "protocol", proto_str);
  2006. add_assoc_string(&tmp, "cipher_name", (char *) SSL_CIPHER_get_name(cipher));
  2007. add_assoc_long(&tmp, "cipher_bits", SSL_CIPHER_get_bits(cipher, NULL));
  2008. add_assoc_string(&tmp, "cipher_version", SSL_CIPHER_get_version(cipher));
  2009. #ifdef HAVE_TLS_ALPN
  2010. {
  2011. const unsigned char *alpn_proto = NULL;
  2012. unsigned int alpn_proto_len = 0;
  2013. SSL_get0_alpn_selected(sslsock->ssl_handle, &alpn_proto, &alpn_proto_len);
  2014. if (alpn_proto) {
  2015. add_assoc_stringl(&tmp, "alpn_protocol", (char *)alpn_proto, alpn_proto_len);
  2016. }
  2017. }
  2018. #endif
  2019. add_assoc_zval((zval *)ptrparam, "crypto", &tmp);
  2020. }
  2021. add_assoc_bool((zval *)ptrparam, "timed_out", sslsock->s.timeout_event);
  2022. add_assoc_bool((zval *)ptrparam, "blocked", sslsock->s.is_blocked);
  2023. add_assoc_bool((zval *)ptrparam, "eof", stream->eof);
  2024. return PHP_STREAM_OPTION_RETURN_OK;
  2025. case PHP_STREAM_OPTION_CHECK_LIVENESS:
  2026. {
  2027. struct timeval tv;
  2028. char buf;
  2029. int alive = 1;
  2030. if (value == -1) {
  2031. if (sslsock->s.timeout.tv_sec == -1) {
  2032. #ifdef _WIN32
  2033. tv.tv_sec = (long)FG(default_socket_timeout);
  2034. #else
  2035. tv.tv_sec = (time_t)FG(default_socket_timeout);
  2036. #endif
  2037. tv.tv_usec = 0;
  2038. } else {
  2039. tv = sslsock->connect_timeout;
  2040. }
  2041. } else {
  2042. tv.tv_sec = value;
  2043. tv.tv_usec = 0;
  2044. }
  2045. if (sslsock->s.socket == -1) {
  2046. alive = 0;
  2047. } else if (php_pollfd_for(sslsock->s.socket, PHP_POLLREADABLE|POLLPRI, &tv) > 0) {
  2048. if (sslsock->ssl_active) {
  2049. int n = SSL_peek(sslsock->ssl_handle, &buf, sizeof(buf));
  2050. if (n <= 0) {
  2051. int err = SSL_get_error(sslsock->ssl_handle, n);
  2052. switch (err) {
  2053. case SSL_ERROR_SYSCALL:
  2054. alive = php_socket_errno() == EAGAIN;
  2055. break;
  2056. case SSL_ERROR_WANT_READ:
  2057. case SSL_ERROR_WANT_WRITE:
  2058. alive = 1;
  2059. break;
  2060. default:
  2061. /* any other problem is a fatal error */
  2062. alive = 0;
  2063. }
  2064. }
  2065. } else if (0 == recv(sslsock->s.socket, &buf, sizeof(buf), MSG_PEEK) && php_socket_errno() != EAGAIN) {
  2066. alive = 0;
  2067. }
  2068. }
  2069. return alive ? PHP_STREAM_OPTION_RETURN_OK : PHP_STREAM_OPTION_RETURN_ERR;
  2070. }
  2071. case PHP_STREAM_OPTION_CRYPTO_API:
  2072. switch(cparam->op) {
  2073. case STREAM_XPORT_CRYPTO_OP_SETUP:
  2074. cparam->outputs.returncode = php_openssl_setup_crypto(stream, sslsock, cparam);
  2075. return PHP_STREAM_OPTION_RETURN_OK;
  2076. break;
  2077. case STREAM_XPORT_CRYPTO_OP_ENABLE:
  2078. cparam->outputs.returncode = php_openssl_enable_crypto(stream, sslsock, cparam);
  2079. return PHP_STREAM_OPTION_RETURN_OK;
  2080. break;
  2081. default:
  2082. /* fall through */
  2083. break;
  2084. }
  2085. break;
  2086. case PHP_STREAM_OPTION_XPORT_API:
  2087. switch(xparam->op) {
  2088. case STREAM_XPORT_OP_CONNECT:
  2089. case STREAM_XPORT_OP_CONNECT_ASYNC:
  2090. /* TODO: Async connects need to check the enable_on_connect option when
  2091. * we notice that the connect has actually been established */
  2092. php_stream_socket_ops.set_option(stream, option, value, ptrparam);
  2093. if ((sslsock->enable_on_connect) &&
  2094. ((xparam->outputs.returncode == 0) ||
  2095. (xparam->op == STREAM_XPORT_OP_CONNECT_ASYNC &&
  2096. xparam->outputs.returncode == 1 && xparam->outputs.error_code == EINPROGRESS)))
  2097. {
  2098. if (php_stream_xport_crypto_setup(stream, sslsock->method, NULL) < 0 ||
  2099. php_stream_xport_crypto_enable(stream, 1) < 0) {
  2100. php_error_docref(NULL, E_WARNING, "Failed to enable crypto");
  2101. xparam->outputs.returncode = -1;
  2102. }
  2103. }
  2104. return PHP_STREAM_OPTION_RETURN_OK;
  2105. case STREAM_XPORT_OP_ACCEPT:
  2106. /* we need to copy the additional fields that the underlying tcp transport
  2107. * doesn't know about */
  2108. xparam->outputs.returncode = php_openssl_tcp_sockop_accept(stream, sslsock, xparam STREAMS_CC);
  2109. return PHP_STREAM_OPTION_RETURN_OK;
  2110. default:
  2111. /* fall through */
  2112. break;
  2113. }
  2114. }
  2115. return php_stream_socket_ops.set_option(stream, option, value, ptrparam);
  2116. }
  2117. /* }}} */
  2118. static int php_openssl_sockop_cast(php_stream *stream, int castas, void **ret) /* {{{ */
  2119. {
  2120. php_openssl_netstream_data_t *sslsock = (php_openssl_netstream_data_t*)stream->abstract;
  2121. switch(castas) {
  2122. case PHP_STREAM_AS_STDIO:
  2123. if (sslsock->ssl_active) {
  2124. return FAILURE;
  2125. }
  2126. if (ret) {
  2127. *ret = fdopen(sslsock->s.socket, stream->mode);
  2128. if (*ret) {
  2129. return SUCCESS;
  2130. }
  2131. return FAILURE;
  2132. }
  2133. return SUCCESS;
  2134. case PHP_STREAM_AS_FD_FOR_SELECT:
  2135. if (ret) {
  2136. size_t pending;
  2137. if (stream->writepos == stream->readpos
  2138. && sslsock->ssl_active
  2139. && (pending = (size_t)SSL_pending(sslsock->ssl_handle)) > 0) {
  2140. php_stream_fill_read_buffer(stream, pending < stream->chunk_size
  2141. ? pending
  2142. : stream->chunk_size);
  2143. }
  2144. *(php_socket_t *)ret = sslsock->s.socket;
  2145. }
  2146. return SUCCESS;
  2147. case PHP_STREAM_AS_FD:
  2148. case PHP_STREAM_AS_SOCKETD:
  2149. if (sslsock->ssl_active) {
  2150. return FAILURE;
  2151. }
  2152. if (ret) {
  2153. *(php_socket_t *)ret = sslsock->s.socket;
  2154. }
  2155. return SUCCESS;
  2156. default:
  2157. return FAILURE;
  2158. }
  2159. }
  2160. /* }}} */
  2161. const php_stream_ops php_openssl_socket_ops = {
  2162. php_openssl_sockop_write, php_openssl_sockop_read,
  2163. php_openssl_sockop_close, php_openssl_sockop_flush,
  2164. "tcp_socket/ssl",
  2165. NULL, /* seek */
  2166. php_openssl_sockop_cast,
  2167. php_openssl_sockop_stat,
  2168. php_openssl_sockop_set_option,
  2169. };
  2170. static zend_long php_openssl_get_crypto_method(
  2171. php_stream_context *ctx, zend_long crypto_method) /* {{{ */
  2172. {
  2173. zval *val;
  2174. if (ctx && (val = php_stream_context_get_option(ctx, "ssl", "crypto_method")) != NULL) {
  2175. crypto_method = zval_get_long(val);
  2176. crypto_method |= STREAM_CRYPTO_IS_CLIENT;
  2177. }
  2178. return crypto_method;
  2179. }
  2180. /* }}} */
  2181. static char *php_openssl_get_url_name(const char *resourcename,
  2182. size_t resourcenamelen, int is_persistent) /* {{{ */
  2183. {
  2184. php_url *url;
  2185. if (!resourcename) {
  2186. return NULL;
  2187. }
  2188. url = php_url_parse_ex(resourcename, resourcenamelen);
  2189. if (!url) {
  2190. return NULL;
  2191. }
  2192. if (url->host) {
  2193. const char * host = ZSTR_VAL(url->host);
  2194. char * url_name = NULL;
  2195. size_t len = ZSTR_LEN(url->host);
  2196. /* skip trailing dots */
  2197. while (len && host[len-1] == '.') {
  2198. --len;
  2199. }
  2200. if (len) {
  2201. url_name = pestrndup(host, len, is_persistent);
  2202. }
  2203. php_url_free(url);
  2204. return url_name;
  2205. }
  2206. php_url_free(url);
  2207. return NULL;
  2208. }
  2209. /* }}} */
  2210. php_stream *php_openssl_ssl_socket_factory(const char *proto, size_t protolen,
  2211. const char *resourcename, size_t resourcenamelen,
  2212. const char *persistent_id, int options, int flags,
  2213. struct timeval *timeout,
  2214. php_stream_context *context STREAMS_DC) /* {{{ */
  2215. {
  2216. php_stream *stream = NULL;
  2217. php_openssl_netstream_data_t *sslsock = NULL;
  2218. sslsock = pemalloc(sizeof(php_openssl_netstream_data_t), persistent_id ? 1 : 0);
  2219. memset(sslsock, 0, sizeof(*sslsock));
  2220. sslsock->s.is_blocked = 1;
  2221. /* this timeout is used by standard stream funcs, therefore it should use the default value */
  2222. #ifdef _WIN32
  2223. sslsock->s.timeout.tv_sec = (long)FG(default_socket_timeout);
  2224. #else
  2225. sslsock->s.timeout.tv_sec = (time_t)FG(default_socket_timeout);
  2226. #endif
  2227. sslsock->s.timeout.tv_usec = 0;
  2228. /* use separate timeout for our private funcs */
  2229. sslsock->connect_timeout.tv_sec = timeout->tv_sec;
  2230. sslsock->connect_timeout.tv_usec = timeout->tv_usec;
  2231. /* we don't know the socket until we have determined if we are binding or
  2232. * connecting */
  2233. sslsock->s.socket = -1;
  2234. /* Initialize context as NULL */
  2235. sslsock->ctx = NULL;
  2236. stream = php_stream_alloc_rel(&php_openssl_socket_ops, sslsock, persistent_id, "r+");
  2237. if (stream == NULL) {
  2238. pefree(sslsock, persistent_id ? 1 : 0);
  2239. return NULL;
  2240. }
  2241. if (strncmp(proto, "ssl", protolen) == 0) {
  2242. sslsock->enable_on_connect = 1;
  2243. sslsock->method = php_openssl_get_crypto_method(context, STREAM_CRYPTO_METHOD_TLS_ANY_CLIENT);
  2244. } else if (strncmp(proto, "sslv2", protolen) == 0) {
  2245. php_error_docref(NULL, E_WARNING, "SSLv2 unavailable in this PHP version");
  2246. php_stream_close(stream);
  2247. return NULL;
  2248. } else if (strncmp(proto, "sslv3", protolen) == 0) {
  2249. #ifdef HAVE_SSL3
  2250. sslsock->enable_on_connect = 1;
  2251. sslsock->method = STREAM_CRYPTO_METHOD_SSLv3_CLIENT;
  2252. #else
  2253. php_error_docref(NULL, E_WARNING,
  2254. "SSLv3 support is not compiled into the OpenSSL library against which PHP is linked");
  2255. php_stream_close(stream);
  2256. return NULL;
  2257. #endif
  2258. } else if (strncmp(proto, "tls", protolen) == 0) {
  2259. sslsock->enable_on_connect = 1;
  2260. sslsock->method = php_openssl_get_crypto_method(context, STREAM_CRYPTO_METHOD_TLS_ANY_CLIENT);
  2261. } else if (strncmp(proto, "tlsv1.0", protolen) == 0) {
  2262. sslsock->enable_on_connect = 1;
  2263. sslsock->method = STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT;
  2264. } else if (strncmp(proto, "tlsv1.1", protolen) == 0) {
  2265. #ifdef HAVE_TLS11
  2266. sslsock->enable_on_connect = 1;
  2267. sslsock->method = STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
  2268. #else
  2269. php_error_docref(NULL, E_WARNING,
  2270. "TLSv1.1 support is not compiled into the OpenSSL library against which PHP is linked");
  2271. php_stream_close(stream);
  2272. return NULL;
  2273. #endif
  2274. } else if (strncmp(proto, "tlsv1.2", protolen) == 0) {
  2275. #ifdef HAVE_TLS12
  2276. sslsock->enable_on_connect = 1;
  2277. sslsock->method = STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
  2278. #else
  2279. php_error_docref(NULL, E_WARNING,
  2280. "TLSv1.2 support is not compiled into the OpenSSL library against which PHP is linked");
  2281. php_stream_close(stream);
  2282. return NULL;
  2283. #endif
  2284. } else if (strncmp(proto, "tlsv1.3", protolen) == 0) {
  2285. #ifdef HAVE_TLS13
  2286. sslsock->enable_on_connect = 1;
  2287. sslsock->method = STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT;
  2288. #else
  2289. php_error_docref(NULL, E_WARNING,
  2290. "TLSv1.3 support is not compiled into the OpenSSL library against which PHP is linked");
  2291. php_stream_close(stream);
  2292. return NULL;
  2293. #endif
  2294. }
  2295. sslsock->url_name = php_openssl_get_url_name(resourcename, resourcenamelen, !!persistent_id);
  2296. return stream;
  2297. }
  2298. /* }}} */