This commit is contained in:
Henry Case 2018-08-10 09:08:43 +01:00
parent a2fe2d9a71
commit 91a6fcebab
2 changed files with 22 additions and 19 deletions

View File

@ -1216,3 +1216,17 @@ func signatureFromSignatureScheme(signatureAlgorithm SignatureScheme) uint8 {
return 0 return 0
} }
} }
// TODO(kk): Use variable length encoding?
func getUint24(b []byte) int {
n := int(b[2])
n += int(b[1] << 8)
n += int(b[0] << 16)
return n
}
func putUint24(b []byte, n int) {
b[0] = byte(n >> 16)
b[1] = byte(n >> 8)
b[2] = byte(n & 0xff)
}

View File

@ -37,6 +37,8 @@ import (
) )
const ( const (
// length of the public key field
dcPubKeyFieldLen = 3
dcMaxTTLSeconds = 60 * 60 * 24 * 7 // 7 days dcMaxTTLSeconds = 60 * 60 * 24 * 7 // 7 days
dcMaxTTL = time.Duration(dcMaxTTLSeconds * time.Second) dcMaxTTL = time.Duration(dcMaxTTLSeconds * time.Second)
dcMaxPublicKeyLen = 1 << 24 // Bytes dcMaxPublicKeyLen = 1 << 24 // Bytes
@ -135,7 +137,7 @@ func (cred *credential) marshal() ([]byte, error) {
paramsLen := 8 paramsLen := 8
// The first 4 bytes are the valid_time, scheme, and version fields. // The first 4 bytes are the valid_time, scheme, and version fields.
serialized := make([]byte, paramsLen+3) // +3 for the length of the public key field serialized := make([]byte, paramsLen+dcPubKeyFieldLen)
binary.BigEndian.PutUint32(serialized, uint32(cred.validTime/time.Second)) binary.BigEndian.PutUint32(serialized, uint32(cred.validTime/time.Second))
binary.BigEndian.PutUint16(serialized[4:], uint16(cred.expectedCertVerifyAlgorithm)) binary.BigEndian.PutUint16(serialized[4:], uint16(cred.expectedCertVerifyAlgorithm))
binary.BigEndian.PutUint16(serialized[6:], cred.expectedVersion) binary.BigEndian.PutUint16(serialized[6:], cred.expectedVersion)
@ -165,7 +167,7 @@ func unmarshalCredential(serialized []byte) (*credential, error) {
// The number of bytes comprising the DC parameters. // The number of bytes comprising the DC parameters.
paramsLen := 8 paramsLen := 8
if len(serialized) < paramsLen+3 { // +3 bytes for the public key length if len(serialized) < paramsLen+dcPubKeyFieldLen {
return nil, errors.New("credential is too short") return nil, errors.New("credential is too short")
} }
@ -175,7 +177,7 @@ func unmarshalCredential(serialized []byte) (*credential, error) {
version := binary.BigEndian.Uint16(serialized[6:]) version := binary.BigEndian.Uint16(serialized[6:])
// Parse the SubjectPublicKeyInfo. // Parse the SubjectPublicKeyInfo.
pk, err := x509.ParsePKIXPublicKey(serialized[paramsLen+3:]) pk, err := x509.ParsePKIXPublicKey(serialized[paramsLen+dcPubKeyFieldLen:])
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -198,7 +200,7 @@ func unmarshalCredential(serialized []byte) (*credential, error) {
// error if the input is too short to contain a credential. // error if the input is too short to contain a credential.
func getCredentialLen(serialized []byte) (int, error) { func getCredentialLen(serialized []byte) (int, error) {
paramsLen := 8 paramsLen := 8
if len(serialized) < paramsLen+3 { // +3 for the public key length if len(serialized) < paramsLen+dcPubKeyFieldLen {
return 0, errors.New("credential is too short") return 0, errors.New("credential is too short")
} }
// First several bytes are the valid_time, scheme, and version fields. // First several bytes are the valid_time, scheme, and version fields.
@ -207,13 +209,13 @@ func getCredentialLen(serialized []byte) (int, error) {
// The next 3 bytes are the length of the serialized public key, which may // The next 3 bytes are the length of the serialized public key, which may
// be up to 2^24 bytes in length. // be up to 2^24 bytes in length.
serializedPublicKeyLen := getUint24(serialized) serializedPublicKeyLen := getUint24(serialized)
serialized = serialized[3:] serialized = serialized[dcPubKeyFieldLen:]
if len(serialized) < serializedPublicKeyLen { if len(serialized) < serializedPublicKeyLen {
return 0, errors.New("public key of credential is too short") return 0, errors.New("public key of credential is too short")
} }
return paramsLen + 3 + serializedPublicKeyLen, nil return paramsLen + dcPubKeyFieldLen + serializedPublicKeyLen, nil
} }
// delegatedCredential stores a credential and its delegation. // delegatedCredential stores a credential and its delegation.
@ -388,16 +390,3 @@ func prepareDelegation(hash crypto.Hash, cred, delegatorCert []byte, delegatorAl
return h.Sum(nil) return h.Sum(nil)
} }
func getUint24(b []byte) int {
n := int(b[2])
n += int(b[1] << 8)
n += int(b[0] << 16)
return n
}
func putUint24(b []byte, n int) {
b[0] = byte(n >> 16)
b[1] = byte(n >> 8)
b[2] = byte(n & 0xff)
}