1 /* 2 * TLS support code for CUPS using Google BoringSSL. 3 * 4 * Copyright 2007-2016 by Apple Inc. 5 * Copyright 1997-2007 by Easy Software Products, all rights reserved. 6 * 7 * These coded instructions, statements, and computer programs are the 8 * property of Apple Inc. and are protected by Federal copyright 9 * law. Distribution and use rights are outlined in the file "LICENSE.txt" 10 * which should have been included with this file. If this file is 11 * file is missing or damaged, see the license at "http://www.cups.org/". 12 * 13 * This file is subject to the Apple OS-Developed Software exception. 14 */ 15 16 /**** This file is included from tls.c ****/ 17 18 /* 19 * Local globals... 20 */ 21 22 #include "cups-private.h" 23 #include "http.h" 24 #include "thread-private.h" 25 #include <openssl/err.h> 26 #include <openssl/ssl.h> 27 28 #include <sys/stat.h> 29 30 static char *tls_keypath = NULL; 31 /* Server cert keychain path */ 32 static int tls_options = -1;/* Options for TLS connections */ 33 34 35 /* 36 * Local functions... 37 */ 38 39 static BIO_METHOD * _httpBIOMethods(void); 40 static int http_bio_write(BIO *h, const char *buf, int num); 41 static int http_bio_read(BIO *h, char *buf, int size); 42 static int http_bio_puts(BIO *h, const char *str); 43 static long http_bio_ctrl(BIO *h, int cmd, long arg1, void *arg2); 44 static int http_bio_new(BIO *h); 45 static int http_bio_free(BIO *data); 46 47 static BIO_METHOD http_bio_methods = 48 { 49 BIO_TYPE_SSL, 50 "http", 51 http_bio_write, 52 http_bio_read, 53 http_bio_puts, 54 NULL, /* http_bio_gets, */ 55 http_bio_ctrl, 56 http_bio_new, 57 http_bio_free, 58 NULL, 59 }; 60 61 /* 62 * 'cupsMakeServerCredentials()' - Make a self-signed certificate and private key pair. 63 * 64 * @since CUPS 2.0/OS 10.10@ 65 */ 66 67 int /* O - 1 on success, 0 on failure */ 68 cupsMakeServerCredentials( 69 const char *path, /* I - Path to keychain/directory */ 70 const char *common_name, /* I - Common name */ 71 int num_alt_names, /* I - Number of subject alternate names */ 72 const char **alt_names, /* I - Subject Alternate Names */ 73 time_t expiration_date) /* I - Expiration date */ 74 { 75 int pid, /* Process ID of command */ 76 status; /* Status of command */ 77 char command[1024], /* Command */ 78 *argv[12], /* Command-line arguments */ 79 *envp[1000], /* Environment variables */ 80 infofile[1024], /* Type-in information for cert */ 81 seedfile[1024]; /* Random number seed file */ 82 int envc, /* Number of environment variables */ 83 bytes; /* Bytes written */ 84 cups_file_t *fp; /* Seed/info file */ 85 int infofd; /* Info file descriptor */ 86 char temp[1024], /* Temporary directory name */ 87 crtfile[1024], /* Certificate filename */ 88 keyfile[1024]; /* Private key filename */ 89 90 DEBUG_printf(("cupsMakeServerCredentials(path=\"%s\", common_name=\"%s\", num_alt_names=%d, alt_names=%p, expiration_date=%d)", path, common_name, num_alt_names, alt_names, (int)expiration_date)); 91 92 return 0; 93 } 94 95 96 /* 97 * '_httpCreateCredentials()' - Create credentials in the internal format. 98 */ 99 100 http_tls_credentials_t /* O - Internal credentials */ 101 _httpCreateCredentials( 102 cups_array_t *credentials) /* I - Array of credentials */ 103 { 104 (void)credentials; 105 106 return (NULL); 107 } 108 109 110 /* 111 * '_httpFreeCredentials()' - Free internal credentials. 112 */ 113 114 void 115 _httpFreeCredentials( 116 http_tls_credentials_t credentials) /* I - Internal credentials */ 117 { 118 (void)credentials; 119 } 120 121 122 /* 123 * '_httpBIOMethods()' - Get the OpenSSL BIO methods for HTTP connections. 124 */ 125 126 static BIO_METHOD * /* O - BIO methods for OpenSSL */ 127 _httpBIOMethods(void) 128 { 129 return (&http_bio_methods); 130 } 131 132 133 /* 134 * 'http_bio_ctrl()' - Control the HTTP connection. 135 */ 136 137 static long /* O - Result/data */ 138 http_bio_ctrl(BIO *h, /* I - BIO data */ 139 int cmd, /* I - Control command */ 140 long arg1, /* I - First argument */ 141 void *arg2) /* I - Second argument */ 142 { 143 switch (cmd) 144 { 145 default : 146 return (0); 147 148 case BIO_CTRL_RESET : 149 h->ptr = NULL; 150 return (0); 151 152 case BIO_C_SET_FILE_PTR : 153 h->ptr = arg2; 154 h->init = 1; 155 return (1); 156 157 case BIO_C_GET_FILE_PTR : 158 if (arg2) 159 { 160 *((void **)arg2) = h->ptr; 161 return (1); 162 } 163 else 164 return (0); 165 166 case BIO_CTRL_DUP : 167 case BIO_CTRL_FLUSH : 168 return (1); 169 } 170 } 171 172 173 /* 174 * 'http_bio_free()' - Free OpenSSL data. 175 */ 176 177 static int /* O - 1 on success, 0 on failure */ 178 http_bio_free(BIO *h) /* I - BIO data */ 179 { 180 if (!h) 181 return (0); 182 183 if (h->shutdown) 184 { 185 h->init = 0; 186 h->flags = 0; 187 } 188 189 return (1); 190 } 191 192 193 /* 194 * 'http_bio_new()' - Initialize an OpenSSL BIO structure. 195 */ 196 197 static int /* O - 1 on success, 0 on failure */ 198 http_bio_new(BIO *h) /* I - BIO data */ 199 { 200 if (!h) 201 return (0); 202 203 h->init = 0; 204 h->num = 0; 205 h->ptr = NULL; 206 h->flags = 0; 207 208 return (1); 209 } 210 211 212 /* 213 * 'http_bio_puts()' - Send a string for OpenSSL. 214 */ 215 216 static int /* O - Bytes written */ 217 http_bio_puts(BIO *h, /* I - BIO data */ 218 const char *str) /* I - String to write */ 219 { 220 return (send(((http_t *)h->ptr)->fd, str, strlen(str), 0)); 221 } 222 223 224 /* 225 * 'http_bio_read()' - Read data for OpenSSL. 226 */ 227 228 static int /* O - Bytes read */ 229 http_bio_read(BIO *h, /* I - BIO data */ 230 char *buf, /* I - Buffer */ 231 int size) /* I - Number of bytes to read */ 232 { 233 http_t *http; /* HTTP connection */ 234 235 236 http = (http_t *)h->ptr; 237 238 if (!http->blocking) 239 { 240 /* 241 * Make sure we have data before we read... 242 */ 243 244 while (!_httpWait(http, http->wait_value, 0)) 245 { 246 if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data)) 247 continue; 248 249 http->error = ETIMEDOUT; 250 251 return (-1); 252 } 253 } 254 255 return (recv(http->fd, buf, size, 0)); 256 } 257 258 259 /* 260 * 'http_bio_write()' - Write data for OpenSSL. 261 */ 262 263 static int /* O - Bytes written */ 264 http_bio_write(BIO *h, /* I - BIO data */ 265 const char *buf, /* I - Buffer to write */ 266 int num) /* I - Number of bytes to write */ 267 { 268 return (send(((http_t *)h->ptr)->fd, buf, num, 0)); 269 } 270 271 272 /* 273 * '_httpTLSInitialize()' - Initialize the TLS stack. 274 */ 275 276 void 277 _httpTLSInitialize(void) 278 { 279 SSL_library_init(); 280 } 281 282 283 /* 284 * '_httpTLSPending()' - Return the number of pending TLS-encrypted bytes. 285 */ 286 287 size_t /* O - Bytes available */ 288 _httpTLSPending(http_t *http) /* I - HTTP connection */ 289 { 290 return (SSL_pending(http->tls)); 291 } 292 293 294 /* 295 * '_httpTLSRead()' - Read from a SSL/TLS connection. 296 */ 297 298 int /* O - Bytes read */ 299 _httpTLSRead(http_t *http, /* I - Connection to server */ 300 char *buf, /* I - Buffer to store data */ 301 int len) /* I - Length of buffer */ 302 { 303 return (SSL_read((SSL *)(http->tls), buf, len)); 304 } 305 306 307 /* 308 * '_httpTLSSetOptions()' - Set TLS protocol and cipher suite options. 309 */ 310 311 void 312 _httpTLSSetOptions(int options) /* I - Options */ 313 { 314 tls_options = options; 315 } 316 317 318 /* 319 * '_httpTLSStart()' - Set up SSL/TLS support on a connection. 320 */ 321 322 int /* O - 0 on success, -1 on failure */ 323 _httpTLSStart(http_t *http) /* I - Connection to server */ 324 { 325 char hostname[256], /* Hostname */ 326 *hostptr; /* Pointer into hostname */ 327 328 SSL_CTX *context; /* Context for encryption */ 329 BIO *bio; /* BIO data */ 330 const char *message = NULL;/* Error message */ 331 332 DEBUG_printf(("3_httpTLSStart(http=%p)", (void *)http)); 333 334 if (tls_options < 0) 335 { 336 DEBUG_puts("4_httpTLSStart: Setting defaults."); 337 _cupsSetDefaults(); 338 DEBUG_printf(("4_httpTLSStart: tls_options=%x", tls_options)); 339 } 340 341 if (http->mode == _HTTP_MODE_SERVER && !tls_keypath) 342 { 343 DEBUG_puts("4_httpTLSStart: cupsSetServerCredentials not called."); 344 http->error = errno = EINVAL; 345 http->status = HTTP_STATUS_ERROR; 346 _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Server credentials not set."), 1); 347 348 return (-1); 349 } 350 351 context = SSL_CTX_new(TLS_method()); 352 if (tls_options & _HTTP_TLS_DENY_TLS10) 353 SSL_CTX_set_min_proto_version(context, TLS1_1_VERSION); 354 355 bio = BIO_new(_httpBIOMethods()); 356 BIO_ctrl(bio, BIO_C_SET_FILE_PTR, 0, (char *)http); 357 358 http->tls = SSL_new(context); 359 SSL_set_bio(http->tls, bio, bio); 360 361 /* http->tls retains an internal reference to the SSL_CTX. */ 362 SSL_CTX_free(context); 363 364 if (http->mode == _HTTP_MODE_CLIENT) 365 { 366 SSL_set_connect_state(http->tls); 367 368 /* 369 * Client: get the hostname to use for TLS... 370 */ 371 372 if (httpAddrLocalhost(http->hostaddr)) 373 { 374 strlcpy(hostname, "localhost", sizeof(hostname)); 375 } 376 else 377 { 378 /* 379 * Otherwise make sure the hostname we have does not end in a trailing dot. 380 */ 381 382 strlcpy(hostname, http->hostname, sizeof(hostname)); 383 if ((hostptr = hostname + strlen(hostname) - 1) >= hostname && 384 *hostptr == '.') 385 *hostptr = '\0'; 386 } 387 SSL_set_tlsext_host_name(http->tls, hostname); 388 } 389 else 390 { 391 /* @@@ TODO @@@ */ 392 _cupsSetError(IPP_STATUS_ERROR_INTERNAL, "Server not supported", 0); 393 } 394 395 396 if (SSL_do_handshake(http->tls) != 1) 397 { 398 unsigned long error; /* Error code */ 399 char buf[256]; 400 401 while ((error = ERR_get_error()) != 0) 402 { 403 ERR_error_string_n(error, buf, sizeof(buf)); 404 DEBUG_printf(("8http_setup_ssl: %s", buf)); 405 } 406 407 SSL_free(http->tls); 408 http->tls = NULL; 409 410 http->error = errno; 411 http->status = HTTP_STATUS_ERROR; 412 413 if (!message) 414 message = _("Unable to establish a secure connection to host."); 415 416 _cupsSetError(IPP_STATUS_ERROR_CUPS_PKI, message, 1); 417 418 return (-1); 419 } 420 421 return (0); 422 } 423 424 425 /* 426 * '_httpTLSStop()' - Shut down SSL/TLS on a connection. 427 */ 428 429 void 430 _httpTLSStop(http_t *http) /* I - Connection to server */ 431 { 432 unsigned long error; /* Error code */ 433 434 switch (SSL_shutdown(http->tls)) 435 { 436 case 1 : 437 break; 438 439 case -1 : 440 _cupsSetError(IPP_STATUS_ERROR_INTERNAL, 441 "Fatal error during SSL shutdown!", 0); 442 default : 443 while ((error = ERR_get_error()) != 0) 444 { 445 char buf[256]; 446 ERR_error_string_n(error, buf, sizeof(buf)); 447 _cupsSetError(IPP_STATUS_ERROR_INTERNAL, buf, 0); 448 } 449 break; 450 } 451 452 SSL_free(http->tls); 453 http->tls = NULL; 454 } 455 456 /* 457 * '_httpTLSWrite()' - Write to a SSL/TLS connection. 458 */ 459 460 int /* O - Bytes written */ 461 _httpTLSWrite(http_t *http, /* I - Connection to server */ 462 const char *buf, /* I - Buffer holding data */ 463 int len) /* I - Length of buffer */ 464 { 465 int result; /* Return value */ 466 467 468 DEBUG_printf(("2http_write_ssl(http=%p, buf=%p, len=%d)", http, buf, len)); 469 470 result = SSL_write((SSL *)(http->tls), buf, len); 471 472 DEBUG_printf(("3http_write_ssl: Returning %d.", result)); 473 474 return result; 475 } 476