//Wrap an existing listener + crypto config and return a new TLS enabled listener. func NewListener(inner net.Listener, config *tls.Config) (net.Listener, error) { l := new(gossl.Listener) l.Listener = inner //FIXME hardcoded in method l.Context = gossl.NewContext(gossl.SSLv23Method()) if l.Context == nil { msg := sslerr.SSLErrorMessage().String() return nil, errors.New("problem creating ssl context:\n" + msg) } //set certificates //grab the private key Kr := config.Certificates[0].PrivateKey private_key_der, err := extractDERKey(Kr) private_key, err := evp.LoadPrivateKeyDER(private_key_der) if err != nil { return nil, err } //set the private key into the context err = l.Context.UsePrivateKey(private_key) if err != nil { return nil, errors.New("problem loading key " + sslerr.SSLErrorMessage().String()) } cert, err := x509.ParseCertificate(config.Certificates[0].Certificate[0]) if err != nil { return nil, err } err = l.Context.UseCertificate(cert) if err != nil { return nil, errors.New("problem loading key " + sslerr.SSLErrorMessage().String()) } return l, nil }
func (self *Context) UseCertificate(cert *Certificate) error { if int(C.SSL_CTX_use_certificate(self.Ctx, (*C.X509)(unsafe.Pointer(cert.X509)))) != 1 { return errors.New("problem loading cert " + sslerr.SSLErrorMessage()) } return nil }
func (self *Context) UseCertificateFile(file string, filetype FileType) error { ret := int(C.SSL_CTX_use_certificate_file(self.Ctx, C.CString(file), C.int(filetype))) if ret != 1 { return errors.New(sslerr.SSLErrorMessage().String()) } return nil }
func (self *Context) UseCertificateChainFile(file string) error { ret := int(C.SSL_CTX_use_certificate_chain_file(self.Ctx, C.CString(file))) if ret != 1 { return errors.New(sslerr.SSLErrorMessage()) } return nil }
func (self *Context) UsePrivateKeyFile(file string, filetype int) error { ret := int(C.SSL_CTX_use_PrivateKey_file(self.Ctx, C.CString(file), C.int(filetype))) if ret != 1 { return errors.New(sslerr.SSLErrorMessage()) } return nil }
func newCurve(nid C.int) *C.EC_GROUP { if !availableCurves[nid] { return nil } curve := C.EC_GROUP_new_by_curve_name(nid) if curve == nil { panic("problem creating ec: " + sslerr.SSLErrorMessage().String()) } return curve }
//Helper function that calls encoding/pem to convert DER to PEM func ParseCertificatePEM(pemData []byte) (*Certificate, error) { length := C.int(len(pemData)) buffer := unsafe.Pointer(&pemData[0]) bio := C.BIO_new_mem_buf(buffer, length) cert := C.PEM_read_bio_X509(bio, nil, nil, nil) if cert == nil { return nil, errors.New("problem loading certificate" + sslerr.SSLErrorMessage().String()) } return &Certificate{x509: cert}, nil }
func LoadPrivateKeyDER(buf []byte) (*PKey, error) { bio := C.BIO_new_mem_buf(unsafe.Pointer(&buf[0]), C.int(len(buf))) if bio == nil { return nil, errors.New("problem converting der key to openssl key") } pkey := C.d2i_PrivateKey_bio(bio, nil) if pkey == nil { return nil, errors.New(sslerr.SSLErrorMessage()) } return &PKey{PKey: pkey}, nil }
//Helper function to load a private key from it's bytes func LoadPrivateKeyPEM(buf []byte) (*PKey, error) { bio := C.BIO_new_mem_buf(unsafe.Pointer(&buf[0]), C.int(len(buf))) if bio == nil { return nil, errors.New("problem converting der key to openssl key") } pkey := C.PEM_read_bio_PrivateKey(bio, nil, nil, nil) if pkey == nil { return nil, errors.New("Problem reading key:" + sslerr.SSLErrorMessage().String()) } return &PKey{PKey: pkey}, nil }
// ParseDERCRL parses a DER encoded CRL from the given bytes. func ParseDERCRL(derBytes []byte) (certList *pkix.CertificateList, err error) { var ( crl *C.X509_CRL buf = unsafe.Pointer(&derBytes[0]) blen = C.int(len(derBytes)) bio = C.BIO_new_mem_buf(buf, blen) ) crl = C.d2i_X509_CRL_bio(bio, nil) if crl == nil { return nil, errors.New("error parsing der data: " + sslerr.SSLErrorMessage().String()) } // use crl return &pkix.CertificateList{}, nil }
func (r *reader) Read(p []byte) (n int, err error) { var ( p_len = len(p) buf *C.uchar = (*C.uchar)(C.malloc(C.size_t(p_len))) ) defer C.free(unsafe.Pointer(buf)) if C.RAND_bytes(buf, C.int(p_len)) == 1 { copy(p, C.GoBytes(unsafe.Pointer(buf), C.int(p_len))) return len(p), nil } //return 0, errors.New("farts") // TODO read the error from SSL return 0, errors.New(sslerr.SSLErrorMessage()) }
//Import an OpenSSL X509 certificate from a DER buffer func ParseCertificate(asn1Data []byte) (*Certificate, error) { //with credit to exarkun and pyopenssl's crypto.c //you're my inspiration! length := C.int(len(asn1Data)) buffer := unsafe.Pointer(&asn1Data[0]) bio := C.BIO_new_mem_buf(buffer, length) sslCert := C.d2i_X509_bio(bio, nil) if sslCert == nil { return nil, errors.New("problem loading cert" + sslerr.SSLErrorMessage().String()) } cert := new(Certificate) cert.X509 = sslCert return cert, nil }
func (self *PKey) DumpPEM() ([]byte, error) { bio := C.BIO_new(C.BIO_s_mem()) defer C.BIO_free(bio) if bio == nil { return nil, errors.New("problem converting pem key to openssl key") } ret := C.PEM_write_bio_PrivateKey(bio, self.PKey, nil, nil, 0, nil, nil) if int(ret) == 0 { return nil, errors.New(sslerr.SSLErrorMessage()) } var temp *C.char buf_len := C.BIO_ctrl(bio, C.BIO_CTRL_INFO, C.long(0), unsafe.Pointer(&temp)) buffer := C.GoBytes(unsafe.Pointer(temp), C.int(buf_len)) return buffer, nil }
func (self *SSL) getError(ret C.int) error { err := C.SSL_get_error(self.SSL, ret) switch err { case C.SSL_ERROR_NONE: case C.SSL_ERROR_ZERO_RETURN: return nil case C.SSL_ERROR_SYSCALL: if int(C.ERR_peek_error()) != 0 { return syscall.Errno(C.get_errno()) } default: msg := sslerr.SSLErrorMessage() return errors.New(msg) } return nil }
// ParseCertificate parses a single certificate from the given ASN.1 DER data. func ParseCertificate(asn1Data []byte) (*Certificate, error) { var ( c *C.X509 dlen = C.long(len(asn1Data)) buf = (*C.uchar)(&asn1Data[0]) counter = C.long(0) ) c = C.d2i_X509_with_counter(&buf, dlen, &counter) if c == nil { return nil, errors.New("error parsing der data: " + sslerr.SSLErrorMessage().String()) } cert, err := getCertificate(asn1Data[:counter], c) if err != nil { return nil, err } return cert, nil }
// ParseCertificates parses one or more certificates from the given ASN.1 DER // data. The certificates must be concatenated with no intermediate padding. func ParseCertificates(asn1Data []byte) ([]*Certificate, error) { var ( cs []*Certificate dlen = C.long(len(asn1Data)) buf = (*C.uchar)(&asn1Data[0]) counter = C.long(0) prev int ) for counter < dlen { c := C.d2i_X509_with_counter(&buf, dlen, &counter) if c == nil { return nil, errors.New("error parsing der data: " + sslerr.SSLErrorMessage().String()) } cert, err := getCertificate(asn1Data[prev:counter], c) if err != nil { return nil, err } cs = append(cs, cert) prev = int(counter) } return cs, nil }
func buildCurveParams(curve *C.EC_GROUP) *elliptic.CurveParams { cp := &elliptic.CurveParams{} // handle go < 1.5 // Name wasn't in CurveParams before elem := reflect.ValueOf(cp).Elem() f := elem.FieldByName("Name") if f.IsValid() { f.SetString(getCurveName(curve)) } cp.BitSize = getCurveBitSize(curve) p := C.BN_new() if p == nil { panic(sslerr.SSLErrorMessage().String()) } defer C.BN_free(p) a := C.BN_new() if a == nil { panic(sslerr.SSLErrorMessage().String()) } defer C.BN_free(a) b := C.BN_new() if b == nil { panic(sslerr.SSLErrorMessage().String()) } defer C.BN_free(b) if C.EC_GROUP_get_curve_GFp(curve, p, a, b, nil) != 1 { panic(sslerr.SSLErrorMessage().String()) } if p == nil || a == nil || b == nil { panic("something went wrong getting GFp params") } cp.P, _ = new(big.Int).SetString(C.GoString(C.BN_bn2dec(p)), 10) cp.N, _ = new(big.Int).SetString(C.GoString(C.BN_bn2dec(a)), 10) cp.B, _ = new(big.Int).SetString(C.GoString(C.BN_bn2hex(b)), 16) generator := C.EC_GROUP_get0_generator(curve) if generator == nil { panic("generator cannot be nil") } x := C.BN_new() if x == nil { panic(sslerr.SSLErrorMessage().String()) } defer C.BN_free(x) y := C.BN_new() if y == nil { panic(sslerr.SSLErrorMessage().String()) } defer C.BN_free(y) if C.EC_POINT_get_affine_coordinates_GFp(curve, generator, x, y, nil) != 1 { panic(sslerr.SSLErrorMessage().String()) } if x == nil || y == nil { panic("something went wrong getting affine coordinates") } cp.Gx, _ = new(big.Int).SetString(C.GoString(C.BN_bn2hex(x)), 16) cp.Gy, _ = new(big.Int).SetString(C.GoString(C.BN_bn2hex(y)), 16) return cp }
func (self *Context) UsePrivateKey(key *evp.PKey) error { if int(C.SSL_CTX_use_PrivateKey(self.Ctx, (*C.EVP_PKEY)(unsafe.Pointer(key.PKey)))) != 1 { return errors.New("problem loading key " + sslerr.SSLErrorMessage()) } return nil }
func (self *Context) CheckPrivateKey() error { if int(C.SSL_CTX_check_private_key(self.Ctx)) != 1 { return errors.New(sslerr.SSLErrorMessage()) } return nil }