diff options
| author | Lars Ingebrigtsen | 2019-08-23 04:49:52 +0200 |
|---|---|---|
| committer | Lars Ingebrigtsen | 2019-08-23 04:49:52 +0200 |
| commit | 53cb3d3e0ddb666dc5b7774957ca863c668213cb (patch) | |
| tree | 011cf32acf25b0cd86debf5b3c22be289e60bd87 /src | |
| parent | b4d3a882a8423e81c418fc56b7a9677f5582fcc7 (diff) | |
| parent | 29d485fb768fbe375d60fd80cb2dbdbd90f3becc (diff) | |
| download | emacs-53cb3d3e0ddb666dc5b7774957ca863c668213cb.tar.gz emacs-53cb3d3e0ddb666dc5b7774957ca863c668213cb.zip | |
Merge remote-tracking branch 'origin/netsec'
Diffstat (limited to 'src')
| -rw-r--r-- | src/gnutls.c | 190 | ||||
| -rw-r--r-- | src/process.c | 108 |
2 files changed, 281 insertions, 17 deletions
diff --git a/src/gnutls.c b/src/gnutls.c index 267ba9aba35..ce977d901c6 100644 --- a/src/gnutls.c +++ b/src/gnutls.c | |||
| @@ -44,6 +44,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 44 | # define HAVE_GNUTLS_EXT__DUMBFW | 44 | # define HAVE_GNUTLS_EXT__DUMBFW |
| 45 | #endif | 45 | #endif |
| 46 | 46 | ||
| 47 | #if GNUTLS_VERSION_NUMBER >= 0x030400 | ||
| 48 | # define HAVE_GNUTLS_ETM_STATUS | ||
| 49 | #endif | ||
| 50 | |||
| 47 | /* gnutls_mac_get_nonce_size was added in GnuTLS 3.2.0, but was | 51 | /* gnutls_mac_get_nonce_size was added in GnuTLS 3.2.0, but was |
| 48 | exported only since 3.3.0. */ | 52 | exported only since 3.3.0. */ |
| 49 | #if GNUTLS_VERSION_NUMBER >= 0x030300 | 53 | #if GNUTLS_VERSION_NUMBER >= 0x030300 |
| @@ -159,6 +163,8 @@ DEF_DLL_FN (int, gnutls_x509_crt_check_hostname, | |||
| 159 | DEF_DLL_FN (int, gnutls_x509_crt_check_issuer, | 163 | DEF_DLL_FN (int, gnutls_x509_crt_check_issuer, |
| 160 | (gnutls_x509_crt_t, gnutls_x509_crt_t)); | 164 | (gnutls_x509_crt_t, gnutls_x509_crt_t)); |
| 161 | DEF_DLL_FN (void, gnutls_x509_crt_deinit, (gnutls_x509_crt_t)); | 165 | DEF_DLL_FN (void, gnutls_x509_crt_deinit, (gnutls_x509_crt_t)); |
| 166 | DEF_DLL_DN (int, gnutls_x509_crt_export, | ||
| 167 | (gnutls_x509_crt_t, gnutls_x509_crt_fmt_t, void *, size_t *)); | ||
| 162 | DEF_DLL_FN (int, gnutls_x509_crt_import, | 168 | DEF_DLL_FN (int, gnutls_x509_crt_import, |
| 163 | (gnutls_x509_crt_t, const gnutls_datum_t *, | 169 | (gnutls_x509_crt_t, const gnutls_datum_t *, |
| 164 | gnutls_x509_crt_fmt_t)); | 170 | gnutls_x509_crt_fmt_t)); |
| @@ -180,6 +186,9 @@ DEF_DLL_FN (int, gnutls_x509_crt_get_dn, | |||
| 180 | (gnutls_x509_crt_t, char *, size_t *)); | 186 | (gnutls_x509_crt_t, char *, size_t *)); |
| 181 | DEF_DLL_FN (int, gnutls_x509_crt_get_pk_algorithm, | 187 | DEF_DLL_FN (int, gnutls_x509_crt_get_pk_algorithm, |
| 182 | (gnutls_x509_crt_t, unsigned int *)); | 188 | (gnutls_x509_crt_t, unsigned int *)); |
| 189 | DEF_DLL_FN (int, gnutls_x509_crt_print, | ||
| 190 | (gnutls_x509_crt_t, gnutls_certificate_print_formats_t, | ||
| 191 | gnutls_datum_t *)); | ||
| 183 | DEF_DLL_FN (const char *, gnutls_pk_algorithm_get_name, | 192 | DEF_DLL_FN (const char *, gnutls_pk_algorithm_get_name, |
| 184 | (gnutls_pk_algorithm_t)); | 193 | (gnutls_pk_algorithm_t)); |
| 185 | DEF_DLL_FN (int, gnutls_pk_bits_to_sec_param, | 194 | DEF_DLL_FN (int, gnutls_pk_bits_to_sec_param, |
| @@ -208,6 +217,11 @@ DEF_DLL_FN (const char *, gnutls_cipher_get_name, | |||
| 208 | (gnutls_cipher_algorithm_t)); | 217 | (gnutls_cipher_algorithm_t)); |
| 209 | DEF_DLL_FN (gnutls_mac_algorithm_t, gnutls_mac_get, (gnutls_session_t)); | 218 | DEF_DLL_FN (gnutls_mac_algorithm_t, gnutls_mac_get, (gnutls_session_t)); |
| 210 | DEF_DLL_FN (const char *, gnutls_mac_get_name, (gnutls_mac_algorithm_t)); | 219 | DEF_DLL_FN (const char *, gnutls_mac_get_name, (gnutls_mac_algorithm_t)); |
| 220 | DEF_DLL_FN (gnutls_compression_method_t, gnutls_compression_get, | ||
| 221 | (gnutls_session_t)); | ||
| 222 | DEF_DLL_FN (const char *, gnutls_compression_get_name, | ||
| 223 | (gnutls_compression_method_t)); | ||
| 224 | DEF_DLL_FN (unsigned, gnutls_safe_renegotiation_status, (gnutls_session_t)); | ||
| 211 | 225 | ||
| 212 | # ifdef HAVE_GNUTLS3 | 226 | # ifdef HAVE_GNUTLS3 |
| 213 | DEF_DLL_FN (int, gnutls_rnd, (gnutls_rnd_level_t, void *, size_t)); | 227 | DEF_DLL_FN (int, gnutls_rnd, (gnutls_rnd_level_t, void *, size_t)); |
| @@ -250,6 +264,9 @@ DEF_DLL_FN (int, gnutls_aead_cipher_decrypt, | |||
| 250 | (gnutls_aead_cipher_hd_t, const void *, size_t, const void *, | 264 | (gnutls_aead_cipher_hd_t, const void *, size_t, const void *, |
| 251 | size_t, size_t, const void *, size_t, void *, size_t *)); | 265 | size_t, size_t, const void *, size_t, void *, size_t *)); |
| 252 | # endif | 266 | # endif |
| 267 | # ifdef HAVE_GNUTLS_ETM_STATUS | ||
| 268 | DEF_DLL_FN (unsigned, gnutls_session_etm_status, (gnutls_session_t)); | ||
| 269 | # endif | ||
| 253 | DEF_DLL_FN (int, gnutls_hmac_init, | 270 | DEF_DLL_FN (int, gnutls_hmac_init, |
| 254 | (gnutls_hmac_hd_t *, gnutls_mac_algorithm_t, const void *, size_t)); | 271 | (gnutls_hmac_hd_t *, gnutls_mac_algorithm_t, const void *, size_t)); |
| 255 | DEF_DLL_FN (int, gnutls_hmac_get_len, (gnutls_mac_algorithm_t)); | 272 | DEF_DLL_FN (int, gnutls_hmac_get_len, (gnutls_mac_algorithm_t)); |
| @@ -322,6 +339,7 @@ init_gnutls_functions (void) | |||
| 322 | LOAD_DLL_FN (library, gnutls_x509_crt_check_hostname); | 339 | LOAD_DLL_FN (library, gnutls_x509_crt_check_hostname); |
| 323 | LOAD_DLL_FN (library, gnutls_x509_crt_check_issuer); | 340 | LOAD_DLL_FN (library, gnutls_x509_crt_check_issuer); |
| 324 | LOAD_DLL_FN (library, gnutls_x509_crt_deinit); | 341 | LOAD_DLL_FN (library, gnutls_x509_crt_deinit); |
| 342 | LOAD_DLL_FN (library, gnutls_x509_crt_export); | ||
| 325 | LOAD_DLL_FN (library, gnutls_x509_crt_import); | 343 | LOAD_DLL_FN (library, gnutls_x509_crt_import); |
| 326 | LOAD_DLL_FN (library, gnutls_x509_crt_init); | 344 | LOAD_DLL_FN (library, gnutls_x509_crt_init); |
| 327 | LOAD_DLL_FN (library, gnutls_x509_crt_get_fingerprint); | 345 | LOAD_DLL_FN (library, gnutls_x509_crt_get_fingerprint); |
| @@ -332,6 +350,7 @@ init_gnutls_functions (void) | |||
| 332 | LOAD_DLL_FN (library, gnutls_x509_crt_get_expiration_time); | 350 | LOAD_DLL_FN (library, gnutls_x509_crt_get_expiration_time); |
| 333 | LOAD_DLL_FN (library, gnutls_x509_crt_get_dn); | 351 | LOAD_DLL_FN (library, gnutls_x509_crt_get_dn); |
| 334 | LOAD_DLL_FN (library, gnutls_x509_crt_get_pk_algorithm); | 352 | LOAD_DLL_FN (library, gnutls_x509_crt_get_pk_algorithm); |
| 353 | LOAD_DLL_FN (library, gnutls_x509_crt_print) | ||
| 335 | LOAD_DLL_FN (library, gnutls_pk_algorithm_get_name); | 354 | LOAD_DLL_FN (library, gnutls_pk_algorithm_get_name); |
| 336 | LOAD_DLL_FN (library, gnutls_pk_bits_to_sec_param); | 355 | LOAD_DLL_FN (library, gnutls_pk_bits_to_sec_param); |
| 337 | LOAD_DLL_FN (library, gnutls_x509_crt_get_issuer_unique_id); | 356 | LOAD_DLL_FN (library, gnutls_x509_crt_get_issuer_unique_id); |
| @@ -349,6 +368,9 @@ init_gnutls_functions (void) | |||
| 349 | LOAD_DLL_FN (library, gnutls_cipher_get_name); | 368 | LOAD_DLL_FN (library, gnutls_cipher_get_name); |
| 350 | LOAD_DLL_FN (library, gnutls_mac_get); | 369 | LOAD_DLL_FN (library, gnutls_mac_get); |
| 351 | LOAD_DLL_FN (library, gnutls_mac_get_name); | 370 | LOAD_DLL_FN (library, gnutls_mac_get_name); |
| 371 | LOAD_DLL_FN (library, gnutls_compression_get); | ||
| 372 | LOAD_DLL_FN (library, gnutls_compression_get_name); | ||
| 373 | LOAD_DLL_FN (library, gnutls_safe_renegotiation_status); | ||
| 352 | # ifdef HAVE_GNUTLS3 | 374 | # ifdef HAVE_GNUTLS3 |
| 353 | LOAD_DLL_FN (library, gnutls_rnd); | 375 | LOAD_DLL_FN (library, gnutls_rnd); |
| 354 | LOAD_DLL_FN (library, gnutls_mac_list); | 376 | LOAD_DLL_FN (library, gnutls_mac_list); |
| @@ -380,6 +402,9 @@ init_gnutls_functions (void) | |||
| 380 | LOAD_DLL_FN (library, gnutls_aead_cipher_encrypt); | 402 | LOAD_DLL_FN (library, gnutls_aead_cipher_encrypt); |
| 381 | LOAD_DLL_FN (library, gnutls_aead_cipher_decrypt); | 403 | LOAD_DLL_FN (library, gnutls_aead_cipher_decrypt); |
| 382 | # endif | 404 | # endif |
| 405 | # ifdef HAVE_GNUTLS_ETM_STATUS | ||
| 406 | LOAD_DLL_FN (library, gnutls_session_etm_status); | ||
| 407 | # endif | ||
| 383 | LOAD_DLL_FN (library, gnutls_hmac_init); | 408 | LOAD_DLL_FN (library, gnutls_hmac_init); |
| 384 | LOAD_DLL_FN (library, gnutls_hmac_get_len); | 409 | LOAD_DLL_FN (library, gnutls_hmac_get_len); |
| 385 | LOAD_DLL_FN (library, gnutls_hmac); | 410 | LOAD_DLL_FN (library, gnutls_hmac); |
| @@ -437,6 +462,9 @@ init_gnutls_functions (void) | |||
| 437 | # define gnutls_kx_get_name fn_gnutls_kx_get_name | 462 | # define gnutls_kx_get_name fn_gnutls_kx_get_name |
| 438 | # define gnutls_mac_get fn_gnutls_mac_get | 463 | # define gnutls_mac_get fn_gnutls_mac_get |
| 439 | # define gnutls_mac_get_name fn_gnutls_mac_get_name | 464 | # define gnutls_mac_get_name fn_gnutls_mac_get_name |
| 465 | # define gnutls_compression_get fn_gnutls_compression_get | ||
| 466 | # define gnutls_compression_get_name fn_gnutls_compression_get_name | ||
| 467 | # define gnutls_safe_renegotiation_status fn_gnutls_safe_renegotiation_status; | ||
| 440 | # define gnutls_pk_algorithm_get_name fn_gnutls_pk_algorithm_get_name | 468 | # define gnutls_pk_algorithm_get_name fn_gnutls_pk_algorithm_get_name |
| 441 | # define gnutls_pk_bits_to_sec_param fn_gnutls_pk_bits_to_sec_param | 469 | # define gnutls_pk_bits_to_sec_param fn_gnutls_pk_bits_to_sec_param |
| 442 | # define gnutls_priority_set_direct fn_gnutls_priority_set_direct | 470 | # define gnutls_priority_set_direct fn_gnutls_priority_set_direct |
| @@ -456,6 +484,7 @@ init_gnutls_functions (void) | |||
| 456 | # define gnutls_x509_crt_check_hostname fn_gnutls_x509_crt_check_hostname | 484 | # define gnutls_x509_crt_check_hostname fn_gnutls_x509_crt_check_hostname |
| 457 | # define gnutls_x509_crt_check_issuer fn_gnutls_x509_crt_check_issuer | 485 | # define gnutls_x509_crt_check_issuer fn_gnutls_x509_crt_check_issuer |
| 458 | # define gnutls_x509_crt_deinit fn_gnutls_x509_crt_deinit | 486 | # define gnutls_x509_crt_deinit fn_gnutls_x509_crt_deinit |
| 487 | # define gnutls_x509_crt_export fn_gnutls_x509_crt_export | ||
| 459 | # define gnutls_x509_crt_get_activation_time fn_gnutls_x509_crt_get_activation_time | 488 | # define gnutls_x509_crt_get_activation_time fn_gnutls_x509_crt_get_activation_time |
| 460 | # define gnutls_x509_crt_get_dn fn_gnutls_x509_crt_get_dn | 489 | # define gnutls_x509_crt_get_dn fn_gnutls_x509_crt_get_dn |
| 461 | # define gnutls_x509_crt_get_expiration_time fn_gnutls_x509_crt_get_expiration_time | 490 | # define gnutls_x509_crt_get_expiration_time fn_gnutls_x509_crt_get_expiration_time |
| @@ -464,6 +493,7 @@ init_gnutls_functions (void) | |||
| 464 | # define gnutls_x509_crt_get_issuer_unique_id fn_gnutls_x509_crt_get_issuer_unique_id | 493 | # define gnutls_x509_crt_get_issuer_unique_id fn_gnutls_x509_crt_get_issuer_unique_id |
| 465 | # define gnutls_x509_crt_get_key_id fn_gnutls_x509_crt_get_key_id | 494 | # define gnutls_x509_crt_get_key_id fn_gnutls_x509_crt_get_key_id |
| 466 | # define gnutls_x509_crt_get_pk_algorithm fn_gnutls_x509_crt_get_pk_algorithm | 495 | # define gnutls_x509_crt_get_pk_algorithm fn_gnutls_x509_crt_get_pk_algorithm |
| 496 | # define gnutls_x509_crt_print fn_gnutls_x509_crt_print | ||
| 467 | # define gnutls_x509_crt_get_serial fn_gnutls_x509_crt_get_serial | 497 | # define gnutls_x509_crt_get_serial fn_gnutls_x509_crt_get_serial |
| 468 | # define gnutls_x509_crt_get_signature_algorithm fn_gnutls_x509_crt_get_signature_algorithm | 498 | # define gnutls_x509_crt_get_signature_algorithm fn_gnutls_x509_crt_get_signature_algorithm |
| 469 | # define gnutls_x509_crt_get_subject_unique_id fn_gnutls_x509_crt_get_subject_unique_id | 499 | # define gnutls_x509_crt_get_subject_unique_id fn_gnutls_x509_crt_get_subject_unique_id |
| @@ -501,6 +531,9 @@ init_gnutls_functions (void) | |||
| 501 | # define gnutls_aead_cipher_init fn_gnutls_aead_cipher_init | 531 | # define gnutls_aead_cipher_init fn_gnutls_aead_cipher_init |
| 502 | # define gnutls_aead_cipher_deinit fn_gnutls_aead_cipher_deinit | 532 | # define gnutls_aead_cipher_deinit fn_gnutls_aead_cipher_deinit |
| 503 | # endif | 533 | # endif |
| 534 | # ifdef HAVE_GNUTLS_ETM_STATUS | ||
| 535 | # define gnutls_session_etm_status fn_gnutls_session_etm_status | ||
| 536 | # endif | ||
| 504 | # define gnutls_hmac_init fn_gnutls_hmac_init | 537 | # define gnutls_hmac_init fn_gnutls_hmac_init |
| 505 | # define gnutls_hmac_get_len fn_gnutls_hmac_get_len | 538 | # define gnutls_hmac_get_len fn_gnutls_hmac_get_len |
| 506 | # define gnutls_hmac fn_gnutls_hmac | 539 | # define gnutls_hmac fn_gnutls_hmac |
| @@ -1041,7 +1074,34 @@ gnutls_hex_string (unsigned char *buf, ptrdiff_t buf_size, const char *prefix) | |||
| 1041 | } | 1074 | } |
| 1042 | 1075 | ||
| 1043 | static Lisp_Object | 1076 | static Lisp_Object |
| 1044 | gnutls_certificate_details (gnutls_x509_crt_t cert) | 1077 | emacs_gnutls_certificate_export_pem (gnutls_x509_crt_t cert) |
| 1078 | { | ||
| 1079 | size_t size = 0; | ||
| 1080 | int err = gnutls_x509_crt_export (cert, GNUTLS_X509_FMT_PEM, NULL, &size); | ||
| 1081 | check_memory_full (err); | ||
| 1082 | |||
| 1083 | if (err == GNUTLS_E_SHORT_MEMORY_BUFFER) | ||
| 1084 | { | ||
| 1085 | unsigned char *buf = xmalloc(size * sizeof (unsigned char)); | ||
| 1086 | err = gnutls_x509_crt_export (cert, GNUTLS_X509_FMT_PEM, buf, &size); | ||
| 1087 | check_memory_full (err); | ||
| 1088 | |||
| 1089 | if (err < GNUTLS_E_SUCCESS) | ||
| 1090 | { | ||
| 1091 | xfree (buf); | ||
| 1092 | error ("GnuTLS certificate export error: %s", emacs_gnutls_strerror (err)); | ||
| 1093 | } | ||
| 1094 | |||
| 1095 | return build_string(buf); | ||
| 1096 | } | ||
| 1097 | else if (err < GNUTLS_E_SUCCESS) | ||
| 1098 | error ("GnuTLS certificate export error: %s", emacs_gnutls_strerror (err)); | ||
| 1099 | |||
| 1100 | return Qnil; | ||
| 1101 | } | ||
| 1102 | |||
| 1103 | static Lisp_Object | ||
| 1104 | emacs_gnutls_certificate_details (gnutls_x509_crt_t cert) | ||
| 1045 | { | 1105 | { |
| 1046 | Lisp_Object res = Qnil; | 1106 | Lisp_Object res = Qnil; |
| 1047 | int err; | 1107 | int err; |
| @@ -1209,6 +1269,10 @@ gnutls_certificate_details (gnutls_x509_crt_t cert) | |||
| 1209 | xfree (buf); | 1269 | xfree (buf); |
| 1210 | } | 1270 | } |
| 1211 | 1271 | ||
| 1272 | /* PEM */ | ||
| 1273 | res = nconc2 (res, list2 (intern (":pem"), | ||
| 1274 | emacs_gnutls_certificate_export_pem(cert))); | ||
| 1275 | |||
| 1212 | return res; | 1276 | return res; |
| 1213 | } | 1277 | } |
| 1214 | 1278 | ||
| @@ -1246,6 +1310,29 @@ DEFUN ("gnutls-peer-status-warning-describe", Fgnutls_peer_status_warning_descri | |||
| 1246 | if (EQ (status_symbol, intern (":no-host-match"))) | 1310 | if (EQ (status_symbol, intern (":no-host-match"))) |
| 1247 | return build_string ("certificate host does not match hostname"); | 1311 | return build_string ("certificate host does not match hostname"); |
| 1248 | 1312 | ||
| 1313 | if (EQ (status_symbol, intern (":signature-failure"))) | ||
| 1314 | return build_string ("certificate signature could not be verified"); | ||
| 1315 | |||
| 1316 | if (EQ (status_symbol, intern (":revocation-data-superseded"))) | ||
| 1317 | return build_string ("certificate revocation data are old and have been " | ||
| 1318 | "superseded"); | ||
| 1319 | |||
| 1320 | if (EQ (status_symbol, intern (":revocation-data-issued-in-future"))) | ||
| 1321 | return build_string ("certificate revocation data have a future issue date"); | ||
| 1322 | |||
| 1323 | if (EQ (status_symbol, intern (":signer-constraints-failure"))) | ||
| 1324 | return build_string ("certificate "); | ||
| 1325 | |||
| 1326 | if (EQ (status_symbol, intern (":purpose-mismatch"))) | ||
| 1327 | return build_string ("certificate does not match the intended purpose"); | ||
| 1328 | |||
| 1329 | if (EQ (status_symbol, intern (":missing-ocsp-status"))) | ||
| 1330 | return build_string ("certificate requires the server to send a OCSP " | ||
| 1331 | "certificate status, but no status was received"); | ||
| 1332 | |||
| 1333 | if (EQ (status_symbol, intern (":invalid-ocsp-status"))) | ||
| 1334 | return build_string ("the received OCSP certificate status is invalid"); | ||
| 1335 | |||
| 1249 | return Qnil; | 1336 | return Qnil; |
| 1250 | } | 1337 | } |
| 1251 | 1338 | ||
| @@ -1297,6 +1384,35 @@ returned as the :certificate entry. */) | |||
| 1297 | if (verification & GNUTLS_CERT_EXPIRED) | 1384 | if (verification & GNUTLS_CERT_EXPIRED) |
| 1298 | warnings = Fcons (intern (":expired"), warnings); | 1385 | warnings = Fcons (intern (":expired"), warnings); |
| 1299 | 1386 | ||
| 1387 | #if GNUTLS_VERSION_NUMBER >= 0x030100 | ||
| 1388 | if (verification & GNUTLS_CERT_SIGNATURE_FAILURE) | ||
| 1389 | warnings = Fcons (intern (":signature-failure"), warnings); | ||
| 1390 | |||
| 1391 | # if GNUTLS_VERSION_NUMBER >= 0x030114 | ||
| 1392 | if (verification & GNUTLS_CERT_REVOCATION_DATA_SUPERSEDED) | ||
| 1393 | warnings = Fcons (intern (":revocation-data-superseded"), warnings); | ||
| 1394 | |||
| 1395 | if (verification & GNUTLS_CERT_REVOCATION_DATA_ISSUED_IN_FUTURE) | ||
| 1396 | warnings = Fcons (intern (":revocation-data-issued-in-future"), warnings); | ||
| 1397 | |||
| 1398 | if (verification & GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE) | ||
| 1399 | warnings = Fcons (intern (":signer-constraints-failure"), warnings); | ||
| 1400 | |||
| 1401 | # if GNUTLS_VERSION_NUMBER >= 0x030400 | ||
| 1402 | if (verification & GNUTLS_CERT_PURPOSE_MISMATCH) | ||
| 1403 | warnings = Fcons (intern (":purpose-mismatch"), warnings); | ||
| 1404 | |||
| 1405 | # if GNUTLS_VERSION_NUMBER >= 0x030501 | ||
| 1406 | if (verification & GNUTLS_CERT_MISSING_OCSP_STATUS) | ||
| 1407 | warnings = Fcons (intern (":missing-ocsp-status"), warnings); | ||
| 1408 | |||
| 1409 | if (verification & GNUTLS_CERT_INVALID_OCSP_STATUS) | ||
| 1410 | warnings = Fcons (intern (":invalid-ocsp-status"), warnings); | ||
| 1411 | # endif | ||
| 1412 | # endif | ||
| 1413 | # endif | ||
| 1414 | #endif | ||
| 1415 | |||
| 1300 | if (XPROCESS (proc)->gnutls_extra_peer_verification & | 1416 | if (XPROCESS (proc)->gnutls_extra_peer_verification & |
| 1301 | CERTIFICATE_NOT_MATCHING) | 1417 | CERTIFICATE_NOT_MATCHING) |
| 1302 | warnings = Fcons (intern (":no-host-match"), warnings); | 1418 | warnings = Fcons (intern (":no-host-match"), warnings); |
| @@ -1319,7 +1435,7 @@ returned as the :certificate entry. */) | |||
| 1319 | 1435 | ||
| 1320 | /* Return all the certificates in a list. */ | 1436 | /* Return all the certificates in a list. */ |
| 1321 | for (int i = 0; i < XPROCESS (proc)->gnutls_certificates_length; i++) | 1437 | for (int i = 0; i < XPROCESS (proc)->gnutls_certificates_length; i++) |
| 1322 | certs = nconc2 (certs, list1 (gnutls_certificate_details | 1438 | certs = nconc2 (certs, list1 (emacs_gnutls_certificate_details |
| 1323 | (XPROCESS (proc)->gnutls_certificates[i]))); | 1439 | (XPROCESS (proc)->gnutls_certificates[i]))); |
| 1324 | 1440 | ||
| 1325 | result = nconc2 (result, list2 (intern (":certificates"), certs)); | 1441 | result = nconc2 (result, list2 (intern (":certificates"), certs)); |
| @@ -1364,6 +1480,26 @@ returned as the :certificate entry. */) | |||
| 1364 | build_string (gnutls_mac_get_name | 1480 | build_string (gnutls_mac_get_name |
| 1365 | (gnutls_mac_get (state))))); | 1481 | (gnutls_mac_get (state))))); |
| 1366 | 1482 | ||
| 1483 | /* Compression name. */ | ||
| 1484 | result = nconc2 | ||
| 1485 | (result, list2 (intern (":compression"), | ||
| 1486 | build_string (gnutls_compression_get_name | ||
| 1487 | (gnutls_compression_get (state))))); | ||
| 1488 | |||
| 1489 | /* Encrypt-then-MAC. */ | ||
| 1490 | result = nconc2 | ||
| 1491 | (result, list2 (intern (":encrypt-then-mac"), | ||
| 1492 | #ifdef HAVE_GNUTLS_ETM_STATUS | ||
| 1493 | gnutls_session_etm_status (state) ? Qt : Qnil | ||
| 1494 | #else | ||
| 1495 | Qnil | ||
| 1496 | #endif | ||
| 1497 | )); | ||
| 1498 | |||
| 1499 | /* Renegotiation Indication */ | ||
| 1500 | result = nconc2 | ||
| 1501 | (result, list2 (intern (":safe-renegotiation"), | ||
| 1502 | gnutls_safe_renegotiation_status (state) ? Qt : Qnil)); | ||
| 1367 | 1503 | ||
| 1368 | return result; | 1504 | return result; |
| 1369 | } | 1505 | } |
| @@ -1425,6 +1561,55 @@ boot_error (struct Lisp_Process *p, const char *m, ...) | |||
| 1425 | va_end (ap); | 1561 | va_end (ap); |
| 1426 | } | 1562 | } |
| 1427 | 1563 | ||
| 1564 | DEFUN ("gnutls-format-certificate", Fgnutls_format_certificate, Sgnutls_format_certificate, 1, 1, 0, | ||
| 1565 | doc: /* Format a X.509 certificate to a string. | ||
| 1566 | |||
| 1567 | Given a PEM-encoded X.509 certificate CERT, returns a human-readable | ||
| 1568 | string representation. */) | ||
| 1569 | (Lisp_Object cert) | ||
| 1570 | { | ||
| 1571 | CHECK_STRING (cert); | ||
| 1572 | |||
| 1573 | int err; | ||
| 1574 | gnutls_x509_crt_t crt; | ||
| 1575 | |||
| 1576 | err = gnutls_x509_crt_init (&crt); | ||
| 1577 | check_memory_full (err); | ||
| 1578 | if (err < GNUTLS_E_SUCCESS) | ||
| 1579 | error ("gnutls-format-certificate error: %s", emacs_gnutls_strerror (err)); | ||
| 1580 | |||
| 1581 | unsigned char *crt_buf = SDATA (cert); | ||
| 1582 | gnutls_datum_t crt_data = { crt_buf, strlen (crt_buf) }; | ||
| 1583 | err = gnutls_x509_crt_import (crt, &crt_data, GNUTLS_X509_FMT_PEM); | ||
| 1584 | check_memory_full (err); | ||
| 1585 | if (err < GNUTLS_E_SUCCESS) | ||
| 1586 | { | ||
| 1587 | gnutls_x509_crt_deinit (crt); | ||
| 1588 | error ("gnutls-format-certificate error: %s", emacs_gnutls_strerror (err)); | ||
| 1589 | } | ||
| 1590 | |||
| 1591 | gnutls_datum_t out; | ||
| 1592 | err = gnutls_x509_crt_print (crt, GNUTLS_CRT_PRINT_FULL, &out); | ||
| 1593 | check_memory_full (err); | ||
| 1594 | if (err < GNUTLS_E_SUCCESS) | ||
| 1595 | { | ||
| 1596 | gnutls_x509_crt_deinit (crt); | ||
| 1597 | error ("gnutls-format-certificate error: %s", emacs_gnutls_strerror (err)); | ||
| 1598 | } | ||
| 1599 | |||
| 1600 | char *out_buf = xmalloc ((out.size + 1) * sizeof (char)); | ||
| 1601 | memset (out_buf, 0, (out.size + 1) * sizeof (char)); | ||
| 1602 | memcpy (out_buf, out.data, out.size); | ||
| 1603 | |||
| 1604 | xfree (out.data); | ||
| 1605 | gnutls_x509_crt_deinit (crt); | ||
| 1606 | |||
| 1607 | Lisp_Object result = build_string (out_buf); | ||
| 1608 | xfree (out_buf); | ||
| 1609 | |||
| 1610 | return result; | ||
| 1611 | } | ||
| 1612 | |||
| 1428 | Lisp_Object | 1613 | Lisp_Object |
| 1429 | gnutls_verify_boot (Lisp_Object proc, Lisp_Object proplist) | 1614 | gnutls_verify_boot (Lisp_Object proc, Lisp_Object proplist) |
| 1430 | { | 1615 | { |
| @@ -2706,6 +2891,7 @@ syms_of_gnutls (void) | |||
| 2706 | defsubr (&Sgnutls_bye); | 2891 | defsubr (&Sgnutls_bye); |
| 2707 | defsubr (&Sgnutls_peer_status); | 2892 | defsubr (&Sgnutls_peer_status); |
| 2708 | defsubr (&Sgnutls_peer_status_warning_describe); | 2893 | defsubr (&Sgnutls_peer_status_warning_describe); |
| 2894 | defsubr (&Sgnutls_format_certificate); | ||
| 2709 | 2895 | ||
| 2710 | #ifdef HAVE_GNUTLS3 | 2896 | #ifdef HAVE_GNUTLS3 |
| 2711 | defsubr (&Sgnutls_ciphers); | 2897 | defsubr (&Sgnutls_ciphers); |
diff --git a/src/process.c b/src/process.c index 066edbc83d6..7097b7ace17 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -276,6 +276,10 @@ static int read_process_output (Lisp_Object, int); | |||
| 276 | static void create_pty (Lisp_Object); | 276 | static void create_pty (Lisp_Object); |
| 277 | static void exec_sentinel (Lisp_Object, Lisp_Object); | 277 | static void exec_sentinel (Lisp_Object, Lisp_Object); |
| 278 | 278 | ||
| 279 | static Lisp_Object | ||
| 280 | network_lookup_address_info_1 (Lisp_Object host, const char *service, | ||
| 281 | struct addrinfo *hints, struct addrinfo **res); | ||
| 282 | |||
| 279 | /* Number of bits set in connect_wait_mask. */ | 283 | /* Number of bits set in connect_wait_mask. */ |
| 280 | static int num_pending_connects; | 284 | static int num_pending_connects; |
| 281 | 285 | ||
| @@ -4106,7 +4110,7 @@ usage: (make-network-process &rest ARGS) */) | |||
| 4106 | if (!NILP (host)) | 4110 | if (!NILP (host)) |
| 4107 | { | 4111 | { |
| 4108 | struct addrinfo *res, *lres; | 4112 | struct addrinfo *res, *lres; |
| 4109 | int ret; | 4113 | Lisp_Object msg; |
| 4110 | 4114 | ||
| 4111 | maybe_quit (); | 4115 | maybe_quit (); |
| 4112 | 4116 | ||
| @@ -4115,20 +4119,11 @@ usage: (make-network-process &rest ARGS) */) | |||
| 4115 | hints.ai_family = family; | 4119 | hints.ai_family = family; |
| 4116 | hints.ai_socktype = socktype; | 4120 | hints.ai_socktype = socktype; |
| 4117 | 4121 | ||
| 4118 | ret = getaddrinfo (SSDATA (host), portstring, &hints, &res); | 4122 | msg = network_lookup_address_info_1 (host, portstring, &hints, &res); |
| 4119 | if (ret) | 4123 | if (!EQ(msg, Qt)) |
| 4120 | #ifdef HAVE_GAI_STRERROR | 4124 | { |
| 4121 | { | 4125 | error ("%s", SSDATA (msg)); |
| 4122 | synchronize_system_messages_locale (); | 4126 | } |
| 4123 | char const *str = gai_strerror (ret); | ||
| 4124 | if (! NILP (Vlocale_coding_system)) | ||
| 4125 | str = SSDATA (code_convert_string_norecord | ||
| 4126 | (build_string (str), Vlocale_coding_system, 0)); | ||
| 4127 | error ("%s/%s %s", SSDATA (host), portstring, str); | ||
| 4128 | } | ||
| 4129 | #else | ||
| 4130 | error ("%s/%s getaddrinfo error %d", SSDATA (host), portstring, ret); | ||
| 4131 | #endif | ||
| 4132 | 4127 | ||
| 4133 | for (lres = res; lres; lres = lres->ai_next) | 4128 | for (lres = res; lres; lres = lres->ai_next) |
| 4134 | addrinfos = Fcons (conv_addrinfo_to_lisp (lres), addrinfos); | 4129 | addrinfos = Fcons (conv_addrinfo_to_lisp (lres), addrinfos); |
| @@ -4576,6 +4571,88 @@ Data that is unavailable is returned as nil. */) | |||
| 4576 | #endif | 4571 | #endif |
| 4577 | } | 4572 | } |
| 4578 | 4573 | ||
| 4574 | static Lisp_Object | ||
| 4575 | network_lookup_address_info_1 (Lisp_Object host, const char *service, | ||
| 4576 | struct addrinfo *hints, struct addrinfo **res) | ||
| 4577 | { | ||
| 4578 | Lisp_Object msg = Qt; | ||
| 4579 | int ret; | ||
| 4580 | |||
| 4581 | if (STRING_MULTIBYTE (host) && SBYTES (host) != SCHARS (host)) | ||
| 4582 | error ("Non-ASCII hostname %s detected, please use puny-encode-domain", | ||
| 4583 | SSDATA (host)); | ||
| 4584 | ret = getaddrinfo (SSDATA (host), service, hints, res); | ||
| 4585 | if (ret) | ||
| 4586 | { | ||
| 4587 | if (service == NULL) | ||
| 4588 | service = "0"; | ||
| 4589 | #ifdef HAVE_GAI_STRERROR | ||
| 4590 | synchronize_system_messages_locale (); | ||
| 4591 | char const *str = gai_strerror (ret); | ||
| 4592 | if (! NILP (Vlocale_coding_system)) | ||
| 4593 | str = SSDATA (code_convert_string_norecord | ||
| 4594 | (build_string (str), Vlocale_coding_system, 0)); | ||
| 4595 | AUTO_STRING (format, "%s/%s %s"); | ||
| 4596 | msg = CALLN (Fformat, format, host, build_string (service), build_string (str)); | ||
| 4597 | #else | ||
| 4598 | AUTO_STRING (format, "%s/%s getaddrinfo error %d"); | ||
| 4599 | msg = CALLN (Fformat, format, host, build_string (service), make_number (ret)); | ||
| 4600 | #endif | ||
| 4601 | } | ||
| 4602 | return msg; | ||
| 4603 | } | ||
| 4604 | |||
| 4605 | DEFUN ("network-lookup-address-info", Fnetwork_lookup_address_info, | ||
| 4606 | Snetwork_lookup_address_info, 1, 2, 0, | ||
| 4607 | doc: /* Look up ip address info of NAME. | ||
| 4608 | Optional parameter FAMILY controls whether to look up IPv4 or IPv6 | ||
| 4609 | addresses. The default of nil means both, symbol `ipv4' means IPv4 | ||
| 4610 | only, symbol `ipv6' means IPv6 only. Returns a list of addresses, or | ||
| 4611 | nil if none were found. Each address is a vector of integers. */) | ||
| 4612 | (Lisp_Object name, Lisp_Object family) | ||
| 4613 | { | ||
| 4614 | Lisp_Object addresses = Qnil; | ||
| 4615 | Lisp_Object msg = Qnil; | ||
| 4616 | |||
| 4617 | struct addrinfo *res, *lres; | ||
| 4618 | struct addrinfo hints; | ||
| 4619 | |||
| 4620 | memset (&hints, 0, sizeof hints); | ||
| 4621 | if (EQ (family, Qnil)) | ||
| 4622 | hints.ai_family = AF_UNSPEC; | ||
| 4623 | else if (EQ (family, Qipv4)) | ||
| 4624 | hints.ai_family = AF_INET; | ||
| 4625 | else if (EQ (family, Qipv6)) | ||
| 4626 | #ifdef AF_INET6 | ||
| 4627 | hints.ai_family = AF_INET6; | ||
| 4628 | #else | ||
| 4629 | /* If we don't support IPv6, querying will never work anyway */ | ||
| 4630 | return addresses; | ||
| 4631 | #endif | ||
| 4632 | else | ||
| 4633 | error ("Unsupported lookup type"); | ||
| 4634 | hints.ai_socktype = SOCK_DGRAM; | ||
| 4635 | |||
| 4636 | msg = network_lookup_address_info_1 (name, NULL, &hints, &res); | ||
| 4637 | if (!EQ(msg, Qt)) | ||
| 4638 | { | ||
| 4639 | message ("%s", SSDATA(msg)); | ||
| 4640 | } | ||
| 4641 | else | ||
| 4642 | { | ||
| 4643 | for (lres = res; lres; lres = lres->ai_next) | ||
| 4644 | { | ||
| 4645 | addresses = Fcons (conv_sockaddr_to_lisp | ||
| 4646 | (lres->ai_addr, lres->ai_addrlen), | ||
| 4647 | addresses); | ||
| 4648 | } | ||
| 4649 | addresses = Fnreverse (addresses); | ||
| 4650 | |||
| 4651 | freeaddrinfo (res); | ||
| 4652 | } | ||
| 4653 | return addresses; | ||
| 4654 | } | ||
| 4655 | |||
| 4579 | /* Turn off input and output for process PROC. */ | 4656 | /* Turn off input and output for process PROC. */ |
| 4580 | 4657 | ||
| 4581 | static void | 4658 | static void |
| @@ -8345,6 +8422,7 @@ returns non-`nil'. */); | |||
| 8345 | defsubr (&Sset_network_process_option); | 8422 | defsubr (&Sset_network_process_option); |
| 8346 | defsubr (&Smake_network_process); | 8423 | defsubr (&Smake_network_process); |
| 8347 | defsubr (&Sformat_network_address); | 8424 | defsubr (&Sformat_network_address); |
| 8425 | defsubr (&Snetwork_lookup_address_info); | ||
| 8348 | defsubr (&Snetwork_interface_list); | 8426 | defsubr (&Snetwork_interface_list); |
| 8349 | defsubr (&Snetwork_interface_info); | 8427 | defsubr (&Snetwork_interface_info); |
| 8350 | #ifdef DATAGRAM_SOCKETS | 8428 | #ifdef DATAGRAM_SOCKETS |