github.com/brimstone/sbuca@v0.0.0-20151202175429-8691d9eba5c5/pkix/cert.go (about)

     1  package pkix
     2  
     3  import (
     4  	"crypto/x509"
     5  	"crypto/x509/pkix"
     6  	"encoding/pem"
     7  	"errors"
     8  	"io/ioutil"
     9  	"math/big"
    10  	"strings"
    11  )
    12  
    13  type Certificate struct {
    14  	DerBytes []byte
    15  
    16  	Crt *x509.Certificate
    17  }
    18  
    19  func GenSubject(organization string) pkix.Name {
    20  	return pkix.Name{
    21  		Organization: []string{organization},
    22  	}
    23  }
    24  func NewCertificateFromDER(derBytes []byte) (*Certificate, error) {
    25  
    26  	crt, err := x509.ParseCertificate(derBytes)
    27  	if err != nil {
    28  		return nil, err
    29  	}
    30  
    31  	cert := &Certificate{
    32  		DerBytes: derBytes,
    33  		Crt:      crt,
    34  	}
    35  
    36  	return cert, nil
    37  }
    38  func NewCertificateFromPEM(pemBytes []byte) (*Certificate, error) {
    39  
    40  	pemBlock, _ := pem.Decode(pemBytes)
    41  	if pemBlock == nil {
    42  		return nil, errors.New("PEM decode failed")
    43  	}
    44  
    45  	crt, err := x509.ParseCertificate(pemBlock.Bytes)
    46  	if err != nil {
    47  		return nil, err
    48  	}
    49  
    50  	cert := &Certificate{
    51  		DerBytes: pemBlock.Bytes,
    52  		Crt:      crt,
    53  	}
    54  
    55  	return cert, nil
    56  }
    57  func NewCertificateFromPEMFile(filename string) (*Certificate, error) {
    58  
    59  	data, err := ioutil.ReadFile(filename)
    60  	if err != nil {
    61  		return nil, err
    62  	}
    63  
    64  	return NewCertificateFromPEM(data)
    65  }
    66  
    67  func (certificate *Certificate) ToPEM() ([]byte, error) {
    68  
    69  	pemBlock := &pem.Block{
    70  		Type:  "CERTIFICATE",
    71  		Bytes: certificate.DerBytes,
    72  	}
    73  
    74  	pemBytes := pem.EncodeToMemory(pemBlock)
    75  
    76  	return pemBytes, nil
    77  }
    78  func (certificate *Certificate) ToPEMFile(filename string) error {
    79  	pemBytes, err := certificate.ToPEM()
    80  	if err != nil {
    81  		return err
    82  	}
    83  
    84  	return ioutil.WriteFile(filename, pemBytes, 0400)
    85  }
    86  func (certificate *Certificate) GetSerialNumber() *big.Int {
    87  	return certificate.Crt.SerialNumber
    88  }
    89  
    90  func Marshal(name pkix.Name) (string, error) {
    91  	var output []string
    92  	if name.CommonName != "" {
    93  		output = append(output, "CN="+name.CommonName)
    94  	}
    95  	if len(name.Country) > 0 {
    96  		for i := range name.Country {
    97  			output = append(output, "C="+name.Country[i])
    98  		}
    99  	}
   100  	if len(name.Locality) > 0 {
   101  		for i := range name.Locality {
   102  			output = append(output, "L="+name.Locality[i])
   103  		}
   104  	}
   105  	if len(name.Province) > 0 {
   106  		for i := range name.Province {
   107  			output = append(output, "ST="+name.Province[i])
   108  		}
   109  	}
   110  	if len(name.StreetAddress) > 0 {
   111  		for i := range name.StreetAddress {
   112  			output = append(output, "SA="+name.StreetAddress[i])
   113  		}
   114  	}
   115  	if len(name.Organization) > 0 {
   116  		for i := range name.Organization {
   117  			output = append(output, "O="+name.Organization[i])
   118  		}
   119  	}
   120  	if len(name.OrganizationalUnit) > 0 {
   121  		for i := range name.OrganizationalUnit {
   122  			output = append(output, "OU="+name.OrganizationalUnit[i])
   123  		}
   124  	}
   125  	return strings.Join(output, ","), nil
   126  }
   127  
   128  func Unmarshal(dn string) (pkix.Name, error) {
   129  	var output pkix.Name
   130  	segments := strings.Split(dn, ",")
   131  	for segment := range segments {
   132  		identifier := strings.SplitN(segments[segment], "=", 2)
   133  		if identifier[0] == "CN" {
   134  			output.CommonName = identifier[1]
   135  		} else if identifier[0] == "C" {
   136  			output.Country = append(output.Country, identifier[1])
   137  		} else if identifier[0] == "L" {
   138  			output.Locality = append(output.Locality, identifier[1])
   139  		} else if identifier[0] == "ST" {
   140  			output.Province = append(output.Province, identifier[1])
   141  		} else if identifier[0] == "SA" {
   142  			output.StreetAddress = append(output.StreetAddress, identifier[1])
   143  		} else if identifier[0] == "O" {
   144  			output.Organization = append(output.Organization, identifier[1])
   145  		} else if identifier[0] == "OU" {
   146  			output.OrganizationalUnit = append(output.OrganizationalUnit, identifier[1])
   147  		}
   148  	}
   149  	return output, nil
   150  }