forked from TrueCloudLab/certificates
Move subject, issuer and serial number.
This commit is contained in:
parent
8069d1246b
commit
abaaec04f1
3 changed files with 151 additions and 143 deletions
|
@ -4,9 +4,7 @@ import (
|
|||
"crypto"
|
||||
"crypto/rand"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/json"
|
||||
"math/big"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
@ -139,144 +137,3 @@ func CreateCertificate(template, parent *x509.Certificate, pub crypto.PublicKey,
|
|||
}
|
||||
return cert, nil
|
||||
}
|
||||
|
||||
// Name is the JSON representation of X.501 type Name, used in the X.509 subject
|
||||
// and issuer fields.
|
||||
type Name struct {
|
||||
Country MultiString `json:"country"`
|
||||
Organization MultiString `json:"organization"`
|
||||
OrganizationalUnit MultiString `json:"organizationUnit"`
|
||||
Locality MultiString `json:"locality"`
|
||||
Province MultiString `json:"province"`
|
||||
StreetAddress MultiString `json:"streetAddress"`
|
||||
PostalCode MultiString `json:"postalCode"`
|
||||
SerialNumber string `json:"serialNumber"`
|
||||
CommonName string `json:"commonName"`
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshal interface and unmarshals a JSON
|
||||
// object in the Subject struct or a string as just the subject common name.
|
||||
func (n *Name) UnmarshalJSON(data []byte) error {
|
||||
if cn, ok := maybeString(data); ok {
|
||||
n.CommonName = cn
|
||||
return nil
|
||||
}
|
||||
|
||||
type nameAlias Name
|
||||
var nn nameAlias
|
||||
if err := json.Unmarshal(data, &nn); err != nil {
|
||||
return errors.Wrap(err, "error unmarshaling json")
|
||||
}
|
||||
*n = Name(nn)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Subject is the JSON representation of the X.509 subject field.
|
||||
type Subject Name
|
||||
|
||||
func newSubject(n pkix.Name) Subject {
|
||||
return Subject{
|
||||
Country: n.Country,
|
||||
Organization: n.Organization,
|
||||
OrganizationalUnit: n.OrganizationalUnit,
|
||||
Locality: n.Locality,
|
||||
Province: n.Province,
|
||||
StreetAddress: n.StreetAddress,
|
||||
PostalCode: n.PostalCode,
|
||||
SerialNumber: n.SerialNumber,
|
||||
CommonName: n.CommonName,
|
||||
}
|
||||
}
|
||||
|
||||
// Set sets the subject in the given certificate.
|
||||
func (s Subject) Set(c *x509.Certificate) {
|
||||
c.Subject = pkix.Name{
|
||||
Country: s.Country,
|
||||
Organization: s.Organization,
|
||||
OrganizationalUnit: s.OrganizationalUnit,
|
||||
Locality: s.Locality,
|
||||
Province: s.Province,
|
||||
StreetAddress: s.StreetAddress,
|
||||
PostalCode: s.PostalCode,
|
||||
SerialNumber: s.SerialNumber,
|
||||
CommonName: s.CommonName,
|
||||
}
|
||||
}
|
||||
|
||||
// Issuer is the JSON representation of the X.509 issuer field.
|
||||
type Issuer Name
|
||||
|
||||
func newIssuer(n pkix.Name) Issuer {
|
||||
return Issuer{
|
||||
Country: n.Country,
|
||||
Organization: n.Organization,
|
||||
OrganizationalUnit: n.OrganizationalUnit,
|
||||
Locality: n.Locality,
|
||||
Province: n.Province,
|
||||
StreetAddress: n.StreetAddress,
|
||||
PostalCode: n.PostalCode,
|
||||
SerialNumber: n.SerialNumber,
|
||||
CommonName: n.CommonName,
|
||||
}
|
||||
}
|
||||
|
||||
// Set sets the issuer in the given certificate.
|
||||
func (i Issuer) Set(c *x509.Certificate) {
|
||||
c.Issuer = pkix.Name{
|
||||
Country: i.Country,
|
||||
Organization: i.Organization,
|
||||
OrganizationalUnit: i.OrganizationalUnit,
|
||||
Locality: i.Locality,
|
||||
Province: i.Province,
|
||||
StreetAddress: i.StreetAddress,
|
||||
PostalCode: i.PostalCode,
|
||||
SerialNumber: i.SerialNumber,
|
||||
CommonName: i.CommonName,
|
||||
}
|
||||
}
|
||||
|
||||
// SerialNumber is the JSON representation of the X509 serial number.
|
||||
type SerialNumber struct {
|
||||
*big.Int
|
||||
}
|
||||
|
||||
// Set sets the serial number in the given certificate.
|
||||
func (s SerialNumber) Set(c *x509.Certificate) {
|
||||
c.SerialNumber = s.Int
|
||||
}
|
||||
|
||||
func (s *SerialNumber) MarshalJSON() ([]byte, error) {
|
||||
if s == nil || s.Int == nil {
|
||||
return []byte(`null`), nil
|
||||
}
|
||||
return s.Int.MarshalJSON()
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshal interface and unmarshals an
|
||||
// integer or a string into a serial number. If a string is used, a prefix of
|
||||
// “0b” or “0B” selects base 2, “0”, “0o” or “0O” selects base 8, and “0x” or
|
||||
// “0X” selects base 16. Otherwise, the selected base is 10 and no prefix is
|
||||
// accepted.
|
||||
func (s *SerialNumber) UnmarshalJSON(data []byte) error {
|
||||
if sn, ok := maybeString(data); ok {
|
||||
// Using base 0 to accept prefixes 0b, 0o, 0x but defaults as base 10.
|
||||
b, ok := new(big.Int).SetString(sn, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("error unmarshaling json: serialNumber %s is not valid", sn)
|
||||
}
|
||||
*s = SerialNumber{
|
||||
Int: b,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Assume a number.
|
||||
var i int64
|
||||
if err := json.Unmarshal(data, &i); err != nil {
|
||||
return errors.Wrap(err, "error unmarshaling json")
|
||||
}
|
||||
*s = SerialNumber{
|
||||
Int: new(big.Int).SetInt64(i),
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"encoding/asn1"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"net"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
@ -373,3 +374,49 @@ func (n NameConstraints) Set(c *x509.Certificate) {
|
|||
c.PermittedURIDomains = n.PermittedURIDomains
|
||||
c.ExcludedURIDomains = n.ExcludedURIDomains
|
||||
}
|
||||
|
||||
// SerialNumber is the JSON representation of the X509 serial number.
|
||||
type SerialNumber struct {
|
||||
*big.Int
|
||||
}
|
||||
|
||||
// Set sets the serial number in the given certificate.
|
||||
func (s SerialNumber) Set(c *x509.Certificate) {
|
||||
c.SerialNumber = s.Int
|
||||
}
|
||||
|
||||
func (s *SerialNumber) MarshalJSON() ([]byte, error) {
|
||||
if s == nil || s.Int == nil {
|
||||
return []byte(`null`), nil
|
||||
}
|
||||
return s.Int.MarshalJSON()
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshal interface and unmarshals an
|
||||
// integer or a string into a serial number. If a string is used, a prefix of
|
||||
// “0b” or “0B” selects base 2, “0”, “0o” or “0O” selects base 8, and “0x” or
|
||||
// “0X” selects base 16. Otherwise, the selected base is 10 and no prefix is
|
||||
// accepted.
|
||||
func (s *SerialNumber) UnmarshalJSON(data []byte) error {
|
||||
if sn, ok := maybeString(data); ok {
|
||||
// Using base 0 to accept prefixes 0b, 0o, 0x but defaults as base 10.
|
||||
b, ok := new(big.Int).SetString(sn, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("error unmarshaling json: serialNumber %s is not valid", sn)
|
||||
}
|
||||
*s = SerialNumber{
|
||||
Int: b,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Assume a number.
|
||||
var i int64
|
||||
if err := json.Unmarshal(data, &i); err != nil {
|
||||
return errors.Wrap(err, "error unmarshaling json")
|
||||
}
|
||||
*s = SerialNumber{
|
||||
Int: new(big.Int).SetInt64(i),
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
104
x509util/pkix.go
Normal file
104
x509util/pkix.go
Normal file
|
@ -0,0 +1,104 @@
|
|||
package x509util
|
||||
|
||||
import (
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// Name is the JSON representation of X.501 type Name, used in the X.509 subject
|
||||
// and issuer fields.
|
||||
type Name struct {
|
||||
Country MultiString `json:"country"`
|
||||
Organization MultiString `json:"organization"`
|
||||
OrganizationalUnit MultiString `json:"organizationUnit"`
|
||||
Locality MultiString `json:"locality"`
|
||||
Province MultiString `json:"province"`
|
||||
StreetAddress MultiString `json:"streetAddress"`
|
||||
PostalCode MultiString `json:"postalCode"`
|
||||
SerialNumber string `json:"serialNumber"`
|
||||
CommonName string `json:"commonName"`
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshal interface and unmarshals a JSON
|
||||
// object in the Subject struct or a string as just the subject common name.
|
||||
func (n *Name) UnmarshalJSON(data []byte) error {
|
||||
if cn, ok := maybeString(data); ok {
|
||||
n.CommonName = cn
|
||||
return nil
|
||||
}
|
||||
|
||||
type nameAlias Name
|
||||
var nn nameAlias
|
||||
if err := json.Unmarshal(data, &nn); err != nil {
|
||||
return errors.Wrap(err, "error unmarshaling json")
|
||||
}
|
||||
*n = Name(nn)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Subject is the JSON representation of the X.509 subject field.
|
||||
type Subject Name
|
||||
|
||||
func newSubject(n pkix.Name) Subject {
|
||||
return Subject{
|
||||
Country: n.Country,
|
||||
Organization: n.Organization,
|
||||
OrganizationalUnit: n.OrganizationalUnit,
|
||||
Locality: n.Locality,
|
||||
Province: n.Province,
|
||||
StreetAddress: n.StreetAddress,
|
||||
PostalCode: n.PostalCode,
|
||||
SerialNumber: n.SerialNumber,
|
||||
CommonName: n.CommonName,
|
||||
}
|
||||
}
|
||||
|
||||
// Set sets the subject in the given certificate.
|
||||
func (s Subject) Set(c *x509.Certificate) {
|
||||
c.Subject = pkix.Name{
|
||||
Country: s.Country,
|
||||
Organization: s.Organization,
|
||||
OrganizationalUnit: s.OrganizationalUnit,
|
||||
Locality: s.Locality,
|
||||
Province: s.Province,
|
||||
StreetAddress: s.StreetAddress,
|
||||
PostalCode: s.PostalCode,
|
||||
SerialNumber: s.SerialNumber,
|
||||
CommonName: s.CommonName,
|
||||
}
|
||||
}
|
||||
|
||||
// Issuer is the JSON representation of the X.509 issuer field.
|
||||
type Issuer Name
|
||||
|
||||
func newIssuer(n pkix.Name) Issuer {
|
||||
return Issuer{
|
||||
Country: n.Country,
|
||||
Organization: n.Organization,
|
||||
OrganizationalUnit: n.OrganizationalUnit,
|
||||
Locality: n.Locality,
|
||||
Province: n.Province,
|
||||
StreetAddress: n.StreetAddress,
|
||||
PostalCode: n.PostalCode,
|
||||
SerialNumber: n.SerialNumber,
|
||||
CommonName: n.CommonName,
|
||||
}
|
||||
}
|
||||
|
||||
// Set sets the issuer in the given certificate.
|
||||
func (i Issuer) Set(c *x509.Certificate) {
|
||||
c.Issuer = pkix.Name{
|
||||
Country: i.Country,
|
||||
Organization: i.Organization,
|
||||
OrganizationalUnit: i.OrganizationalUnit,
|
||||
Locality: i.Locality,
|
||||
Province: i.Province,
|
||||
StreetAddress: i.StreetAddress,
|
||||
PostalCode: i.PostalCode,
|
||||
SerialNumber: i.SerialNumber,
|
||||
CommonName: i.CommonName,
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue