http_trust_t /* O - Level of trust */ httpCredentialsGetTrust( cups_array_t *credentials, /* I - Credentials */ const char *common_name) /* I - Common name for trust lookup */ { http_trust_t trust = HTTP_TRUST_OK; /* Trusted? */ gnutls_x509_crt_t cert; /* Certificate */ cups_array_t *tcreds = NULL; /* Trusted credentials */ _cups_globals_t *cg = _cupsGlobals(); /* Per-thread globals */ if (!common_name) return (HTTP_TRUST_UNKNOWN); if ((cert = http_gnutls_create_credential((http_credential_t *)cupsArrayFirst(credentials))) == NULL) return (HTTP_TRUST_UNKNOWN); if (cg->any_root < 0) _cupsSetDefaults(); /* * Look this common name up in the default keychains... */ httpLoadCredentials(NULL, &tcreds, common_name); if (tcreds) { char credentials_str[1024], /* String for incoming credentials */ tcreds_str[1024]; /* String for saved credentials */ httpCredentialsString(credentials, credentials_str, sizeof(credentials_str)); httpCredentialsString(tcreds, tcreds_str, sizeof(tcreds_str)); if (strcmp(credentials_str, tcreds_str)) { /* * Credentials don't match, let's look at the expiration date of the new * credentials and allow if the new ones have a later expiration... */ if (httpCredentialsGetExpiration(credentials) <= httpCredentialsGetExpiration(tcreds) || !httpCredentialsAreValidForName(credentials, common_name)) { /* * Either the new credentials are not newly issued, or the common name * does not match the issued certificate... */ trust = HTTP_TRUST_INVALID; } else if (httpCredentialsGetExpiration(tcreds) < time(NULL)) { /* * Save the renewed credentials... */ trust = HTTP_TRUST_RENEWED; httpSaveCredentials(NULL, credentials, common_name); } } httpFreeCredentials(tcreds); } else if (cg->validate_certs && !httpCredentialsAreValidForName(credentials, common_name)) trust = HTTP_TRUST_INVALID; if (trust == HTTP_TRUST_OK && !cg->expired_certs) { time_t curtime; /* Current date/time */ time(&curtime); if (curtime < gnutls_x509_crt_get_activation_time(cert) || curtime > gnutls_x509_crt_get_expiration_time(cert)) trust = HTTP_TRUST_EXPIRED; } if (trust == HTTP_TRUST_OK && !cg->any_root && cupsArrayCount(credentials) == 1) trust = HTTP_TRUST_INVALID; gnutls_x509_crt_deinit(cert); return (trust); }
int /* O - 0 on success, -1 on error */ httpLoadCredentials( const char *path, /* I - Keychain/PKCS#12 path */ cups_array_t **credentials, /* IO - Credentials */ const char *common_name) /* I - Common name for credentials */ { cups_file_t *fp; /* Certificate file */ char filename[1024], /* filename.crt */ temp[1024], /* Temporary string */ line[256]; /* Base64-encoded line */ unsigned char *data = NULL; /* Buffer for cert data */ size_t alloc_data = 0, /* Bytes allocated */ num_data = 0; /* Bytes used */ int decoded; /* Bytes decoded */ if (!credentials || !common_name) return (-1); if (!path) path = http_gnutls_default_path(temp, sizeof(temp)); if (!path) return (-1); http_gnutls_make_path(filename, sizeof(filename), path, common_name, "crt"); if ((fp = cupsFileOpen(filename, "r")) == NULL) return (-1); while (cupsFileGets(fp, line, sizeof(line))) { if (!strcmp(line, "-----BEGIN CERTIFICATE-----")) { if (num_data) { /* * Missing END CERTIFICATE... */ httpFreeCredentials(*credentials); *credentials = NULL; break; } } else if (!strcmp(line, "-----END CERTIFICATE-----")) { if (!num_data) { /* * Missing data... */ httpFreeCredentials(*credentials); *credentials = NULL; break; } if (!*credentials) *credentials = cupsArrayNew(NULL, NULL); if (httpAddCredential(*credentials, data, num_data)) { httpFreeCredentials(*credentials); *credentials = NULL; break; } num_data = 0; } else { if (alloc_data == 0) { data = malloc(2048); alloc_data = 2048; if (!data) break; } else if ((num_data + strlen(line)) >= alloc_data) { unsigned char *tdata = realloc(data, alloc_data + 1024); /* Expanded buffer */ if (!tdata) { httpFreeCredentials(*credentials); *credentials = NULL; break; } data = tdata; alloc_data += 1024; } decoded = alloc_data - num_data; httpDecode64_2((char *)data + num_data, &decoded, line); num_data += (size_t)decoded; } } cupsFileClose(fp); if (num_data) { /* * Missing END CERTIFICATE... */ httpFreeCredentials(*credentials); *credentials = NULL; } if (data) free(data); return (*credentials ? 0 : -1); }
int /* O - Exit status */ main(int argc, /* I - Number of command-line arguments */ char *argv[]) /* I - Command-line arguments */ { int i; /* Looping var */ http_t *http; /* HTTP connection */ const char *server = NULL; /* Hostname from command-line */ int port = 0; /* Port number */ cups_array_t *creds; /* Server credentials */ char creds_str[2048]; /* Credentials string */ const char *cipherName = "UNKNOWN";/* Cipher suite name */ int dhBits = 0; /* Diffie-Hellman bits */ int tlsVersion = 0; /* TLS version number */ char uri[1024], /* Printer URI */ scheme[32], /* URI scheme */ host[256], /* Hostname */ userpass[256], /* Username/password */ resource[256]; /* Resource path */ int af = AF_UNSPEC, /* Address family */ tls_options = _HTTP_TLS_NONE, /* TLS options */ tls_min_version = _HTTP_TLS_1_0, tls_max_version = _HTTP_TLS_MAX, verbose = 0; /* Verbosity */ ipp_t *request, /* IPP Get-Printer-Attributes request */ *response; /* IPP Get-Printer-Attributes response */ ipp_attribute_t *attr; /* Current attribute */ const char *name; /* Attribute name */ char value[1024]; /* Attribute (string) value */ static const char * const pattrs[] = /* Requested attributes */ { "color-supported", "compression-supported", "document-format-supported", "pages-per-minute", "printer-location", "printer-make-and-model", "printer-state", "printer-state-reasons", "sides-supported", "uri-authentication-supported", "uri-security-supported" }; for (i = 1; i < argc; i ++) { if (!strcmp(argv[i], "--dh")) { tls_options |= _HTTP_TLS_ALLOW_DH; } else if (!strcmp(argv[i], "--no-cbc")) { tls_options |= _HTTP_TLS_DENY_CBC; } else if (!strcmp(argv[i], "--no-tls10")) { tls_min_version = _HTTP_TLS_1_1; } else if (!strcmp(argv[i], "--tls10")) { tls_min_version = _HTTP_TLS_1_0; tls_max_version = _HTTP_TLS_1_0; } else if (!strcmp(argv[i], "--tls11")) { tls_min_version = _HTTP_TLS_1_1; tls_max_version = _HTTP_TLS_1_1; } else if (!strcmp(argv[i], "--tls12")) { tls_min_version = _HTTP_TLS_1_2; tls_max_version = _HTTP_TLS_1_2; } else if (!strcmp(argv[i], "--tls13")) { tls_min_version = _HTTP_TLS_1_3; tls_max_version = _HTTP_TLS_1_3; } else if (!strcmp(argv[i], "--rc4")) { tls_options |= _HTTP_TLS_ALLOW_RC4; } else if (!strcmp(argv[i], "--verbose") || !strcmp(argv[i], "-v")) { verbose = 1; } else if (!strcmp(argv[i], "-4")) { af = AF_INET; } else if (!strcmp(argv[i], "-6")) { af = AF_INET6; } else if (argv[i][0] == '-') { printf("tlscheck: Unknown option '%s'.\n", argv[i]); usage(); } else if (!server) { if (!strncmp(argv[i], "ipps://", 7)) { httpSeparateURI(HTTP_URI_CODING_ALL, argv[i], scheme, sizeof(scheme), userpass, sizeof(userpass), host, sizeof(host), &port, resource, sizeof(resource)); server = host; } else { server = argv[i]; strlcpy(resource, "/ipp/print", sizeof(resource)); } } else if (!port && (argv[i][0] == '=' || isdigit(argv[i][0] & 255))) { if (argv[i][0] == '=') port = atoi(argv[i] + 1); else port = atoi(argv[i]); } else { printf("tlscheck: Unexpected argument '%s'.\n", argv[i]); usage(); } } if (!server) usage(); if (!port) port = 631; _httpTLSSetOptions(tls_options, tls_min_version, tls_max_version); http = httpConnect2(server, port, NULL, af, HTTP_ENCRYPTION_ALWAYS, 1, 30000, NULL); if (!http) { printf("%s: ERROR (%s)\n", server, cupsLastErrorString()); return (1); } if (httpCopyCredentials(http, &creds)) { strlcpy(creds_str, "Unable to get server X.509 credentials.", sizeof(creds_str)); } else { httpCredentialsString(creds, creds_str, sizeof(creds_str)); httpFreeCredentials(creds); } #ifdef __APPLE__ SSLProtocol protocol; SSLCipherSuite cipher; char unknownCipherName[256]; int paramsNeeded = 0; const void *params; size_t paramsLen; OSStatus err; if ((err = SSLGetNegotiatedProtocolVersion(http->tls, &protocol)) != noErr) { printf("%s: ERROR (No protocol version - %d)\n", server, (int)err); httpClose(http); return (1); } switch (protocol) { default : tlsVersion = 0; break; case kSSLProtocol3 : tlsVersion = 30; break; case kTLSProtocol1 : tlsVersion = 10; break; case kTLSProtocol11 : tlsVersion = 11; break; case kTLSProtocol12 : tlsVersion = 12; break; } if ((err = SSLGetNegotiatedCipher(http->tls, &cipher)) != noErr) { printf("%s: ERROR (No cipher suite - %d)\n", server, (int)err); httpClose(http); return (1); } switch (cipher) { case TLS_NULL_WITH_NULL_NULL: cipherName = "TLS_NULL_WITH_NULL_NULL"; break; case TLS_RSA_WITH_NULL_MD5: cipherName = "TLS_RSA_WITH_NULL_MD5"; break; case TLS_RSA_WITH_NULL_SHA: cipherName = "TLS_RSA_WITH_NULL_SHA"; break; case TLS_RSA_WITH_RC4_128_MD5: cipherName = "TLS_RSA_WITH_RC4_128_MD5"; break; case TLS_RSA_WITH_RC4_128_SHA: cipherName = "TLS_RSA_WITH_RC4_128_SHA"; break; case TLS_RSA_WITH_3DES_EDE_CBC_SHA: cipherName = "TLS_RSA_WITH_3DES_EDE_CBC_SHA"; break; case TLS_RSA_WITH_NULL_SHA256: cipherName = "TLS_RSA_WITH_NULL_SHA256"; break; case TLS_RSA_WITH_AES_128_CBC_SHA256: cipherName = "TLS_RSA_WITH_AES_128_CBC_SHA256"; break; case TLS_RSA_WITH_AES_256_CBC_SHA256: cipherName = "TLS_RSA_WITH_AES_256_CBC_SHA256"; break; case TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA: cipherName = "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA"; paramsNeeded = 1; break; case TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA: cipherName = "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA"; paramsNeeded = 1; break; case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA: cipherName = "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA"; paramsNeeded = 1; break; case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA: cipherName = "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA"; paramsNeeded = 1; break; case TLS_DH_DSS_WITH_AES_128_CBC_SHA256: cipherName = "TLS_DH_DSS_WITH_AES_128_CBC_SHA256"; paramsNeeded = 1; break; case TLS_DH_RSA_WITH_AES_128_CBC_SHA256: cipherName = "TLS_DH_RSA_WITH_AES_128_CBC_SHA256"; paramsNeeded = 1; break; case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: cipherName = "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256"; paramsNeeded = 1; break; case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: cipherName = "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256"; paramsNeeded = 1; break; case TLS_DH_DSS_WITH_AES_256_CBC_SHA256: cipherName = "TLS_DH_DSS_WITH_AES_256_CBC_SHA256"; paramsNeeded = 1; break; case TLS_DH_RSA_WITH_AES_256_CBC_SHA256: cipherName = "TLS_DH_RSA_WITH_AES_256_CBC_SHA256"; paramsNeeded = 1; break; case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: cipherName = "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256"; paramsNeeded = 1; break; case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: cipherName = "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"; paramsNeeded = 1; break; case TLS_DH_anon_WITH_RC4_128_MD5: cipherName = "TLS_DH_anon_WITH_RC4_128_MD5"; paramsNeeded = 1; break; case TLS_DH_anon_WITH_3DES_EDE_CBC_SHA: cipherName = "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA"; paramsNeeded = 1; break; case TLS_DH_anon_WITH_AES_128_CBC_SHA256: cipherName = "TLS_DH_anon_WITH_AES_128_CBC_SHA256"; paramsNeeded = 1; break; case TLS_DH_anon_WITH_AES_256_CBC_SHA256: cipherName = "TLS_DH_anon_WITH_AES_256_CBC_SHA256"; paramsNeeded = 1; break; case TLS_PSK_WITH_RC4_128_SHA: cipherName = "TLS_PSK_WITH_RC4_128_SHA"; break; case TLS_PSK_WITH_3DES_EDE_CBC_SHA: cipherName = "TLS_PSK_WITH_3DES_EDE_CBC_SHA"; break; case TLS_PSK_WITH_AES_128_CBC_SHA: cipherName = "TLS_PSK_WITH_AES_128_CBC_SHA"; break; case TLS_PSK_WITH_AES_256_CBC_SHA: cipherName = "TLS_PSK_WITH_AES_256_CBC_SHA"; break; case TLS_DHE_PSK_WITH_RC4_128_SHA: cipherName = "TLS_DHE_PSK_WITH_RC4_128_SHA"; paramsNeeded = 1; break; case TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA: cipherName = "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA"; paramsNeeded = 1; break; case TLS_DHE_PSK_WITH_AES_128_CBC_SHA: cipherName = "TLS_DHE_PSK_WITH_AES_128_CBC_SHA"; paramsNeeded = 1; break; case TLS_DHE_PSK_WITH_AES_256_CBC_SHA: cipherName = "TLS_DHE_PSK_WITH_AES_256_CBC_SHA"; paramsNeeded = 1; break; case TLS_RSA_PSK_WITH_RC4_128_SHA: cipherName = "TLS_RSA_PSK_WITH_RC4_128_SHA"; break; case TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA: cipherName = "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA"; break; case TLS_RSA_PSK_WITH_AES_128_CBC_SHA: cipherName = "TLS_RSA_PSK_WITH_AES_128_CBC_SHA"; break; case TLS_RSA_PSK_WITH_AES_256_CBC_SHA: cipherName = "TLS_RSA_PSK_WITH_AES_256_CBC_SHA"; break; case TLS_PSK_WITH_NULL_SHA: cipherName = "TLS_PSK_WITH_NULL_SHA"; break; case TLS_DHE_PSK_WITH_NULL_SHA: cipherName = "TLS_DHE_PSK_WITH_NULL_SHA"; paramsNeeded = 1; break; case TLS_RSA_PSK_WITH_NULL_SHA: cipherName = "TLS_RSA_PSK_WITH_NULL_SHA"; break; case TLS_RSA_WITH_AES_128_GCM_SHA256: cipherName = "TLS_RSA_WITH_AES_128_GCM_SHA256"; break; case TLS_RSA_WITH_AES_256_GCM_SHA384: cipherName = "TLS_RSA_WITH_AES_256_GCM_SHA384"; break; case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: cipherName = "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"; paramsNeeded = 1; break; case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: cipherName = "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384"; paramsNeeded = 1; break; case TLS_DH_RSA_WITH_AES_128_GCM_SHA256: cipherName = "TLS_DH_RSA_WITH_AES_128_GCM_SHA256"; paramsNeeded = 1; break; case TLS_DH_RSA_WITH_AES_256_GCM_SHA384: cipherName = "TLS_DH_RSA_WITH_AES_256_GCM_SHA384"; paramsNeeded = 1; break; case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: cipherName = "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256"; paramsNeeded = 1; break; case TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: cipherName = "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384"; paramsNeeded = 1; break; case TLS_DH_DSS_WITH_AES_128_GCM_SHA256: cipherName = "TLS_DH_DSS_WITH_AES_128_GCM_SHA256"; paramsNeeded = 1; break; case TLS_DH_DSS_WITH_AES_256_GCM_SHA384: cipherName = "TLS_DH_DSS_WITH_AES_256_GCM_SHA384"; paramsNeeded = 1; break; case TLS_DH_anon_WITH_AES_128_GCM_SHA256: cipherName = "TLS_DH_anon_WITH_AES_128_GCM_SHA256"; paramsNeeded = 1; break; case TLS_DH_anon_WITH_AES_256_GCM_SHA384: cipherName = "TLS_DH_anon_WITH_AES_256_GCM_SHA384"; paramsNeeded = 1; break; case TLS_PSK_WITH_AES_128_GCM_SHA256: cipherName = "TLS_PSK_WITH_AES_128_GCM_SHA256"; break; case TLS_PSK_WITH_AES_256_GCM_SHA384: cipherName = "TLS_PSK_WITH_AES_256_GCM_SHA384"; break; case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256: cipherName = "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256"; paramsNeeded = 1; break; case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384: cipherName = "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384"; paramsNeeded = 1; break; case TLS_RSA_PSK_WITH_AES_128_GCM_SHA256: cipherName = "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256"; break; case TLS_RSA_PSK_WITH_AES_256_GCM_SHA384: cipherName = "TLS_RSA_PSK_WITH_AES_256_GCM_SHA384"; break; case TLS_PSK_WITH_AES_128_CBC_SHA256: cipherName = "TLS_PSK_WITH_AES_128_CBC_SHA256"; break; case TLS_PSK_WITH_AES_256_CBC_SHA384: cipherName = "TLS_PSK_WITH_AES_256_CBC_SHA384"; break; case TLS_PSK_WITH_NULL_SHA256: cipherName = "TLS_PSK_WITH_NULL_SHA256"; break; case TLS_PSK_WITH_NULL_SHA384: cipherName = "TLS_PSK_WITH_NULL_SHA384"; break; case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256: cipherName = "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256"; paramsNeeded = 1; break; case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384: cipherName = "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384"; paramsNeeded = 1; break; case TLS_DHE_PSK_WITH_NULL_SHA256: cipherName = "TLS_DHE_PSK_WITH_NULL_SHA256"; paramsNeeded = 1; break; case TLS_DHE_PSK_WITH_NULL_SHA384: cipherName = "TLS_DHE_PSK_WITH_NULL_SHA384"; paramsNeeded = 1; break; case TLS_RSA_PSK_WITH_AES_128_CBC_SHA256: cipherName = "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256"; break; case TLS_RSA_PSK_WITH_AES_256_CBC_SHA384: cipherName = "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384"; break; case TLS_RSA_PSK_WITH_NULL_SHA256: cipherName = "TLS_RSA_PSK_WITH_NULL_SHA256"; break; case TLS_RSA_PSK_WITH_NULL_SHA384: cipherName = "TLS_RSA_PSK_WITH_NULL_SHA384"; break; case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: cipherName = "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"; paramsNeeded = 1; break; case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: cipherName = "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384"; paramsNeeded = 1; break; case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: cipherName = "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256"; paramsNeeded = 1; break; case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: cipherName = "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384"; paramsNeeded = 1; break; case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: cipherName = "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"; paramsNeeded = 1; break; case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: cipherName = "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"; paramsNeeded = 1; break; case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: cipherName = "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256"; paramsNeeded = 1; break; case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: cipherName = "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384"; paramsNeeded = 1; break; case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: cipherName = "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"; paramsNeeded = 1; break; case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: cipherName = "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"; paramsNeeded = 1; break; case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: cipherName = "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256"; paramsNeeded = 1; break; case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: cipherName = "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384"; paramsNeeded = 1; break; case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: cipherName = "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"; paramsNeeded = 1; break; case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: cipherName = "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"; paramsNeeded = 1; break; case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: cipherName = "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256"; paramsNeeded = 1; break; case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: cipherName = "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384"; paramsNeeded = 1; break; case TLS_RSA_WITH_AES_128_CBC_SHA: cipherName = "TLS_RSA_WITH_AES_128_CBC_SHA"; break; case TLS_DH_DSS_WITH_AES_128_CBC_SHA: cipherName = "TLS_DH_DSS_WITH_AES_128_CBC_SHA"; paramsNeeded = 1; break; case TLS_DH_RSA_WITH_AES_128_CBC_SHA: cipherName = "TLS_DH_RSA_WITH_AES_128_CBC_SHA"; paramsNeeded = 1; break; case TLS_DHE_DSS_WITH_AES_128_CBC_SHA: cipherName = "TLS_DHE_DSS_WITH_AES_128_CBC_SHA"; paramsNeeded = 1; break; case TLS_DHE_RSA_WITH_AES_128_CBC_SHA: cipherName = "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"; paramsNeeded = 1; break; case TLS_DH_anon_WITH_AES_128_CBC_SHA: cipherName = "TLS_DH_anon_WITH_AES_128_CBC_SHA"; paramsNeeded = 1; break; case TLS_RSA_WITH_AES_256_CBC_SHA: cipherName = "TLS_RSA_WITH_AES_256_CBC_SHA"; break; case TLS_DH_DSS_WITH_AES_256_CBC_SHA: cipherName = "TLS_DH_DSS_WITH_AES_256_CBC_SHA"; paramsNeeded = 1; break; case TLS_DH_RSA_WITH_AES_256_CBC_SHA: cipherName = "TLS_DH_RSA_WITH_AES_256_CBC_SHA"; paramsNeeded = 1; break; case TLS_DHE_DSS_WITH_AES_256_CBC_SHA: cipherName = "TLS_DHE_DSS_WITH_AES_256_CBC_SHA"; paramsNeeded = 1; break; case TLS_DHE_RSA_WITH_AES_256_CBC_SHA: cipherName = "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"; paramsNeeded = 1; break; case TLS_DH_anon_WITH_AES_256_CBC_SHA: cipherName = "TLS_DH_anon_WITH_AES_256_CBC_SHA"; paramsNeeded = 1; break; case TLS_ECDH_ECDSA_WITH_NULL_SHA: cipherName = "TLS_ECDH_ECDSA_WITH_NULL_SHA"; paramsNeeded = 1; break; case TLS_ECDH_ECDSA_WITH_RC4_128_SHA: cipherName = "TLS_ECDH_ECDSA_WITH_RC4_128_SHA"; paramsNeeded = 1; break; case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: cipherName = "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA"; paramsNeeded = 1; break; case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: cipherName = "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA"; paramsNeeded = 1; break; case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: cipherName = "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA"; paramsNeeded = 1; break; case TLS_ECDHE_ECDSA_WITH_NULL_SHA: cipherName = "TLS_ECDHE_ECDSA_WITH_NULL_SHA"; paramsNeeded = 1; break; case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: cipherName = "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA"; paramsNeeded = 1; break; case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: cipherName = "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA"; paramsNeeded = 1; break; case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: cipherName = "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"; paramsNeeded = 1; break; case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: cipherName = "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"; paramsNeeded = 1; break; case TLS_ECDH_RSA_WITH_NULL_SHA: cipherName = "TLS_ECDH_RSA_WITH_NULL_SHA"; paramsNeeded = 1; break; case TLS_ECDH_RSA_WITH_RC4_128_SHA: cipherName = "TLS_ECDH_RSA_WITH_RC4_128_SHA"; paramsNeeded = 1; break; case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA: cipherName = "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA"; paramsNeeded = 1; break; case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: cipherName = "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA"; paramsNeeded = 1; break; case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: cipherName = "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA"; paramsNeeded = 1; break; case TLS_ECDHE_RSA_WITH_NULL_SHA: cipherName = "TLS_ECDHE_RSA_WITH_NULL_SHA"; paramsNeeded = 1; break; case TLS_ECDHE_RSA_WITH_RC4_128_SHA: cipherName = "TLS_ECDHE_RSA_WITH_RC4_128_SHA"; paramsNeeded = 1; break; case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: cipherName = "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA"; paramsNeeded = 1; break; case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: cipherName = "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"; paramsNeeded = 1; break; case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: cipherName = "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"; paramsNeeded = 1; break; case TLS_ECDH_anon_WITH_NULL_SHA: cipherName = "TLS_ECDH_anon_WITH_NULL_SHA"; paramsNeeded = 1; break; case TLS_ECDH_anon_WITH_RC4_128_SHA: cipherName = "TLS_ECDH_anon_WITH_RC4_128_SHA"; paramsNeeded = 1; break; case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA: cipherName = "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA"; paramsNeeded = 1; break; case TLS_ECDH_anon_WITH_AES_128_CBC_SHA: cipherName = "TLS_ECDH_anon_WITH_AES_128_CBC_SHA"; paramsNeeded = 1; break; case TLS_ECDH_anon_WITH_AES_256_CBC_SHA: cipherName = "TLS_ECDH_anon_WITH_AES_256_CBC_SHA"; paramsNeeded = 1; break; default : snprintf(unknownCipherName, sizeof(unknownCipherName), "UNKNOWN_%04X", cipher); cipherName = unknownCipherName; break; } if (cipher == TLS_RSA_WITH_RC4_128_MD5 || cipher == TLS_RSA_WITH_RC4_128_SHA) { printf("%s: ERROR (Printers MUST NOT negotiate RC4 cipher suites.)\n", server); httpClose(http); return (1); } if ((err = SSLGetDiffieHellmanParams(http->tls, ¶ms, ¶msLen)) != noErr && paramsNeeded) { printf("%s: ERROR (Unable to get Diffie-Hellman parameters - %d)\n", server, (int)err); httpClose(http); return (1); } if (paramsLen < 128 && paramsLen != 0) { printf("%s: ERROR (Diffie-Hellman parameters MUST be at least 2048 bits, but Printer uses only %d bits/%d bytes)\n", server, (int)paramsLen * 8, (int)paramsLen); httpClose(http); return (1); } dhBits = (int)paramsLen * 8; #endif /* __APPLE__ */ if (dhBits > 0) printf("%s: OK (TLS: %d.%d, %s, %d DH bits)\n", server, tlsVersion / 10, tlsVersion % 10, cipherName, dhBits); else printf("%s: OK (TLS: %d.%d, %s)\n", server, tlsVersion / 10, tlsVersion % 10, cipherName); printf(" %s\n", creds_str); if (verbose) { httpAssembleURI(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipps", NULL, host, port, resource); request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", (int)(sizeof(pattrs) / sizeof(pattrs[0])), NULL, pattrs); response = cupsDoRequest(http, request, resource); for (attr = ippFirstAttribute(response); attr; attr = ippNextAttribute(response)) { if (ippGetGroupTag(attr) != IPP_TAG_PRINTER) continue; if ((name = ippGetName(attr)) == NULL) continue; ippAttributeString(attr, value, sizeof(value)); printf(" %s=%s\n", name, value); } ippDelete(response); puts(""); } httpClose(http); return (0); }