static int _SSL_check_subject_altname (X509 *cert, const char *host) { STACK_OF(GENERAL_NAME) *altname_stack = NULL; GInetAddress *addr; GSocketFamily family; int type = GEN_DNS; int count, i; int rv = -1; altname_stack = X509_get_ext_d2i (cert, NID_subject_alt_name, NULL, NULL); if (altname_stack == NULL) return -1; addr = g_inet_address_new_from_string (host); if (addr != NULL) { family = g_inet_address_get_family (addr); if (family == G_SOCKET_FAMILY_IPV4 || family == G_SOCKET_FAMILY_IPV6) type = GEN_IPADD; } count = sk_GENERAL_NAME_num(altname_stack); for (i = 0; i < count; i++) { GENERAL_NAME *altname; altname = sk_GENERAL_NAME_value (altname_stack, i); if (altname->type != type) continue; if (type == GEN_DNS) { unsigned char *data; int format; format = ASN1_STRING_type (altname->d.dNSName); if (format == V_ASN1_IA5STRING) { data = ASN1_STRING_data (altname->d.dNSName); if (ASN1_STRING_length (altname->d.dNSName) != (int)strlen(data)) { g_warning("NUL byte in subjectAltName, probably a malicious certificate.\n"); rv = -2; break; } if (_SSL_match_hostname (data, host) == 0) { rv = 0; break; } } else g_warning ("unhandled subjectAltName dNSName encoding (%d)\n", format); } else if (type == GEN_IPADD) { unsigned char *data; const guint8 *addr_bytes; int datalen, addr_len; datalen = ASN1_STRING_length (altname->d.iPAddress); data = ASN1_STRING_data (altname->d.iPAddress); addr_bytes = g_inet_address_to_bytes (addr); addr_len = (int)g_inet_address_get_native_size (addr); if (datalen == addr_len && memcmp (data, addr_bytes, addr_len) == 0) { rv = 0; break; } } } if (addr != NULL) g_object_unref (addr); sk_GENERAL_NAME_free (altname_stack); return rv; }
static VALUE rg_get_native_size(VALUE self) { return GSIZE2RVAL(g_inet_address_get_native_size(_SELF(self))); }