mirror of
https://github.com/gregtwallace/apc-p15-tool.git
synced 2025-07-14 11:03:25 +00:00
key: finish key encoding and start cert
This commit is contained in:
parent
85462c93b1
commit
1f6dad4907
14 changed files with 592 additions and 115 deletions
pkg/pkcs15
|
@ -1,36 +1,127 @@
|
|||
package pkcs15
|
||||
|
||||
import (
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"apc-p15-tool/pkg/tools/asn1obj"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
// pkcs15KeyCert holds the data for a key and certificate pair; it provides
|
||||
// various methods to transform pkcs15 data
|
||||
type pkcs15KeyCert struct {
|
||||
key *rsa.PrivateKey
|
||||
cert *x509.Certificate
|
||||
}
|
||||
const (
|
||||
apcKeyLabel = "Private key"
|
||||
)
|
||||
|
||||
// ParsePEMToPKCS15 parses the provide pem files to a pkcs15 struct; it also does some
|
||||
// basic sanity check; if any of this fails, an error is returned
|
||||
func ParsePEMToPKCS15(keyPem, certPem []byte) (*pkcs15KeyCert, error) {
|
||||
// decode / check key
|
||||
key, err := pemKeyDecode(keyPem)
|
||||
// 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()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// decode / check cert
|
||||
cert, err := pemCertDecode(certPem, keyPem)
|
||||
cert, err := p15.toP15Cert()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
p15 := &pkcs15KeyCert{
|
||||
key: key,
|
||||
cert: cert,
|
||||
// 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
|
||||
}
|
||||
|
||||
return p15, nil
|
||||
// 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(),
|
||||
// p15.keyIdInt3(),
|
||||
// p15.keyIdInt6(),
|
||||
// p15.keyIdInt7(),
|
||||
// p15.keyIdInt8(),
|
||||
// p15.keyIdInt9(),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
|
||||
return cert, nil
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue