2016-01-29 07:35:17 -05:00
|
|
|
package common
|
2016-01-28 12:58:58 -05:00
|
|
|
|
|
|
|
import (
|
2016-02-05 02:23:11 -08:00
|
|
|
"errors"
|
2016-01-28 12:58:58 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
2016-01-29 07:22:31 -05:00
|
|
|
CERT_NULL = iota
|
|
|
|
CERT_HASHCASH
|
|
|
|
CERT_HIDDEN
|
|
|
|
CERT_SIGNED
|
|
|
|
CERT_MULTIPLE
|
|
|
|
CERT_KEY
|
2016-01-28 12:58:58 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
2016-01-29 07:22:31 -05:00
|
|
|
KEYCERT_SIGN_DSA_SHA1 = iota
|
|
|
|
KEYCERT_SIGN_P256
|
|
|
|
KEYCERT_SIGN_P384
|
|
|
|
KEYCERT_SIGN_P521
|
|
|
|
KEYCERT_SIGN_RSA2048
|
|
|
|
KEYCERT_SIGN_RSA3072
|
|
|
|
KEYCERT_SIGN_RSA4096
|
|
|
|
KEYCERT_SIGN_ED25519
|
2016-01-28 12:58:58 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
2016-01-29 07:22:31 -05:00
|
|
|
KEYCERT_CRYPTO_ELG = iota
|
2016-01-28 12:58:58 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
type Certificate []byte
|
|
|
|
|
2016-02-05 02:23:11 -08:00
|
|
|
func (certificate Certificate) Type() byte {
|
|
|
|
return certificate[0]
|
2016-01-28 12:58:58 -05:00
|
|
|
}
|
|
|
|
|
2016-02-05 02:23:11 -08:00
|
|
|
func (certificate Certificate) Length() (int, error) {
|
|
|
|
if len(certificate) < 3 {
|
|
|
|
// log
|
|
|
|
return 0, errors.New("error parsing certificate length: certificate is too short")
|
2016-01-29 08:36:04 -05:00
|
|
|
}
|
2016-02-05 02:23:11 -08:00
|
|
|
length := Integer(certificate[1:3])
|
|
|
|
inferred_len := length + 3
|
|
|
|
cert_len := len(certificate)
|
|
|
|
if inferred_len > cert_len {
|
|
|
|
// log
|
|
|
|
return length, errors.New("certificate parsing warning: certificate data is shorter than specified by length")
|
|
|
|
} else if cert_len > inferred_len {
|
|
|
|
//log
|
|
|
|
return length, errors.New("certificate parsing warning: certificate contains data beyond length")
|
2016-01-29 07:22:31 -05:00
|
|
|
}
|
2016-02-05 02:23:11 -08:00
|
|
|
return length, nil
|
2016-01-28 12:58:58 -05:00
|
|
|
}
|
|
|
|
|
2016-02-05 02:23:11 -08:00
|
|
|
func (certificate Certificate) Data() ([]byte, error) {
|
|
|
|
length, err := certificate.Length()
|
|
|
|
if err != nil {
|
|
|
|
switch err.Error() {
|
|
|
|
case "error parsing certificate length: certificate is too short":
|
|
|
|
return make([]byte, 0), err
|
|
|
|
case "certificate parsing warning: certificate data is shorter than specified by length":
|
|
|
|
return certificate[3:], err
|
|
|
|
case "certificate parsing warning: certificate contains data beyond length":
|
|
|
|
return certificate[3 : length+3], err
|
|
|
|
}
|
2016-01-29 07:22:31 -05:00
|
|
|
}
|
2016-02-05 02:23:11 -08:00
|
|
|
return certificate[3:], nil
|
2016-01-28 12:58:58 -05:00
|
|
|
}
|
2016-02-01 01:56:10 -08:00
|
|
|
|
2016-02-05 02:23:11 -08:00
|
|
|
func (certificate Certificate) SignatureSize() int {
|
2016-02-01 01:56:10 -08:00
|
|
|
sizes := map[int]int{
|
|
|
|
KEYCERT_SIGN_DSA_SHA1: 40,
|
|
|
|
KEYCERT_SIGN_P256: 64,
|
|
|
|
KEYCERT_SIGN_P384: 96,
|
|
|
|
KEYCERT_SIGN_P521: 132,
|
|
|
|
KEYCERT_SIGN_RSA2048: 256,
|
|
|
|
KEYCERT_SIGN_RSA3072: 384,
|
|
|
|
KEYCERT_SIGN_RSA4096: 512,
|
|
|
|
KEYCERT_SIGN_ED25519: 64,
|
|
|
|
}
|
2016-02-05 02:23:11 -08:00
|
|
|
return sizes[int(certificate.Type())]
|
|
|
|
}
|
|
|
|
|
|
|
|
func ReadCertificate(data []byte) (Certificate, []byte, error) {
|
|
|
|
certificate := Certificate(data)
|
|
|
|
length, err := certificate.Length()
|
|
|
|
if err != nil {
|
|
|
|
switch err.Error() {
|
|
|
|
case "error parsing certificate length: certificate is too short":
|
|
|
|
return Certificate{}, make([]byte, 0), err
|
|
|
|
case "certificate parsing warning: certificate data is shorter than specified by length":
|
|
|
|
return certificate, make([]byte, 0), err
|
|
|
|
case "certificate parsing warning: certificate contains data beyond length":
|
|
|
|
return Certificate(certificate[:length+3]), certificate[length+3:], nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return certificate, make([]byte, 0), nil
|
2016-02-01 01:56:10 -08:00
|
|
|
}
|