mirror of
https://github.com/gregtwallace/apc-p15-tool.git
synced 2025-06-10 05:36:50 +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/tools/asn1obj
46
pkg/tools/asn1obj/explicit.go
Normal file
46
pkg/tools/asn1obj/explicit.go
Normal file
|
@ -0,0 +1,46 @@
|
|||
package asn1obj
|
||||
|
||||
import "encoding/asn1"
|
||||
|
||||
// ExplicitCompound wraps another ASN.1 Object(s) with the EXPLICIT wrapper using
|
||||
// the tag number specified
|
||||
func ExplicitCompound(explicitTagNumber int, wrappedElements [][]byte) []byte {
|
||||
val := []byte{}
|
||||
for i := range wrappedElements {
|
||||
val = append(val, wrappedElements[i]...)
|
||||
}
|
||||
|
||||
raw := asn1.RawValue{
|
||||
Class: asn1.ClassContextSpecific,
|
||||
Tag: explicitTagNumber,
|
||||
IsCompound: true,
|
||||
Bytes: val,
|
||||
}
|
||||
|
||||
// should never error
|
||||
asn1result, err := asn1.Marshal(raw)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return asn1result
|
||||
}
|
||||
|
||||
// ExplicitValue creates an EXPLICIT Object with a byte data value (i.e. it
|
||||
// is NOT compound) using the tag number specified
|
||||
func ExplicitValue(explicitTagNumber int, val []byte) []byte {
|
||||
raw := asn1.RawValue{
|
||||
Class: asn1.ClassContextSpecific,
|
||||
Tag: explicitTagNumber,
|
||||
IsCompound: false,
|
||||
Bytes: val,
|
||||
}
|
||||
|
||||
// should never error
|
||||
asn1result, err := asn1.Marshal(raw)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return asn1result
|
||||
}
|
85
pkg/tools/asn1obj/generalizedtime.go
Normal file
85
pkg/tools/asn1obj/generalizedtime.go
Normal file
|
@ -0,0 +1,85 @@
|
|||
package asn1obj
|
||||
|
||||
import (
|
||||
"encoding/asn1"
|
||||
"time"
|
||||
)
|
||||
|
||||
// GeneralizedTime returns the specified time as a GeneralizedTime
|
||||
func GeneralizedTime(t time.Time) []byte {
|
||||
// should never error
|
||||
asn1result, err := asn1.MarshalWithParams(t, "generalized")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return asn1result
|
||||
}
|
||||
|
||||
// helper funcs from golang asn1 package
|
||||
func appendTwoDigits(dst []byte, v int) []byte {
|
||||
return append(dst, byte('0'+(v/10)%10), byte('0'+v%10))
|
||||
}
|
||||
|
||||
func appendFourDigits(dst []byte, v int) []byte {
|
||||
var bytes [4]byte
|
||||
for i := range bytes {
|
||||
bytes[3-i] = '0' + byte(v%10)
|
||||
v /= 10
|
||||
}
|
||||
return append(dst, bytes[:]...)
|
||||
}
|
||||
|
||||
// generalizedTimevalue returns the specified time encoded as a
|
||||
// GeneralizedTime but WITHOUT the ASN.1 headers (class/tag/length)
|
||||
func generalizedTimevalue(t time.Time) []byte {
|
||||
dst := []byte{}
|
||||
|
||||
year := t.Year()
|
||||
if year < 0 || year > 9999 {
|
||||
panic("cannot represent time as GeneralizedTime (invalid year)")
|
||||
}
|
||||
|
||||
dst = appendFourDigits(dst, year)
|
||||
|
||||
_, month, day := t.Date()
|
||||
|
||||
dst = appendTwoDigits(dst, int(month))
|
||||
dst = appendTwoDigits(dst, day)
|
||||
|
||||
hour, min, sec := t.Clock()
|
||||
|
||||
dst = appendTwoDigits(dst, hour)
|
||||
dst = appendTwoDigits(dst, min)
|
||||
dst = appendTwoDigits(dst, sec)
|
||||
|
||||
_, offset := t.Zone()
|
||||
|
||||
switch {
|
||||
case offset/60 == 0:
|
||||
return append(dst, 'Z')
|
||||
case offset > 0:
|
||||
dst = append(dst, '+')
|
||||
case offset < 0:
|
||||
dst = append(dst, '-')
|
||||
}
|
||||
|
||||
offsetMinutes := offset / 60
|
||||
if offsetMinutes < 0 {
|
||||
offsetMinutes = -offsetMinutes
|
||||
}
|
||||
|
||||
dst = appendTwoDigits(dst, offsetMinutes/60)
|
||||
dst = appendTwoDigits(dst, offsetMinutes%60)
|
||||
|
||||
return dst
|
||||
}
|
||||
|
||||
// helper funcs from golang asn1 package - END
|
||||
|
||||
// GeneralizedTimeExplicitValue returns t encoded as a GeneralizedTime, however
|
||||
// instead of tagging it with GeneralizedTime it is instead tagged with an
|
||||
// explicit tag of the specified tag number
|
||||
func GeneralizedTimeExplicitValue(explicitTagNumber int, t time.Time) []byte {
|
||||
return ExplicitValue(explicitTagNumber, generalizedTimevalue(t))
|
||||
}
|
|
@ -15,3 +15,20 @@ func Integer(bigInt *big.Int) []byte {
|
|||
|
||||
return asn1result
|
||||
}
|
||||
|
||||
// IntegerExplicitValue returns bigInt encoded as an Integer, however
|
||||
// instead of tagging it with Integer it is instead tagged with an
|
||||
// explicit tag of the specified tag number
|
||||
func IntegerExplicitValue(explicitTagNumber int, bigInt *big.Int) []byte {
|
||||
intBytes := Integer(bigInt)
|
||||
|
||||
asn1Obj := asn1.RawValue{}
|
||||
rest, err := asn1.Unmarshal(intBytes, &asn1Obj)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
} else if len(rest) > 0 {
|
||||
panic("invalid extra data")
|
||||
}
|
||||
|
||||
return ExplicitValue(explicitTagNumber, asn1Obj.Bytes)
|
||||
}
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
package asn1obj
|
||||
|
||||
import "encoding/asn1"
|
||||
|
||||
// Explicit wraps another ASN.1 Object with the EXPLICIT wrapper using
|
||||
// the tag number specified
|
||||
func Explicit(explicitTagNumber int, wrappedElement []byte) []byte {
|
||||
raw := asn1.RawValue{
|
||||
Class: asn1.ClassContextSpecific,
|
||||
Tag: explicitTagNumber,
|
||||
IsCompound: true,
|
||||
Bytes: wrappedElement,
|
||||
}
|
||||
|
||||
// should never error
|
||||
asn1result, err := asn1.Marshal(raw)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return asn1result
|
||||
}
|
||||
|
||||
// Null returns the NULL value
|
||||
func Null() []byte {
|
||||
return asn1.NullBytes
|
||||
}
|
|
@ -3,8 +3,14 @@ package asn1obj
|
|||
import "encoding/asn1"
|
||||
|
||||
var (
|
||||
OIDPkscs15Content = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 15, 3, 1} // pkcs15content (PKCS #15 content type)
|
||||
OIDrsaEncryptionPKCS1 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1} // rsaEncryption (PKCS #1)
|
||||
OIDPkscs15Content = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 15, 3, 1} // pkcs15content (PKCS #15 content type)
|
||||
OIDrsaEncryptionPKCS1 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1} // rsaEncryption (PKCS #1)
|
||||
OIDpkcs5PBKDF2 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 5, 12} // pkcs5PBKDF2 (PKCS #5 v2.0)
|
||||
OIDhmacWithSHA256 = asn1.ObjectIdentifier{1, 2, 840, 113549, 2, 9} // hmacWithSHA256 (RSADSI digestAlgorithm)
|
||||
OIDpwriKEK = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 16, 3, 9} // pwriKEK (S/MIME Algorithms)
|
||||
OIDdesEDE3CBC = asn1.ObjectIdentifier{1, 2, 840, 113549, 3, 7} // des-EDE3-CBC (RSADSI encryptionAlgorithm)
|
||||
OIDpkcs7Data = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 1} // data (PKCS #7)
|
||||
OIDauthEnc128 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 16, 3, 15} // authEnc128 (S/MIME Algorithms)
|
||||
)
|
||||
|
||||
// ObjectIdentifier returns an ASN.1 OBJECT IDENTIFIER with the oidValue bytes
|
||||
|
|
26
pkg/tools/asn1obj/set.go
Normal file
26
pkg/tools/asn1obj/set.go
Normal file
|
@ -0,0 +1,26 @@
|
|||
package asn1obj
|
||||
|
||||
import "encoding/asn1"
|
||||
|
||||
// Set returns an ASN.1 SET with the specified content
|
||||
func Set(content [][]byte) []byte {
|
||||
val := []byte{}
|
||||
for i := range content {
|
||||
val = append(val, content[i]...)
|
||||
}
|
||||
|
||||
raw := asn1.RawValue{
|
||||
Class: asn1.ClassUniversal,
|
||||
Tag: asn1.TagSet,
|
||||
IsCompound: true,
|
||||
Bytes: val,
|
||||
}
|
||||
|
||||
// should never error
|
||||
asn1result, err := asn1.Marshal(raw)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return asn1result
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue