Merge pull request #21 from lunixbochs/store

Add support for loading chains from a single PEM
This commit is contained in:
JT Olds 2014-11-19 00:50:28 -07:00
commit ee399ccc2a
2 changed files with 78 additions and 1 deletions

47
ctx.go
View File

@ -184,7 +184,12 @@ func NewCtxFromFiles(cert_file string, key_file string) (*Ctx, error) {
return nil, err
}
cert, err := LoadCertificateFromPEM(cert_bytes)
certs := SplitPEM(cert_bytes)
if len(certs) == 0 {
return nil, fmt.Errorf("No PEM certificate found in '%s'", cert_file)
}
first, certs := certs[0], certs[1:]
cert, err := LoadCertificateFromPEM(first)
if err != nil {
return nil, err
}
@ -194,6 +199,17 @@ func NewCtxFromFiles(cert_file string, key_file string) (*Ctx, error) {
return nil, err
}
for _, pem := range certs {
cert, err := LoadCertificateFromPEM(pem)
if err != nil {
return nil, err
}
err = ctx.AddChainCertificate(cert)
if err != nil {
return nil, err
}
}
key_bytes, err := ioutil.ReadFile(key_file)
if err != nil {
return nil, err
@ -285,6 +301,35 @@ type CertificateStore struct {
certs []*Certificate
}
// Allocate a new, empty CertificateStore
func NewCertificateStore() (*CertificateStore, error) {
s := C.X509_STORE_new()
if s == nil {
return nil, errors.New("failed to allocate X509_STORE")
}
store := &CertificateStore{store: s}
runtime.SetFinalizer(store, func(s *CertificateStore) {
C.X509_STORE_free(s.store)
})
return store, nil
}
// Parse a chained PEM file, loading all certificates into the Store.
func (s *CertificateStore) LoadCertificatesFromPEM(data []byte) error {
pems := SplitPEM(data)
for _, pem := range pems {
cert, err := LoadCertificateFromPEM(pem)
if err != nil {
return err
}
err = s.AddCertificate(cert)
if err != nil {
return err
}
}
return nil
}
// GetCertificateStore returns the context's certificate store that will be
// used for peer validation.
func (c *Ctx) GetCertificateStore() *CertificateStore {

32
pem.go Normal file
View File

@ -0,0 +1,32 @@
// Copyright (C) 2014 Ryan Hileman
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package openssl
import (
"regexp"
)
var pemSplit *regexp.Regexp = regexp.MustCompile(`(?sm)` +
`(^-----[\s-]*?BEGIN.*?-----$` +
`.*?` +
`^-----[\s-]*?END.*?-----$)`)
func SplitPEM(data []byte) [][]byte {
var results [][]byte
for _, block := range pemSplit.FindAll(data, -1) {
results = append(results, block)
}
return results
}