very rough su3 creation and signing
This commit is contained in:
@@ -19,6 +19,38 @@ func certForSigner(signer string) (*x509.Certificate, error) {
|
||||
|
||||
var (
|
||||
reseedKeys = map[string][]byte{
|
||||
"matt@drollette.com": []byte(`-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
5wYKnjW5pFMnWeBlDXkVUPOIM+/paw==
|
||||
-----END CERTIFICATE-----`),
|
||||
"backup@mail.i2p": []byte(`-----BEGIN CERTIFICATE-----
|
||||
MIIFfTCCA2WgAwIBAgIEOprmhjANBgkqhkiG9w0BAQ0FADBvMQswCQYDVQQGEwJY
|
||||
WDELMAkGA1UECBMCWFgxCzAJBgNVBAcTAlhYMR4wHAYDVQQKExVJMlAgQW5vbnlt
|
||||
|
143
su3/su3.go
143
su3/su3.go
@@ -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)))
|
||||
|
Reference in New Issue
Block a user