From 521512423dd8a90e8148d46c7461c5cb6538fd1b Mon Sep 17 00:00:00 2001 From: rainesli Date: Fri, 22 Nov 2019 15:39:16 +0800 Subject: [PATCH] list subject alternative name for dns --- hostname.c | 25 +++++++++++++++++++++++++ hostname.go | 22 ++++++++++++++++++++++ hostname.h | 6 ++++++ 3 files changed, 53 insertions(+) create mode 100644 hostname.h diff --git a/hostname.c b/hostname.c index 0bffecad..449c62c7 100644 --- a/hostname.c +++ b/hostname.c @@ -6,6 +6,7 @@ */ #include +#include "hostname.h" #ifndef X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT @@ -271,6 +272,30 @@ static int do_check_string(ASN1_STRING *a, int cmp_type, equal_fn equal, } } +void list_x509_san(X509 *x, SanList *list) +{ + STACK_OF(GENERAL_NAME) *gens = NULL; + gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL); + if (gens) + { + int i; + int gens_length=sk_GENERAL_NAME_num(gens); + list->length = gens_length; + list->sans = (char**)realloc(list->sans, gens_length*sizeof(char*)); + for (i = 0; i < gens_length; i++) + { + unsigned char *astr; + GENERAL_NAME *gen; + ASN1_STRING *cstr; + + gen = sk_GENERAL_NAME_value(gens, i); + ASN1_STRING_to_UTF8(&astr, gen->d.dNSName); + list->sans[i] = astr; + } + GENERAL_NAMES_free(gens); + } +} + static int do_x509_check(X509 *x, const unsigned char *chk, size_t chklen, unsigned int flags, int check_type) { diff --git a/hostname.go b/hostname.go index c92d959e..bd294476 100644 --- a/hostname.go +++ b/hostname.go @@ -18,6 +18,7 @@ package openssl #include #include #include +#include "hostname.h" #ifndef X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT #define X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT 0x1 @@ -29,6 +30,7 @@ extern int X509_check_email(X509 *x, const unsigned char *chk, size_t chklen, unsigned int flags); extern int X509_check_ip(X509 *x, const unsigned char *chk, size_t chklen, unsigned int flags); +extern void list_x509_san(X509 *x, SanList *sans); #endif */ import "C" @@ -36,6 +38,7 @@ import "C" import ( "errors" "net" + "reflect" "unsafe" ) @@ -50,6 +53,25 @@ const ( NoWildcards CheckFlags = C.X509_CHECK_FLAG_NO_WILDCARDS ) +func (c *Certificate) ListSanDns() []string { + list := C.SanList{} + list.sans = (**C.char)(C.malloc(100)) + defer C.free(unsafe.Pointer(list.sans)) + C.list_x509_san(c.x, &list) + + var str []string + var pbuf []*C.char + header := (*reflect.SliceHeader)(unsafe.Pointer(&pbuf)) + header.Cap = int(list.length) + header.Len = int(list.length) + header.Data = uintptr(unsafe.Pointer(list.sans)) + for _, i := range pbuf { + str = append(str, C.GoString(i)) + } + + return str +} + // CheckHost checks that the X509 certificate is signed for the provided // host name. See http://www.openssl.org/docs/crypto/X509_check_host.html for // more. Note that CheckHost does not check the IP field. See VerifyHostname. diff --git a/hostname.h b/hostname.h new file mode 100644 index 00000000..4e959dd5 --- /dev/null +++ b/hostname.h @@ -0,0 +1,6 @@ +#include + +typedef struct _SanList { + int length; + char** sans; +} SanList;