// LoadPublicKeyFromDER loads a public key from a DER-encoded block. func LoadPublicKeyFromDER(der_block []byte) (PublicKey, error) { if len(der_block) == 0 { return nil, errors.New("empty der block") } bio := C.BIO_new_mem_buf(unsafe.Pointer(&der_block[0]), C.int(len(der_block))) if bio == nil { return nil, errors.New("failed creating bio") } defer C.BIO_free(bio) rsakey := C.d2i_RSA_PUBKEY_bio(bio, nil) if rsakey == nil { return nil, errors.New("failed reading rsa key") } defer C.RSA_free(rsakey) // convert to PKEY key := C.EVP_PKEY_new() if key == nil { return nil, errors.New("failed converting to evp_pkey") } if C.EVP_PKEY_set1_RSA(key, (*C.struct_rsa_st)(rsakey)) != 1 { C.EVP_PKEY_free(key) return nil, errors.New("failed converting to evp_pkey") } p := &pKey{key: key} runtime.SetFinalizer(p, func(p *pKey) { C.EVP_PKEY_free(p.key) }) return p, nil }
// LoadPrivateKeyFromPEM loads a private key from a PEM-encoded block. func LoadPrivateKeyFromPEMWidthPassword(pem_block []byte, password string) ( PrivateKey, error) { if len(pem_block) == 0 { return nil, errors.New("empty pem block") } bio := C.BIO_new_mem_buf(unsafe.Pointer(&pem_block[0]), C.int(len(pem_block))) if bio == nil { return nil, errors.New("failed creating bio") } defer C.BIO_free(bio) cs := C.CString(password) defer C.free(unsafe.Pointer(cs)) rsakey := C.PEM_read_bio_RSAPrivateKey(bio, nil, nil, unsafe.Pointer(cs)) if rsakey == nil { return nil, errors.New("failed reading rsa key") } defer C.RSA_free(rsakey) // convert to PKEY key := C.EVP_PKEY_new() if key == nil { return nil, errors.New("failed converting to evp_pkey") } if C.EVP_PKEY_set1_RSA(key, (*C.struct_rsa_st)(rsakey)) != 1 { C.EVP_PKEY_free(key) return nil, errors.New("failed converting to evp_pkey") } p := &pKey{key: key} runtime.SetFinalizer(p, func(p *pKey) { C.EVP_PKEY_free(p.key) }) return p, nil }
//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 }
//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 }
// ParseCRL parses a CRL from the given bytes. It's often the case that PEM // encoded CRLs will appear where they should be DER encoded, so this function // will transparently handle PEM encoding as long as there isn't any leading // garbage. func ParseCRL(crlBytes []byte) (certList *pkix.CertificateList, err error) { if bytes.HasPrefix(crlBytes, pemCRLPrefix) { var ( crl *C.X509_CRL buf = unsafe.Pointer(&crlBytes[0]) blen = C.int(len(crlBytes)) bio = C.BIO_new_mem_buf(buf, blen) ) crl = C.PEM_read_bio_X509_CRL(bio, nil, nil, nil) if crl != nil { // use crl return &pkix.CertificateList{}, nil } } return ParseDERCRL(crlBytes) }
// LoadCertificateFromPEM loads an X509 certificate from a PEM-encoded block. func LoadCertificateFromPEM(pem_block []byte) (*Certificate, error) { if len(pem_block) == 0 { return nil, errors.New("empty pem block") } runtime.LockOSThread() defer runtime.UnlockOSThread() bio := C.BIO_new_mem_buf(unsafe.Pointer(&pem_block[0]), C.int(len(pem_block))) cert := C.PEM_read_bio_X509(bio, nil, nil, nil) C.BIO_free(bio) if cert == nil { return nil, errorFromErrorQueue() } x := &Certificate{x: cert} runtime.SetFinalizer(x, func(x *Certificate) { C.X509_free(x.x) }) return x, nil }
// LoadDHParametersFromPEM loads the Diffie-Hellman parameters from // a PEM-encoded block. func LoadDHParametersFromPEM(pem_block []byte) (*DH, error) { if len(pem_block) == 0 { return nil, errors.New("empty pem block") } bio := C.BIO_new_mem_buf(unsafe.Pointer(&pem_block[0]), C.int(len(pem_block))) if bio == nil { return nil, errors.New("failed creating bio") } defer C.BIO_free(bio) params := C.PEM_read_bio_DHparams(bio, nil, nil, nil) if params == nil { return nil, errors.New("failed reading dh parameters") } dhparams := &DH{dh: params} runtime.SetFinalizer(dhparams, func(dhparams *DH) { C.DH_free(dhparams.dh) }) return dhparams, nil }
// LoadPrivateKeyFromPEM loads a private key from a PEM-encoded block. func LoadPrivateKeyFromPEM(pem_block []byte) (PrivateKey, error) { // // Check and load the PEM data // if len(pem_block) == 0 { return nil, errors.New("empty pem block") } bio := C.BIO_new_mem_buf(unsafe.Pointer(&pem_block[0]), C.int(len(pem_block))) if bio == nil { return nil, errors.New("failed creating bio") } defer C.BIO_free(bio) rsakey := C.PEM_read_bio_RSAPrivateKey(bio, nil, nil, nil) if rsakey == nil { return nil, errors.New("failed reading rsa key") } defer C.RSA_free(rsakey) // // Create a private key // key := C.EVP_PKEY_new() if key == nil { return nil, errors.New("failed converting to evp_pkey") } if C.EVP_PKEY_set1_RSA(key, (*C.struct_rsa_st)(rsakey)) != 1 { C.EVP_PKEY_free(key) return nil, errors.New("failed converting to evp_pkey") } p := &pKey{key: key} runtime.SetFinalizer(p, func(p *pKey) { C.EVP_PKEY_free(p.key) }) return p, nil }