2024-01-26 01:16:37 +00:00
|
|
|
package pkcs15
|
|
|
|
|
|
|
|
import (
|
2024-01-27 16:35:35 +00:00
|
|
|
"apc-p15-tool/pkg/tools/asn1obj"
|
|
|
|
"math/big"
|
2024-01-26 01:16:37 +00:00
|
|
|
)
|
|
|
|
|
2024-01-27 16:35:35 +00:00
|
|
|
const (
|
|
|
|
apcKeyLabel = "Private key"
|
|
|
|
)
|
2024-01-26 01:16:37 +00:00
|
|
|
|
2024-01-27 16:35:35 +00:00
|
|
|
// ToP15File turns the key and cert into a properly formatted and encoded
|
|
|
|
// p15 file
|
|
|
|
func (p15 *pkcs15KeyCert) ToP15File() ([]byte, error) {
|
|
|
|
// private key object
|
|
|
|
pkey, err := p15.toP15PrivateKey()
|
2024-01-26 01:16:37 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2024-01-27 16:35:35 +00:00
|
|
|
cert, err := p15.toP15Cert()
|
2024-01-26 01:16:37 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2024-01-27 16:35:35 +00:00
|
|
|
// ContentInfo
|
|
|
|
p15File := asn1obj.Sequence([][]byte{
|
|
|
|
|
|
|
|
// contentType: OID: 1.2.840.113549.1.15.3.1 pkcs15content (PKCS #15 content type)
|
|
|
|
asn1obj.ObjectIdentifier(asn1obj.OIDPkscs15Content),
|
|
|
|
|
|
|
|
// content
|
|
|
|
asn1obj.ExplicitCompound(0, [][]byte{
|
|
|
|
asn1obj.Sequence([][]byte{
|
|
|
|
asn1obj.Integer(big.NewInt(0)),
|
|
|
|
asn1obj.Sequence([][]byte{
|
|
|
|
asn1obj.ExplicitCompound(0, [][]byte{
|
|
|
|
asn1obj.ExplicitCompound(0, [][]byte{
|
|
|
|
pkey,
|
|
|
|
}),
|
|
|
|
}),
|
|
|
|
asn1obj.ExplicitCompound(4, [][]byte{
|
|
|
|
asn1obj.ExplicitCompound(0, [][]byte{
|
|
|
|
cert,
|
|
|
|
}),
|
|
|
|
}),
|
|
|
|
}),
|
|
|
|
}),
|
|
|
|
}),
|
|
|
|
})
|
|
|
|
|
|
|
|
return p15File, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// toP15PrivateKey creates the encoded private key. it is broken our from the larger p15
|
|
|
|
// function for readability
|
|
|
|
// NOTE: Do not use this to try and turn just a private key into a p15, the format isn't
|
|
|
|
// quite the same.
|
|
|
|
func (p15 *pkcs15KeyCert) toP15PrivateKey() ([]byte, error) {
|
|
|
|
// rsa encrypted key in encrypted envelope
|
|
|
|
envelope, err := p15.encryptedKeyEnvelope()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2024-01-26 01:16:37 +00:00
|
|
|
}
|
|
|
|
|
2024-01-27 16:35:35 +00:00
|
|
|
// key object
|
|
|
|
key := asn1obj.Sequence([][]byte{
|
|
|
|
// commonObjectAttributes - Label
|
|
|
|
asn1obj.Sequence([][]byte{
|
|
|
|
asn1obj.UTF8String(apcKeyLabel),
|
|
|
|
}),
|
|
|
|
// CommonKeyAttributes
|
|
|
|
asn1obj.Sequence([][]byte{
|
|
|
|
// CommonKeyAttributes - iD - uses keyId that is SHA1( SubjectPublicKeyInfo SEQUENCE )
|
|
|
|
asn1obj.OctetString(p15.keyId()),
|
|
|
|
// CommonKeyAttributes - usage (trailing 0s will drop)
|
|
|
|
asn1obj.BitString([]byte{byte(0b11100010)}),
|
|
|
|
// CommonKeyAttributes - accessFlags (trailing 0s will drop)
|
|
|
|
asn1obj.BitString([]byte{byte(0b10110000)}),
|
|
|
|
// CommonKeyAttributes - startDate
|
|
|
|
asn1obj.GeneralizedTime(p15.cert.NotBefore),
|
|
|
|
// CommonKeyAttributes - [0] endDate
|
|
|
|
asn1obj.GeneralizedTimeExplicitValue(0, p15.cert.NotAfter),
|
|
|
|
}),
|
|
|
|
// ObjectValue - indirect-protected
|
|
|
|
asn1obj.ExplicitCompound(1, [][]byte{
|
|
|
|
asn1obj.Sequence([][]byte{
|
|
|
|
// AuthEnvelopedData Type ([4])
|
|
|
|
asn1obj.ExplicitCompound(4, [][]byte{
|
|
|
|
envelope,
|
|
|
|
}),
|
|
|
|
}),
|
|
|
|
}),
|
|
|
|
})
|
|
|
|
|
|
|
|
return key, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// toP15Cert creates the encoded certificate. it is broken our from the larger p15
|
|
|
|
// function for readability
|
|
|
|
// NOTE: Do not use this to try and turn just a cert into a p15. I don't believe,
|
|
|
|
// such a thing is permissible under the spec.
|
|
|
|
func (p15 *pkcs15KeyCert) toP15Cert() ([]byte, error) {
|
|
|
|
// cert object
|
|
|
|
cert := asn1obj.Sequence([][]byte{
|
|
|
|
// commonObjectAttributes - Label
|
|
|
|
asn1obj.Sequence([][]byte{
|
|
|
|
asn1obj.UTF8String(apcKeyLabel),
|
|
|
|
}),
|
|
|
|
// keyIds of various types
|
|
|
|
asn1obj.Sequence([][]byte{
|
|
|
|
asn1obj.OctetString(p15.keyId()),
|
|
|
|
// additional keyids
|
|
|
|
asn1obj.ExplicitCompound(2, [][]byte{
|
|
|
|
p15.keyIdInt2(),
|
2024-01-27 16:35:36 +00:00
|
|
|
p15.keyIdInt3(),
|
|
|
|
p15.keyIdInt6(),
|
|
|
|
p15.keyIdInt7(),
|
|
|
|
p15.keyIdInt8(),
|
|
|
|
p15.keyIdInt9(),
|
|
|
|
}),
|
|
|
|
// CommonKeyAttributes - startDate
|
|
|
|
asn1obj.GeneralizedTime(p15.cert.NotBefore),
|
|
|
|
// CommonKeyAttributes - [4] endDate
|
|
|
|
asn1obj.GeneralizedTimeExplicitValue(4, p15.cert.NotAfter),
|
|
|
|
}),
|
|
|
|
// actual certificate itself
|
|
|
|
asn1obj.ExplicitCompound(1, [][]byte{
|
|
|
|
asn1obj.Sequence([][]byte{
|
|
|
|
asn1obj.ExplicitCompound(0, [][]byte{
|
|
|
|
p15.cert.Raw,
|
|
|
|
}),
|
2024-01-27 16:35:35 +00:00
|
|
|
}),
|
|
|
|
}),
|
|
|
|
})
|
|
|
|
|
|
|
|
return cert, nil
|
2024-01-26 01:16:37 +00:00
|
|
|
}
|