From 09d72588f7aa9ef6116596ce13028719803d73c2 Mon Sep 17 00:00:00 2001 From: Tiger Date: Sat, 23 May 2020 17:24:57 +0530 Subject: [PATCH 1/3] - add custom extension support - add support to retrive custom extension value - add support to add custom protocol for protocol negotiation Signed-off-by: Tiger --- cert.go | 22 ++++++++++++++++++++++ ctx.go | 23 +++++++++++++++++++++++ exntension.c | 40 ++++++++++++++++++++++++++++++++++++++++ extension.c | 40 ++++++++++++++++++++++++++++++++++++++++ object.go | 4 ++-- shim.h | 8 +++++++- 6 files changed, 134 insertions(+), 3 deletions(-) create mode 100644 exntension.c create mode 100644 extension.c diff --git a/cert.go b/cert.go index e841e22c..458b23a2 100644 --- a/cert.go +++ b/cert.go @@ -331,6 +331,14 @@ func (c *Certificate) AddExtension(nid NID, value string) error { return nil } +// AddCustomExtension add custom extenstion to the certificate. +func (c *Certificate) AddCustomExtension(nid NID, value []byte) error { + if int(C.add_custom_ext(c.x, C.int(nid), (*C.char)(C.CBytes(value)), C.int(len(value)))) == 0 { + return errors.New("Unable to add extension") + } + return nil +} + // Wraps AddExtension using a map of NID to text extension. // Will return without finishing if it encounters an error. func (c *Certificate) AddExtensions(extensions map[NID]string) error { @@ -413,3 +421,17 @@ func (c *Certificate) SetVersion(version X509_Version) error { } return nil } + +// GetExtensionValue returns the value of the given NID's extension. +func (c *Certificate) GetExtensionValue(nid NID) []byte { + dataLength := C.int(0) + val := C.get_extention(c.x, C.int(nid), &dataLength) + return charToBytes(val, int(dataLength)) +} + +// charToBytes converts c unisgned char to golang bytes +func charToBytes(src *C.uchar, sz int) []byte { + dest := make([]byte, sz) + copy(dest, (*(*[1024]byte)(unsafe.Pointer(src)))[:sz:sz]) + return dest +} diff --git a/ctx.go b/ctx.go index 33befc40..271defa1 100644 --- a/ctx.go +++ b/ctx.go @@ -522,6 +522,29 @@ func (c *Ctx) SetCipherList(list string) error { return nil } +// SetNextProtos sets Negotiation protocol to the ctx. +func (c *Ctx) SetNextProtos(protos []string) error { + if len(protos) == 0 { + return nil + } + vector := make([]byte, 0) + for _, proto := range protos { + if len(proto) > 255 { + return fmt.Errorf( + "Proto length can't be more than 255. But got a proto %s with length %d", + proto, len(proto)) + } + vector = append(vector, byte(uint8(len(proto)))) + vector = append(vector, []byte(proto)...) + } + ret := int(C.SSL_CTX_set_alpn_protos(c.ctx, (*C.uchar)(unsafe.Pointer(&vector[0])), + C.uint(len(vector)))) + if ret != 0 { + return errors.New("Error while setting protos to ctx") + } + return nil +} + type SessionCacheModes int const ( diff --git a/exntension.c b/exntension.c new file mode 100644 index 00000000..99f1ca3d --- /dev/null +++ b/exntension.c @@ -0,0 +1,40 @@ + + +#include +#include + +const unsigned char * get_extention(X509 *x, int NID, int *data_len){ + int loc; + ASN1_OCTET_STRING *octet_str; + long xlen; + int tag, xclass; + + loc = X509_get_ext_by_NID( x, NID, -1); + X509_EXTENSION *ex = X509_get_ext(x, loc); + octet_str = X509_EXTENSION_get_data(ex); + *data_len = octet_str->length; + return octet_str->data; +} + +// Copied from https://github.com/libtor/openssl/blob/master/demos/x509/mkcert.c#L153 +int add_custom_ext(X509 *cert, int nid,unsigned char *value, int len) +{ + X509_EXTENSION *ex; + ASN1_OCTET_STRING *os = ASN1_OCTET_STRING_new(); + ASN1_OCTET_STRING_set(os,value,len); + X509V3_CTX ctx; + /* This sets the 'context' of the extensions. */ + /* No configuration database */ + X509V3_set_ctx_nodb(&ctx); + /* Issuer and subject certs: both the target since it is self signed, + * no request and no CRL + */ + X509V3_set_ctx(&ctx, cert, cert, NULL, NULL, 0); + // ref http://openssl.6102.n7.nabble.com/Adding-a-custom-extension-to-a-CSR-td47446.html + ex = X509_EXTENSION_create_by_NID( NULL, nid, 0, os); + if (!X509_add_ext(cert,ex,-1)) + return 0; + + X509_EXTENSION_free(ex); + return 1; +} \ No newline at end of file diff --git a/extension.c b/extension.c new file mode 100644 index 00000000..99f1ca3d --- /dev/null +++ b/extension.c @@ -0,0 +1,40 @@ + + +#include +#include + +const unsigned char * get_extention(X509 *x, int NID, int *data_len){ + int loc; + ASN1_OCTET_STRING *octet_str; + long xlen; + int tag, xclass; + + loc = X509_get_ext_by_NID( x, NID, -1); + X509_EXTENSION *ex = X509_get_ext(x, loc); + octet_str = X509_EXTENSION_get_data(ex); + *data_len = octet_str->length; + return octet_str->data; +} + +// Copied from https://github.com/libtor/openssl/blob/master/demos/x509/mkcert.c#L153 +int add_custom_ext(X509 *cert, int nid,unsigned char *value, int len) +{ + X509_EXTENSION *ex; + ASN1_OCTET_STRING *os = ASN1_OCTET_STRING_new(); + ASN1_OCTET_STRING_set(os,value,len); + X509V3_CTX ctx; + /* This sets the 'context' of the extensions. */ + /* No configuration database */ + X509V3_set_ctx_nodb(&ctx); + /* Issuer and subject certs: both the target since it is self signed, + * no request and no CRL + */ + X509V3_set_ctx(&ctx, cert, cert, NULL, NULL, 0); + // ref http://openssl.6102.n7.nabble.com/Adding-a-custom-extension-to-a-CSR-td47446.html + ex = X509_EXTENSION_create_by_NID( NULL, nid, 0, os); + if (!X509_add_ext(cert,ex,-1)) + return 0; + + X509_EXTENSION_free(ex); + return 1; +} \ No newline at end of file diff --git a/object.go b/object.go index 86ab1e4c..4d908e6c 100644 --- a/object.go +++ b/object.go @@ -19,6 +19,6 @@ import "C" // CreateObjectIdentifier creates ObjectIdentifier and returns NID for the created // ObjectIdentifier -func CreateObjectIdentifier(oid string, shortName string, longName string) int { - return int(C.OBJ_create(C.CString(oid), C.CString(shortName), C.CString(longName))) +func CreateObjectIdentifier(oid string, shortName string, longName string) NID { + return NID(C.OBJ_create(C.CString(oid), C.CString(shortName), C.CString(longName))) } diff --git a/shim.h b/shim.h index 75ee0b19..c63a9595 100644 --- a/shim.h +++ b/shim.h @@ -90,6 +90,8 @@ extern int X_SSL_CTX_set_tlsext_ticket_key_cb(SSL_CTX *sslctx, extern int X_SSL_CTX_ticket_key_cb(SSL *s, unsigned char key_name[16], unsigned char iv[EVP_MAX_IV_LENGTH], EVP_CIPHER_CTX *cctx, HMAC_CTX *hctx, int enc); +extern int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos, + unsigned int protos_len); /* BIO methods */ extern int X_BIO_get_flags(BIO *b); @@ -173,4 +175,8 @@ extern int X_X509_set_version(X509 *x, long version); extern int X_PEM_write_bio_PrivateKey_traditional(BIO *bio, EVP_PKEY *key, const EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *cb, void *u); /* Object methods */ -extern int OBJ_create(const char *oid,const char *sn,const char *ln); \ No newline at end of file +extern int OBJ_create(const char *oid,const char *sn,const char *ln); + +/* Extension helper method */ +extern const unsigned char * get_extention(X509 *x, int NID, int *data_len); +extern int add_custom_ext(X509 *cert, int nid, char *value, int len); \ No newline at end of file From 1fdf237b9851cadc8bc6d18825ce0b086137e858 Mon Sep 17 00:00:00 2001 From: Tiger Date: Sat, 23 May 2020 17:28:22 +0530 Subject: [PATCH 2/3] remove unwanted Signed-off-by: Tiger --- exntension.c | 40 ---------------------------------------- 1 file changed, 40 deletions(-) delete mode 100644 exntension.c diff --git a/exntension.c b/exntension.c deleted file mode 100644 index 99f1ca3d..00000000 --- a/exntension.c +++ /dev/null @@ -1,40 +0,0 @@ - - -#include -#include - -const unsigned char * get_extention(X509 *x, int NID, int *data_len){ - int loc; - ASN1_OCTET_STRING *octet_str; - long xlen; - int tag, xclass; - - loc = X509_get_ext_by_NID( x, NID, -1); - X509_EXTENSION *ex = X509_get_ext(x, loc); - octet_str = X509_EXTENSION_get_data(ex); - *data_len = octet_str->length; - return octet_str->data; -} - -// Copied from https://github.com/libtor/openssl/blob/master/demos/x509/mkcert.c#L153 -int add_custom_ext(X509 *cert, int nid,unsigned char *value, int len) -{ - X509_EXTENSION *ex; - ASN1_OCTET_STRING *os = ASN1_OCTET_STRING_new(); - ASN1_OCTET_STRING_set(os,value,len); - X509V3_CTX ctx; - /* This sets the 'context' of the extensions. */ - /* No configuration database */ - X509V3_set_ctx_nodb(&ctx); - /* Issuer and subject certs: both the target since it is self signed, - * no request and no CRL - */ - X509V3_set_ctx(&ctx, cert, cert, NULL, NULL, 0); - // ref http://openssl.6102.n7.nabble.com/Adding-a-custom-extension-to-a-CSR-td47446.html - ex = X509_EXTENSION_create_by_NID( NULL, nid, 0, os); - if (!X509_add_ext(cert,ex,-1)) - return 0; - - X509_EXTENSION_free(ex); - return 1; -} \ No newline at end of file From 38a6bec6d1223a499e3527b6a93c236313478790 Mon Sep 17 00:00:00 2001 From: Tiger Date: Sat, 13 Jun 2020 14:12:43 +0530 Subject: [PATCH 3/3] fix comments Signed-off-by: Tiger --- cert.go | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/cert.go b/cert.go index 458b23a2..82dfc369 100644 --- a/cert.go +++ b/cert.go @@ -333,7 +333,9 @@ func (c *Certificate) AddExtension(nid NID, value string) error { // AddCustomExtension add custom extenstion to the certificate. func (c *Certificate) AddCustomExtension(nid NID, value []byte) error { - if int(C.add_custom_ext(c.x, C.int(nid), (*C.char)(C.CBytes(value)), C.int(len(value)))) == 0 { + val := (*C.char)(C.CBytes(value)) + defer C.free(unsafe.Pointer(val)) + if int(C.add_custom_ext(c.x, C.int(nid), val, C.int(len(value)))) == 0 { return errors.New("Unable to add extension") } return nil @@ -426,12 +428,5 @@ func (c *Certificate) SetVersion(version X509_Version) error { func (c *Certificate) GetExtensionValue(nid NID) []byte { dataLength := C.int(0) val := C.get_extention(c.x, C.int(nid), &dataLength) - return charToBytes(val, int(dataLength)) -} - -// charToBytes converts c unisgned char to golang bytes -func charToBytes(src *C.uchar, sz int) []byte { - dest := make([]byte, sz) - copy(dest, (*(*[1024]byte)(unsafe.Pointer(src)))[:sz:sz]) - return dest + return C.GoBytes(unsafe.Pointer(val), dataLength) }