very rough su3 creation and signing

This commit is contained in:
Matt Drollette
2014-12-10 01:10:37 -06:00
parent 2d445337c8
commit a2891a2bc6
11 changed files with 511 additions and 19 deletions

View File

@@ -19,6 +19,38 @@ func certForSigner(signer string) (*x509.Certificate, error) {
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

View File

@@ -3,14 +3,20 @@ package su3
import (
"archive/zip"
"bytes"
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/binary"
"fmt"
"os"
"strconv"
"time"
)
const (
MAGIC_BYTES = "I2Psu3"
MAGIC_BYTES = "I2Psu3"
MIN_VERSION_LENGTH = 16
SIGTYPE_DSA = uint16(0)
SIGTYPE_ECDSA_SHA256 = uint16(1)
@@ -34,14 +40,14 @@ const (
type Su3File struct {
Magic [6]byte
Format [1]byte
Format uint8
SignatureType uint16
SignatureLength uint16
VersionLength uint8
SignerIdLength uint8
ContentLength uint64
FileType [1]byte
ContentType [1]byte
FileType uint8
ContentType uint16
Version []byte
SignerId []byte
@@ -50,6 +56,129 @@ type Su3File struct {
SignedBytes []byte
}
func NewSu3File() *Su3File {
var a [6]byte
copy(a[:], MAGIC_BYTES)
s := Su3File{Magic: a}
s.SetVersion(strconv.FormatInt(time.Now().Unix(), 10))
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 {
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)
hashType = crypto.SHA512
default:
return fmt.Errorf("Unknown signature type")
}
h := hashType.New()
h.Write(s.ContentBytes())
digest := h.Sum(nil)
sig, err := rsa.SignPKCS1v15(rand.Reader, privkey, 0, digest)
if nil != err {
return err
}
s.Signature = sig
return nil
}
func (s *Su3File) ContentBytes() []byte {
buf := new(bytes.Buffer)
var (
skip [1]byte
bigSkip [12]byte
)
// 0-5
binary.Write(buf, binary.BigEndian, s.Magic)
// 6
binary.Write(buf, binary.BigEndian, skip)
// 7
binary.Write(buf, binary.BigEndian, s.Format)
// 8-9
binary.Write(buf, binary.BigEndian, s.SignatureType)
// 10-11
binary.Write(buf, binary.BigEndian, s.SignatureLength)
// 12
binary.Write(buf, binary.BigEndian, skip)
// 13
binary.Write(buf, binary.BigEndian, s.VersionLength)
// 14
binary.Write(buf, binary.BigEndian, skip)
// 15
binary.Write(buf, binary.BigEndian, s.SignerIdLength)
// 16-23
binary.Write(buf, binary.BigEndian, s.ContentLength)
// 24
binary.Write(buf, binary.BigEndian, skip)
// 25
binary.Write(buf, binary.BigEndian, s.FileType)
// 26
binary.Write(buf, binary.BigEndian, skip)
// 27
binary.Write(buf, binary.BigEndian, s.ContentType)
// 28-39
binary.Write(buf, binary.BigEndian, bigSkip)
// 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.Write(buf, binary.BigEndian, s.Version)
// xx+ ID of signer, (e.g. "zzz@mail.i2p") UTF-8, not padded, length specified at byte 15
binary.Write(buf, binary.BigEndian, s.SignerId)
// xx+ Content, length and format specified in header
binary.Write(buf, binary.BigEndian, s.Content)
return buf.Bytes()
}
func (s *Su3File) Bytes() []byte {
buf := new(bytes.Buffer)
buf.Write(s.ContentBytes())
// xx+ Signature, length specified in header, covers everything starting at byte 0
binary.Write(buf, binary.BigEndian, s.Signature)
return buf.Bytes()
}
func (s *Su3File) VerifySignature() error {
return verifySig(s.SignatureType, s.SignerId, s.Signature, s.SignedBytes)
}
func (s *Su3File) String() string {
var b bytes.Buffer
@@ -72,17 +201,13 @@ func (s *Su3File) String() string {
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.Fprintf(&b, "Signature: %q\n", s.Signature)
fmt.Fprintln(&b, "---------------------------")
return b.String()
}
func (s *Su3File) VerifySignature() error {
return verifySig(s.SignatureType, s.SignerId, s.Signature, s.SignedBytes)
}
func uzipData(c []byte) ([]byte, error) {
input := bytes.NewReader(c)
zipReader, err := zip.NewReader(input, int64(len(c)))