Read in public and private keys when reading in keysandcert from a byte slice

This commit is contained in:
idk
2021-04-24 15:32:45 -04:00
parent 896df4e483
commit 1cd9d16760
4 changed files with 113 additions and 95 deletions

View File

@ -61,7 +61,11 @@ type Certificate struct {
var ci CertificateInterface = &Certificate{}
func (certificate Certificate) Cert() []byte {
return certificate.CertBytes
var ret []byte
ret = append(ret, IntegerBytes(certificate.CertType)...)
ret = append(ret, IntegerBytes(certificate.CertLen)...)
ret = append(ret, certificate.CertBytes...)
return ret
}
//
@ -69,17 +73,10 @@ func (certificate Certificate) Cert() []byte {
// and an error if the certificate is shorter than the minimum certificate size.
//
func (certificate Certificate) Type() (cert_type int, err error) {
cert_len := len(certificate.Cert())
if cert_len < CERT_MIN_SIZE {
log.WithFields(log.Fields{
"at": "(Certificate) Type",
"certificate_bytes_length": cert_len,
"reason": "too short (len < CERT_MIN_SIZE)",
}).Error("invalid certificate")
err = errors.New("error parsing certificate length: certificate is too short")
_, err = certificate.Type()
if err != nil {
return
}
cert_type = certificate.CertType
return
}
@ -89,7 +86,6 @@ func (certificate Certificate) Type() (cert_type int, err error) {
// match the provided data.
//
func (certificate Certificate) Length() (length int, err error) {
cert_len := len(certificate.Cert())
_, err = certificate.Type()
if err != nil {
return
@ -115,7 +111,7 @@ func (certificate Certificate) Data() (data []byte, err error) {
return
}
}
data = certificate.Cert()[CERT_MIN_SIZE:]
data = certificate.Cert()
return
}

View File

@ -24,11 +24,11 @@ type Destination struct {
}
func (destination Destination) PublicKey() (crypto.PublicKey, error) {
return destination.KeysAndCert.PublicKey()
return destination.KeysAndCert.GetPublicKey()
}
func (destination Destination) SigningPublicKey() (crypto.SigningPublicKey, error) {
return destination.KeysAndCert.SigningPublicKey()
return destination.KeysAndCert.GetSigningPublicKey()
}
func (destination Destination) Certificate() (Certificate, error) {

View File

@ -60,8 +60,8 @@ const (
)
type KeysAndCert struct {
//crypto.SigningPublicKey
//crypto.PublicKey
crypto.SigningPublicKey
crypto.PublicKey
Certificate
}
@ -71,7 +71,7 @@ type KeysAndCert struct {
// Return the PublicKey for this KeysAndCert, reading from the Key Certificate if it is present to
// determine correct lengths.
//
func (keys_and_cert KeysAndCert) PublicKey() (key crypto.PublicKey, err error) {
func (keys_and_cert KeysAndCert) GetPublicKey() (key crypto.PublicKey, err error) {
cert, err := keys_and_cert.GetCertificate()
if err != nil {
return
@ -80,35 +80,8 @@ func (keys_and_cert KeysAndCert) PublicKey() (key crypto.PublicKey, err error) {
if err != nil {
return
}
if cert_len == 0 {
// No Certificate is present, return the KEYS_AND_CERT_PUBKEY_SIZE byte
// PublicKey space as ElgPublicKey.
var elg_key crypto.ElgPublicKey
copy(keys_and_cert.Cert()[:KEYS_AND_CERT_PUBKEY_SIZE], elg_key[:])
key = elg_key
} else {
// A Certificate is present in this KeysAndCert
cert_type, _ := cert.Type()
if cert_type == CERT_KEY {
// This KeysAndCert contains a Key Certificate, construct
// a PublicKey from the data in the KeysAndCert and
// any additional data in the Certificate.
key, err = KeyCertificate{PKType: cert_type}.ConstructPublicKey(
keys_and_cert.Cert()[:KEYS_AND_CERT_PUBKEY_SIZE],
)
} else {
// Key Certificate is not present, return the KEYS_AND_CERT_PUBKEY_SIZE byte
// PublicKey space as ElgPublicKey. No other Certificate
// types are currently in use.
var elg_key crypto.ElgPublicKey
copy(keys_and_cert.Cert()[:KEYS_AND_CERT_PUBKEY_SIZE], elg_key[:])
key = elg_key
log.WithFields(log.Fields{
"at": "(KeysAndCert) PublicKey",
"cert_type": cert_type,
}).Warn("unused certificate type observed")
}
if cert_len != 0 {
key = keys_and_cert.PublicKey
}
return
}
@ -117,7 +90,7 @@ func (keys_and_cert KeysAndCert) PublicKey() (key crypto.PublicKey, err error) {
// Return the SigningPublicKey for this KeysAndCert, reading from the Key Certificate if it is present to
// determine correct lengths.
//
func (keys_and_cert KeysAndCert) SigningPublicKey() (signing_public_key crypto.SigningPublicKey, err error) {
func (keys_and_cert KeysAndCert) GetSigningPublicKey() (signing_public_key crypto.SigningPublicKey, err error) {
cert, err := keys_and_cert.GetCertificate()
if err != nil {
return
@ -126,31 +99,8 @@ func (keys_and_cert KeysAndCert) SigningPublicKey() (signing_public_key crypto.S
if err != nil {
return
}
if cert_len == 0 {
// No Certificate is present, return the KEYS_AND_CERT_SPK_SIZE byte
// SigningPublicKey space as legacy DSA SHA1 SigningPublicKey.
var dsa_pk crypto.DSAPublicKey
copy(dsa_pk[:], keys_and_cert.Cert()[KEYS_AND_CERT_PUBKEY_SIZE:KEYS_AND_CERT_PUBKEY_SIZE+KEYS_AND_CERT_SPK_SIZE])
signing_public_key = dsa_pk
} else {
// A Certificate is present in this KeysAndCert
cert_type, _ := cert.Type()
if cert_type == CERT_KEY {
// This KeysAndCert contains a Key Certificate, construct
// a SigningPublicKey from the data in the KeysAndCert and
// any additional data in the Certificate.
signing_public_key, err = KeyCertificate{SPKType: cert_type}.ConstructSigningPublicKey(
keys_and_cert.Cert()[KEYS_AND_CERT_PUBKEY_SIZE : KEYS_AND_CERT_PUBKEY_SIZE+KEYS_AND_CERT_SPK_SIZE],
)
} else {
// Key Certificate is not present, return the KEYS_AND_CERT_SPK_SIZE byte
// SigningPublicKey space as legacy SHA DSA1 SigningPublicKey.
// No other Certificate types are currently in use.
var dsa_pk crypto.DSAPublicKey
copy(dsa_pk[:], keys_and_cert.Cert()[KEYS_AND_CERT_PUBKEY_SIZE:KEYS_AND_CERT_PUBKEY_SIZE+KEYS_AND_CERT_SPK_SIZE])
signing_public_key = dsa_pk
}
if cert_len != 0 {
signing_public_key = keys_and_cert.SigningPublicKey
}
return
}
@ -160,18 +110,11 @@ func (keys_and_cert KeysAndCert) SigningPublicKey() (signing_public_key crypto.S
// KeysAndCert or Certificate.
//
func (keys_and_cert KeysAndCert) GetCertificate() (cert Certificate, err error) {
keys_cert_len := len(keys_and_cert.Cert())
if keys_cert_len < KEYS_AND_CERT_MIN_SIZE {
log.WithFields(log.Fields{
"at": "(KeysAndCert) Certificate",
"data_len": keys_cert_len,
"required_len": KEYS_AND_CERT_MIN_SIZE,
"reason": "not enough data",
}).Error("error parsing keys and cert")
err = errors.New("error parsing KeysAndCert: data is smaller than minimum valid size")
_, err = keys_and_cert.Certificate.Type()
if err != nil {
return
}
cert, _, err = ReadCertificate(keys_and_cert.Cert()[KEYS_AND_CERT_DATA_SIZE:])
cert = keys_and_cert.Certificate
return
}
@ -191,14 +134,20 @@ func ReadKeysAndCert(data []byte) (keys_and_cert KeysAndCert, remainder []byte,
err = errors.New("error parsing KeysAndCert: data is smaller than minimum valid size")
return
}
/* keys_and_cert = KeysAndCert{
KeyCertificate: KeyCertificate{
Certificate: data[:KEYS_AND_CERT_MIN_SIZE],
PublicKey:,
SigningPublicKey:,
}*/
cert, _ := keys_and_cert.GetCertificate()
cert, remainder, err := ReadCertificate(data[:KEYS_AND_CERT_MIN_SIZE])
if err != nil {
return
}
cert, _ = keys_and_cert.GetCertificate()
spk, pk, remainder, err := ReadKeys(data, cert)
if err != nil {
return
}
keys_and_cert = KeysAndCert{
SigningPublicKey: spk,
PublicKey: pk,
Certificate: cert,
}
cert_len, cert_len_err := cert.Length()
if cert_len == 0 {
remainder = data[KEYS_AND_CERT_MIN_SIZE:]
@ -213,3 +162,72 @@ func ReadKeysAndCert(data []byte) (keys_and_cert KeysAndCert, remainder []byte,
}
return
}
func ReadKeys(data []byte, cert Certificate) (spk crypto.SigningPublicKey, pk crypto.PublicKey, remainder []byte, err error) {
data_len := len(data)
if data_len < KEYS_AND_CERT_MIN_SIZE {
log.WithFields(log.Fields{
"at": "ReadKeysAndCert",
"data_len": data_len,
"required_len": KEYS_AND_CERT_MIN_SIZE,
"reason": "not enough data",
}).Error("error parsing keys and cert")
err = errors.New("error parsing KeysAndCert: data is smaller than minimum valid size")
return
}
if data_len == 0 {
// No Certificate is present, return the KEYS_AND_CERT_PUBKEY_SIZE byte
// PublicKey space as ElgPublicKey.
var elg_key crypto.ElgPublicKey
copy(data[:KEYS_AND_CERT_PUBKEY_SIZE], elg_key[:])
pk = elg_key
} else {
// A Certificate is present in this KeysAndCert
cert_type, _ := cert.Type()
if cert_type == CERT_KEY {
// This KeysAndCert contains a Key Certificate, construct
// a PublicKey from the data in the KeysAndCert and
// any additional data in the Certificate.
pk, err = KeyCertificate{PKType: cert_type}.ConstructPublicKey(
data[:KEYS_AND_CERT_PUBKEY_SIZE],
)
} else {
// Key Certificate is not present, return the KEYS_AND_CERT_PUBKEY_SIZE byte
// PublicKey space as ElgPublicKey. No other Certificate
// types are currently in use.
var elg_key crypto.ElgPublicKey
copy(data[:KEYS_AND_CERT_PUBKEY_SIZE], elg_key[:])
pk = elg_key
log.WithFields(log.Fields{
"at": "(KeysAndCert) PublicKey",
"cert_type": cert_type,
}).Warn("unused certificate type observed")
}
}
if data_len == 0 {
// No Certificate is present, return the KEYS_AND_CERT_SPK_SIZE byte
// SigningPublicKey space as legacy DSA SHA1 SigningPublicKey.
var dsa_pk crypto.DSAPublicKey
copy(dsa_pk[:], data[KEYS_AND_CERT_PUBKEY_SIZE:KEYS_AND_CERT_PUBKEY_SIZE+KEYS_AND_CERT_SPK_SIZE])
spk = dsa_pk
} else {
// A Certificate is present in this KeysAndCert
cert_type, _ := cert.Type()
if cert_type == CERT_KEY {
// This KeysAndCert contains a Key Certificate, construct
// a SigningPublicKey from the data in the KeysAndCert and
// any additional data in the Certificate.
spk, err = KeyCertificate{SPKType: cert_type}.ConstructSigningPublicKey(
data[KEYS_AND_CERT_PUBKEY_SIZE : KEYS_AND_CERT_PUBKEY_SIZE+KEYS_AND_CERT_SPK_SIZE],
)
} else {
// Key Certificate is not present, return the KEYS_AND_CERT_SPK_SIZE byte
// SigningPublicKey space as legacy SHA DSA1 SigningPublicKey.
// No other Certificate types are currently in use.
var dsa_pk crypto.DSAPublicKey
copy(dsa_pk[:], data[KEYS_AND_CERT_PUBKEY_SIZE:KEYS_AND_CERT_PUBKEY_SIZE+KEYS_AND_CERT_SPK_SIZE])
spk = dsa_pk
}
}
return
}

View File

@ -95,16 +95,19 @@ const (
type LeaseSet struct {
Destination
Leases []Lease
LeaseList []Lease
}
//
// Read a Destination from the LeaseSet.
//
func (lease_set LeaseSet) Destination() (destination Destination, err error) {
keys_and_cert, _, err := ReadKeysAndCert(lease_set)
destination = Destination(keys_and_cert)
return Destination
func (lease_set LeaseSet) GetDestination() (destination Destination, err error) {
if &lease_set.Destination != nil {
destination = lease_set.Destination
} else {
err = errors.New("Error leaseset does not contain a destination")
}
return
}
//
@ -132,6 +135,7 @@ func (lease_set LeaseSet) PublicKey() (public_key crypto.ElgPublicKey, err error
// Return the SigningPublicKey, as specified in the LeaseSet's Destination's Key Certificate if
// present, or a legacy DSA key.
//
func (lease_set LeaseSet) SigningKey() (signing_public_key crypto.SigningPublicKey, err error) {
destination, err := lease_set.Destination()
if err != nil {