simplify su3file

This commit is contained in:
Matt Drollette
2014-12-10 17:21:40 -06:00
parent a2891a2bc6
commit 4be2dbe247
6 changed files with 132 additions and 271 deletions

View File

@@ -3,149 +3,22 @@ package su3
import (
"crypto/x509"
"encoding/pem"
"fmt"
"io/ioutil"
"path/filepath"
"strings"
)
func certForSigner(signer string) (*x509.Certificate, error) {
var certString []byte
var ok bool
if certString, ok = reseedKeys[string(signer)]; !ok {
return nil, fmt.Errorf("Unknown signer '%s'", signer)
func signerCertificate(signer string) (*x509.Certificate, error) {
certFile := filepath.Base(signerFilename(signer))
certString, err := ioutil.ReadFile(filepath.Join("./certificates", certFile))
if nil != err {
return nil, err
}
certPem, _ := pem.Decode(certString)
return x509.ParseCertificate(certPem.Bytes)
}
var (
reseedKeys = map[string][]byte{
"matt@drollette.com": []byte(`-----BEGIN CERTIFICATE-----
MIIFgjCCA2ygAwIBAgICBNIwCwYJKoZIhvcNAQELMFUxCzAJBgNVBAYTAlhYMR4w
HAYDVQQKExVJMlAgQW5vbnltb3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDELMAkG
A1UEBxMCWFgxCzAJBgNVBAkTAlhYMB4XDTE0MTIxMDA1MzQ1M1oXDTI0MTIxMDA1
MzQ1M1owVTELMAkGA1UEBhMCWFgxHjAcBgNVBAoTFUkyUCBBbm9ueW1vdXMgTmV0
d29yazEMMAoGA1UECxMDSTJQMQswCQYDVQQHEwJYWDELMAkGA1UECRMCWFgwggIi
MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDo0Y1eOyG/5GHJLZssrKCdtLCU
8MIfguIv0sU+Q69kGS5yCe1TlrhpSEvHDneZRWc+rbc+eKpPXUdReIFLeuS8cPh7
dkLArx88qEaff2cx1Ss4g+wErVZcPlMf+6og50Z2JxEJe/7WW1B38eQ1f+6i5j33
twruk0Xa9vAnyP+bO53PNyJw548N7qFA/nGeW/r88iYquFtGxGyVv8zMzGeHsmXm
7G+B6LG2FHecg5ZT2shaOCY27i6Rq08qiGV7+qZ6tGGUFFEr6cpcudrzA0yGzsyy
pIUdhWw2+r9AftF0Si4+ic5aIiZzmaBvuzdn6GQkmEQDt5KG6pj7RJN73qCWz85T
tUf/5QI4/0itTQnEtHFJA2Hh1OWRha6HSbHVcHuZdJUtCSKRyXHwMZgYM5e3PAW2
uEuTPA+F81AKBnDWy2FVs/I80epr8526mkRIMTswqLJ8+/MZenmzJ2fUHItwNb4e
qSMrczmlTbB4xEWGKqEb/gij8qr+6Sd4EqR6B5jDo23I39iy33QN924KirlXb2Hl
kMWGjXf/qOEdoqvCMynhathAnVtYhJ1M7scw3Z5v035j/3uidyYX+lKQpf8kSCDo
igImjYewmzCZBgU8n3iCIfhuR+Fw8l3d6f6UdEIVF9Qi0EpJ9kCXyrXYhg3ulckU
S+MQcHqjUewDJUwMLwIDAQABo2AwXjAOBgNVHQ8BAf8EBAMCAIQwHQYDVR0lBBYw
FAYIKwYBBQUHAwIGCCsGAQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wDAYDVR0OBAUE
AwECAzAOBgNVHSMEBzAFgAMBAgMwCwYJKoZIhvcNAQELA4ICAQARD/2NHcnXUE1F
W5exDU4RHQt4Y8FfwXY/ijBtdbHz39BEQ6+P5eS/JwcdXYEn3Kfoan5j42jiYZQq
LpQEJDSDYEy22FkN+NnDawdXX/PMOUs84TIYpPv5h0mESjA+3j6k+cXmnacATsIv
qv/ssrRkAL3yJ5T3MOqRTkYKWXPUAttylLbahRlMyi2l4tq1dsIuGGdEdarpkt78
r0OkYaOO3yJDgloZhDZ1TrUgZ60HKdyUSUNn3QlXU5LlMPNJ2godqRpfsgBa3XZK
fxh0kM1KPJuVy9UzGiZuKWXEGY/q/hMDKcviKFWZb2P6mIU4Q7aT9ph/kQWJG8We
GK1uqLdHqKKHRMAK+KHVVwkbwy60mMDunsl6y9Q9q9uh5Mrre7uc36uO2h1IJUNV
O+1ifGNKrd27sgTmw7RofKetM/k9x/22wU7UDnUhnBCkZOjLyYFCNF6rT0l9CvVC
1aud5NWOPIIEoYMw7QRPWijw6wNqQ1hslm7d+boz/p0b+qk/bq12sw1Nfi5wOGV7
dOZRnaoG2eCD+/RsrhbXymFbIpU+sLGuoFH4lTcfChhXvq2YgedzhrYNC6Sy1sq9
rHSwJ5eBGMqE59+Sda/JkPiMw06VtPYqiGmqLPlFxnziX0o9Gw+v4dNZvuU3DZ+y
5wYKnjW5pFMnWeBlDXkVUPOIM+/paw==
-----END CERTIFICATE-----`),
"backup@mail.i2p": []byte(`-----BEGIN CERTIFICATE-----
MIIFfTCCA2WgAwIBAgIEOprmhjANBgkqhkiG9w0BAQ0FADBvMQswCQYDVQQGEwJY
WDELMAkGA1UECBMCWFgxCzAJBgNVBAcTAlhYMR4wHAYDVQQKExVJMlAgQW5vbnlt
b3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEYMBYGA1UEAwwPYmFja3VwQG1haWwu
aTJwMB4XDTEzMTAxMzEzNDQ1NVoXDTIzMTAxMzEzNDQ1NVowbzELMAkGA1UEBhMC
WFgxCzAJBgNVBAgTAlhYMQswCQYDVQQHEwJYWDEeMBwGA1UEChMVSTJQIEFub255
bW91cyBOZXR3b3JrMQwwCgYDVQQLEwNJMlAxGDAWBgNVBAMMD2JhY2t1cEBtYWls
LmkycDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAIoAkobXwk/Enf1d
roHyqCyvcJfZJVTwb/LgYWAvCBMCr+RGqlSgtk3g69Y3I0xU08fD2kGt3r5Pwsbr
omXIbJAcccyLqmQ5QX6QgL+X9VpMDp9C4h2RogCrqLBAWw4cuZ4RS9VCpP1Yis7H
uejYqENP86p7BsRnuW/4cYnfunAdMpss4LpRGQXt1nTX+kfgCYgnKFbFqwAHt7yV
Ds+Pe6FuBHPlp+sc1amKRcUnSvhXLsv43VicnT7xYL/kUsN83wrtHA3B4aGDx3aA
3/EzuRmIXQB0BlTZILMEyYwG/nc4OsW82QYrvEZ9BIg9A4lF/wS/KZCICPxLF2zo
dGjnmlgkiA4s8eO+va/ElHyELjckVXqmG1eXHhSkEsDvOQJy01IUuwLinvq7cUbJ
HfJBZJllEg+sLDCv3FkEqN+XjBNFfQN4oNew4w6IPY6YH1INVB9LL0Cmdu4DudLv
TY8OcI8eSfez3hmm+pYQ23PJRYYnvRDnRECyIWBegkckWRh8U/WvZUYUvETK6EDl
/0KpTtfzX6MqHA5D6bTAB8Y3ijGMLrZ/B5vj5yCoZbLiGme9X2moR2k1LEhdhtzV
exsqezCpg6dn48FTX7mHjvR5/r4kz2jqBGmdPUWIIxnjFUzDUK3llVQiHihleHpe
jL4LqnhBGKWFRTaVwaIkBG4zAfIzAgMBAAGjITAfMB0GA1UdDgQWBBQNkfW7bSMl
1/4KDbgwrkf9x1Zu/TANBgkqhkiG9w0BAQ0FAAOCAgEAGg3a3rTf0EznQocmio0T
5gCoL0n8h6yKW/PyPAIELrd9wiYjhJFcWvMTcJJJnVqmAL5vpvhaAFVtAfx70MGa
0DZ7FvytK5hEfF4IqOFDyEEVGJR5rIpVK4MeI1nmwEsxdbW+FhODjtRzgYO8XBME
Xj4aY1FWg9vxc3reUj6PSFsZtsB0aLiRgL9JDovJIiRw0Uqr1v2wXBte5yVCxDge
vTREZtpK4cKetoOa68pwSXI32JwKE18j6bfdKVBCcYQKlKP/3gHGduaDrQv3w32S
DRym5s6MREeTUOtAw4wq46KpdOX8yyAqJPrCfMwS6ORd3t+egqOw0PUnsqb97w4O
lUtrRYvb2cOj60SmRx4vJvItyuHbKqIK7o2e1RcUZPXYoAVx2ww4XB2Wk4D7LSAs
cS7nLj8yAqzJ2qqtBzxu+zILJtkVa12dKF0xmS0BxBp4sCYiBtmAVE8AWQqEuSHA
FrMWqoXcjcfdvvyX487FFWWUE7ZBIn0hee2sK9J9+SPtqczJaN7TF3K3nzo65WJG
1epltmq2Ugjb67Gz7v4y7H23DJ/qhm8yLtCHTj69HTta5I08j6Kut924WLZaiMO/
4YoEL5AE63X0sxYibKFQiq7FW5nUJA280GRlY3xSMFzlB2ggazrUV3YAWVDhfdnI
flpzWXkFM2D36OUaubfe9YY=
-----END CERTIFICATE-----`),
"echelon@mail.i2p": []byte(`-----BEGIN CERTIFICATE-----
MIIFfzCCA2egAwIBAgIESg3kkzANBgkqhkiG9w0BAQ0FADBwMQswCQYDVQQGEwJY
WDELMAkGA1UECBMCWFgxCzAJBgNVBAcTAlhYMR4wHAYDVQQKExVJMlAgQW5vbnlt
b3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEZMBcGA1UEAwwQZWNoZWxvbkBtYWls
LmkycDAeFw0xNDA3MzExNjQ3MDJaFw0yNDA3MzAxNjQ3MDJaMHAxCzAJBgNVBAYT
AlhYMQswCQYDVQQIEwJYWDELMAkGA1UEBxMCWFgxHjAcBgNVBAoTFUkyUCBBbm9u
eW1vdXMgTmV0d29yazEMMAoGA1UECxMDSTJQMRkwFwYDVQQDDBBlY2hlbG9uQG1h
aWwuaTJwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAmcEgLwwhzLNe
XLOMSrhwB8hWpOhfjo4s6S/wjBtjjUc8nI3D0hSn3HY26p0rvcvNEWexPUpPULmC
exGkU463nu7PiFONiORI1eJAiUFHibRiaA7Wboyo38pO73KirwjG07Y+Ua0jp+HS
+4FQ/I/9H/bPplReTOU/6hmRbgQ69U8nE68HzZHQxP68yVJ2rPHSXMPhF4R1h0G1
1mCAT+TgTsnwHNGF77XHJnY4/M4e2cgycEZjZow36C3t2mNDVkMgF19QQeb9WmLR
zREn3nq9BJqHpUkn9yWw0kKXTZSds+7UxESfzf3BzK0+hky2fh5H+qbYAo2lz4yj
81MXTAu+4RRkg4DBLlF+2dkclhwQLxxzvkRC6tPkn5i33Yltg7EfzA9IoQ05potJ
I+iOcF+aStfFgFj9u3B5UkcF4P0cH1QD3c6BK4hIezQYqRoPly1gHqg+XdwjG/dr
4as7HA9FTz3p2E8nClpIC1x3hfgwAdfd29aeBxO1WW/z99iMF7TBAF+u5T86XEW1
WpknqCbTli36yJ8a5fPWxZHrryBRJT5yLxejjFeadtutBSwljiVFq+Y38VqwFivq
VLiBt7IxAsZ8iilgfnnnAvBH6chWfSKb4H7kB4TJvDiV96QmmvoEaWYNHZozMhyK
tO3b5w+xqbJXyCLA3Q75jD0km76hjcECAwEAAaMhMB8wHQYDVR0OBBYEFAHQcAam
QRS/EUhuCSr9pB4Ux0rYMA0GCSqGSIb3DQEBDQUAA4ICAQBq1+1QLmgLAjrTg3tb
4XKgAVICQRoBDNUEobQg3pYeUX9eFNya2RxNljuvYpwT80ilGMPOXcjddmr5ngiK
dbGRcuuJk9MPEHtPaPT3+JJlvKQ3B3g2wva2Wz2OAyLZUGQs389K4nTbwh4QF0n2
aHFL8BHiD62hiKnCoNaW4ZovUNNvOxo9lMyAiaFU2gqQNcdad8hP9EAllbvbxDx9
Tjww2UbwQUIHS9rna4Tlu+f0hDXTWIutc2A51W2fJCb7L3+lYO7Wv55ND/WtryLZ
XpMp27+MpuEnN3kQmz/l9R0hIJsWc/x9GQkjm5wEaIZEyTtenqwRKGmVCtAj0Pgv
jn1L3/lWmrNq+OZHb/QeyfKtA3nXfQKVmT98ewQiK/S5i1xIAXCJPytOD887b/o1
cdurTmCiZMwgiQ+HLJqCg3MDa5mvKqRkRdZXfE6aQWEcSbpAhpV15R17q7L+Fg0W
shLSNucxyGNU8PjiC/nOmqfqUiPiMltJjPmscxBLim8foyxjakC4+6N6m+Jzgznj
PocBehFAfKYj66XEwzIBN7Z2uuXoYH9YptkocFjTzvchcryVulDWZ4FWxreUMhpM
4oyjjhSB4tB9clXlwMqg577q3D6Ms0zLTqsztyPN3zr6jGev3jpVq7Q1GOlciHPv
JNJOWTH/Vas1W6XlwGcOOAARTQ==
-----END CERTIFICATE-----`),
"meeh@mail.i2p": []byte(`-----BEGIN CERTIFICATE-----
MIIFeTCCA2GgAwIBAgIEZZozujANBgkqhkiG9w0BAQ0FADBtMQswCQYDVQQGEwJY
WDELMAkGA1UECBMCWFgxCzAJBgNVBAcTAlhYMR4wHAYDVQQKExVJMlAgQW5vbnlt
b3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEWMBQGA1UEAwwNbWVlaEBtYWlsLmky
cDAeFw0xNDA2MjgyMjQ5MDlaFw0yNDA2MjcyMjQ5MDlaMG0xCzAJBgNVBAYTAlhY
MQswCQYDVQQIEwJYWDELMAkGA1UEBxMCWFgxHjAcBgNVBAoTFUkyUCBBbm9ueW1v
dXMgTmV0d29yazEMMAoGA1UECxMDSTJQMRYwFAYDVQQDDA1tZWVoQG1haWwuaTJw
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnVnmPE4uUvCky0yCnnVH
cJEDqzwDPupx0zr0YDlhZk5VOPPecx5haayJ/V6nXPc1aVVWn+CHfedcF2aBgN4K
5aBueS/l6l5WHcv02DofAqlTmyAws3oQeR1qoTuW24cKRtLR7h5bxv63f6bgp6e+
RihFNez6UxErnRPuJOJEO2Im6EgVp6fz7tQ7R35zxAUeES2YILPySvzy2vYm/EEG
jXX7Ap2A5svVo90xCMOeUZ/55vLsjyIshN+tV87U4xwvAkUmwsmWVHm3BQpHkI6z
zMJie6epB8Bqm0GYm0EcElJH4OCxGTvDLoghpswbuUO7iy3JSfoL7ZCnoiQdK9K4
yVVChj8lG+r7KaTowK96iZep+sZefjOt5VFGuW2Fi/WBv3ldiLlJAo/ZfrUM4+vG
fyNBXbl6bX87uTCGOT1p3dazo+zJMsAZ+Y93DlM/mDEWFa1kKNrs74syzaWEqF4L
KQE6VoYn80OOzafSigTVQgSwUtQtB0XGhMzJhyxU2XHWe1LFIy7Pta0B+lDiZj7c
I8nXxYjsDfEu/Elj/Ra9N6bH0awmgB5JDa+Tbir+oEM5SyDfpSaCGuatdGxjweGI
kVmFU0SqCZV/8TXbIu6MUVzTZMZVT94edifFSRad4fqw7eZbSXlPu++3d1/btn6h
ibM04nkv0mm+FxCKB/wdAkECAwEAAaMhMB8wHQYDVR0OBBYEFO7jIkSRkoXyJcho
9/Q0gDOINa5EMA0GCSqGSIb3DQEBDQUAA4ICAQBzfWO7+8HWOKLaYWToJ6XZbpNF
3wXv1yC4W/HRR80m4JSsq9r0d7838Nvd7vLVP6MY6MaVb/JnV76FdQ5WQ6ticD0Y
o3zmpqqbKVSspN0lrkig4surT88AjfVQz/vEIzKNQEbpzc3hC2LCiE2u+cK/ix4j
b9RohnaPvwLnew5RNQRpcmk+XejaNITISr2yQIwXL7TEYy8HdGCfzFSSFhKe9vkb
GsWS5ASrUzRoprswmlgRe8gEHI+d51Z7mWgna0/5mBz9bH/3QXtpxlLWm3bVV+kt
pZjQDTHE0GqG2YsD1Gmp4LU/JFhCojMTtiPCXmr9KFtpiVlx06DuKm5PC8Ak+5w+
m/DQYYfv9z+AA5Y430bjnzwg67bhqVyyek4wcDQinFswv3h4bIB7CJujDcEqXXza
lhG1ufPPCUTMrVjh7AShohZraqlSlyQPY9vEppLwD4W1d+MqDHM7ljOH7gQYaUPi
wE30AdXEOxLZcT3aRKxkKf2esNofSuUC/+NXQvPjpuI4UJKO3eegi+M9dbnKoNWs
MPPLPpycecWPheFYM5K6Ao63cjlUY2wYwCfDTFgjA5q8i/Rp7i6Z6fLE3YWJ4VdR
WOFB7hlluQ//jMW6M1qz6IYXmlUjcXl81VEvlOH/QBNrPvX3I3SYXYgVRnVGUudB
o3eNsanvTU+TIFBh2Q==
-----END CERTIFICATE-----`),
}
)
func signerFilename(signer string) string {
return strings.Replace(signer, "@", "_at_", 2) + ".crt"
}

View File

@@ -15,7 +15,6 @@ import (
)
const (
MAGIC_BYTES = "I2Psu3"
MIN_VERSION_LENGTH = 16
SIGTYPE_DSA = uint16(0)
@@ -26,11 +25,11 @@ const (
SIGTYPE_RSA_SHA384 = uint16(5)
SIGTYPE_RSA_SHA512 = uint16(6)
CONTENT_TYPE_UNKNOWN = uint16(0)
CONTENT_TYPE_ROUTER = uint16(1)
CONTENT_TYPE_PLUGIN = uint16(2)
CONTENT_TYPE_RESEED = uint16(3)
CONTENT_TYPE_NEWS = uint16(4)
CONTENT_TYPE_UNKNOWN = uint8(0)
CONTENT_TYPE_ROUTER = uint8(1)
CONTENT_TYPE_PLUGIN = uint8(2)
CONTENT_TYPE_RESEED = uint8(3)
CONTENT_TYPE_NEWS = uint8(4)
FILE_TYPE_ZIP = uint8(0)
FILE_TYPE_XML = uint8(1)
@@ -38,16 +37,15 @@ const (
FILE_TYPE_XMLGZ = uint8(3)
)
var (
MAGIC_BYTES = []byte("I2Psu3")
)
type Su3File struct {
Magic [6]byte
Format uint8
SignatureType uint16
SignatureLength uint16
VersionLength uint8
SignerIdLength uint8
ContentLength uint64
FileType uint8
ContentType uint16
Format uint8
SignatureType uint16
FileType uint8
ContentType uint8
Version []byte
SignerId []byte
@@ -57,47 +55,24 @@ type Su3File struct {
}
func NewSu3File() *Su3File {
var a [6]byte
copy(a[:], MAGIC_BYTES)
s := Su3File{Magic: a}
s.SetVersion(strconv.FormatInt(time.Now().Unix(), 10))
s := Su3File{
Version: []byte(strconv.FormatInt(time.Now().Unix(), 10)),
SignatureType: SIGTYPE_RSA_SHA512,
}
return &s
}
func (s *Su3File) SetSignerId(signer string) {
s.SignerId = []byte(signer)
s.SignerIdLength = uint8(len(s.SignerId))
}
func (s *Su3File) SetContent(content []byte) {
s.Content = content
s.ContentLength = uint64(len(s.Content))
}
func (s *Su3File) SetVersion(version string) {
s.Version = []byte(version)
minBytes := make([]byte, MIN_VERSION_LENGTH)
if len(s.Version) < len(minBytes) {
copy(minBytes, s.Version)
s.Version = minBytes
}
s.VersionLength = uint8(len(s.Version))
}
func (s *Su3File) Sign(privkey *rsa.PrivateKey, sigType uint16) error {
func (s *Su3File) Sign(privkey *rsa.PrivateKey) error {
var hashType crypto.Hash
switch sigType {
// case SIGTYPE_DSA:
// case SIGTYPE_ECDSA_SHA256:
// case SIGTYPE_ECDSA_SHA384:
// case SIGTYPE_ECDSA_SHA512:
// case SIGTYPE_RSA_SHA256:
// case SIGTYPE_RSA_SHA384:
case SIGTYPE_RSA_SHA512:
s.SignatureType = SIGTYPE_RSA_SHA512
s.SignatureLength = uint16(512)
switch s.SignatureType {
case SIGTYPE_DSA:
hashType = crypto.SHA1
case SIGTYPE_ECDSA_SHA256, SIGTYPE_RSA_SHA256:
hashType = crypto.SHA256
case SIGTYPE_ECDSA_SHA384, SIGTYPE_RSA_SHA384:
hashType = crypto.SHA384
case SIGTYPE_ECDSA_SHA512, SIGTYPE_RSA_SHA512:
hashType = crypto.SHA512
default:
return fmt.Errorf("Unknown signature type")
@@ -123,10 +98,34 @@ func (s *Su3File) ContentBytes() []byte {
var (
skip [1]byte
bigSkip [12]byte
versionLength = uint8(len(s.Version))
signatureLength = uint16(40)
signerIdLength = uint8(len(s.SignerId))
contentLength = uint64(len(s.Content))
)
switch s.SignatureType {
case SIGTYPE_DSA:
signatureLength = uint16(40)
case SIGTYPE_ECDSA_SHA256, SIGTYPE_RSA_SHA256:
signatureLength = uint16(256)
case SIGTYPE_ECDSA_SHA384, SIGTYPE_RSA_SHA384:
signatureLength = uint16(384)
case SIGTYPE_ECDSA_SHA512, SIGTYPE_RSA_SHA512:
signatureLength = uint16(512)
}
// pad the version field
if len(s.Version) < MIN_VERSION_LENGTH {
minBytes := make([]byte, MIN_VERSION_LENGTH)
copy(minBytes, s.Version)
s.Version = minBytes
versionLength = uint8(len(s.Version))
}
// 0-5
binary.Write(buf, binary.BigEndian, s.Magic)
binary.Write(buf, binary.BigEndian, MAGIC_BYTES)
// 6
binary.Write(buf, binary.BigEndian, skip)
// 7
@@ -134,17 +133,17 @@ func (s *Su3File) ContentBytes() []byte {
// 8-9
binary.Write(buf, binary.BigEndian, s.SignatureType)
// 10-11
binary.Write(buf, binary.BigEndian, s.SignatureLength)
binary.Write(buf, binary.BigEndian, signatureLength)
// 12
binary.Write(buf, binary.BigEndian, skip)
// 13
binary.Write(buf, binary.BigEndian, s.VersionLength)
binary.Write(buf, binary.BigEndian, versionLength)
// 14
binary.Write(buf, binary.BigEndian, skip)
// 15
binary.Write(buf, binary.BigEndian, s.SignerIdLength)
binary.Write(buf, binary.BigEndian, signerIdLength)
// 16-23
binary.Write(buf, binary.BigEndian, s.ContentLength)
binary.Write(buf, binary.BigEndian, contentLength)
// 24
binary.Write(buf, binary.BigEndian, skip)
// 25
@@ -176,7 +175,31 @@ func (s *Su3File) Bytes() []byte {
}
func (s *Su3File) VerifySignature() error {
return verifySig(s.SignatureType, s.SignerId, s.Signature, s.SignedBytes)
var sigAlg x509.SignatureAlgorithm
switch s.SignatureType {
case SIGTYPE_DSA:
sigAlg = x509.DSAWithSHA1
case SIGTYPE_ECDSA_SHA256:
sigAlg = x509.ECDSAWithSHA256
case SIGTYPE_ECDSA_SHA384:
sigAlg = x509.ECDSAWithSHA384
case SIGTYPE_ECDSA_SHA512:
sigAlg = x509.ECDSAWithSHA512
case SIGTYPE_RSA_SHA256:
sigAlg = x509.SHA256WithRSA
case SIGTYPE_RSA_SHA384:
sigAlg = x509.SHA384WithRSA
case SIGTYPE_RSA_SHA512:
sigAlg = x509.SHA512WithRSA
default:
return fmt.Errorf("Unsupported signature type.")
}
if cert, err := signerCertificate(string(s.SignerId)); nil != err {
return err
} else {
return checkSignature(cert, sigAlg, s.ContentBytes(), s.Signature)
}
}
func (s *Su3File) String() string {
@@ -184,27 +207,19 @@ func (s *Su3File) String() string {
// header
fmt.Fprintln(&b, "---------------------------")
fmt.Fprintf(&b, "Magic: %s\n", s.Magic)
fmt.Fprintf(&b, "Format: %q\n", s.Format)
fmt.Fprintf(&b, "SignatureType: %q\n", s.SignatureType)
fmt.Fprintf(&b, "SignatureLength: %s\n", s.SignatureLength)
fmt.Fprintf(&b, "VersionLength: %s\n", s.VersionLength)
fmt.Fprintf(&b, "SignerIdLength: %s\n", s.SignerIdLength)
fmt.Fprintf(&b, "ContentLength: %s\n", s.ContentLength)
fmt.Fprintf(&b, "FileType: %q\n", s.FileType)
fmt.Fprintf(&b, "ContentType: %q\n", s.ContentType)
// content
fmt.Fprintln(&b, "---------------------------")
fmt.Fprintf(&b, "Version: %q\n", bytes.Trim(s.Version, "\x00"))
fmt.Fprintf(&b, "SignerId: %q\n", s.SignerId)
// fmt.Fprintf(&b, "Content: %q\n", s.Content)
fmt.Fprintf(&b, "Signature: %q\n", s.Signature)
fmt.Fprintln(&b, "---------------------------")
// content & signature
// fmt.Fprintf(&b, "Content: %q\n", s.Content)
// fmt.Fprintf(&b, "Signature: %q\n", s.Signature)
// fmt.Fprintln(&b, "---------------------------")
return b.String()
}
@@ -228,92 +243,64 @@ func uzipData(c []byte) ([]byte, error) {
return uncompressed, nil
}
func verifySig(sigType uint16, signer, signature, signed []byte) (err error) {
var cert *x509.Certificate
if cert, err = certForSigner(string(signer)); nil != err {
return err
}
var sigAlg x509.SignatureAlgorithm
switch sigType {
case SIGTYPE_DSA:
sigAlg = x509.DSAWithSHA1
case SIGTYPE_ECDSA_SHA256:
sigAlg = x509.ECDSAWithSHA256
case SIGTYPE_ECDSA_SHA384:
sigAlg = x509.ECDSAWithSHA384
case SIGTYPE_ECDSA_SHA512:
sigAlg = x509.ECDSAWithSHA512
case SIGTYPE_RSA_SHA256:
sigAlg = x509.SHA256WithRSA
case SIGTYPE_RSA_SHA384:
sigAlg = x509.SHA384WithRSA
case SIGTYPE_RSA_SHA512:
sigAlg = x509.SHA512WithRSA
default:
return fmt.Errorf("Unsupported signature type.")
}
return checkSignature(cert, sigAlg, signed, signature)
}
func ReadSu3(file *os.File, su3File *Su3File) error {
func ReadSu3(file *os.File) (*Su3File, error) {
var (
skip [1]byte
s = Su3File{}
skip uint8
bigSkip [12]byte
signatureLength uint16
versionLength uint8
signerIdLength uint8
contentLength uint64
magic [6]byte
)
// 0-5
binary.Read(file, binary.BigEndian, &su3File.Magic)
binary.Read(file, binary.BigEndian, &magic)
// 6
binary.Read(file, binary.BigEndian, &skip)
// 7
binary.Read(file, binary.BigEndian, &su3File.Format)
binary.Read(file, binary.BigEndian, &s.Format)
// 8-9
binary.Read(file, binary.BigEndian, &su3File.SignatureType)
binary.Read(file, binary.BigEndian, &s.SignatureType)
// 10-11
binary.Read(file, binary.BigEndian, &su3File.SignatureLength)
binary.Read(file, binary.BigEndian, &signatureLength)
// 12
binary.Read(file, binary.BigEndian, &skip)
// 13
binary.Read(file, binary.BigEndian, &su3File.VersionLength)
binary.Read(file, binary.BigEndian, &versionLength)
// 14
binary.Read(file, binary.BigEndian, &skip)
// 15
binary.Read(file, binary.BigEndian, &su3File.SignerIdLength)
binary.Read(file, binary.BigEndian, &signerIdLength)
// 16-23
binary.Read(file, binary.BigEndian, &su3File.ContentLength)
binary.Read(file, binary.BigEndian, &contentLength)
// 24
binary.Read(file, binary.BigEndian, &skip)
// 25
binary.Read(file, binary.BigEndian, &su3File.FileType)
binary.Read(file, binary.BigEndian, &s.FileType)
// 26
binary.Read(file, binary.BigEndian, &skip)
// 27
binary.Read(file, binary.BigEndian, &su3File.ContentType)
binary.Read(file, binary.BigEndian, &s.ContentType)
// 28-39
binary.Read(file, binary.BigEndian, &bigSkip)
su3File.Version = make([]byte, su3File.VersionLength)
su3File.SignerId = make([]byte, su3File.SignerIdLength)
su3File.Content = make([]byte, su3File.ContentLength)
su3File.Signature = make([]byte, su3File.SignatureLength)
s.Version = make([]byte, versionLength)
s.SignerId = make([]byte, signerIdLength)
s.Content = make([]byte, contentLength)
s.Signature = make([]byte, signatureLength)
// 40-55+ Version, UTF-8 padded with trailing 0x00, 16 bytes minimum, length specified at byte 13. Do not append 0x00 bytes if the length is 16 or more.
binary.Read(file, binary.BigEndian, su3File.Version)
binary.Read(file, binary.BigEndian, &s.Version)
// xx+ ID of signer, (e.g. "zzz@mail.i2p") UTF-8, not padded, length specified at byte 15
binary.Read(file, binary.BigEndian, su3File.SignerId)
binary.Read(file, binary.BigEndian, &s.SignerId)
// xx+ Content, length and format specified in header
binary.Read(file, binary.BigEndian, su3File.Content)
// re-read from the beginning to get the signed content
signedEnd, _ := file.Seek(0, 1)
file.Seek(0, 0)
su3File.SignedBytes = make([]byte, signedEnd)
binary.Read(file, binary.BigEndian, su3File.SignedBytes)
binary.Read(file, binary.BigEndian, &s.Content)
// xx+ Signature, length specified in header, covers everything starting at byte 0
binary.Read(file, binary.BigEndian, su3File.Signature)
binary.Read(file, binary.BigEndian, &s.Signature)
return nil
return &s, nil
}