2016-01-29 07:35:17 -05:00
|
|
|
package common
|
2016-01-28 12:58:58 -05:00
|
|
|
|
|
|
|
import (
|
2016-01-29 07:22:31 -05:00
|
|
|
"github.com/bounce-chat/go-i2p/lib/crypto"
|
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
|
|
|
)
|
|
|
|
|
|
|
|
// used to append data to existing data structures
|
|
|
|
type Certificate []byte
|
|
|
|
|
2016-01-29 07:22:31 -05:00
|
|
|
// return the type of this certificate
|
2016-01-28 12:58:58 -05:00
|
|
|
func (c Certificate) Type() byte {
|
2016-01-29 07:22:31 -05:00
|
|
|
return c[0]
|
2016-01-28 12:58:58 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// get the length of the data in this certificate
|
2016-01-29 08:36:04 -05:00
|
|
|
// return -1 if the size of the certificate is invalid
|
2016-01-28 12:58:58 -05:00
|
|
|
func (c Certificate) Len() int {
|
2016-01-29 08:36:04 -05:00
|
|
|
if len(c) <= 2 {
|
|
|
|
// invalid size
|
|
|
|
return -1
|
|
|
|
}
|
2016-02-04 00:54:51 -08:00
|
|
|
return Integer(c[1:3])
|
2016-01-28 12:58:58 -05:00
|
|
|
}
|
|
|
|
|
2016-01-29 08:36:04 -05:00
|
|
|
// get the data for this certificate or null if none exists
|
2016-01-28 12:58:58 -05:00
|
|
|
func (c Certificate) Data() (d []byte) {
|
2016-01-29 07:22:31 -05:00
|
|
|
l := c.Len()
|
2016-01-29 08:36:04 -05:00
|
|
|
if l > 0 && len(c) <= 3+l {
|
2016-01-29 07:22:31 -05:00
|
|
|
d = c[3 : 3+l]
|
|
|
|
}
|
|
|
|
return
|
2016-01-28 12:58:58 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// a Certificate of type KEY
|
|
|
|
type KeyCert []byte
|
|
|
|
|
|
|
|
func (c KeyCert) Type() byte {
|
2016-01-29 07:22:31 -05:00
|
|
|
return Certificate(c).Type()
|
2016-01-28 12:58:58 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
func (c KeyCert) Data() []byte {
|
2016-01-29 07:22:31 -05:00
|
|
|
return Certificate(c).Data()
|
2016-01-28 12:58:58 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// get the signing public key from this key cert
|
2016-01-28 15:11:54 -05:00
|
|
|
func (c KeyCert) SigningPublicKey() (k crypto.SigningPublicKey) {
|
2016-01-29 07:22:31 -05:00
|
|
|
data := c.Data()
|
2016-02-04 00:54:51 -08:00
|
|
|
ktype := Integer(data[:2])
|
2016-01-29 07:22:31 -05:00
|
|
|
// set data to be the key data now
|
|
|
|
data = data[4:]
|
|
|
|
// determine the key type
|
|
|
|
if ktype == KEYCERT_SIGN_DSA_SHA1 {
|
|
|
|
var pk crypto.DSAPublicKey
|
|
|
|
copy(pk[:], data[:pk.Len()])
|
|
|
|
k = pk
|
|
|
|
} else if ktype == KEYCERT_SIGN_P256 {
|
|
|
|
var pk crypto.ECP256PublicKey
|
|
|
|
copy(pk[:], data[:pk.Len()])
|
|
|
|
k = pk
|
|
|
|
} else if ktype == KEYCERT_SIGN_P384 {
|
|
|
|
var pk crypto.ECP384PublicKey
|
|
|
|
copy(pk[:], data[:pk.Len()])
|
|
|
|
k = pk
|
|
|
|
} else if ktype == KEYCERT_SIGN_P521 {
|
|
|
|
var pk crypto.ECP521PublicKey
|
|
|
|
copy(pk[:], data[:pk.Len()])
|
|
|
|
k = pk
|
|
|
|
}
|
|
|
|
// TODO: rsa/eddsa
|
|
|
|
return
|
2016-01-28 12:58:58 -05:00
|
|
|
}
|
2016-02-01 01:56:10 -08:00
|
|
|
|
|
|
|
func (c Certificate) signatureSize() int {
|
|
|
|
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,
|
|
|
|
}
|
|
|
|
return sizes[int(c.Type())]
|
|
|
|
}
|