Add OCSP support

This commit is contained in:
Manuel de Brito Fontes 2017-10-04 17:11:03 -03:00
parent 1c6ff88228
commit f6ba3abca3
15 changed files with 1519 additions and 2 deletions

View file

@ -0,0 +1,75 @@
package certUtil
import (
"crypto/x509"
"io/ioutil"
"net/http"
)
func isSelfSigned(cert *x509.Certificate) bool {
return cert.CheckSignatureFrom(cert) == nil
}
func isChainRootNode(cert *x509.Certificate) bool {
if isSelfSigned(cert) {
return true
}
return false
}
func FetchCertificateChain(cert *x509.Certificate) ([]*x509.Certificate, error) {
var certs []*x509.Certificate
certs = append(certs, cert)
for certs[len(certs)-1].IssuingCertificateURL != nil {
parentURL := certs[len(certs)-1].IssuingCertificateURL[0]
resp, err := http.Get(parentURL)
if resp != nil {
defer resp.Body.Close()
}
if err != nil {
return nil, err
}
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
cert, err := DecodeCertificate(data)
if err != nil {
return nil, err
}
if isChainRootNode(cert) {
break
}
certs = append(certs, cert)
}
return certs, nil
}
func AddRootCA(certs []*x509.Certificate) ([]*x509.Certificate, error) {
lastCert := certs[len(certs)-1]
chains, err := lastCert.Verify(x509.VerifyOptions{})
if err != nil {
if _, e := err.(x509.UnknownAuthorityError); e {
return certs, nil
}
return nil, err
}
for _, cert := range chains[0] {
if lastCert.Equal(cert) {
continue
}
certs = append(certs, cert)
}
return certs, nil
}

View file

@ -0,0 +1,110 @@
package certUtil
import (
"bytes"
"crypto/x509"
"encoding/pem"
"errors"
"github.com/fullsailor/pkcs7"
)
var pemStart = []byte("-----BEGIN ")
var certBlockType = "CERTIFICATE"
func IsPEM(data []byte) bool {
return bytes.HasPrefix(data, pemStart)
}
func DecodeCertificates(data []byte) ([]*x509.Certificate, error) {
if IsPEM(data) {
var certs []*x509.Certificate
for len(data) > 0 {
var block *pem.Block
block, data = pem.Decode(data)
if block == nil {
return nil, errors.New("Invalid certificate.")
}
if block.Type != certBlockType {
return nil, errors.New("Invalid certificate.")
}
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return nil, errors.New("Invalid certificate.")
}
certs = append(certs, cert)
}
return certs, nil
} else {
certs, err := x509.ParseCertificates(data)
if err != nil {
return nil, errors.New("Invalid certificate.")
}
return certs, nil
}
}
func DecodeCertificate(data []byte) (*x509.Certificate, error) {
if IsPEM(data) {
block, _ := pem.Decode(data)
if block == nil {
return nil, errors.New("Invalid certificate.")
}
if block.Type != certBlockType {
return nil, errors.New("Invalid certificate.")
}
data = block.Bytes
}
cert, err := x509.ParseCertificate(data)
if err == nil {
return cert, nil
}
p, err := pkcs7.Parse(data)
if err == nil {
return p.Certificates[0], nil
}
return nil, errors.New("Invalid certificate.")
}
func EncodeCertificate(cert *x509.Certificate) []byte {
block := pem.Block{
Type: certBlockType,
Bytes: cert.Raw,
}
return pem.EncodeToMemory(&block)
}
func EncodeCertificateDER(cert *x509.Certificate) []byte {
return cert.Raw
}
func EncodeCertificates(certs []*x509.Certificate) []byte {
var data []byte
for _, cert := range certs {
data2 := EncodeCertificate(cert)
data = append(data, data2...)
}
return data
}
func EncodeCertificatesDER(certs []*x509.Certificate) []byte {
var data []byte
for _, cert := range certs {
data2 := EncodeCertificateDER(cert)
data = append(data, data2...)
}
return data
}