diff --git a/ctx.go b/ctx.go
index 538679f..f2683e2 100644
--- a/ctx.go
+++ b/ctx.go
@@ -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 {
diff --git a/pem.go b/pem.go
new file mode 100644
index 0000000..6dad597
--- /dev/null
+++ b/pem.go
@@ -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
+}