Commit 5133f00e by Ian Lance Taylor

Update to current version of Go library (revision 94d654be2064).

From-SVN: r171076
parent f617201f
...@@ -1078,7 +1078,7 @@ Type::make_type_descriptor_type() ...@@ -1078,7 +1078,7 @@ Type::make_type_descriptor_type()
bloc); bloc);
Struct_type* type_descriptor_type = Struct_type* type_descriptor_type =
Type::make_builtin_struct_type(9, Type::make_builtin_struct_type(10,
"Kind", uint8_type, "Kind", uint8_type,
"align", uint8_type, "align", uint8_type,
"fieldAlign", uint8_type, "fieldAlign", uint8_type,
...@@ -1087,7 +1087,9 @@ Type::make_type_descriptor_type() ...@@ -1087,7 +1087,9 @@ Type::make_type_descriptor_type()
"hashfn", hashfn_type, "hashfn", hashfn_type,
"equalfn", equalfn_type, "equalfn", equalfn_type,
"string", pointer_string_type, "string", pointer_string_type,
"", pointer_uncommon_type); "", pointer_uncommon_type,
"ptrToThis",
pointer_type_descriptor_type);
Named_type* named = Type::make_builtin_named_type("commonType", Named_type* named = Type::make_builtin_named_type("commonType",
type_descriptor_type); type_descriptor_type);
...@@ -1260,6 +1262,16 @@ Type::type_descriptor_constructor(Gogo* gogo, int runtime_type_kind, ...@@ -1260,6 +1262,16 @@ Type::type_descriptor_constructor(Gogo* gogo, int runtime_type_kind,
} }
++p; ++p;
gcc_assert(p->field_name() == "ptrToThis");
if (name == NULL)
vals->push_back(Expression::make_nil(bloc));
else
{
Type* pt = Type::make_pointer_type(name);
vals->push_back(Expression::make_type_descriptor(pt, bloc));
}
++p;
gcc_assert(p == fields->end()); gcc_assert(p == fields->end());
mpz_clear(iv); mpz_clear(iv);
......
559f12e8fcd5 94d654be2064
The first line of this file holds the Mercurial revision number of the The first line of this file holds the Mercurial revision number of the
last merge done from the master library sources. last merge done from the master library sources.
...@@ -42,6 +42,10 @@ type File struct { ...@@ -42,6 +42,10 @@ type File struct {
bodyOffset int64 bodyOffset int64
} }
func (f *File) hasDataDescriptor() bool {
return f.Flags&0x8 != 0
}
// OpenReader will open the Zip file specified by name and return a Reader. // OpenReader will open the Zip file specified by name and return a Reader.
func OpenReader(name string) (*Reader, os.Error) { func OpenReader(name string) (*Reader, os.Error) {
f, err := os.Open(name, os.O_RDONLY, 0644) f, err := os.Open(name, os.O_RDONLY, 0644)
...@@ -93,7 +97,16 @@ func (f *File) Open() (rc io.ReadCloser, err os.Error) { ...@@ -93,7 +97,16 @@ func (f *File) Open() (rc io.ReadCloser, err os.Error) {
return return
} }
} }
r := io.NewSectionReader(f.zipr, off+f.bodyOffset, int64(f.CompressedSize)) size := int64(f.CompressedSize)
if f.hasDataDescriptor() {
if size == 0 {
// permit SectionReader to see the rest of the file
size = f.zipsize - (off + f.bodyOffset)
} else {
size += dataDescriptorLen
}
}
r := io.NewSectionReader(f.zipr, off+f.bodyOffset, size)
switch f.Method { switch f.Method {
case 0: // store (no compression) case 0: // store (no compression)
rc = nopCloser{r} rc = nopCloser{r}
...@@ -103,7 +116,7 @@ func (f *File) Open() (rc io.ReadCloser, err os.Error) { ...@@ -103,7 +116,7 @@ func (f *File) Open() (rc io.ReadCloser, err os.Error) {
err = UnsupportedMethod err = UnsupportedMethod
} }
if rc != nil { if rc != nil {
rc = &checksumReader{rc, crc32.NewIEEE(), f.CRC32} rc = &checksumReader{rc, crc32.NewIEEE(), f, r}
} }
return return
} }
...@@ -111,7 +124,8 @@ func (f *File) Open() (rc io.ReadCloser, err os.Error) { ...@@ -111,7 +124,8 @@ func (f *File) Open() (rc io.ReadCloser, err os.Error) {
type checksumReader struct { type checksumReader struct {
rc io.ReadCloser rc io.ReadCloser
hash hash.Hash32 hash hash.Hash32
sum uint32 f *File
zipr io.Reader // for reading the data descriptor
} }
func (r *checksumReader) Read(b []byte) (n int, err os.Error) { func (r *checksumReader) Read(b []byte) (n int, err os.Error) {
...@@ -120,7 +134,12 @@ func (r *checksumReader) Read(b []byte) (n int, err os.Error) { ...@@ -120,7 +134,12 @@ func (r *checksumReader) Read(b []byte) (n int, err os.Error) {
if err != os.EOF { if err != os.EOF {
return return
} }
if r.hash.Sum32() != r.sum { if r.f.hasDataDescriptor() {
if err = readDataDescriptor(r.zipr, r.f); err != nil {
return
}
}
if r.hash.Sum32() != r.f.CRC32 {
err = ChecksumError err = ChecksumError
} }
return return
...@@ -205,6 +224,18 @@ func readDirectoryHeader(f *File, r io.Reader) (err os.Error) { ...@@ -205,6 +224,18 @@ func readDirectoryHeader(f *File, r io.Reader) (err os.Error) {
return return
} }
func readDataDescriptor(r io.Reader, f *File) (err os.Error) {
defer func() {
if rerr, ok := recover().(os.Error); ok {
err = rerr
}
}()
read(r, &f.CRC32)
read(r, &f.CompressedSize)
read(r, &f.UncompressedSize)
return
}
func readDirectoryEnd(r io.ReaderAt, size int64) (d *directoryEnd, err os.Error) { func readDirectoryEnd(r io.ReaderAt, size int64) (d *directoryEnd, err os.Error) {
// look for directoryEndSignature in the last 1k, then in the last 65k // look for directoryEndSignature in the last 1k, then in the last 65k
var b []byte var b []byte
......
...@@ -52,6 +52,15 @@ var tests = []ZipTest{ ...@@ -52,6 +52,15 @@ var tests = []ZipTest{
}, },
{Name: "readme.zip"}, {Name: "readme.zip"},
{Name: "readme.notzip", Error: FormatError}, {Name: "readme.notzip", Error: FormatError},
{
Name: "dd.zip",
File: []ZipTestFile{
{
Name: "filename",
Content: []byte("This is a test textfile.\n"),
},
},
},
} }
func TestReader(t *testing.T) { func TestReader(t *testing.T) {
...@@ -102,16 +111,18 @@ func readTestZip(t *testing.T, zt ZipTest) { ...@@ -102,16 +111,18 @@ func readTestZip(t *testing.T, zt ZipTest) {
} }
// test invalid checksum // test invalid checksum
z.File[0].CRC32++ // invalidate if !z.File[0].hasDataDescriptor() { // skip test when crc32 in dd
r, err := z.File[0].Open() z.File[0].CRC32++ // invalidate
if err != nil { r, err := z.File[0].Open()
t.Error(err) if err != nil {
return t.Error(err)
} return
var b bytes.Buffer }
_, err = io.Copy(&b, r) var b bytes.Buffer
if err != ChecksumError { _, err = io.Copy(&b, r)
t.Errorf("%s: copy error=%v, want %v", z.File[0].Name, err, ChecksumError) if err != ChecksumError {
t.Errorf("%s: copy error=%v, want %v", z.File[0].Name, err, ChecksumError)
}
} }
} }
......
...@@ -4,6 +4,7 @@ const ( ...@@ -4,6 +4,7 @@ const (
fileHeaderSignature = 0x04034b50 fileHeaderSignature = 0x04034b50
directoryHeaderSignature = 0x02014b50 directoryHeaderSignature = 0x02014b50
directoryEndSignature = 0x06054b50 directoryEndSignature = 0x06054b50
dataDescriptorLen = 12
) )
type FileHeader struct { type FileHeader struct {
......
...@@ -317,7 +317,7 @@ func marshalBody(out *forkableWriter, value reflect.Value, params fieldParameter ...@@ -317,7 +317,7 @@ func marshalBody(out *forkableWriter, value reflect.Value, params fieldParameter
switch v := value.(type) { switch v := value.(type) {
case *reflect.BoolValue: case *reflect.BoolValue:
if v.Get() { if v.Get() {
return out.WriteByte(1) return out.WriteByte(255)
} else { } else {
return out.WriteByte(0) return out.WriteByte(0)
} }
......
...@@ -286,7 +286,8 @@ func (b *Reader) ReadSlice(delim byte) (line []byte, err os.Error) { ...@@ -286,7 +286,8 @@ func (b *Reader) ReadSlice(delim byte) (line []byte, err os.Error) {
// returning a slice containing the data up to and including the delimiter. // returning a slice containing the data up to and including the delimiter.
// If ReadBytes encounters an error before finding a delimiter, // If ReadBytes encounters an error before finding a delimiter,
// it returns the data read before the error and the error itself (often os.EOF). // it returns the data read before the error and the error itself (often os.EOF).
// ReadBytes returns err != nil if and only if line does not end in delim. // ReadBytes returns err != nil if and only if the returned data does not end in
// delim.
func (b *Reader) ReadBytes(delim byte) (line []byte, err os.Error) { func (b *Reader) ReadBytes(delim byte) (line []byte, err os.Error) {
// Use ReadSlice to look for array, // Use ReadSlice to look for array,
// accumulating full buffers. // accumulating full buffers.
...@@ -332,7 +333,8 @@ func (b *Reader) ReadBytes(delim byte) (line []byte, err os.Error) { ...@@ -332,7 +333,8 @@ func (b *Reader) ReadBytes(delim byte) (line []byte, err os.Error) {
// returning a string containing the data up to and including the delimiter. // returning a string containing the data up to and including the delimiter.
// If ReadString encounters an error before finding a delimiter, // If ReadString encounters an error before finding a delimiter,
// it returns the data read before the error and the error itself (often os.EOF). // it returns the data read before the error and the error itself (often os.EOF).
// ReadString returns err != nil if and only if line does not end in delim. // ReadString returns err != nil if and only if the returned data does not end in
// delim.
func (b *Reader) ReadString(delim byte) (line string, err os.Error) { func (b *Reader) ReadString(delim byte) (line string, err os.Error) {
bytes, e := b.ReadBytes(delim) bytes, e := b.ReadBytes(delim)
return string(bytes), e return string(bytes), e
...@@ -383,6 +385,9 @@ func (b *Writer) Flush() os.Error { ...@@ -383,6 +385,9 @@ func (b *Writer) Flush() os.Error {
if b.err != nil { if b.err != nil {
return b.err return b.err
} }
if b.n == 0 {
return nil
}
n, e := b.wr.Write(b.buf[0:b.n]) n, e := b.wr.Write(b.buf[0:b.n])
if n < b.n && e == nil { if n < b.n && e == nil {
e = io.ErrShortWrite e = io.ErrShortWrite
......
...@@ -154,17 +154,20 @@ func (b *Buffer) ReadFrom(r io.Reader) (n int64, err os.Error) { ...@@ -154,17 +154,20 @@ func (b *Buffer) ReadFrom(r io.Reader) (n int64, err os.Error) {
} }
// WriteTo writes data to w until the buffer is drained or an error // WriteTo writes data to w until the buffer is drained or an error
// occurs. The return value n is the number of bytes written. // occurs. The return value n is the number of bytes written; it always
// fits into an int, but it is int64 to match the io.WriterTo interface.
// Any error encountered during the write is also returned. // Any error encountered during the write is also returned.
func (b *Buffer) WriteTo(w io.Writer) (n int64, err os.Error) { func (b *Buffer) WriteTo(w io.Writer) (n int64, err os.Error) {
b.lastRead = opInvalid b.lastRead = opInvalid
for b.off < len(b.buf) { if b.off < len(b.buf) {
m, e := w.Write(b.buf[b.off:]) m, e := w.Write(b.buf[b.off:])
n += int64(m)
b.off += m b.off += m
n = int64(m)
if e != nil { if e != nil {
return n, e return n, e
} }
// otherwise all bytes were written, by definition of
// Write method in io.Writer
} }
// Buffer is now empty; reset. // Buffer is now empty; reset.
b.Truncate(0) b.Truncate(0)
...@@ -301,6 +304,36 @@ func (b *Buffer) UnreadByte() os.Error { ...@@ -301,6 +304,36 @@ func (b *Buffer) UnreadByte() os.Error {
return nil return nil
} }
// ReadBytes reads until the first occurrence of delim in the input,
// returning a slice containing the data up to and including the delimiter.
// If ReadBytes encounters an error before finding a delimiter,
// it returns the data read before the error and the error itself (often os.EOF).
// ReadBytes returns err != nil if and only if the returned data does not end in
// delim.
func (b *Buffer) ReadBytes(delim byte) (line []byte, err os.Error) {
i := IndexByte(b.buf[b.off:], delim)
size := i + 1
if i < 0 {
size = len(b.buf) - b.off
err = os.EOF
}
line = make([]byte, size)
copy(line, b.buf[b.off:])
b.off += size
return
}
// ReadString reads until the first occurrence of delim in the input,
// returning a string containing the data up to and including the delimiter.
// If ReadString encounters an error before finding a delimiter,
// it returns the data read before the error and the error itself (often os.EOF).
// ReadString returns err != nil if and only if the returned data does not end
// in delim.
func (b *Buffer) ReadString(delim byte) (line string, err os.Error) {
bytes, err := b.ReadBytes(delim)
return string(bytes), err
}
// NewBuffer creates and initializes a new Buffer using buf as its initial // NewBuffer creates and initializes a new Buffer using buf as its initial
// contents. It is intended to prepare a Buffer to read existing data. It // contents. It is intended to prepare a Buffer to read existing data. It
// can also be used to size the internal buffer for writing. To do that, // can also be used to size the internal buffer for writing. To do that,
......
...@@ -6,6 +6,7 @@ package bytes_test ...@@ -6,6 +6,7 @@ package bytes_test
import ( import (
. "bytes" . "bytes"
"os"
"rand" "rand"
"testing" "testing"
"utf8" "utf8"
...@@ -238,7 +239,7 @@ func TestMixedReadsAndWrites(t *testing.T) { ...@@ -238,7 +239,7 @@ func TestMixedReadsAndWrites(t *testing.T) {
func TestNil(t *testing.T) { func TestNil(t *testing.T) {
var b *Buffer var b *Buffer
if b.String() != "<nil>" { if b.String() != "<nil>" {
t.Errorf("expcted <nil>; got %q", b.String()) t.Errorf("expected <nil>; got %q", b.String())
} }
} }
...@@ -347,3 +348,38 @@ func TestNext(t *testing.T) { ...@@ -347,3 +348,38 @@ func TestNext(t *testing.T) {
} }
} }
} }
var readBytesTests = []struct {
buffer string
delim byte
expected []string
err os.Error
}{
{"", 0, []string{""}, os.EOF},
{"a\x00", 0, []string{"a\x00"}, nil},
{"abbbaaaba", 'b', []string{"ab", "b", "b", "aaab"}, nil},
{"hello\x01world", 1, []string{"hello\x01"}, nil},
{"foo\nbar", 0, []string{"foo\nbar"}, os.EOF},
{"alpha\nbeta\ngamma\n", '\n', []string{"alpha\n", "beta\n", "gamma\n"}, nil},
{"alpha\nbeta\ngamma", '\n', []string{"alpha\n", "beta\n", "gamma"}, os.EOF},
}
func TestReadBytes(t *testing.T) {
for _, test := range readBytesTests {
buf := NewBufferString(test.buffer)
var err os.Error
for _, expected := range test.expected {
var bytes []byte
bytes, err = buf.ReadBytes(test.delim)
if string(bytes) != expected {
t.Errorf("expected %q, got %q", expected, bytes)
}
if err != nil {
break
}
}
if err != test.err {
t.Errorf("expected error %v, got %v", test.err, err)
}
}
}
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package bzip2
import (
"bufio"
"io"
"os"
)
// bitReader wraps an io.Reader and provides the ability to read values,
// bit-by-bit, from it. Its Read* methods don't return the usual os.Error
// because the error handling was verbose. Instead, any error is kept and can
// be checked afterwards.
type bitReader struct {
r byteReader
n uint64
bits uint
err os.Error
}
// bitReader needs to read bytes from an io.Reader. We attempt to cast the
// given io.Reader to this interface and, if it doesn't already fit, we wrap in
// a bufio.Reader.
type byteReader interface {
ReadByte() (byte, os.Error)
}
func newBitReader(r io.Reader) bitReader {
byter, ok := r.(byteReader)
if !ok {
byter = bufio.NewReader(r)
}
return bitReader{r: byter}
}
// ReadBits64 reads the given number of bits and returns them in the
// least-significant part of a uint64. In the event of an error, it returns 0
// and the error can be obtained by calling Error().
func (br *bitReader) ReadBits64(bits uint) (n uint64) {
for bits > br.bits {
b, err := br.r.ReadByte()
if err == os.EOF {
err = io.ErrUnexpectedEOF
}
if err != nil {
br.err = err
return 0
}
br.n <<= 8
br.n |= uint64(b)
br.bits += 8
}
// br.n looks like this (assuming that br.bits = 14 and bits = 6):
// Bit: 111111
// 5432109876543210
//
// (6 bits, the desired output)
// |-----|
// V V
// 0101101101001110
// ^ ^
// |------------|
// br.bits (num valid bits)
//
// This the next line right shifts the desired bits into the
// least-significant places and masks off anything above.
n = (br.n >> (br.bits - bits)) & ((1 << bits) - 1)
br.bits -= bits
return
}
func (br *bitReader) ReadBits(bits uint) (n int) {
n64 := br.ReadBits64(bits)
return int(n64)
}
func (br *bitReader) ReadBit() bool {
n := br.ReadBits(1)
return n != 0
}
func (br *bitReader) Error() os.Error {
return br.err
}
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package bzip2
import (
"os"
"sort"
)
// A huffmanTree is a binary tree which is navigated, bit-by-bit to reach a
// symbol.
type huffmanTree struct {
// nodes contains all the non-leaf nodes in the tree. nodes[0] is the
// root of the tree and nextNode contains the index of the next element
// of nodes to use when the tree is being constructed.
nodes []huffmanNode
nextNode int
}
// A huffmanNode is a node in the tree. left and right contain indexes into the
// nodes slice of the tree. If left or right is invalidNodeValue then the child
// is a left node and its value is in leftValue/rightValue.
//
// The symbols are uint16s because bzip2 encodes not only MTF indexes in the
// tree, but also two magic values for run-length encoding and an EOF symbol.
// Thus there are more than 256 possible symbols.
type huffmanNode struct {
left, right uint16
leftValue, rightValue uint16
}
// invalidNodeValue is an invalid index which marks a leaf node in the tree.
const invalidNodeValue = 0xffff
// Decode reads bits from the given bitReader and navigates the tree until a
// symbol is found.
func (t huffmanTree) Decode(br *bitReader) (v uint16) {
nodeIndex := uint16(0) // node 0 is the root of the tree.
for {
node := &t.nodes[nodeIndex]
bit := br.ReadBit()
// bzip2 encodes left as a true bit.
if bit {
// left
if node.left == invalidNodeValue {
return node.leftValue
}
nodeIndex = node.left
} else {
// right
if node.right == invalidNodeValue {
return node.rightValue
}
nodeIndex = node.right
}
}
panic("unreachable")
}
// newHuffmanTree builds a Huffman tree from a slice containing the code
// lengths of each symbol. The maximum code length is 32 bits.
func newHuffmanTree(lengths []uint8) (huffmanTree, os.Error) {
// There are many possible trees that assign the same code length to
// each symbol (consider reflecting a tree down the middle, for
// example). Since the code length assignments determine the
// efficiency of the tree, each of these trees is equally good. In
// order to minimise the amount of information needed to build a tree
// bzip2 uses a canonical tree so that it can be reconstructed given
// only the code length assignments.
if len(lengths) < 2 {
panic("newHuffmanTree: too few symbols")
}
var t huffmanTree
// First we sort the code length assignments by ascending code length,
// using the symbol value to break ties.
pairs := huffmanSymbolLengthPairs(make([]huffmanSymbolLengthPair, len(lengths)))
for i, length := range lengths {
pairs[i].value = uint16(i)
pairs[i].length = length
}
sort.Sort(pairs)
// Now we assign codes to the symbols, starting with the longest code.
// We keep the codes packed into a uint32, at the most-significant end.
// So branches are taken from the MSB downwards. This makes it easy to
// sort them later.
code := uint32(0)
length := uint8(32)
codes := huffmanCodes(make([]huffmanCode, len(lengths)))
for i := len(pairs) - 1; i >= 0; i-- {
if length > pairs[i].length {
// If the code length decreases we shift in order to
// zero any bits beyond the end of the code.
length >>= 32 - pairs[i].length
length <<= 32 - pairs[i].length
length = pairs[i].length
}
codes[i].code = code
codes[i].codeLen = length
codes[i].value = pairs[i].value
// We need to 'increment' the code, which means treating |code|
// like a |length| bit number.
code += 1 << (32 - length)
}
// Now we can sort by the code so that the left half of each branch are
// grouped together, recursively.
sort.Sort(codes)
t.nodes = make([]huffmanNode, len(codes))
_, err := buildHuffmanNode(&t, codes, 0)
return t, err
}
// huffmanSymbolLengthPair contains a symbol and its code length.
type huffmanSymbolLengthPair struct {
value uint16
length uint8
}
// huffmanSymbolLengthPair is used to provide an interface for sorting.
type huffmanSymbolLengthPairs []huffmanSymbolLengthPair
func (h huffmanSymbolLengthPairs) Len() int {
return len(h)
}
func (h huffmanSymbolLengthPairs) Less(i, j int) bool {
if h[i].length < h[j].length {
return true
}
if h[i].length > h[j].length {
return false
}
if h[i].value < h[j].value {
return true
}
return false
}
func (h huffmanSymbolLengthPairs) Swap(i, j int) {
h[i], h[j] = h[j], h[i]
}
// huffmanCode contains a symbol, its code and code length.
type huffmanCode struct {
code uint32
codeLen uint8
value uint16
}
// huffmanCodes is used to provide an interface for sorting.
type huffmanCodes []huffmanCode
func (n huffmanCodes) Len() int {
return len(n)
}
func (n huffmanCodes) Less(i, j int) bool {
return n[i].code < n[j].code
}
func (n huffmanCodes) Swap(i, j int) {
n[i], n[j] = n[j], n[i]
}
// buildHuffmanNode takes a slice of sorted huffmanCodes and builds a node in
// the Huffman tree at the given level. It returns the index of the newly
// constructed node.
func buildHuffmanNode(t *huffmanTree, codes []huffmanCode, level uint32) (nodeIndex uint16, err os.Error) {
test := uint32(1) << (31 - level)
// We have to search the list of codes to find the divide between the left and right sides.
firstRightIndex := len(codes)
for i, code := range codes {
if code.code&test != 0 {
firstRightIndex = i
break
}
}
left := codes[:firstRightIndex]
right := codes[firstRightIndex:]
if len(left) == 0 || len(right) == 0 {
return 0, StructuralError("superfluous level in Huffman tree")
}
nodeIndex = uint16(t.nextNode)
node := &t.nodes[t.nextNode]
t.nextNode++
if len(left) == 1 {
// leaf node
node.left = invalidNodeValue
node.leftValue = left[0].value
} else {
node.left, err = buildHuffmanNode(t, left, level+1)
}
if err != nil {
return
}
if len(right) == 1 {
// leaf node
node.right = invalidNodeValue
node.rightValue = right[0].value
} else {
node.right, err = buildHuffmanNode(t, right, level+1)
}
return
}
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package bzip2
// moveToFrontDecoder implements a move-to-front list. Such a list is an
// efficient way to transform a string with repeating elements into one with
// many small valued numbers, which is suitable for entropy encoding. It works
// by starting with an initial list of symbols and references symbols by their
// index into that list. When a symbol is referenced, it's moved to the front
// of the list. Thus, a repeated symbol ends up being encoded with many zeros,
// as the symbol will be at the front of the list after the first access.
type moveToFrontDecoder struct {
// Rather than actually keep the list in memory, the symbols are stored
// as a circular, double linked list with the symbol indexed by head
// at the front of the list.
symbols []byte
next []uint8
prev []uint8
head uint8
}
// newMTFDecoder creates a move-to-front decoder with an explicit initial list
// of symbols.
func newMTFDecoder(symbols []byte) *moveToFrontDecoder {
if len(symbols) > 256 {
panic("too many symbols")
}
m := &moveToFrontDecoder{
symbols: symbols,
next: make([]uint8, len(symbols)),
prev: make([]uint8, len(symbols)),
}
m.threadLinkedList()
return m
}
// newMTFDecoderWithRange creates a move-to-front decoder with an initial
// symbol list of 0...n-1.
func newMTFDecoderWithRange(n int) *moveToFrontDecoder {
if n > 256 {
panic("newMTFDecoderWithRange: cannot have > 256 symbols")
}
m := &moveToFrontDecoder{
symbols: make([]uint8, n),
next: make([]uint8, n),
prev: make([]uint8, n),
}
for i := 0; i < n; i++ {
m.symbols[i] = byte(i)
}
m.threadLinkedList()
return m
}
// threadLinkedList creates the initial linked-list pointers.
func (m *moveToFrontDecoder) threadLinkedList() {
if len(m.symbols) == 0 {
return
}
m.prev[0] = uint8(len(m.symbols) - 1)
for i := 0; i < len(m.symbols)-1; i++ {
m.next[i] = uint8(i + 1)
m.prev[i+1] = uint8(i)
}
m.next[len(m.symbols)-1] = 0
}
func (m *moveToFrontDecoder) Decode(n int) (b byte) {
// Most of the time, n will be zero so it's worth dealing with this
// simple case.
if n == 0 {
return m.symbols[m.head]
}
i := m.head
for j := 0; j < n; j++ {
i = m.next[i]
}
b = m.symbols[i]
m.next[m.prev[i]] = m.next[i]
m.prev[m.next[i]] = m.prev[i]
m.next[i] = m.head
m.prev[i] = m.prev[m.head]
m.next[m.prev[m.head]] = i
m.prev[m.head] = i
m.head = i
return
}
// First returns the symbol at the front of the list.
func (m *moveToFrontDecoder) First() byte {
return m.symbols[m.head]
}
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// The lzw package implements the Lempel-Ziv-Welch compressed data format,
// described in T. A. Welch, ``A Technique for High-Performance Data
// Compression'', Computer, 17(6) (June 1984), pp 8-19.
//
// In particular, it implements LZW as used by the GIF, TIFF and PDF file
// formats, which means variable-width codes up to 12 bits and the first
// two non-literal codes are a clear code and an EOF code.
package lzw
// TODO(nigeltao): check that TIFF and PDF use LZW in the same way as GIF,
// modulo LSB/MSB packing order.
import (
"bufio"
"fmt"
"io"
"os"
)
// Order specifies the bit ordering in an LZW data stream.
type Order int
const (
// LSB means Least Significant Bits first, as used in the GIF file format.
LSB Order = iota
// MSB means Most Significant Bits first, as used in the TIFF and PDF
// file formats.
MSB
)
// decoder is the state from which the readXxx method converts a byte
// stream into a code stream.
type decoder struct {
r io.ByteReader
bits uint32
nBits uint
width uint
}
// readLSB returns the next code for "Least Significant Bits first" data.
func (d *decoder) readLSB() (uint16, os.Error) {
for d.nBits < d.width {
x, err := d.r.ReadByte()
if err != nil {
return 0, err
}
d.bits |= uint32(x) << d.nBits
d.nBits += 8
}
code := uint16(d.bits & (1<<d.width - 1))
d.bits >>= d.width
d.nBits -= d.width
return code, nil
}
// readMSB returns the next code for "Most Significant Bits first" data.
func (d *decoder) readMSB() (uint16, os.Error) {
for d.nBits < d.width {
x, err := d.r.ReadByte()
if err != nil {
return 0, err
}
d.bits |= uint32(x) << (24 - d.nBits)
d.nBits += 8
}
code := uint16(d.bits >> (32 - d.width))
d.bits <<= d.width
d.nBits -= d.width
return code, nil
}
// decode decompresses bytes from r and writes them to pw.
// read specifies how to decode bytes into codes.
// litWidth is the width in bits of literal codes.
func decode(r io.Reader, read func(*decoder) (uint16, os.Error), litWidth int, pw *io.PipeWriter) {
br, ok := r.(io.ByteReader)
if !ok {
br = bufio.NewReader(r)
}
pw.CloseWithError(decode1(pw, br, read, uint(litWidth)))
}
func decode1(pw *io.PipeWriter, r io.ByteReader, read func(*decoder) (uint16, os.Error), litWidth uint) os.Error {
const (
maxWidth = 12
invalidCode = 0xffff
)
d := decoder{r, 0, 0, 1 + litWidth}
w := bufio.NewWriter(pw)
// The first 1<<litWidth codes are literal codes.
// The next two codes mean clear and EOF.
// Other valid codes are in the range [lo, hi] where lo := clear + 2,
// with the upper bound incrementing on each code seen.
clear := uint16(1) << litWidth
eof, hi := clear+1, clear+1
// overflow is the code at which hi overflows the code width.
overflow := uint16(1) << d.width
var (
// Each code c in [lo, hi] expands to two or more bytes. For c != hi:
// suffix[c] is the last of these bytes.
// prefix[c] is the code for all but the last byte.
// This code can either be a literal code or another code in [lo, c).
// The c == hi case is a special case.
suffix [1 << maxWidth]uint8
prefix [1 << maxWidth]uint16
// buf is a scratch buffer for reconstituting the bytes that a code expands to.
// Code suffixes are written right-to-left from the end of the buffer.
buf [1 << maxWidth]byte
)
// Loop over the code stream, converting codes into decompressed bytes.
last := uint16(invalidCode)
for {
code, err := read(&d)
if err != nil {
if err == os.EOF {
err = io.ErrUnexpectedEOF
}
return err
}
switch {
case code < clear:
// We have a literal code.
if err := w.WriteByte(uint8(code)); err != nil {
return err
}
if last != invalidCode {
// Save what the hi code expands to.
suffix[hi] = uint8(code)
prefix[hi] = last
}
case code == clear:
d.width = 1 + litWidth
hi = eof
overflow = 1 << d.width
last = invalidCode
continue
case code == eof:
return w.Flush()
case code <= hi:
c, i := code, len(buf)-1
if code == hi {
// code == hi is a special case which expands to the last expansion
// followed by the head of the last expansion. To find the head, we walk
// the prefix chain until we find a literal code.
c = last
for c >= clear {
c = prefix[c]
}
buf[i] = uint8(c)
i--
c = last
}
// Copy the suffix chain into buf and then write that to w.
for c >= clear {
buf[i] = suffix[c]
i--
c = prefix[c]
}
buf[i] = uint8(c)
if _, err := w.Write(buf[i:]); err != nil {
return err
}
// Save what the hi code expands to.
suffix[hi] = uint8(c)
prefix[hi] = last
default:
return os.NewError("lzw: invalid code")
}
last, hi = code, hi+1
if hi == overflow {
if d.width == maxWidth {
return os.NewError("lzw: missing clear code")
}
d.width++
overflow <<= 1
}
}
panic("unreachable")
}
// NewReader creates a new io.ReadCloser that satisfies reads by decompressing
// the data read from r.
// It is the caller's responsibility to call Close on the ReadCloser when
// finished reading.
// The number of bits to use for literal codes, litWidth, must be in the
// range [2,8] and is typically 8.
func NewReader(r io.Reader, order Order, litWidth int) io.ReadCloser {
pr, pw := io.Pipe()
var read func(*decoder) (uint16, os.Error)
switch order {
case LSB:
read = (*decoder).readLSB
case MSB:
read = (*decoder).readMSB
default:
pw.CloseWithError(os.NewError("lzw: unknown order"))
return pr
}
if litWidth < 2 || 8 < litWidth {
pw.CloseWithError(fmt.Errorf("lzw: litWidth %d out of range", litWidth))
return pr
}
go decode(r, read, litWidth, pw)
return pr
}
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package lzw
import (
"bytes"
"io"
"io/ioutil"
"os"
"strconv"
"strings"
"testing"
)
type lzwTest struct {
desc string
raw string
compressed string
err os.Error
}
var lzwTests = []lzwTest{
{
"empty;LSB;8",
"",
"\x01\x01",
nil,
},
{
"empty;MSB;8",
"",
"\x80\x80",
nil,
},
{
"tobe;LSB;7",
"TOBEORNOTTOBEORTOBEORNOT",
"\x54\x4f\x42\x45\x4f\x52\x4e\x4f\x54\x82\x84\x86\x8b\x85\x87\x89\x81",
nil,
},
{
"tobe;LSB;8",
"TOBEORNOTTOBEORTOBEORNOT",
"\x54\x9e\x08\x29\xf2\x44\x8a\x93\x27\x54\x04\x12\x34\xb8\xb0\xe0\xc1\x84\x01\x01",
nil,
},
{
"tobe;MSB;7",
"TOBEORNOTTOBEORTOBEORNOT",
"\x54\x4f\x42\x45\x4f\x52\x4e\x4f\x54\x82\x84\x86\x8b\x85\x87\x89\x81",
nil,
},
{
"tobe;MSB;8",
"TOBEORNOTTOBEORTOBEORNOT",
"\x2a\x13\xc8\x44\x52\x79\x48\x9c\x4f\x2a\x40\xa0\x90\x68\x5c\x16\x0f\x09\x80\x80",
nil,
},
{
"tobe-truncated;LSB;8",
"TOBEORNOTTOBEORTOBEORNOT",
"\x54\x9e\x08\x29\xf2\x44\x8a\x93\x27\x54\x04",
io.ErrUnexpectedEOF,
},
// This example comes from http://en.wikipedia.org/wiki/Graphics_Interchange_Format.
{
"gif;LSB;8",
"\x28\xff\xff\xff\x28\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff",
"\x00\x51\xfc\x1b\x28\x70\xa0\xc1\x83\x01\x01",
nil,
},
// This example comes from http://compgroups.net/comp.lang.ruby/Decompressing-LZW-compression-from-PDF-file
{
"pdf;MSB;8",
"-----A---B",
"\x80\x0b\x60\x50\x22\x0c\x0c\x85\x01",
nil,
},
}
func TestReader(t *testing.T) {
b := bytes.NewBuffer(nil)
for _, tt := range lzwTests {
d := strings.Split(tt.desc, ";", -1)
var order Order
switch d[1] {
case "LSB":
order = LSB
case "MSB":
order = MSB
default:
t.Errorf("%s: bad order %q", tt.desc, d[1])
}
litWidth, _ := strconv.Atoi(d[2])
rc := NewReader(strings.NewReader(tt.compressed), order, litWidth)
defer rc.Close()
b.Reset()
n, err := io.Copy(b, rc)
if err != nil {
if err != tt.err {
t.Errorf("%s: io.Copy: %v want %v", tt.desc, err, tt.err)
}
continue
}
s := b.String()
if s != tt.raw {
t.Errorf("%s: got %d-byte %q want %d-byte %q", tt.desc, n, s, len(tt.raw), tt.raw)
}
}
}
type devNull struct{}
func (devNull) Write(p []byte) (int, os.Error) {
return len(p), nil
}
func BenchmarkDecoder(b *testing.B) {
b.StopTimer()
buf0, _ := ioutil.ReadFile("../testdata/e.txt")
compressed := bytes.NewBuffer(nil)
w := NewWriter(compressed, LSB, 8)
io.Copy(w, bytes.NewBuffer(buf0))
w.Close()
buf1 := compressed.Bytes()
b.StartTimer()
for i := 0; i < b.N; i++ {
io.Copy(devNull{}, NewReader(bytes.NewBuffer(buf1), LSB, 8))
}
}
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package lzw
import (
"bufio"
"fmt"
"io"
"os"
)
// A writer is a buffered, flushable writer.
type writer interface {
WriteByte(byte) os.Error
Flush() os.Error
}
// An errWriteCloser is an io.WriteCloser that always returns a given error.
type errWriteCloser struct {
err os.Error
}
func (e *errWriteCloser) Write([]byte) (int, os.Error) {
return 0, e.err
}
func (e *errWriteCloser) Close() os.Error {
return e.err
}
const (
// A code is a 12 bit value, stored as a uint32 when encoding to avoid
// type conversions when shifting bits.
maxCode = 1<<12 - 1
invalidCode = 1<<32 - 1
// There are 1<<12 possible codes, which is an upper bound on the number of
// valid hash table entries at any given point in time. tableSize is 4x that.
tableSize = 4 * 1 << 12
tableMask = tableSize - 1
// A hash table entry is a uint32. Zero is an invalid entry since the
// lower 12 bits of a valid entry must be a non-literal code.
invalidEntry = 0
)
// encoder is LZW compressor.
type encoder struct {
// w is the writer that compressed bytes are written to.
w writer
// write, bits, nBits and width are the state for converting a code stream
// into a byte stream.
write func(*encoder, uint32) os.Error
bits uint32
nBits uint
width uint
// litWidth is the width in bits of literal codes.
litWidth uint
// hi is the code implied by the next code emission.
// overflow is the code at which hi overflows the code width.
hi, overflow uint32
// savedCode is the accumulated code at the end of the most recent Write
// call. It is equal to invalidCode if there was no such call.
savedCode uint32
// err is the first error encountered during writing. Closing the encoder
// will make any future Write calls return os.EINVAL.
err os.Error
// table is the hash table from 20-bit keys to 12-bit values. Each table
// entry contains key<<12|val and collisions resolve by linear probing.
// The keys consist of a 12-bit code prefix and an 8-bit byte suffix.
// The values are a 12-bit code.
table [tableSize]uint32
}
// writeLSB writes the code c for "Least Significant Bits first" data.
func (e *encoder) writeLSB(c uint32) os.Error {
e.bits |= c << e.nBits
e.nBits += e.width
for e.nBits >= 8 {
if err := e.w.WriteByte(uint8(e.bits)); err != nil {
return err
}
e.bits >>= 8
e.nBits -= 8
}
return nil
}
// writeMSB writes the code c for "Most Significant Bits first" data.
func (e *encoder) writeMSB(c uint32) os.Error {
e.bits |= c << (32 - e.width - e.nBits)
e.nBits += e.width
for e.nBits >= 8 {
if err := e.w.WriteByte(uint8(e.bits >> 24)); err != nil {
return err
}
e.bits <<= 8
e.nBits -= 8
}
return nil
}
// errOutOfCodes is an internal error that means that the encoder has run out
// of unused codes and a clear code needs to be sent next.
var errOutOfCodes = os.NewError("lzw: out of codes")
// incHi increments e.hi and checks for both overflow and running out of
// unused codes. In the latter case, incHi sends a clear code, resets the
// encoder state and returns errOutOfCodes.
func (e *encoder) incHi() os.Error {
e.hi++
if e.hi == e.overflow {
e.width++
e.overflow <<= 1
}
if e.hi == maxCode {
clear := uint32(1) << e.litWidth
if err := e.write(e, clear); err != nil {
return err
}
e.width = uint(e.litWidth) + 1
e.hi = clear + 1
e.overflow = clear << 1
for i := range e.table {
e.table[i] = invalidEntry
}
return errOutOfCodes
}
return nil
}
// Write writes a compressed representation of p to e's underlying writer.
func (e *encoder) Write(p []byte) (int, os.Error) {
if e.err != nil {
return 0, e.err
}
if len(p) == 0 {
return 0, nil
}
litMask := uint32(1<<e.litWidth - 1)
code := e.savedCode
if code == invalidCode {
// The first code sent is always a literal code.
code, p = uint32(p[0])&litMask, p[1:]
}
loop:
for _, x := range p {
literal := uint32(x) & litMask
key := code<<8 | literal
// If there is a hash table hit for this key then we continue the loop
// and do not emit a code yet.
hash := (key>>12 ^ key) & tableMask
for h, t := hash, e.table[hash]; t != invalidEntry; {
if key == t>>12 {
code = t & maxCode
continue loop
}
h = (h + 1) & tableMask
t = e.table[h]
}
// Otherwise, write the current code, and literal becomes the start of
// the next emitted code.
if e.err = e.write(e, code); e.err != nil {
return 0, e.err
}
code = literal
// Increment e.hi, the next implied code. If we run out of codes, reset
// the encoder state (including clearing the hash table) and continue.
if err := e.incHi(); err != nil {
if err == errOutOfCodes {
continue
}
e.err = err
return 0, e.err
}
// Otherwise, insert key -> e.hi into the map that e.table represents.
for {
if e.table[hash] == invalidEntry {
e.table[hash] = (key << 12) | e.hi
break
}
hash = (hash + 1) & tableMask
}
}
e.savedCode = code
return len(p), nil
}
// Close closes the encoder, flushing any pending output. It does not close or
// flush e's underlying writer.
func (e *encoder) Close() os.Error {
if e.err != nil {
if e.err == os.EINVAL {
return nil
}
return e.err
}
// Make any future calls to Write return os.EINVAL.
e.err = os.EINVAL
// Write the savedCode if valid.
if e.savedCode != invalidCode {
if err := e.write(e, e.savedCode); err != nil {
return err
}
if err := e.incHi(); err != nil && err != errOutOfCodes {
return err
}
}
// Write the eof code.
eof := uint32(1)<<e.litWidth + 1
if err := e.write(e, eof); err != nil {
return err
}
// Write the final bits.
if e.nBits > 0 {
if e.write == (*encoder).writeMSB {
e.bits >>= 24
}
if err := e.w.WriteByte(uint8(e.bits)); err != nil {
return err
}
}
return e.w.Flush()
}
// NewWriter creates a new io.WriteCloser that satisfies writes by compressing
// the data and writing it to w.
// It is the caller's responsibility to call Close on the WriteCloser when
// finished writing.
// The number of bits to use for literal codes, litWidth, must be in the
// range [2,8] and is typically 8.
func NewWriter(w io.Writer, order Order, litWidth int) io.WriteCloser {
var write func(*encoder, uint32) os.Error
switch order {
case LSB:
write = (*encoder).writeLSB
case MSB:
write = (*encoder).writeMSB
default:
return &errWriteCloser{os.NewError("lzw: unknown order")}
}
if litWidth < 2 || 8 < litWidth {
return &errWriteCloser{fmt.Errorf("lzw: litWidth %d out of range", litWidth)}
}
bw, ok := w.(writer)
if !ok {
bw = bufio.NewWriter(w)
}
lw := uint(litWidth)
return &encoder{
w: bw,
write: write,
width: 1 + lw,
litWidth: lw,
hi: 1<<lw + 1,
overflow: 1 << (lw + 1),
savedCode: invalidCode,
}
}
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package lzw
import (
"io"
"io/ioutil"
"os"
"testing"
)
var filenames = []string{
"../testdata/e.txt",
"../testdata/pi.txt",
}
// testFile tests that compressing and then decompressing the given file with
// the given options yields equivalent bytes to the original file.
func testFile(t *testing.T, fn string, order Order, litWidth int) {
// Read the file, as golden output.
golden, err := os.Open(fn, os.O_RDONLY, 0400)
if err != nil {
t.Errorf("%s (order=%d litWidth=%d): %v", fn, order, litWidth, err)
return
}
defer golden.Close()
// Read the file again, and push it through a pipe that compresses at the write end, and decompresses at the read end.
raw, err := os.Open(fn, os.O_RDONLY, 0400)
if err != nil {
t.Errorf("%s (order=%d litWidth=%d): %v", fn, order, litWidth, err)
return
}
piper, pipew := io.Pipe()
defer piper.Close()
go func() {
defer raw.Close()
defer pipew.Close()
lzww := NewWriter(pipew, order, litWidth)
defer lzww.Close()
var b [4096]byte
for {
n, err0 := raw.Read(b[:])
if err0 != nil && err0 != os.EOF {
t.Errorf("%s (order=%d litWidth=%d): %v", fn, order, litWidth, err0)
return
}
_, err1 := lzww.Write(b[:n])
if err1 == os.EPIPE {
// Fail, but do not report the error, as some other (presumably reportable) error broke the pipe.
return
}
if err1 != nil {
t.Errorf("%s (order=%d litWidth=%d): %v", fn, order, litWidth, err1)
return
}
if err0 == os.EOF {
break
}
}
}()
lzwr := NewReader(piper, order, litWidth)
defer lzwr.Close()
// Compare the two.
b0, err0 := ioutil.ReadAll(golden)
b1, err1 := ioutil.ReadAll(lzwr)
if err0 != nil {
t.Errorf("%s (order=%d litWidth=%d): %v", fn, order, litWidth, err0)
return
}
if err1 != nil {
t.Errorf("%s (order=%d litWidth=%d): %v", fn, order, litWidth, err1)
return
}
if len(b0) != len(b1) {
t.Errorf("%s (order=%d litWidth=%d): length mismatch %d versus %d", fn, order, litWidth, len(b0), len(b1))
return
}
for i := 0; i < len(b0); i++ {
if b0[i] != b1[i] {
t.Errorf("%s (order=%d litWidth=%d): mismatch at %d, 0x%02x versus 0x%02x\n", fn, order, litWidth, i, b0[i], b1[i])
return
}
}
}
func TestWriter(t *testing.T) {
for _, filename := range filenames {
for _, order := range [...]Order{LSB, MSB} {
// The test data "2.71828 etcetera" is ASCII text requiring at least 6 bits.
for _, litWidth := range [...]int{6, 7, 8} {
testFile(t, filename, order, litWidth)
}
}
}
}
func BenchmarkEncoder(b *testing.B) {
b.StopTimer()
buf, _ := ioutil.ReadFile("../testdata/e.txt")
b.StartTimer()
for i := 0; i < b.N; i++ {
w := NewWriter(devNull{}, LSB, 8)
w.Write(buf)
w.Close()
}
}
2.7182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274274663919320030599218174135966290435729003342952605956307381323286279434907632338298807531952510190115738341879307021540891499348841675092447614606680822648001684774118537423454424371075390777449920695517027618386062613313845830007520449338265602976067371132007093287091274437470472306969772093101416928368190255151086574637721112523897844250569536967707854499699679468644549059879316368892300987931277361782154249992295763514822082698951936680331825288693984964651058209392398294887933203625094431173012381970684161403970198376793206832823764648042953118023287825098194558153017567173613320698112509961818815930416903515988885193458072738667385894228792284998920868058257492796104841984443634632449684875602336248270419786232090021609902353043699418491463140934317381436405462531520961836908887070167683964243781405927145635490613031072085103837505101157477041718986106873969655212671546889570350354021234078498193343210681701210056278802351930332247450158539047304199577770935036604169973297250886876966403555707162268447162560798826517871341951246652010305921236677194325278675398558944896970964097545918569563802363701621120477427228364896134225164450781824423529486363721417402388934412479635743702637552944483379980161254922785092577825620926226483262779333865664816277251640191059004916449982893150566047258027786318641551956532442586982946959308019152987211725563475463964479101459040905862984967912874068705048958586717479854667757573205681288459205413340539220001137863009455606881667400169842055804033637953764520304024322566135278369511778838638744396625322498506549958862342818997077332761717839280349465014345588970719425863987727547109629537415211151368350627526023264847287039207643100595841166120545297030236472549296669381151373227536450988890313602057248176585118063036442812314965507047510254465011727211555194866850800368532281831521960037356252794495158284188294787610852639813955990067376482922443752871846245780361929819713991475644882626039033814418232625150974827987779964373089970388867782271383605772978824125611907176639465070633045279546618550966661856647097113444740160704626215680717481877844371436988218559670959102596862002353718588748569652200050311734392073211390803293634479727355955277349071783793421637012050054513263835440001863239914907054797780566978533580489669062951194324730995876552368128590413832411607226029983305353708761389396391779574540161372236187893652605381558415871869255386061647798340254351284396129460352913325942794904337299085731580290958631382683291477116396337092400316894586360606458459251269946557248391865642097526850823075442545993769170419777800853627309417101634349076964237222943523661255725088147792231519747780605696725380171807763603462459278778465850656050780844211529697521890874019660906651803516501792504619501366585436632712549639908549144200014574760819302212066024330096412704894390397177195180699086998606636583232278709376502260149291011517177635944602023249300280401867723910288097866605651183260043688508817157238669842242201024950551881694803221002515426494639812873677658927688163598312477886520141174110913601164995076629077943646005851941998560162647907615321038727557126992518275687989302761761146162549356495903798045838182323368612016243736569846703785853305275833337939907521660692380533698879565137285593883499894707416181550125397064648171946708348197214488898790676503795903669672494992545279033729636162658976039498576741397359441023744329709355477982629614591442936451428617158587339746791897571211956187385783644758448423555581050025611492391518893099463428413936080383091662818811503715284967059741625628236092168075150177725387402564253470879089137291722828611515915683725241630772254406337875931059826760944203261924285317018781772960235413060672136046000389661093647095141417185777014180606443636815464440053316087783143174440811949422975599314011888683314832802706553833004693290115744147563139997221703804617092894579096271662260740718749975359212756084414737823303270330168237193648002173285734935947564334129943024850235732214597843282641421684878721673367010615094243456984401873312810107945127223737886126058165668053714396127888732527373890392890506865324138062796025930387727697783792868409325365880733988457218746021005311483351323850047827169376218004904795597959290591655470505777514308175112698985188408718564026035305583737832422924185625644255022672155980274012617971928047139600689163828665277009752767069777036439260224372841840883251848770472638440379530166905465937461619323840363893131364327137688841026811219891275223056256756254701725086349765367288605966752740868627407912856576996313789753034660616669804218267724560530660773899624218340859882071864682623215080288286359746839654358856685503773131296587975810501214916207656769950659715344763470320853215603674828608378656803073062657633469774295634643716709397193060876963495328846833613038829431040800296873869117066666146800015121143442256023874474325250769387077775193299942137277211258843608715834835626961661980572526612206797540621062080649882918454395301529982092503005498257043390553570168653120526495614857249257386206917403695213533732531666345466588597286659451136441370331393672118569553952108458407244323835586063106806964924851232632699514603596037297253198368423363904632136710116192821711150282801604488058802382031981493096369596735832742024988245684941273860566491352526706046234450549227581151709314921879592718001940968866986837037302200475314338181092708030017205935530520700706072233999463990571311587099635777359027196285061146514837526209565346713290025994397663114545902685898979115837093419370441155121920117164880566945938131183843765620627846310490346293950029458341164824114969758326011800731699437393506966295712410273239138741754923071862454543222039552735295240245903805744502892246886285336542213815722131163288112052146489805180092024719391710555390113943316681515828843687606961102505171007392762385553386272553538830960671644662370922646809671254061869502143176211668140097595281493907222601112681153108387317617323235263605838173151034595736538223534992935822836851007810884634349983518404451704270189381994243410090575376257767571118090088164183319201962623416288166521374717325477727783488774366518828752156685719506371936565390389449366421764003121527870222366463635755503565576948886549500270853923617105502131147413744106134445544192101336172996285694899193369184729478580729156088510396781959429833186480756083679551496636448965592948187851784038773326247051945050419847742014183947731202815886845707290544057510601285258056594703046836344592652552137008068752009593453607316226118728173928074623094685367823106097921599360019946237993434210687813497346959246469752506246958616909178573976595199392993995567542714654910456860702099012606818704984178079173924071945996323060254707901774527513186809982284730860766536866855516467702911336827563107223346726113705490795365834538637196235856312618387156774118738527722922594743373785695538456246801013905727871016512966636764451872465653730402443684140814488732957847348490003019477888020460324660842875351848364959195082888323206522128104190448047247949291342284951970022601310430062410717971502793433263407995960531446053230488528972917659876016667811937932372453857209607582277178483361613582612896226118129455927462767137794487586753657544861407611931125958512655759734573015333642630767985443385761715333462325270572005303988289499034259566232975782488735029259166825894456894655992658454762694528780516501720674785417887982276806536650641910973434528878338621726156269582654478205672987756426325321594294418039943217000090542650763095588465895171709147607437136893319469090981904501290307099566226620303182649365733698419555776963787624918852865686607600566025605445711337286840205574416030837052312242587223438854123179481388550075689381124935386318635287083799845692619981794523364087429591180747453419551420351726184200845509170845682368200897739455842679214273477560879644279202708312150156406341341617166448069815483764491573900121217041547872591998943825364950514771379399147205219529079396137621107238494290616357604596231253506068537651423115349665683715116604220796394466621163255157729070978473156278277598788136491951257483328793771571459091064841642678309949723674420175862269402159407924480541255360431317992696739157542419296607312393763542139230617876753958711436104089409966089471418340698362993675362621545247298464213752891079884381306095552622720837518629837066787224430195793793786072107254277289071732854874374355781966511716618330881129120245204048682200072344035025448202834254187884653602591506445271657700044521097735585897622655484941621714989532383421600114062950718490427789258552743035221396835679018076406042138307308774460170842688272261177180842664333651780002171903449234264266292261456004337383868335555343453004264818473989215627086095650629340405264943244261445665921291225648893569655009154306426134252668472594914314239398845432486327461842846655985332312210466259890141712103446084271616619001257195870793217569698544013397622096749454185407118446433946990162698351607848924514058940946395267807354579700307051163682519487701189764002827648414160587206184185297189154019688253289309149665345753571427318482016384644832499037886069008072709327673127581966563941148961716832980455139729506687604740915420428429993541025829113502241690769431668574242522509026939034814856451303069925199590436384028429267412573422447765584177886171737265462085498294498946787350929581652632072258992368768457017823038096567883112289305809140572610865884845873101658151167533327674887014829167419701512559782572707406431808601428149024146780472327597684269633935773542930186739439716388611764209004068663398856841681003872389214483176070116684503887212364367043314091155733280182977988736590916659612402021778558854876176161989370794380056663364884365089144805571039765214696027662583599051987042300179465536788
3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989380952572010654858632788659361533818279682303019520353018529689957736225994138912497217752834791315155748572424541506959508295331168617278558890750983817546374649393192550604009277016711390098488240128583616035637076601047101819429555961989467678374494482553797747268471040475346462080466842590694912933136770289891521047521620569660240580381501935112533824300355876402474964732639141992726042699227967823547816360093417216412199245863150302861829745557067498385054945885869269956909272107975093029553211653449872027559602364806654991198818347977535663698074265425278625518184175746728909777727938000816470600161452491921732172147723501414419735685481613611573525521334757418494684385233239073941433345477624168625189835694855620992192221842725502542568876717904946016534668049886272327917860857843838279679766814541009538837863609506800642251252051173929848960841284886269456042419652850222106611863067442786220391949450471237137869609563643719172874677646575739624138908658326459958133904780275900994657640789512694683983525957098258226205224894077267194782684826014769909026401363944374553050682034962524517493996514314298091906592509372216964615157098583874105978859597729754989301617539284681382686838689427741559918559252459539594310499725246808459872736446958486538367362226260991246080512438843904512441365497627807977156914359977001296160894416948685558484063534220722258284886481584560285060168427394522674676788952521385225499546667278239864565961163548862305774564980355936345681743241125150760694794510965960940252288797108931456691368672287489405601015033086179286809208747609178249385890097149096759852613655497818931297848216829989487226588048575640142704775551323796414515237462343645428584447952658678210511413547357395231134271661021359695362314429524849371871101457654035902799344037420073105785390621983874478084784896833214457138687519435064302184531910484810053706146806749192781911979399520614196634287544406437451237181921799983910159195618146751426912397489409071864942319615679452080951465502252316038819301420937621378559566389377870830390697920773467221825625996615014215030680384477345492026054146659252014974428507325186660021324340881907104863317346496514539057962685610055081066587969981635747363840525714591028970641401109712062804390397595156771577004203378699360072305587631763594218731251471205329281918261861258673215791984148488291644706095752706957220917567116722910981690915280173506712748583222871835209353965725121083579151369882091444210067510334671103141267111369908658516398315019701651511685171437657618351556508849099898599823873455283316355076479185358932261854896321329330898570642046752590709154814165498594616371802709819943099244889575712828905923233260972997120844335732654893823911932597463667305836041428138830320382490375898524374417029132765618093773444030707469211201913020330380197621101100449293215160842444859637669838952286847831235526582131449576857262433441893039686426243410773226978028073189154411010446823252716201052652272111660396665573092547110557853763466820653109896526918620564769312570586356620185581007293606598764861179104533488503461136576867532494416680396265797877185560845529654126654085306143444318586769751456614068007002378776591344017127494704205622305389945613140711270004078547332699390814546646458807972708266830634328587856983052358089330657574067954571637752542021149557615814002501262285941302164715509792592309907965473761255176567513575178296664547791745011299614890304639947132962107340437518957359614589019389713111790429782856475032031986915140287080859904801094121472213179476477726224142548545403321571853061422881375850430633217518297986622371721591607716692547487389866549494501146540628433663937900397692656721463853067360965712091807638327166416274888800786925602902284721040317211860820419000422966171196377921337575114959501566049631862947265473642523081770367515906735023507283540567040386743513622224771589150495309844489333096340878076932599397805419341447377441842631298608099888687413260472156951623965864573021631598193195167353812974167729478672422924654366800980676928238280689964004824354037014163149658979409243237896907069779422362508221688957383798623001593776471651228935786015881617557829735233446042815126272037343146531977774160319906655418763979293344195215413418994854447345673831624993419131814809277771038638773431772075456545322077709212019051660962804909263601975988281613323166636528619326686336062735676303544776280350450777235547105859548702790814356240145171806246436267945612753181340783303362542327839449753824372058353114771199260638133467768796959703098339130771098704085913374641442822772634659470474587847787201927715280731767907707157213444730605700733492436931138350493163128404251219256517980694113528013147013047816437885185290928545201165839341965621349143415956258658655705526904965209858033850722426482939728584783163057777560688876446248246857926039535277348030480290058760758251047470916439613626760449256274204208320856611906254543372131535958450687724602901618766795240616342522577195429162991930645537799140373404328752628889639958794757291746426357455254079091451357111369410911939325191076020825202618798531887705842972591677813149699009019211697173727847684726860849003377024242916513005005168323364350389517029893922334517220138128069650117844087451960121228599371623130171144484640903890644954440061986907548516026327505298349187407866808818338510228334508504860825039302133219715518430635455007668282949304137765527939751754613953984683393638304746119966538581538420568533862186725233402830871123282789212507712629463229563989898935821167456270102183564622013496715188190973038119800497340723961036854066431939509790190699639552453005450580685501956730229219139339185680344903982059551002263535361920419947455385938102343955449597783779023742161727111723643435439478221818528624085140066604433258885698670543154706965747458550332323342107301545940516553790686627333799585115625784322988273723198987571415957811196358330059408730681216028764962867446047746491599505497374256269010490377819868359381465741268049256487985561453723478673303904688383436346553794986419270563872931748723320837601123029911367938627089438799362016295154133714248928307220126901475466847653576164773794675200490757155527819653621323926406160136358155907422020203187277605277219005561484255518792530343513984425322341576233610642506390497500865627109535919465897514131034822769306247435363256916078154781811528436679570611086153315044521274739245449454236828860613408414863776700961207151249140430272538607648236341433462351897576645216413767969031495019108575984423919862916421939949072362346468441173940326591840443780513338945257423995082965912285085558215725031071257012668302402929525220118726767562204154205161841634847565169998116141010029960783869092916030288400269104140792886215078424516709087000699282120660418371806535567252532567532861291042487761825829765157959847035622262934860034158722980534989650226291748788202734209222245339856264766914905562842503912757710284027998066365825488926488025456610172967026640765590429099456815065265305371829412703369313785178609040708667114965583434347693385781711386455873678123014587687126603489139095620099393610310291616152881384379099042317473363948045759314931405297634757481193567091101377517210080315590248530906692037671922033229094334676851422144773793937517034436619910403375111735471918550464490263655128162288244625759163330391072253837421821408835086573917715096828874782656995995744906617583441375223970968340800535598491754173818839994469748676265516582765848358845314277568790029095170283529716344562129640435231176006651012412006597558512761785838292041974844236080071930457618932349229279650198751872127267507981255470958904556357921221033346697499235630254947802490114195212382815309114079073860251522742995818072471625916685451333123948049470791191532673430282441860414263639548000448002670496248201792896476697583183271314251702969234889627668440323260927524960357996469256504936818360900323809293459588970695365349406034021665443755890045632882250545255640564482465151875471196218443965825337543885690941130315095261793780029741207665147939425902989695946995565761218656196733786236256125216320862869222103274889218654364802296780705765615144632046927906821207388377814233562823608963208068222468012248261177185896381409183903673672220888321513755600372798394004152970028783076670944474560134556417254370906979396122571429894671543578468788614445812314593571984922528471605049221242470141214780573455105008019086996033027634787081081754501193071412233908663938339529425786905076431006383519834389341596131854347546495569781038293097164651438407007073604112373599843452251610507027056235266012764848308407611830130527932054274628654036036745328651057065874882256981579367897669742205750596834408697350201410206723585020072452256326513410559240190274216248439140359989535394590944070469120914093870012645600162374288021092764579310657922955249887275846101264836999892256959688159205600101655256375678
...@@ -12,8 +12,8 @@ import ( ...@@ -12,8 +12,8 @@ import (
) )
var filenames = []string{ var filenames = []string{
"testdata/e.txt", "../testdata/e.txt",
"testdata/pi.txt", "../testdata/pi.txt",
} }
// Tests that compressing and then decompressing the given file at the given compression level // Tests that compressing and then decompressing the given file at the given compression level
......
...@@ -138,16 +138,13 @@ func (r *Ring) Len() int { ...@@ -138,16 +138,13 @@ func (r *Ring) Len() int {
} }
func (r *Ring) Iter() <-chan interface{} { // Do calls function f on each element of the ring, in forward order.
c := make(chan interface{}) // The behavior of Do is undefined if f changes *r.
go func() { func (r *Ring) Do(f func(interface{})) {
if r != nil { if r != nil {
c <- r.Value f(r.Value)
for p := r.Next(); p != r; p = p.next { for p := r.Next(); p != r; p = p.next {
c <- p.Value f(p.Value)
}
} }
close(c) }
}()
return c
} }
...@@ -35,12 +35,12 @@ func verify(t *testing.T, r *Ring, N int, sum int) { ...@@ -35,12 +35,12 @@ func verify(t *testing.T, r *Ring, N int, sum int) {
// iteration // iteration
n = 0 n = 0
s := 0 s := 0
for p := range r.Iter() { r.Do(func(p interface{}) {
n++ n++
if p != nil { if p != nil {
s += p.(int) s += p.(int)
} }
} })
if n != N { if n != N {
t.Errorf("number of forward iterations == %d; expected %d", n, N) t.Errorf("number of forward iterations == %d; expected %d", n, N)
} }
...@@ -128,16 +128,6 @@ func makeN(n int) *Ring { ...@@ -128,16 +128,6 @@ func makeN(n int) *Ring {
return r return r
} }
func sum(r *Ring) int {
s := 0
for p := range r.Iter() {
s += p.(int)
}
return s
}
func sumN(n int) int { return (n*n + n) / 2 } func sumN(n int) int { return (n*n + n) / 2 }
......
...@@ -12,11 +12,21 @@ type ocfbEncrypter struct { ...@@ -12,11 +12,21 @@ type ocfbEncrypter struct {
outUsed int outUsed int
} }
// An OCFBResyncOption determines if the "resynchronization step" of OCFB is
// performed.
type OCFBResyncOption bool
const (
OCFBResync OCFBResyncOption = true
OCFBNoResync OCFBResyncOption = false
)
// NewOCFBEncrypter returns a Stream which encrypts data with OpenPGP's cipher // NewOCFBEncrypter returns a Stream which encrypts data with OpenPGP's cipher
// feedback mode using the given Block, and an initial amount of ciphertext. // feedback mode using the given Block, and an initial amount of ciphertext.
// randData must be random bytes and be the same length as the Block's block // randData must be random bytes and be the same length as the Block's block
// size. // size. Resync determines if the "resynchronization step" from RFC 4880, 13.9
func NewOCFBEncrypter(block Block, randData []byte) (Stream, []byte) { // step 7 is performed. Different parts of OpenPGP vary on this point.
func NewOCFBEncrypter(block Block, randData []byte, resync OCFBResyncOption) (Stream, []byte) {
blockSize := block.BlockSize() blockSize := block.BlockSize()
if len(randData) != blockSize { if len(randData) != blockSize {
return nil, nil return nil, nil
...@@ -38,7 +48,13 @@ func NewOCFBEncrypter(block Block, randData []byte) (Stream, []byte) { ...@@ -38,7 +48,13 @@ func NewOCFBEncrypter(block Block, randData []byte) (Stream, []byte) {
prefix[blockSize] = x.fre[0] ^ randData[blockSize-2] prefix[blockSize] = x.fre[0] ^ randData[blockSize-2]
prefix[blockSize+1] = x.fre[1] ^ randData[blockSize-1] prefix[blockSize+1] = x.fre[1] ^ randData[blockSize-1]
block.Encrypt(x.fre, prefix[2:]) if resync {
block.Encrypt(x.fre, prefix[2:])
} else {
x.fre[0] = prefix[blockSize]
x.fre[1] = prefix[blockSize+1]
x.outUsed = 2
}
return x, prefix return x, prefix
} }
...@@ -64,8 +80,10 @@ type ocfbDecrypter struct { ...@@ -64,8 +80,10 @@ type ocfbDecrypter struct {
// NewOCFBDecrypter returns a Stream which decrypts data with OpenPGP's cipher // NewOCFBDecrypter returns a Stream which decrypts data with OpenPGP's cipher
// feedback mode using the given Block. Prefix must be the first blockSize + 2 // feedback mode using the given Block. Prefix must be the first blockSize + 2
// bytes of the ciphertext, where blockSize is the Block's block size. If an // bytes of the ciphertext, where blockSize is the Block's block size. If an
// incorrect key is detected then nil is returned. // incorrect key is detected then nil is returned. Resync determines if the
func NewOCFBDecrypter(block Block, prefix []byte) Stream { // "resynchronization step" from RFC 4880, 13.9 step 7 is performed. Different
// parts of OpenPGP vary on this point.
func NewOCFBDecrypter(block Block, prefix []byte, resync OCFBResyncOption) Stream {
blockSize := block.BlockSize() blockSize := block.BlockSize()
if len(prefix) != blockSize+2 { if len(prefix) != blockSize+2 {
return nil return nil
...@@ -93,7 +111,13 @@ func NewOCFBDecrypter(block Block, prefix []byte) Stream { ...@@ -93,7 +111,13 @@ func NewOCFBDecrypter(block Block, prefix []byte) Stream {
return nil return nil
} }
block.Encrypt(x.fre, prefix[2:]) if resync {
block.Encrypt(x.fre, prefix[2:])
} else {
x.fre[0] = prefix[blockSize]
x.fre[1] = prefix[blockSize+1]
x.outUsed = 2
}
return x return x
} }
......
...@@ -11,29 +11,34 @@ import ( ...@@ -11,29 +11,34 @@ import (
"testing" "testing"
) )
func TestOCFB(t *testing.T) { func testOCFB(t *testing.T, resync OCFBResyncOption) {
block, err := aes.NewCipher(commonKey128) block, err := aes.NewCipher(commonKey128)
if err != nil { if err != nil {
t.Error(err) t.Error(err)
return return
} }
plaintext := []byte("this is the plaintext") plaintext := []byte("this is the plaintext, which is long enough to span several blocks.")
randData := make([]byte, block.BlockSize()) randData := make([]byte, block.BlockSize())
rand.Reader.Read(randData) rand.Reader.Read(randData)
ocfb, prefix := NewOCFBEncrypter(block, randData) ocfb, prefix := NewOCFBEncrypter(block, randData, resync)
ciphertext := make([]byte, len(plaintext)) ciphertext := make([]byte, len(plaintext))
ocfb.XORKeyStream(ciphertext, plaintext) ocfb.XORKeyStream(ciphertext, plaintext)
ocfbdec := NewOCFBDecrypter(block, prefix) ocfbdec := NewOCFBDecrypter(block, prefix, resync)
if ocfbdec == nil { if ocfbdec == nil {
t.Error("NewOCFBDecrypter failed") t.Errorf("NewOCFBDecrypter failed (resync: %t)", resync)
return return
} }
plaintextCopy := make([]byte, len(plaintext)) plaintextCopy := make([]byte, len(plaintext))
ocfbdec.XORKeyStream(plaintextCopy, ciphertext) ocfbdec.XORKeyStream(plaintextCopy, ciphertext)
if !bytes.Equal(plaintextCopy, plaintext) { if !bytes.Equal(plaintextCopy, plaintext) {
t.Errorf("got: %x, want: %x", plaintextCopy, plaintext) t.Errorf("got: %x, want: %x (resync: %t)", plaintextCopy, plaintext, resync)
} }
} }
func TestOCFB(t *testing.T) {
testOCFB(t, OCFBNoResync)
testOCFB(t, OCFBResync)
}
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// The crypto package collects common cryptographic constants.
package crypto
import (
"hash"
)
// Hash identifies a cryptographic hash function that is implemented in another
// package.
type Hash uint
const (
MD4 Hash = 1 + iota // in package crypto/md4
MD5 // in package crypto/md5
SHA1 // in package crypto/sha1
SHA224 // in package crypto/sha256
SHA256 // in package crypto/sha256
SHA384 // in package crypto/sha512
SHA512 // in package crypto/sha512
MD5SHA1 // no implementation; MD5+SHA1 used for TLS RSA
RIPEMD160 // in package crypto/ripemd160
maxHash
)
var digestSizes = []uint8{
MD4: 16,
MD5: 16,
SHA1: 20,
SHA224: 28,
SHA256: 32,
SHA384: 48,
SHA512: 64,
MD5SHA1: 36,
RIPEMD160: 20,
}
// Size returns the length, in bytes, of a digest resulting from the given hash
// function. It doesn't require that the hash function in question be linked
// into the program.
func (h Hash) Size() int {
if h > 0 && h < maxHash {
return int(digestSizes[h])
}
panic("crypto: Size of unknown hash function")
}
var hashes = make([]func() hash.Hash, maxHash)
// New returns a new hash.Hash calculating the given hash function. If the
// hash function is not linked into the binary, New returns nil.
func (h Hash) New() hash.Hash {
if h > 0 && h < maxHash {
f := hashes[h]
if f != nil {
return f()
}
}
return nil
}
// RegisterHash registers a function that returns a new instance of the given
// hash function. This is intended to be called from the init function in
// packages that implement hash functions.
func RegisterHash(h Hash, f func() hash.Hash) {
if h >= maxHash {
panic("crypto: RegisterHash of unknown hash function")
}
hashes[h] = f
}
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package dsa implements the Digital Signature Algorithm, as defined in FIPS 186-3
package dsa
import (
"big"
"io"
"os"
)
// Parameters represents the domain parameters for a key. These parameters can
// be shared across many keys. The bit length of Q must be a multiple of 8.
type Parameters struct {
P, Q, G *big.Int
}
// PublicKey represents a DSA public key.
type PublicKey struct {
Parameters
Y *big.Int
}
// PrivateKey represents a DSA private key.
type PrivateKey struct {
PublicKey
X *big.Int
}
type invalidPublicKeyError int
func (invalidPublicKeyError) String() string {
return "crypto/dsa: invalid public key"
}
// InvalidPublicKeyError results when a public key is not usable by this code.
// FIPS is quite strict about the format of DSA keys, but other code may be
// less so. Thus, when using keys which may have been generated by other code,
// this error must be handled.
var InvalidPublicKeyError = invalidPublicKeyError(0)
// ParameterSizes is a enumeration of the acceptable bit lengths of the primes
// in a set of DSA parameters. See FIPS 186-3, section 4.2.
type ParameterSizes int
const (
L1024N160 ParameterSizes = iota
L2048N224
L2048N256
L3072N256
)
// numMRTests is the number of Miller-Rabin primality tests that we perform. We
// pick the largest recommended number from table C.1 of FIPS 186-3.
const numMRTests = 64
// GenerateParameters puts a random, valid set of DSA parameters into params.
// This function takes many seconds, even on fast machines.
func GenerateParameters(params *Parameters, rand io.Reader, sizes ParameterSizes) (err os.Error) {
// This function doesn't follow FIPS 186-3 exactly in that it doesn't
// use a verification seed to generate the primes. The verification
// seed doesn't appear to be exported or used by other code and
// omitting it makes the code cleaner.
var L, N int
switch sizes {
case L1024N160:
L = 1024
N = 160
case L2048N224:
L = 2048
N = 224
case L2048N256:
L = 2048
N = 256
case L3072N256:
L = 3072
N = 256
default:
return os.ErrorString("crypto/dsa: invalid ParameterSizes")
}
qBytes := make([]byte, N/8)
pBytes := make([]byte, L/8)
q := new(big.Int)
p := new(big.Int)
rem := new(big.Int)
one := new(big.Int)
one.SetInt64(1)
GeneratePrimes:
for {
_, err = io.ReadFull(rand, qBytes)
if err != nil {
return
}
qBytes[len(qBytes)-1] |= 1
qBytes[0] |= 0x80
q.SetBytes(qBytes)
if !big.ProbablyPrime(q, numMRTests) {
continue
}
for i := 0; i < 4*L; i++ {
_, err = io.ReadFull(rand, pBytes)
if err != nil {
return
}
pBytes[len(pBytes)-1] |= 1
pBytes[0] |= 0x80
p.SetBytes(pBytes)
rem.Mod(p, q)
rem.Sub(rem, one)
p.Sub(p, rem)
if p.BitLen() < L {
continue
}
if !big.ProbablyPrime(p, numMRTests) {
continue
}
params.P = p
params.Q = q
break GeneratePrimes
}
}
h := new(big.Int)
h.SetInt64(2)
g := new(big.Int)
pm1 := new(big.Int).Sub(p, one)
e := new(big.Int).Div(pm1, q)
for {
g.Exp(h, e, p)
if g.Cmp(one) == 0 {
h.Add(h, one)
continue
}
params.G = g
return
}
panic("unreachable")
}
// GenerateKey generates a public&private key pair. The Parameters of the
// PrivateKey must already be valid (see GenerateParameters).
func GenerateKey(priv *PrivateKey, rand io.Reader) os.Error {
if priv.P == nil || priv.Q == nil || priv.G == nil {
return os.ErrorString("crypto/dsa: parameters not set up before generating key")
}
x := new(big.Int)
xBytes := make([]byte, priv.Q.BitLen()/8)
for {
_, err := io.ReadFull(rand, xBytes)
if err != nil {
return err
}
x.SetBytes(xBytes)
if x.Sign() != 0 && x.Cmp(priv.Q) < 0 {
break
}
}
priv.X = x
priv.Y = new(big.Int)
priv.Y.Exp(priv.G, x, priv.P)
return nil
}
// Sign signs an arbitrary length hash (which should be the result of hashing a
// larger message) using the private key, priv. It returns the signature as a
// pair of integers. The security of the private key depends on the entropy of
// rand.
func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err os.Error) {
// FIPS 186-3, section 4.6
n := priv.Q.BitLen()
if n&7 != 0 {
err = InvalidPublicKeyError
return
}
n >>= 3
for {
k := new(big.Int)
buf := make([]byte, n)
for {
_, err = io.ReadFull(rand, buf)
if err != nil {
return
}
k.SetBytes(buf)
if k.Sign() > 0 && k.Cmp(priv.Q) < 0 {
break
}
}
kInv := new(big.Int).ModInverse(k, priv.Q)
r = new(big.Int).Exp(priv.G, k, priv.P)
r.Mod(r, priv.Q)
if r.Sign() == 0 {
continue
}
if n > len(hash) {
n = len(hash)
}
z := k.SetBytes(hash[:n])
s = new(big.Int).Mul(priv.X, r)
s.Add(s, z)
s.Mod(s, priv.Q)
s.Mul(s, kInv)
s.Mod(s, priv.Q)
if s.Sign() != 0 {
break
}
}
return
}
// Verify verifies the signature in r, s of hash using the public key, pub. It
// returns true iff the signature is valid.
func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool {
// FIPS 186-3, section 4.7
if r.Sign() < 1 || r.Cmp(pub.Q) >= 0 {
return false
}
if s.Sign() < 1 || s.Cmp(pub.Q) >= 0 {
return false
}
w := new(big.Int).ModInverse(s, pub.Q)
n := pub.Q.BitLen()
if n&7 != 0 {
return false
}
n >>= 3
if n > len(hash) {
n = len(hash)
}
z := new(big.Int).SetBytes(hash[:n])
u1 := new(big.Int).Mul(z, w)
u1.Mod(u1, pub.Q)
u2 := w.Mul(r, w)
u2.Mod(u2, pub.Q)
v := u1.Exp(pub.G, u1, pub.P)
u2.Exp(pub.Y, u2, pub.P)
v.Mul(v, u2)
v.Mod(v, pub.P)
v.Mod(v, pub.Q)
return v.Cmp(r) == 0
}
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package dsa
import (
"big"
"crypto/rand"
"testing"
)
func testSignAndVerify(t *testing.T, i int, priv *PrivateKey) {
hashed := []byte("testing")
r, s, err := Sign(rand.Reader, priv, hashed)
if err != nil {
t.Errorf("%d: error signing: %s", i, err)
return
}
if !Verify(&priv.PublicKey, hashed, r, s) {
t.Errorf("%d: Verify failed", i)
}
}
func testParameterGeneration(t *testing.T, sizes ParameterSizes, L, N int) {
var priv PrivateKey
params := &priv.Parameters
err := GenerateParameters(params, rand.Reader, sizes)
if err != nil {
t.Errorf("%d: %s", int(sizes), err)
return
}
if params.P.BitLen() != L {
t.Errorf("%d: params.BitLen got:%d want:%d", int(sizes), params.P.BitLen(), L)
}
if params.Q.BitLen() != N {
t.Errorf("%d: q.BitLen got:%d want:%d", int(sizes), params.Q.BitLen(), L)
}
one := new(big.Int)
one.SetInt64(1)
pm1 := new(big.Int).Sub(params.P, one)
quo, rem := new(big.Int).DivMod(pm1, params.Q, new(big.Int))
if rem.Sign() != 0 {
t.Errorf("%d: p-1 mod q != 0", int(sizes))
}
x := new(big.Int).Exp(params.G, quo, params.P)
if x.Cmp(one) == 0 {
t.Errorf("%d: invalid generator", int(sizes))
}
err = GenerateKey(&priv, rand.Reader)
if err != nil {
t.Errorf("error generating key: %s", err)
return
}
testSignAndVerify(t, int(sizes), &priv)
}
func TestParameterGeneration(t *testing.T) {
// This test is too slow to run all the time.
return
testParameterGeneration(t, L1024N160, 1024, 160)
testParameterGeneration(t, L2048N224, 2048, 224)
testParameterGeneration(t, L2048N256, 2048, 256)
testParameterGeneration(t, L3072N256, 3072, 256)
}
func TestSignAndVerify(t *testing.T) {
var priv PrivateKey
priv.P, _ = new(big.Int).SetString("A9B5B793FB4785793D246BAE77E8FF63CA52F442DA763C440259919FE1BC1D6065A9350637A04F75A2F039401D49F08E066C4D275A5A65DA5684BC563C14289D7AB8A67163BFBF79D85972619AD2CFF55AB0EE77A9002B0EF96293BDD0F42685EBB2C66C327079F6C98000FBCB79AACDE1BC6F9D5C7B1A97E3D9D54ED7951FEF", 16)
priv.Q, _ = new(big.Int).SetString("E1D3391245933D68A0714ED34BBCB7A1F422B9C1", 16)
priv.G, _ = new(big.Int).SetString("634364FC25248933D01D1993ECABD0657CC0CB2CEED7ED2E3E8AECDFCDC4A25C3B15E9E3B163ACA2984B5539181F3EFF1A5E8903D71D5B95DA4F27202B77D2C44B430BB53741A8D59A8F86887525C9F2A6A5980A195EAA7F2FF910064301DEF89D3AA213E1FAC7768D89365318E370AF54A112EFBA9246D9158386BA1B4EEFDA", 16)
priv.Y, _ = new(big.Int).SetString("32969E5780CFE1C849A1C276D7AEB4F38A23B591739AA2FE197349AEEBD31366AEE5EB7E6C6DDB7C57D02432B30DB5AA66D9884299FAA72568944E4EEDC92EA3FBC6F39F53412FBCC563208F7C15B737AC8910DBC2D9C9B8C001E72FDC40EB694AB1F06A5A2DBD18D9E36C66F31F566742F11EC0A52E9F7B89355C02FB5D32D2", 16)
priv.X, _ = new(big.Int).SetString("5078D4D29795CBE76D3AACFE48C9AF0BCDBEE91A", 16)
testSignAndVerify(t, 0, &priv)
}
...@@ -6,10 +6,15 @@ ...@@ -6,10 +6,15 @@
package md4 package md4
import ( import (
"crypto"
"hash" "hash"
"os" "os"
) )
func init() {
crypto.RegisterHash(crypto.MD4, New)
}
// The size of an MD4 checksum in bytes. // The size of an MD4 checksum in bytes.
const Size = 16 const Size = 16
......
...@@ -6,10 +6,15 @@ ...@@ -6,10 +6,15 @@
package md5 package md5
import ( import (
"crypto"
"hash" "hash"
"os" "os"
) )
func init() {
crypto.RegisterHash(crypto.MD5, New)
}
// The size of an MD5 checksum in bytes. // The size of an MD5 checksum in bytes.
const Size = 16 const Size = 16
......
...@@ -9,8 +9,9 @@ package ocsp ...@@ -9,8 +9,9 @@ package ocsp
import ( import (
"asn1" "asn1"
"crypto"
"crypto/rsa" "crypto/rsa"
"crypto/sha1" _ "crypto/sha1"
"crypto/x509" "crypto/x509"
"os" "os"
"time" "time"
...@@ -168,8 +169,8 @@ func ParseResponse(bytes []byte) (*Response, os.Error) { ...@@ -168,8 +169,8 @@ func ParseResponse(bytes []byte) (*Response, os.Error) {
return nil, x509.UnsupportedAlgorithmError{} return nil, x509.UnsupportedAlgorithmError{}
} }
h := sha1.New() hashType := crypto.SHA1
hashType := rsa.HashSHA1 h := hashType.New()
pub := ret.Certificate.PublicKey.(*rsa.PublicKey) pub := ret.Certificate.PublicKey.(*rsa.PublicKey)
h.Write(basicResp.TBSResponseData.Raw) h.Write(basicResp.TBSResponseData.Raw)
......
...@@ -112,7 +112,7 @@ func (l *lineReader) Read(p []byte) (n int, err os.Error) { ...@@ -112,7 +112,7 @@ func (l *lineReader) Read(p []byte) (n int, err os.Error) {
return 0, os.EOF return 0, os.EOF
} }
if len(line) != 64 { if len(line) > 64 {
return 0, ArmorCorrupt return 0, ArmorCorrupt
} }
......
...@@ -34,7 +34,7 @@ func TestDecodeEncode(t *testing.T) { ...@@ -34,7 +34,7 @@ func TestDecodeEncode(t *testing.T) {
t.Error(err) t.Error(err)
} }
if adler32.Checksum(contents) != 0x789d7f00 { if adler32.Checksum(contents) != 0x27b144be {
t.Errorf("contents: got: %x", contents) t.Errorf("contents: got: %x", contents)
} }
...@@ -73,13 +73,11 @@ func TestLongHeader(t *testing.T) { ...@@ -73,13 +73,11 @@ func TestLongHeader(t *testing.T) {
const armorExample1 = `-----BEGIN PGP SIGNATURE----- const armorExample1 = `-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux) Version: GnuPG v1.4.10 (GNU/Linux)
iQEcBAABAgAGBQJMtFESAAoJEKsQXJGvOPsVj40H/1WW6jaMXv4BW+1ueDSMDwM8 iJwEAAECAAYFAk1Fv/0ACgkQo01+GMIMMbsYTwQAiAw+QAaNfY6WBdplZ/uMAccm
kx1fLOXbVM5/Kn5LStZNt1jWWnpxdz7eq3uiqeCQjmqUoRde3YbB2EMnnwRbAhpp 4g+81QPmTSGHnetSb6WBiY13kVzK4HQiZH8JSkmmroMLuGeJwsRTEL4wbjRyUKEt
cacnAvy9ZQ78OTxUdNW1mhX5bS6q1MTEJnl+DcyigD70HG/yNNQD7sOPMdYQw0TA p1xwUZDECs234F1xiG5enc5SGlRtP7foLBz9lOsjx+LEcA4sTl5/2eZR9zyFZqWW
byQBwmLwmTsuZsrYqB68QyLHI+DUugn+kX6Hd2WDB62DKa2suoIUIHQQCd/ofwB3 TxRjs+fJCIFuo71xb1g=
WfCYInXQKKOSxu2YOg2Eb4kLNhSMc1i9uKUWAH+sdgJh7NBgdoE4MaNtBFkHXRvv =/teI
okWuf3+xA9ksp1npSY/mDvgHijmjvtpRDe6iUeqfCn8N9u9CBg8geANgaG8+QA4=
=wfQG
-----END PGP SIGNATURE-----` -----END PGP SIGNATURE-----`
const armorLongLine = `-----BEGIN PGP SIGNATURE----- const armorLongLine = `-----BEGIN PGP SIGNATURE-----
......
...@@ -116,6 +116,7 @@ func (e *encoding) Close() (err os.Error) { ...@@ -116,6 +116,7 @@ func (e *encoding) Close() (err os.Error) {
if err != nil { if err != nil {
return return
} }
e.breaker.Close()
var checksumBytes [3]byte var checksumBytes [3]byte
checksumBytes[0] = byte(e.crc >> 16) checksumBytes[0] = byte(e.crc >> 16)
...@@ -144,11 +145,9 @@ func Encode(out io.Writer, blockType string, headers map[string]string) (w io.Wr ...@@ -144,11 +145,9 @@ func Encode(out io.Writer, blockType string, headers map[string]string) (w io.Wr
} }
} }
if len(headers) > 0 { _, err = out.Write(newline)
_, err := out.Write(newline) if err != nil {
if err != nil { return
return
}
} }
e := &encoding{ e := &encoding{
......
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package openpgp
import (
"hash"
"os"
)
// NewCanonicalTextHash reformats text written to it into the canonical
// form and then applies the hash h. See RFC 4880, section 5.2.1.
func NewCanonicalTextHash(h hash.Hash) hash.Hash {
return &canonicalTextHash{h, 0}
}
type canonicalTextHash struct {
h hash.Hash
s int
}
var newline = []byte{'\r', '\n'}
func (cth *canonicalTextHash) Write(buf []byte) (int, os.Error) {
start := 0
for i, c := range buf {
switch cth.s {
case 0:
if c == '\r' {
cth.s = 1
} else if c == '\n' {
cth.h.Write(buf[start:i])
cth.h.Write(newline)
start = i + 1
}
case 1:
cth.s = 0
}
}
cth.h.Write(buf[start:])
return len(buf), nil
}
func (cth *canonicalTextHash) Sum() []byte {
return cth.h.Sum()
}
func (cth *canonicalTextHash) Reset() {
cth.h.Reset()
cth.s = 0
}
func (cth *canonicalTextHash) Size() int {
return cth.h.Size()
}
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package openpgp
import (
"bytes"
"os"
"testing"
)
type recordingHash struct {
buf *bytes.Buffer
}
func (r recordingHash) Write(b []byte) (n int, err os.Error) {
return r.buf.Write(b)
}
func (r recordingHash) Sum() []byte {
return r.buf.Bytes()
}
func (r recordingHash) Reset() {
panic("shouldn't be called")
}
func (r recordingHash) Size() int {
panic("shouldn't be called")
}
func testCanonicalText(t *testing.T, input, expected string) {
r := recordingHash{bytes.NewBuffer(nil)}
c := NewCanonicalTextHash(r)
c.Write([]byte(input))
result := c.Sum()
if expected != string(result) {
t.Errorf("input: %x got: %x want: %x", input, result, expected)
}
}
func TestCanonicalText(t *testing.T) {
testCanonicalText(t, "foo\n", "foo\r\n")
testCanonicalText(t, "foo", "foo")
testCanonicalText(t, "foo\r\n", "foo\r\n")
testCanonicalText(t, "foo\r\nbar", "foo\r\nbar")
testCanonicalText(t, "foo\r\nbar\n\n", "foo\r\nbar\r\n\r\n")
}
...@@ -5,6 +5,10 @@ ...@@ -5,6 +5,10 @@
// This package contains common error types for the OpenPGP packages. // This package contains common error types for the OpenPGP packages.
package error package error
import (
"strconv"
)
// A StructuralError is returned when OpenPGP data is found to be syntactically // A StructuralError is returned when OpenPGP data is found to be syntactically
// invalid. // invalid.
type StructuralError string type StructuralError string
...@@ -44,3 +48,17 @@ func (ki keyIncorrect) String() string { ...@@ -44,3 +48,17 @@ func (ki keyIncorrect) String() string {
} }
var KeyIncorrectError = keyIncorrect(0) var KeyIncorrectError = keyIncorrect(0)
type unknownIssuer int
func (unknownIssuer) String() string {
return "signature make by unknown entity"
}
var UnknownIssuerError = unknownIssuer(0)
type UnknownPacketTypeError uint8
func (upte UnknownPacketTypeError) String() string {
return "unknown OpenPGP packet type: " + strconv.Itoa(int(upte))
}
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package openpgp
import (
"crypto/openpgp/error"
"crypto/openpgp/packet"
"io"
"os"
)
// PublicKeyType is the armor type for a PGP public key.
var PublicKeyType = "PGP PUBLIC KEY BLOCK"
// An Entity represents the components of an OpenPGP key: a primary public key
// (which must be a signing key), one or more identities claimed by that key,
// and zero or more subkeys, which may be encryption keys.
type Entity struct {
PrimaryKey *packet.PublicKey
PrivateKey *packet.PrivateKey
Identities map[string]*Identity // indexed by Identity.Name
Subkeys []Subkey
}
// An Identity represents an identity claimed by an Entity and zero or more
// assertions by other entities about that claim.
type Identity struct {
Name string // by convention, has the form "Full Name (comment) <email@example.com>"
UserId *packet.UserId
SelfSignature *packet.Signature
Signatures []*packet.Signature
}
// A Subkey is an additional public key in an Entity. Subkeys can be used for
// encryption.
type Subkey struct {
PublicKey *packet.PublicKey
PrivateKey *packet.PrivateKey
Sig *packet.Signature
}
// A Key identifies a specific public key in an Entity. This is either the
// Entity's primary key or a subkey.
type Key struct {
Entity *Entity
PublicKey *packet.PublicKey
PrivateKey *packet.PrivateKey
SelfSignature *packet.Signature
}
// A KeyRing provides access to public and private keys.
type KeyRing interface {
// KeysById returns the set of keys that have the given key id.
KeysById(id uint64) []Key
// DecryptionKeys returns all private keys that are valid for
// decryption.
DecryptionKeys() []Key
}
// An EntityList contains one or more Entities.
type EntityList []*Entity
// KeysById returns the set of keys that have the given key id.
func (el EntityList) KeysById(id uint64) (keys []Key) {
for _, e := range el {
if e.PrimaryKey.KeyId == id {
var selfSig *packet.Signature
for _, ident := range e.Identities {
if selfSig == nil {
selfSig = ident.SelfSignature
} else if ident.SelfSignature.IsPrimaryId != nil && *ident.SelfSignature.IsPrimaryId {
selfSig = ident.SelfSignature
break
}
}
keys = append(keys, Key{e, e.PrimaryKey, e.PrivateKey, selfSig})
}
for _, subKey := range e.Subkeys {
if subKey.PublicKey.KeyId == id {
keys = append(keys, Key{e, subKey.PublicKey, subKey.PrivateKey, subKey.Sig})
}
}
}
return
}
// DecryptionKeys returns all private keys that are valid for decryption.
func (el EntityList) DecryptionKeys() (keys []Key) {
for _, e := range el {
for _, subKey := range e.Subkeys {
if subKey.PrivateKey != nil && (!subKey.Sig.FlagsValid || subKey.Sig.FlagEncryptStorage || subKey.Sig.FlagEncryptCommunications) {
keys = append(keys, Key{e, subKey.PublicKey, subKey.PrivateKey, subKey.Sig})
}
}
}
return
}
// ReadArmoredKeyRing reads one or more public/private keys from an armor keyring file.
func ReadArmoredKeyRing(r io.Reader) (EntityList, os.Error) {
body, err := readArmored(r, PublicKeyType)
if err != nil {
return nil, err
}
return ReadKeyRing(body)
}
// ReadKeyRing reads one or more public/private keys, ignoring unsupported keys.
func ReadKeyRing(r io.Reader) (el EntityList, err os.Error) {
packets := packet.NewReader(r)
for {
var e *Entity
e, err = readEntity(packets)
if err != nil {
if _, ok := err.(error.UnsupportedError); ok {
err = readToNextPublicKey(packets)
}
if err == os.EOF {
err = nil
return
}
if err != nil {
el = nil
return
}
} else {
el = append(el, e)
}
}
return
}
// readToNextPublicKey reads packets until the start of the entity and leaves
// the first packet of the new entity in the Reader.
func readToNextPublicKey(packets *packet.Reader) (err os.Error) {
var p packet.Packet
for {
p, err = packets.Next()
if err == os.EOF {
return
} else if err != nil {
if _, ok := err.(error.UnsupportedError); ok {
err = nil
continue
}
return
}
if pk, ok := p.(*packet.PublicKey); ok && !pk.IsSubkey {
packets.Unread(p)
return
}
}
panic("unreachable")
}
// readEntity reads an entity (public key, identities, subkeys etc) from the
// given Reader.
func readEntity(packets *packet.Reader) (*Entity, os.Error) {
e := new(Entity)
e.Identities = make(map[string]*Identity)
p, err := packets.Next()
if err != nil {
return nil, err
}
var ok bool
if e.PrimaryKey, ok = p.(*packet.PublicKey); !ok {
if e.PrivateKey, ok = p.(*packet.PrivateKey); !ok {
packets.Unread(p)
return nil, error.StructuralError("first packet was not a public/private key")
} else {
e.PrimaryKey = &e.PrivateKey.PublicKey
}
}
var current *Identity
EachPacket:
for {
p, err := packets.Next()
if err == os.EOF {
break
} else if err != nil {
return nil, err
}
switch pkt := p.(type) {
case *packet.UserId:
current = new(Identity)
current.Name = pkt.Id
current.UserId = pkt
e.Identities[pkt.Id] = current
p, err = packets.Next()
if err == os.EOF {
err = io.ErrUnexpectedEOF
}
if err != nil {
if _, ok := err.(error.UnsupportedError); ok {
return nil, err
}
return nil, error.StructuralError("identity self-signature invalid: " + err.String())
}
current.SelfSignature, ok = p.(*packet.Signature)
if !ok {
return nil, error.StructuralError("user ID packet not followed by self signature")
}
if current.SelfSignature.SigType != packet.SigTypePositiveCert {
return nil, error.StructuralError("user ID self-signature with wrong type")
}
if err = e.PrimaryKey.VerifyUserIdSignature(pkt.Id, current.SelfSignature); err != nil {
return nil, error.StructuralError("user ID self-signature invalid: " + err.String())
}
case *packet.Signature:
if current == nil {
return nil, error.StructuralError("signature packet found before user id packet")
}
current.Signatures = append(current.Signatures, pkt)
case *packet.PrivateKey:
if pkt.IsSubkey == false {
packets.Unread(p)
break EachPacket
}
err = addSubkey(e, packets, &pkt.PublicKey, pkt)
if err != nil {
return nil, err
}
case *packet.PublicKey:
if pkt.IsSubkey == false {
packets.Unread(p)
break EachPacket
}
err = addSubkey(e, packets, pkt, nil)
if err != nil {
return nil, err
}
default:
// we ignore unknown packets
}
}
if len(e.Identities) == 0 {
return nil, error.StructuralError("entity without any identities")
}
return e, nil
}
func addSubkey(e *Entity, packets *packet.Reader, pub *packet.PublicKey, priv *packet.PrivateKey) os.Error {
var subKey Subkey
subKey.PublicKey = pub
subKey.PrivateKey = priv
p, err := packets.Next()
if err == os.EOF {
return io.ErrUnexpectedEOF
}
if err != nil {
return error.StructuralError("subkey signature invalid: " + err.String())
}
var ok bool
subKey.Sig, ok = p.(*packet.Signature)
if !ok {
return error.StructuralError("subkey packet not followed by signature")
}
if subKey.Sig.SigType != packet.SigTypeSubkeyBinding {
return error.StructuralError("subkey signature with wrong type")
}
err = e.PrimaryKey.VerifyKeySignature(subKey.PublicKey, subKey.Sig)
if err != nil {
return error.StructuralError("subkey signature invalid: " + err.String())
}
e.Subkeys = append(e.Subkeys, subKey)
return nil
}
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package packet
import (
"compress/flate"
"compress/zlib"
"crypto/openpgp/error"
"io"
"os"
"strconv"
)
// Compressed represents a compressed OpenPGP packet. The decompressed contents
// will contain more OpenPGP packets. See RFC 4880, section 5.6.
type Compressed struct {
Body io.Reader
}
func (c *Compressed) parse(r io.Reader) os.Error {
var buf [1]byte
_, err := readFull(r, buf[:])
if err != nil {
return err
}
switch buf[0] {
case 1:
c.Body = flate.NewReader(r)
case 2:
c.Body, err = zlib.NewReader(r)
default:
err = error.UnsupportedError("unknown compression algorithm: " + strconv.Itoa(int(buf[0])))
}
return err
}
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package packet
import (
"bytes"
"encoding/hex"
"os"
"io/ioutil"
"testing"
)
func TestCompressed(t *testing.T) {
packet, err := Read(readerFromHex(compressedHex))
if err != nil {
t.Errorf("failed to read Compressed: %s", err)
return
}
c, ok := packet.(*Compressed)
if !ok {
t.Error("didn't find Compressed packet")
return
}
contents, err := ioutil.ReadAll(c.Body)
if err != nil && err != os.EOF {
t.Error(err)
return
}
expected, _ := hex.DecodeString(compressedExpectedHex)
if !bytes.Equal(expected, contents) {
t.Errorf("got:%x want:%x", contents, expected)
}
}
const compressedHex = "a3013b2d90c4e02b72e25f727e5e496a5e49b11e1700"
const compressedExpectedHex = "cb1062004d14c8fe636f6e74656e74732e0a"
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package packet
import (
"crypto/openpgp/error"
"crypto/rand"
"crypto/rsa"
"encoding/binary"
"io"
"os"
"strconv"
)
// EncryptedKey represents a public-key encrypted session key. See RFC 4880,
// section 5.1.
type EncryptedKey struct {
KeyId uint64
Algo PublicKeyAlgorithm
Encrypted []byte
CipherFunc CipherFunction // only valid after a successful Decrypt
Key []byte // only valid after a successful Decrypt
}
func (e *EncryptedKey) parse(r io.Reader) (err os.Error) {
var buf [10]byte
_, err = readFull(r, buf[:])
if err != nil {
return
}
if buf[0] != 3 {
return error.UnsupportedError("unknown EncryptedKey version " + strconv.Itoa(int(buf[0])))
}
e.KeyId = binary.BigEndian.Uint64(buf[1:9])
e.Algo = PublicKeyAlgorithm(buf[9])
if e.Algo == PubKeyAlgoRSA || e.Algo == PubKeyAlgoRSAEncryptOnly {
e.Encrypted, _, err = readMPI(r)
}
_, err = consumeAll(r)
return
}
// DecryptRSA decrypts an RSA encrypted session key with the given private key.
func (e *EncryptedKey) DecryptRSA(priv *rsa.PrivateKey) (err os.Error) {
if e.Algo != PubKeyAlgoRSA && e.Algo != PubKeyAlgoRSAEncryptOnly {
return error.InvalidArgumentError("EncryptedKey not RSA encrypted")
}
b, err := rsa.DecryptPKCS1v15(rand.Reader, priv, e.Encrypted)
if err != nil {
return
}
e.CipherFunc = CipherFunction(b[0])
e.Key = b[1 : len(b)-2]
expectedChecksum := uint16(b[len(b)-2])<<8 | uint16(b[len(b)-1])
var checksum uint16
for _, v := range e.Key {
checksum += uint16(v)
}
if checksum != expectedChecksum {
return error.StructuralError("EncryptedKey checksum incorrect")
}
return
}
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package packet
import (
"big"
"crypto/rsa"
"fmt"
"testing"
)
func bigFromBase10(s string) *big.Int {
b, ok := new(big.Int).SetString(s, 10)
if !ok {
panic("bigFromBase10 failed")
}
return b
}
func TestEncryptedKey(t *testing.T) {
p, err := Read(readerFromHex(encryptedKeyHex))
if err != nil {
t.Errorf("error from Read: %s", err)
return
}
ek, ok := p.(*EncryptedKey)
if !ok {
t.Errorf("didn't parse an EncryptedKey, got %#v", p)
return
}
if ek.KeyId != 0x2a67d68660df41c7 || ek.Algo != PubKeyAlgoRSA {
t.Errorf("unexpected EncryptedKey contents: %#v", ek)
return
}
pub := rsa.PublicKey{
E: 65537,
N: bigFromBase10("115804063926007623305902631768113868327816898845124614648849934718568541074358183759250136204762053879858102352159854352727097033322663029387610959884180306668628526686121021235757016368038585212410610742029286439607686208110250133174279811431933746643015923132833417396844716207301518956640020862630546868823"),
}
priv := &rsa.PrivateKey{
PublicKey: pub,
D: bigFromBase10("32355588668219869544751561565313228297765464314098552250409557267371233892496951383426602439009993875125222579159850054973310859166139474359774543943714622292329487391199285040721944491839695981199720170366763547754915493640685849961780092241140181198779299712578774460837139360803883139311171713302987058393"),
}
err = ek.DecryptRSA(priv)
if err != nil {
t.Errorf("error from DecryptRSA: %s", err)
return
}
if ek.CipherFunc != CipherAES256 {
t.Errorf("unexpected EncryptedKey contents: %#v", ek)
return
}
keyHex := fmt.Sprintf("%x", ek.Key)
if keyHex != expectedKeyHex {
t.Errorf("bad key, got %s want %x", keyHex, expectedKeyHex)
}
}
const encryptedKeyHex = "c18c032a67d68660df41c70104005789d0de26b6a50c985a02a13131ca829c413a35d0e6fa8d6842599252162808ac7439c72151c8c6183e76923fe3299301414d0c25a2f06a2257db3839e7df0ec964773f6e4c4ac7ff3b48c444237166dd46ba8ff443a5410dc670cb486672fdbe7c9dfafb75b4fea83af3a204fe2a7dfa86bd20122b4f3d2646cbeecb8f7be8"
const expectedKeyHex = "d930363f7e0308c333b9618617ea728963d8df993665ae7be1092d4926fd864b"
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package packet
import (
"encoding/binary"
"io"
"os"
)
// LiteralData represents an encrypted file. See RFC 4880, section 5.9.
type LiteralData struct {
IsBinary bool
FileName string
Time uint32 // Unix epoch time. Either creation time or modification time. 0 means undefined.
Body io.Reader
}
// ForEyesOnly returns whether the contents of the LiteralData have been marked
// as especially sensitive.
func (l *LiteralData) ForEyesOnly() bool {
return l.FileName == "_CONSOLE"
}
func (l *LiteralData) parse(r io.Reader) (err os.Error) {
var buf [256]byte
_, err = readFull(r, buf[:2])
if err != nil {
return
}
l.IsBinary = buf[0] == 'b'
fileNameLen := int(buf[1])
_, err = readFull(r, buf[:fileNameLen])
if err != nil {
return
}
l.FileName = string(buf[:fileNameLen])
_, err = readFull(r, buf[:4])
if err != nil {
return
}
l.Time = binary.BigEndian.Uint32(buf[:4])
l.Body = r
return
}
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package packet
import (
"crypto"
"crypto/openpgp/error"
"crypto/openpgp/s2k"
"encoding/binary"
"io"
"os"
"strconv"
)
// OnePassSignature represents a one-pass signature packet. See RFC 4880,
// section 5.4.
type OnePassSignature struct {
SigType SignatureType
Hash crypto.Hash
PubKeyAlgo PublicKeyAlgorithm
KeyId uint64
IsLast bool
}
func (ops *OnePassSignature) parse(r io.Reader) (err os.Error) {
var buf [13]byte
_, err = readFull(r, buf[:])
if err != nil {
return
}
if buf[0] != 3 {
err = error.UnsupportedError("one-pass-signature packet version " + strconv.Itoa(int(buf[0])))
}
var ok bool
ops.Hash, ok = s2k.HashIdToHash(buf[2])
if !ok {
return error.UnsupportedError("hash function: " + strconv.Itoa(int(buf[2])))
}
ops.SigType = SignatureType(buf[1])
ops.PubKeyAlgo = PublicKeyAlgorithm(buf[3])
ops.KeyId = binary.BigEndian.Uint64(buf[4:12])
ops.IsLast = buf[12] != 0
return
}
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// This package implements parsing and serialisation of OpenPGP packets, as
// specified in RFC 4880.
package packet
import (
"crypto/aes"
"crypto/cast5"
"crypto/cipher"
"crypto/openpgp/error"
"io"
"os"
)
// readFull is the same as io.ReadFull except that reading zero bytes returns
// ErrUnexpectedEOF rather than EOF.
func readFull(r io.Reader, buf []byte) (n int, err os.Error) {
n, err = io.ReadFull(r, buf)
if err == os.EOF {
err = io.ErrUnexpectedEOF
}
return
}
// readLength reads an OpenPGP length from r. See RFC 4880, section 4.2.2.
func readLength(r io.Reader) (length int64, isPartial bool, err os.Error) {
var buf [4]byte
_, err = readFull(r, buf[:1])
if err != nil {
return
}
switch {
case buf[0] < 192:
length = int64(buf[0])
case buf[0] < 224:
length = int64(buf[0]-192) << 8
_, err = readFull(r, buf[0:1])
if err != nil {
return
}
length += int64(buf[0]) + 192
case buf[0] < 255:
length = int64(1) << (buf[0] & 0x1f)
isPartial = true
default:
_, err = readFull(r, buf[0:4])
if err != nil {
return
}
length = int64(buf[0])<<24 |
int64(buf[1])<<16 |
int64(buf[2])<<8 |
int64(buf[3])
}
return
}
// partialLengthReader wraps an io.Reader and handles OpenPGP partial lengths.
// The continuation lengths are parsed and removed from the stream and EOF is
// returned at the end of the packet. See RFC 4880, section 4.2.2.4.
type partialLengthReader struct {
r io.Reader
remaining int64
isPartial bool
}
func (r *partialLengthReader) Read(p []byte) (n int, err os.Error) {
for r.remaining == 0 {
if !r.isPartial {
return 0, os.EOF
}
r.remaining, r.isPartial, err = readLength(r.r)
if err != nil {
return 0, err
}
}
toRead := int64(len(p))
if toRead > r.remaining {
toRead = r.remaining
}
n, err = r.r.Read(p[:int(toRead)])
r.remaining -= int64(n)
if n < int(toRead) && err == os.EOF {
err = io.ErrUnexpectedEOF
}
return
}
// A spanReader is an io.LimitReader, but it returns ErrUnexpectedEOF if the
// underlying Reader returns EOF before the limit has been reached.
type spanReader struct {
r io.Reader
n int64
}
func (l *spanReader) Read(p []byte) (n int, err os.Error) {
if l.n <= 0 {
return 0, os.EOF
}
if int64(len(p)) > l.n {
p = p[0:l.n]
}
n, err = l.r.Read(p)
l.n -= int64(n)
if l.n > 0 && err == os.EOF {
err = io.ErrUnexpectedEOF
}
return
}
// readHeader parses a packet header and returns an io.Reader which will return
// the contents of the packet. See RFC 4880, section 4.2.
func readHeader(r io.Reader) (tag packetType, length int64, contents io.Reader, err os.Error) {
var buf [4]byte
_, err = io.ReadFull(r, buf[:1])
if err != nil {
return
}
if buf[0]&0x80 == 0 {
err = error.StructuralError("tag byte does not have MSB set")
return
}
if buf[0]&0x40 == 0 {
// Old format packet
tag = packetType((buf[0] & 0x3f) >> 2)
lengthType := buf[0] & 3
if lengthType == 3 {
length = -1
contents = r
return
}
lengthBytes := 1 << lengthType
_, err = readFull(r, buf[0:lengthBytes])
if err != nil {
return
}
for i := 0; i < lengthBytes; i++ {
length <<= 8
length |= int64(buf[i])
}
contents = &spanReader{r, length}
return
}
// New format packet
tag = packetType(buf[0] & 0x3f)
length, isPartial, err := readLength(r)
if err != nil {
return
}
if isPartial {
contents = &partialLengthReader{
remaining: length,
isPartial: true,
r: r,
}
length = -1
} else {
contents = &spanReader{r, length}
}
return
}
// serialiseHeader writes an OpenPGP packet header to w. See RFC 4880, section
// 4.2.
func serialiseHeader(w io.Writer, ptype packetType, length int) (err os.Error) {
var buf [5]byte
var n int
buf[0] = 0x80 | 0x40 | byte(ptype)
if length < 192 {
buf[1] = byte(length)
n = 2
} else if length < 8384 {
length -= 192
buf[1] = byte(length >> 8)
buf[2] = byte(length)
n = 3
} else {
buf[0] = 255
buf[1] = byte(length >> 24)
buf[2] = byte(length >> 16)
buf[3] = byte(length >> 8)
buf[4] = byte(length)
n = 5
}
_, err = w.Write(buf[:n])
return
}
// Packet represents an OpenPGP packet. Users are expected to try casting
// instances of this interface to specific packet types.
type Packet interface {
parse(io.Reader) os.Error
}
// consumeAll reads from the given Reader until error, returning the number of
// bytes read.
func consumeAll(r io.Reader) (n int64, err os.Error) {
var m int
var buf [1024]byte
for {
m, err = r.Read(buf[:])
n += int64(m)
if err == os.EOF {
err = nil
return
}
if err != nil {
return
}
}
panic("unreachable")
}
// packetType represents the numeric ids of the different OpenPGP packet types. See
// http://www.iana.org/assignments/pgp-parameters/pgp-parameters.xhtml#pgp-parameters-2
type packetType uint8
const (
packetTypeEncryptedKey packetType = 1
packetTypeSignature packetType = 2
packetTypeSymmetricKeyEncrypted packetType = 3
packetTypeOnePassSignature packetType = 4
packetTypePrivateKey packetType = 5
packetTypePublicKey packetType = 6
packetTypePrivateSubkey packetType = 7
packetTypeCompressed packetType = 8
packetTypeSymmetricallyEncrypted packetType = 9
packetTypeLiteralData packetType = 11
packetTypeUserId packetType = 13
packetTypePublicSubkey packetType = 14
packetTypeSymmetricallyEncryptedMDC packetType = 18
)
// Read reads a single OpenPGP packet from the given io.Reader. If there is an
// error parsing a packet, the whole packet is consumed from the input.
func Read(r io.Reader) (p Packet, err os.Error) {
tag, _, contents, err := readHeader(r)
if err != nil {
return
}
switch tag {
case packetTypeEncryptedKey:
p = new(EncryptedKey)
case packetTypeSignature:
p = new(Signature)
case packetTypeSymmetricKeyEncrypted:
p = new(SymmetricKeyEncrypted)
case packetTypeOnePassSignature:
p = new(OnePassSignature)
case packetTypePrivateKey, packetTypePrivateSubkey:
pk := new(PrivateKey)
if tag == packetTypePrivateSubkey {
pk.IsSubkey = true
}
p = pk
case packetTypePublicKey, packetTypePublicSubkey:
pk := new(PublicKey)
if tag == packetTypePublicSubkey {
pk.IsSubkey = true
}
p = pk
case packetTypeCompressed:
p = new(Compressed)
case packetTypeSymmetricallyEncrypted:
p = new(SymmetricallyEncrypted)
case packetTypeLiteralData:
p = new(LiteralData)
case packetTypeUserId:
p = new(UserId)
case packetTypeSymmetricallyEncryptedMDC:
se := new(SymmetricallyEncrypted)
se.MDC = true
p = se
default:
err = error.UnknownPacketTypeError(tag)
}
if p != nil {
err = p.parse(contents)
}
if err != nil {
consumeAll(contents)
}
return
}
// SignatureType represents the different semantic meanings of an OpenPGP
// signature. See RFC 4880, section 5.2.1.
type SignatureType uint8
const (
SigTypeBinary SignatureType = 0
SigTypeText = 1
SigTypeGenericCert = 0x10
SigTypePersonaCert = 0x11
SigTypeCasualCert = 0x12
SigTypePositiveCert = 0x13
SigTypeSubkeyBinding = 0x18
)
// PublicKeyAlgorithm represents the different public key system specified for
// OpenPGP. See
// http://www.iana.org/assignments/pgp-parameters/pgp-parameters.xhtml#pgp-parameters-12
type PublicKeyAlgorithm uint8
const (
PubKeyAlgoRSA PublicKeyAlgorithm = 1
PubKeyAlgoRSAEncryptOnly PublicKeyAlgorithm = 2
PubKeyAlgoRSASignOnly PublicKeyAlgorithm = 3
PubKeyAlgoElgamal PublicKeyAlgorithm = 16
PubKeyAlgoDSA PublicKeyAlgorithm = 17
)
// CipherFunction represents the different block ciphers specified for OpenPGP. See
// http://www.iana.org/assignments/pgp-parameters/pgp-parameters.xhtml#pgp-parameters-13
type CipherFunction uint8
const (
CipherCAST5 = 3
CipherAES128 = 7
CipherAES192 = 8
CipherAES256 = 9
)
// keySize returns the key size, in bytes, of cipher.
func (cipher CipherFunction) keySize() int {
switch cipher {
case CipherCAST5:
return cast5.KeySize
case CipherAES128:
return 16
case CipherAES192:
return 24
case CipherAES256:
return 32
}
return 0
}
// blockSize returns the block size, in bytes, of cipher.
func (cipher CipherFunction) blockSize() int {
switch cipher {
case CipherCAST5:
return 8
case CipherAES128, CipherAES192, CipherAES256:
return 16
}
return 0
}
// new returns a fresh instance of the given cipher.
func (cipher CipherFunction) new(key []byte) (block cipher.Block) {
switch cipher {
case CipherCAST5:
block, _ = cast5.NewCipher(key)
case CipherAES128, CipherAES192, CipherAES256:
block, _ = aes.NewCipher(key)
}
return
}
// readMPI reads a big integer from r. The bit length returned is the bit
// length that was specified in r. This is preserved so that the integer can be
// reserialised exactly.
func readMPI(r io.Reader) (mpi []byte, bitLength uint16, err os.Error) {
var buf [2]byte
_, err = readFull(r, buf[0:])
if err != nil {
return
}
bitLength = uint16(buf[0])<<8 | uint16(buf[1])
numBytes := (int(bitLength) + 7) / 8
mpi = make([]byte, numBytes)
_, err = readFull(r, mpi)
return
}
// writeMPI serialises a big integer to r.
func writeMPI(w io.Writer, bitLength uint16, mpiBytes []byte) (err os.Error) {
_, err = w.Write([]byte{byte(bitLength >> 8), byte(bitLength)})
if err == nil {
_, err = w.Write(mpiBytes)
}
return
}
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package packet
import (
"bytes"
"crypto/openpgp/error"
"encoding/hex"
"fmt"
"io"
"io/ioutil"
"os"
"testing"
)
func TestReadFull(t *testing.T) {
var out [4]byte
b := bytes.NewBufferString("foo")
n, err := readFull(b, out[:3])
if n != 3 || err != nil {
t.Errorf("full read failed n:%d err:%s", n, err)
}
b = bytes.NewBufferString("foo")
n, err = readFull(b, out[:4])
if n != 3 || err != io.ErrUnexpectedEOF {
t.Errorf("partial read failed n:%d err:%s", n, err)
}
b = bytes.NewBuffer(nil)
n, err = readFull(b, out[:3])
if n != 0 || err != io.ErrUnexpectedEOF {
t.Errorf("empty read failed n:%d err:%s", n, err)
}
}
func readerFromHex(s string) io.Reader {
data, err := hex.DecodeString(s)
if err != nil {
panic("readerFromHex: bad input")
}
return bytes.NewBuffer(data)
}
var readLengthTests = []struct {
hexInput string
length int64
isPartial bool
err os.Error
}{
{"", 0, false, io.ErrUnexpectedEOF},
{"1f", 31, false, nil},
{"c0", 0, false, io.ErrUnexpectedEOF},
{"c101", 256 + 1 + 192, false, nil},
{"e0", 1, true, nil},
{"e1", 2, true, nil},
{"e2", 4, true, nil},
{"ff", 0, false, io.ErrUnexpectedEOF},
{"ff00", 0, false, io.ErrUnexpectedEOF},
{"ff0000", 0, false, io.ErrUnexpectedEOF},
{"ff000000", 0, false, io.ErrUnexpectedEOF},
{"ff00000000", 0, false, nil},
{"ff01020304", 16909060, false, nil},
}
func TestReadLength(t *testing.T) {
for i, test := range readLengthTests {
length, isPartial, err := readLength(readerFromHex(test.hexInput))
if test.err != nil {
if err != test.err {
t.Errorf("%d: expected different error got:%s want:%s", i, err, test.err)
}
continue
}
if err != nil {
t.Errorf("%d: unexpected error: %s", i, err)
continue
}
if length != test.length || isPartial != test.isPartial {
t.Errorf("%d: bad result got:(%d,%t) want:(%d,%t)", i, length, isPartial, test.length, test.isPartial)
}
}
}
var partialLengthReaderTests = []struct {
hexInput string
err os.Error
hexOutput string
}{
{"e0", io.ErrUnexpectedEOF, ""},
{"e001", io.ErrUnexpectedEOF, ""},
{"e0010102", nil, "0102"},
{"ff00000000", nil, ""},
{"e10102e1030400", nil, "01020304"},
{"e101", io.ErrUnexpectedEOF, ""},
}
func TestPartialLengthReader(t *testing.T) {
for i, test := range partialLengthReaderTests {
r := &partialLengthReader{readerFromHex(test.hexInput), 0, true}
out, err := ioutil.ReadAll(r)
if test.err != nil {
if err != test.err {
t.Errorf("%d: expected different error got:%s want:%s", i, err, test.err)
}
continue
}
if err != nil {
t.Errorf("%d: unexpected error: %s", i, err)
continue
}
got := fmt.Sprintf("%x", out)
if got != test.hexOutput {
t.Errorf("%d: got:%s want:%s", i, test.hexOutput, got)
}
}
}
var readHeaderTests = []struct {
hexInput string
structuralError bool
unexpectedEOF bool
tag int
length int64
hexOutput string
}{
{"", false, false, 0, 0, ""},
{"7f", true, false, 0, 0, ""},
// Old format headers
{"80", false, true, 0, 0, ""},
{"8001", false, true, 0, 1, ""},
{"800102", false, false, 0, 1, "02"},
{"81000102", false, false, 0, 1, "02"},
{"820000000102", false, false, 0, 1, "02"},
{"860000000102", false, false, 1, 1, "02"},
{"83010203", false, false, 0, -1, "010203"},
// New format headers
{"c0", false, true, 0, 0, ""},
{"c000", false, false, 0, 0, ""},
{"c00102", false, false, 0, 1, "02"},
{"c0020203", false, false, 0, 2, "0203"},
{"c00202", false, true, 0, 2, ""},
{"c3020203", false, false, 3, 2, "0203"},
}
func TestReadHeader(t *testing.T) {
for i, test := range readHeaderTests {
tag, length, contents, err := readHeader(readerFromHex(test.hexInput))
if test.structuralError {
if _, ok := err.(error.StructuralError); ok {
continue
}
t.Errorf("%d: expected StructuralError, got:%s", i, err)
continue
}
if err != nil {
if len(test.hexInput) == 0 && err == os.EOF {
continue
}
if !test.unexpectedEOF || err != io.ErrUnexpectedEOF {
t.Errorf("%d: unexpected error from readHeader: %s", i, err)
}
continue
}
if int(tag) != test.tag || length != test.length {
t.Errorf("%d: got:(%d,%d) want:(%d,%d)", i, int(tag), length, test.tag, test.length)
continue
}
body, err := ioutil.ReadAll(contents)
if err != nil {
if !test.unexpectedEOF || err != io.ErrUnexpectedEOF {
t.Errorf("%d: unexpected error from contents: %s", i, err)
}
continue
}
if test.unexpectedEOF {
t.Errorf("%d: expected ErrUnexpectedEOF from contents but got no error", i)
continue
}
got := fmt.Sprintf("%x", body)
if got != test.hexOutput {
t.Errorf("%d: got:%s want:%s", i, got, test.hexOutput)
}
}
}
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package packet
import (
"big"
"bytes"
"crypto/cipher"
"crypto/openpgp/error"
"crypto/openpgp/s2k"
"crypto/rsa"
"crypto/sha1"
"io"
"io/ioutil"
"os"
"strconv"
)
// PrivateKey represents a possibly encrypted private key. See RFC 4880,
// section 5.5.3.
type PrivateKey struct {
PublicKey
Encrypted bool // if true then the private key is unavailable until Decrypt has been called.
encryptedData []byte
cipher CipherFunction
s2k func(out, in []byte)
PrivateKey interface{} // An *rsa.PrivateKey.
sha1Checksum bool
iv []byte
}
func (pk *PrivateKey) parse(r io.Reader) (err os.Error) {
err = (&pk.PublicKey).parse(r)
if err != nil {
return
}
var buf [1]byte
_, err = readFull(r, buf[:])
if err != nil {
return
}
s2kType := buf[0]
switch s2kType {
case 0:
pk.s2k = nil
pk.Encrypted = false
case 254, 255:
_, err = readFull(r, buf[:])
if err != nil {
return
}
pk.cipher = CipherFunction(buf[0])
pk.Encrypted = true
pk.s2k, err = s2k.Parse(r)
if err != nil {
return
}
if s2kType == 254 {
pk.sha1Checksum = true
}
default:
return error.UnsupportedError("deprecated s2k function in private key")
}
if pk.Encrypted {
blockSize := pk.cipher.blockSize()
if blockSize == 0 {
return error.UnsupportedError("unsupported cipher in private key: " + strconv.Itoa(int(pk.cipher)))
}
pk.iv = make([]byte, blockSize)
_, err = readFull(r, pk.iv)
if err != nil {
return
}
}
pk.encryptedData, err = ioutil.ReadAll(r)
if err != nil {
return
}
if !pk.Encrypted {
return pk.parsePrivateKey(pk.encryptedData)
}
return
}
// Decrypt decrypts an encrypted private key using a passphrase.
func (pk *PrivateKey) Decrypt(passphrase []byte) os.Error {
if !pk.Encrypted {
return nil
}
key := make([]byte, pk.cipher.keySize())
pk.s2k(key, passphrase)
block := pk.cipher.new(key)
cfb := cipher.NewCFBDecrypter(block, pk.iv)
data := pk.encryptedData
cfb.XORKeyStream(data, data)
if pk.sha1Checksum {
if len(data) < sha1.Size {
return error.StructuralError("truncated private key data")
}
h := sha1.New()
h.Write(data[:len(data)-sha1.Size])
sum := h.Sum()
if !bytes.Equal(sum, data[len(data)-sha1.Size:]) {
return error.StructuralError("private key checksum failure")
}
data = data[:len(data)-sha1.Size]
} else {
if len(data) < 2 {
return error.StructuralError("truncated private key data")
}
var sum uint16
for i := 0; i < len(data)-2; i++ {
sum += uint16(data[i])
}
if data[len(data)-2] != uint8(sum>>8) ||
data[len(data)-1] != uint8(sum) {
return error.StructuralError("private key checksum failure")
}
data = data[:len(data)-2]
}
return pk.parsePrivateKey(data)
}
func (pk *PrivateKey) parsePrivateKey(data []byte) (err os.Error) {
// TODO(agl): support DSA and ECDSA private keys.
rsaPub := pk.PublicKey.PublicKey.(*rsa.PublicKey)
rsaPriv := new(rsa.PrivateKey)
rsaPriv.PublicKey = *rsaPub
buf := bytes.NewBuffer(data)
d, _, err := readMPI(buf)
if err != nil {
return
}
p, _, err := readMPI(buf)
if err != nil {
return
}
q, _, err := readMPI(buf)
if err != nil {
return
}
rsaPriv.D = new(big.Int).SetBytes(d)
rsaPriv.P = new(big.Int).SetBytes(p)
rsaPriv.Q = new(big.Int).SetBytes(q)
pk.PrivateKey = rsaPriv
pk.Encrypted = false
pk.encryptedData = nil
return nil
}
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package packet
import (
"testing"
)
func TestPrivateKeyRead(t *testing.T) {
packet, err := Read(readerFromHex(privKeyHex))
if err != nil {
t.Error(err)
return
}
privKey := packet.(*PrivateKey)
if !privKey.Encrypted {
t.Error("private key isn't encrypted")
return
}
err = privKey.Decrypt([]byte("testing"))
if err != nil {
t.Error(err)
return
}
if privKey.CreationTime != 0x4cc349a8 || privKey.Encrypted {
t.Errorf("failed to parse, got: %#v", privKey)
}
}
// Generated with `gpg --export-secret-keys "Test Key 2"`
const privKeyHex = "9501fe044cc349a8010400b70ca0010e98c090008d45d1ee8f9113bd5861fd57b88bacb7c68658747663f1e1a3b5a98f32fda6472373c024b97359cd2efc88ff60f77751adfbf6af5e615e6a1408cfad8bf0cea30b0d5f53aa27ad59089ba9b15b7ebc2777a25d7b436144027e3bcd203909f147d0e332b240cf63d3395f5dfe0df0a6c04e8655af7eacdf0011010001fe0303024a252e7d475fd445607de39a265472aa74a9320ba2dac395faa687e9e0336aeb7e9a7397e511b5afd9dc84557c80ac0f3d4d7bfec5ae16f20d41c8c84a04552a33870b930420e230e179564f6d19bb153145e76c33ae993886c388832b0fa042ddda7f133924f3854481533e0ede31d51278c0519b29abc3bf53da673e13e3e1214b52413d179d7f66deee35cac8eacb060f78379d70ef4af8607e68131ff529439668fc39c9ce6dfef8a5ac234d234802cbfb749a26107db26406213ae5c06d4673253a3cbee1fcbae58d6ab77e38d6e2c0e7c6317c48e054edadb5a40d0d48acb44643d998139a8a66bb820be1f3f80185bc777d14b5954b60effe2448a036d565c6bc0b915fcea518acdd20ab07bc1529f561c58cd044f723109b93f6fd99f876ff891d64306b5d08f48bab59f38695e9109c4dec34013ba3153488ce070268381ba923ee1eb77125b36afcb4347ec3478c8f2735b06ef17351d872e577fa95d0c397c88c71b59629a36aec"
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package packet
import (
"big"
"crypto/dsa"
"crypto/openpgp/error"
"crypto/rsa"
"crypto/sha1"
"encoding/binary"
"hash"
"io"
"os"
)
// PublicKey represents an OpenPGP public key. See RFC 4880, section 5.5.2.
type PublicKey struct {
CreationTime uint32 // seconds since the epoch
PubKeyAlgo PublicKeyAlgorithm
PublicKey interface{} // Either a *rsa.PublicKey or *dsa.PublicKey
Fingerprint [20]byte
KeyId uint64
IsSubkey bool
n, e, p, q, g, y parsedMPI
}
func (pk *PublicKey) parse(r io.Reader) (err os.Error) {
// RFC 4880, section 5.5.2
var buf [6]byte
_, err = readFull(r, buf[:])
if err != nil {
return
}
if buf[0] != 4 {
return error.UnsupportedError("public key version")
}
pk.CreationTime = uint32(buf[1])<<24 | uint32(buf[2])<<16 | uint32(buf[3])<<8 | uint32(buf[4])
pk.PubKeyAlgo = PublicKeyAlgorithm(buf[5])
switch pk.PubKeyAlgo {
case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
err = pk.parseRSA(r)
case PubKeyAlgoDSA:
err = pk.parseDSA(r)
default:
err = error.UnsupportedError("public key type")
}
if err != nil {
return
}
// RFC 4880, section 12.2
fingerPrint := sha1.New()
pk.SerializeSignaturePrefix(fingerPrint)
pk.Serialize(fingerPrint)
copy(pk.Fingerprint[:], fingerPrint.Sum())
pk.KeyId = binary.BigEndian.Uint64(pk.Fingerprint[12:20])
return
}
// parseRSA parses RSA public key material from the given Reader. See RFC 4880,
// section 5.5.2.
func (pk *PublicKey) parseRSA(r io.Reader) (err os.Error) {
pk.n.bytes, pk.n.bitLength, err = readMPI(r)
if err != nil {
return
}
pk.e.bytes, pk.e.bitLength, err = readMPI(r)
if err != nil {
return
}
if len(pk.e.bytes) > 3 {
err = error.UnsupportedError("large public exponent")
return
}
rsa := &rsa.PublicKey{
N: new(big.Int).SetBytes(pk.n.bytes),
E: 0,
}
for i := 0; i < len(pk.e.bytes); i++ {
rsa.E <<= 8
rsa.E |= int(pk.e.bytes[i])
}
pk.PublicKey = rsa
return
}
// parseRSA parses DSA public key material from the given Reader. See RFC 4880,
// section 5.5.2.
func (pk *PublicKey) parseDSA(r io.Reader) (err os.Error) {
pk.p.bytes, pk.p.bitLength, err = readMPI(r)
if err != nil {
return
}
pk.q.bytes, pk.q.bitLength, err = readMPI(r)
if err != nil {
return
}
pk.g.bytes, pk.g.bitLength, err = readMPI(r)
if err != nil {
return
}
pk.y.bytes, pk.y.bitLength, err = readMPI(r)
if err != nil {
return
}
dsa := new(dsa.PublicKey)
dsa.P = new(big.Int).SetBytes(pk.p.bytes)
dsa.Q = new(big.Int).SetBytes(pk.q.bytes)
dsa.G = new(big.Int).SetBytes(pk.g.bytes)
dsa.Y = new(big.Int).SetBytes(pk.y.bytes)
pk.PublicKey = dsa
return
}
// SerializeSignaturePrefix writes the prefix for this public key to the given Writer.
// The prefix is used when calculating a signature over this public key. See
// RFC 4880, section 5.2.4.
func (pk *PublicKey) SerializeSignaturePrefix(h hash.Hash) {
var pLength uint16
switch pk.PubKeyAlgo {
case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
pLength += 2 + uint16(len(pk.n.bytes))
pLength += 2 + uint16(len(pk.e.bytes))
case PubKeyAlgoDSA:
pLength += 2 + uint16(len(pk.p.bytes))
pLength += 2 + uint16(len(pk.q.bytes))
pLength += 2 + uint16(len(pk.g.bytes))
pLength += 2 + uint16(len(pk.y.bytes))
default:
panic("unknown public key algorithm")
}
pLength += 6
h.Write([]byte{0x99, byte(pLength >> 8), byte(pLength)})
return
}
// Serialize marshals the PublicKey to w in the form of an OpenPGP public key
// packet, not including the packet header.
func (pk *PublicKey) Serialize(w io.Writer) (err os.Error) {
var buf [6]byte
buf[0] = 4
buf[1] = byte(pk.CreationTime >> 24)
buf[2] = byte(pk.CreationTime >> 16)
buf[3] = byte(pk.CreationTime >> 8)
buf[4] = byte(pk.CreationTime)
buf[5] = byte(pk.PubKeyAlgo)
_, err = w.Write(buf[:])
if err != nil {
return
}
switch pk.PubKeyAlgo {
case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
return writeMPIs(w, pk.n, pk.e)
case PubKeyAlgoDSA:
return writeMPIs(w, pk.p, pk.q, pk.g, pk.y)
}
return error.InvalidArgumentError("bad public-key algorithm")
}
// CanSign returns true iff this public key can generate signatures
func (pk *PublicKey) CanSign() bool {
return pk.PubKeyAlgo != PubKeyAlgoRSAEncryptOnly && pk.PubKeyAlgo != PubKeyAlgoElgamal
}
// VerifySignature returns nil iff sig is a valid signature, made by this
// public key, of the data hashed into signed. signed is mutated by this call.
func (pk *PublicKey) VerifySignature(signed hash.Hash, sig *Signature) (err os.Error) {
if !pk.CanSign() {
return error.InvalidArgumentError("public key cannot generate signatures")
}
rsaPublicKey, ok := pk.PublicKey.(*rsa.PublicKey)
if !ok {
// TODO(agl): support DSA and ECDSA keys.
return error.UnsupportedError("non-RSA public key")
}
signed.Write(sig.HashSuffix)
hashBytes := signed.Sum()
if hashBytes[0] != sig.HashTag[0] || hashBytes[1] != sig.HashTag[1] {
return error.SignatureError("hash tag doesn't match")
}
err = rsa.VerifyPKCS1v15(rsaPublicKey, sig.Hash, hashBytes, sig.Signature)
if err != nil {
return error.SignatureError("RSA verification failure")
}
return nil
}
// VerifyKeySignature returns nil iff sig is a valid signature, make by this
// public key, of the public key in signed.
func (pk *PublicKey) VerifyKeySignature(signed *PublicKey, sig *Signature) (err os.Error) {
h := sig.Hash.New()
if h == nil {
return error.UnsupportedError("hash function")
}
// RFC 4880, section 5.2.4
pk.SerializeSignaturePrefix(h)
pk.Serialize(h)
signed.SerializeSignaturePrefix(h)
signed.Serialize(h)
return pk.VerifySignature(h, sig)
}
// VerifyUserIdSignature returns nil iff sig is a valid signature, make by this
// public key, of the given user id.
func (pk *PublicKey) VerifyUserIdSignature(id string, sig *Signature) (err os.Error) {
h := sig.Hash.New()
if h == nil {
return error.UnsupportedError("hash function")
}
// RFC 4880, section 5.2.4
pk.SerializeSignaturePrefix(h)
pk.Serialize(h)
var buf [5]byte
buf[0] = 0xb4
buf[1] = byte(len(id) >> 24)
buf[2] = byte(len(id) >> 16)
buf[3] = byte(len(id) >> 8)
buf[4] = byte(len(id))
h.Write(buf[:])
h.Write([]byte(id))
return pk.VerifySignature(h, sig)
}
// A parsedMPI is used to store the contents of a big integer, along with the
// bit length that was specified in the original input. This allows the MPI to
// be reserialised exactly.
type parsedMPI struct {
bytes []byte
bitLength uint16
}
// writeMPIs is a utility function for serialising several big integers to the
// given Writer.
func writeMPIs(w io.Writer, mpis ...parsedMPI) (err os.Error) {
for _, mpi := range mpis {
err = writeMPI(w, mpi.bitLength, mpi.bytes)
if err != nil {
return
}
}
return
}
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package packet
import (
"bytes"
"encoding/hex"
"testing"
)
var pubKeyTests = []struct {
hexData string
hexFingerprint string
creationTime uint32
pubKeyAlgo PublicKeyAlgorithm
keyId uint64
}{
{rsaPkDataHex, rsaFingerprintHex, 0x4d3c5c10, PubKeyAlgoRSA, 0xa34d7e18c20c31bb},
{dsaPkDataHex, dsaFingerprintHex, 0x4d432f89, PubKeyAlgoDSA, 0x8e8fbe54062f19ed},
}
func TestPublicKeyRead(t *testing.T) {
for i, test := range pubKeyTests {
packet, err := Read(readerFromHex(test.hexData))
if err != nil {
t.Errorf("#%d: Read error: %s", i, err)
return
}
pk, ok := packet.(*PublicKey)
if !ok {
t.Errorf("#%d: failed to parse, got: %#v", i, packet)
return
}
if pk.PubKeyAlgo != test.pubKeyAlgo {
t.Errorf("#%d: bad public key algorithm got:%x want:%x", i, pk.PubKeyAlgo, test.pubKeyAlgo)
}
if pk.CreationTime != test.creationTime {
t.Errorf("#%d: bad creation time got:%x want:%x", i, pk.CreationTime, test.creationTime)
}
expectedFingerprint, _ := hex.DecodeString(test.hexFingerprint)
if !bytes.Equal(expectedFingerprint, pk.Fingerprint[:]) {
t.Errorf("#%d: bad fingerprint got:%x want:%x", i, pk.Fingerprint[:], expectedFingerprint)
}
if pk.KeyId != test.keyId {
t.Errorf("#%d: bad keyid got:%x want:%x", i, pk.KeyId, test.keyId)
}
}
}
const rsaFingerprintHex = "5fb74b1d03b1e3cb31bc2f8aa34d7e18c20c31bb"
const rsaPkDataHex = "988d044d3c5c10010400b1d13382944bd5aba23a4312968b5095d14f947f600eb478e14a6fcb16b0e0cac764884909c020bc495cfcc39a935387c661507bdb236a0612fb582cac3af9b29cc2c8c70090616c41b662f4da4c1201e195472eb7f4ae1ccbcbf9940fe21d985e379a5563dde5b9a23d35f1cfaa5790da3b79db26f23695107bfaca8e7b5bcd0011010001"
const dsaFingerprintHex = "eece4c094db002103714c63c8e8fbe54062f19ed"
const dsaPkDataHex = "9901a2044d432f89110400cd581334f0d7a1e1bdc8b9d6d8c0baf68793632735d2bb0903224cbaa1dfbf35a60ee7a13b92643421e1eb41aa8d79bea19a115a677f6b8ba3c7818ce53a6c2a24a1608bd8b8d6e55c5090cbde09dd26e356267465ae25e69ec8bdd57c7bbb2623e4d73336f73a0a9098f7f16da2e25252130fd694c0e8070c55a812a423ae7f00a0ebf50e70c2f19c3520a551bd4b08d30f23530d3d03ff7d0bf4a53a64a09dc5e6e6e35854b7d70c882b0c60293401958b1bd9e40abec3ea05ba87cf64899299d4bd6aa7f459c201d3fbbd6c82004bdc5e8a9eb8082d12054cc90fa9d4ec251a843236a588bf49552441817436c4f43326966fe85447d4e6d0acf8fa1ef0f014730770603ad7634c3088dc52501c237328417c31c89ed70400b2f1a98b0bf42f11fefc430704bebbaa41d9f355600c3facee1e490f64208e0e094ea55e3a598a219a58500bf78ac677b670a14f4e47e9cf8eab4f368cc1ddcaa18cc59309d4cc62dd4f680e73e6cc3e1ce87a84d0925efbcb26c575c093fc42eecf45135fabf6403a25c2016e1774c0484e440a18319072c617cc97ac0a3bb0"
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package packet
import (
"crypto/openpgp/error"
"io"
"os"
)
// Reader reads packets from an io.Reader and allows packets to be 'unread' so
// that they result from the next call to Next.
type Reader struct {
q []Packet
readers []io.Reader
}
// Next returns the most recently unread Packet, or reads another packet from
// the top-most io.Reader. Unknown packet types are skipped.
func (r *Reader) Next() (p Packet, err os.Error) {
if len(r.q) > 0 {
p = r.q[len(r.q)-1]
r.q = r.q[:len(r.q)-1]
return
}
for len(r.readers) > 0 {
p, err = Read(r.readers[len(r.readers)-1])
if err == nil {
return
}
if err == os.EOF {
r.readers = r.readers[:len(r.readers)-1]
continue
}
if _, ok := err.(error.UnknownPacketTypeError); !ok {
return nil, err
}
}
return nil, os.EOF
}
// Push causes the Reader to start reading from a new io.Reader. When an EOF
// error is seen from the new io.Reader, it is popped and the Reader continues
// to read from the next most recent io.Reader.
func (r *Reader) Push(reader io.Reader) {
r.readers = append(r.readers, reader)
}
// Unread causes the given Packet to be returned from the next call to Next.
func (r *Reader) Unread(p Packet) {
r.q = append(r.q, p)
}
func NewReader(r io.Reader) *Reader {
return &Reader{
q: nil,
readers: []io.Reader{r},
}
}
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package packet
import (
"bytes"
"crypto"
"encoding/hex"
"testing"
)
func TestSignatureRead(t *testing.T) {
signatureData, _ := hex.DecodeString(signatureDataHex)
buf := bytes.NewBuffer(signatureData)
packet, err := Read(buf)
if err != nil {
t.Error(err)
return
}
sig, ok := packet.(*Signature)
if !ok || sig.SigType != SigTypeBinary || sig.PubKeyAlgo != PubKeyAlgoRSA || sig.Hash != crypto.SHA1 {
t.Errorf("failed to parse, got: %#v", packet)
}
}
const signatureDataHex = "89011c04000102000605024cb45112000a0910ab105c91af38fb158f8d07ff5596ea368c5efe015bed6e78348c0f033c931d5f2ce5db54ce7f2a7e4b4ad64db758d65a7a71773edeab7ba2a9e0908e6a94a1175edd86c1d843279f045b021a6971a72702fcbd650efc393c5474d5b59a15f96d2eaad4c4c426797e0dcca2803ef41c6ff234d403eec38f31d610c344c06f2401c262f0993b2e66cad8a81ebc4322c723e0d4ba09fe917e8777658307ad8329adacba821420741009dfe87f007759f0982275d028a392c6ed983a0d846f890b36148c7358bdb8a516007fac760261ecd06076813831a36d0459075d1befa245ae7f7fb103d92ca759e9498fe60ef8078a39a3beda510deea251ea9f0a7f0df6ef42060f20780360686f3e400e"
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package packet
import (
"crypto/cipher"
"crypto/openpgp/error"
"crypto/openpgp/s2k"
"io"
"os"
"strconv"
)
// This is the largest session key that we'll support. Since no 512-bit cipher
// has even been seriously used, this is comfortably large.
const maxSessionKeySizeInBytes = 64
// SymmetricKeyEncrypted represents a passphrase protected session key. See RFC
// 4880, section 5.3.
type SymmetricKeyEncrypted struct {
CipherFunc CipherFunction
Encrypted bool
Key []byte // Empty unless Encrypted is false.
s2k func(out, in []byte)
encryptedKey []byte
}
func (ske *SymmetricKeyEncrypted) parse(r io.Reader) (err os.Error) {
// RFC 4880, section 5.3.
var buf [2]byte
_, err = readFull(r, buf[:])
if err != nil {
return
}
if buf[0] != 4 {
return error.UnsupportedError("SymmetricKeyEncrypted version")
}
ske.CipherFunc = CipherFunction(buf[1])
if ske.CipherFunc.keySize() == 0 {
return error.UnsupportedError("unknown cipher: " + strconv.Itoa(int(buf[1])))
}
ske.s2k, err = s2k.Parse(r)
if err != nil {
return
}
encryptedKey := make([]byte, maxSessionKeySizeInBytes)
// The session key may follow. We just have to try and read to find
// out. If it exists then we limit it to maxSessionKeySizeInBytes.
n, err := readFull(r, encryptedKey)
if err != nil && err != io.ErrUnexpectedEOF {
return
}
err = nil
if n != 0 {
if n == maxSessionKeySizeInBytes {
return error.UnsupportedError("oversized encrypted session key")
}
ske.encryptedKey = encryptedKey[:n]
}
ske.Encrypted = true
return
}
// Decrypt attempts to decrypt an encrypted session key. If it returns nil,
// ske.Key will contain the session key.
func (ske *SymmetricKeyEncrypted) Decrypt(passphrase []byte) os.Error {
if !ske.Encrypted {
return nil
}
key := make([]byte, ske.CipherFunc.keySize())
ske.s2k(key, passphrase)
if len(ske.encryptedKey) == 0 {
ske.Key = key
} else {
// the IV is all zeros
iv := make([]byte, ske.CipherFunc.blockSize())
c := cipher.NewCFBDecrypter(ske.CipherFunc.new(key), iv)
c.XORKeyStream(ske.encryptedKey, ske.encryptedKey)
ske.CipherFunc = CipherFunction(ske.encryptedKey[0])
if ske.CipherFunc.blockSize() == 0 {
return error.UnsupportedError("unknown cipher: " + strconv.Itoa(int(ske.CipherFunc)))
}
ske.CipherFunc = CipherFunction(ske.encryptedKey[0])
ske.Key = ske.encryptedKey[1:]
if len(ske.Key)%ske.CipherFunc.blockSize() != 0 {
ske.Key = nil
return error.StructuralError("length of decrypted key not a multiple of block size")
}
}
ske.Encrypted = false
return nil
}
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package packet
import (
"bytes"
"encoding/hex"
"io/ioutil"
"os"
"testing"
)
func TestSymmetricKeyEncrypted(t *testing.T) {
buf := readerFromHex(symmetricallyEncryptedHex)
packet, err := Read(buf)
if err != nil {
t.Errorf("failed to read SymmetricKeyEncrypted: %s", err)
return
}
ske, ok := packet.(*SymmetricKeyEncrypted)
if !ok {
t.Error("didn't find SymmetricKeyEncrypted packet")
return
}
err = ske.Decrypt([]byte("password"))
if err != nil {
t.Error(err)
return
}
packet, err = Read(buf)
if err != nil {
t.Errorf("failed to read SymmetricallyEncrypted: %s", err)
return
}
se, ok := packet.(*SymmetricallyEncrypted)
if !ok {
t.Error("didn't find SymmetricallyEncrypted packet")
return
}
r, err := se.Decrypt(ske.CipherFunc, ske.Key)
if err != nil {
t.Error(err)
return
}
contents, err := ioutil.ReadAll(r)
if err != nil && err != os.EOF {
t.Error(err)
return
}
expectedContents, _ := hex.DecodeString(symmetricallyEncryptedContentsHex)
if !bytes.Equal(expectedContents, contents) {
t.Errorf("bad contents got:%x want:%x", contents, expectedContents)
}
}
const symmetricallyEncryptedHex = "8c0d04030302371a0b38d884f02060c91cf97c9973b8e58e028e9501708ccfe618fb92afef7fa2d80ddadd93cf"
const symmetricallyEncryptedContentsHex = "cb1062004d14c4df636f6e74656e74732e0a"
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package packet
import (
"crypto/cipher"
"crypto/openpgp/error"
"crypto/sha1"
"crypto/subtle"
"hash"
"io"
"os"
"strconv"
)
// SymmetricallyEncrypted represents a symmetrically encrypted byte string. The
// encrypted contents will consist of more OpenPGP packets. See RFC 4880,
// sections 5.7 and 5.13.
type SymmetricallyEncrypted struct {
MDC bool // true iff this is a type 18 packet and thus has an embedded MAC.
contents io.Reader
prefix []byte
}
func (se *SymmetricallyEncrypted) parse(r io.Reader) os.Error {
if se.MDC {
// See RFC 4880, section 5.13.
var buf [1]byte
_, err := readFull(r, buf[:])
if err != nil {
return err
}
if buf[0] != 1 {
return error.UnsupportedError("unknown SymmetricallyEncrypted version")
}
}
se.contents = r
return nil
}
// Decrypt returns a ReadCloser, from which the decrypted contents of the
// packet can be read. An incorrect key can, with high probability, be detected
// immediately and this will result in a KeyIncorrect error being returned.
func (se *SymmetricallyEncrypted) Decrypt(c CipherFunction, key []byte) (io.ReadCloser, os.Error) {
keySize := c.keySize()
if keySize == 0 {
return nil, error.UnsupportedError("unknown cipher: " + strconv.Itoa(int(c)))
}
if len(key) != keySize {
return nil, error.InvalidArgumentError("SymmetricallyEncrypted: incorrect key length")
}
if se.prefix == nil {
se.prefix = make([]byte, c.blockSize()+2)
_, err := readFull(se.contents, se.prefix)
if err != nil {
return nil, err
}
} else if len(se.prefix) != c.blockSize()+2 {
return nil, error.InvalidArgumentError("can't try ciphers with different block lengths")
}
ocfbResync := cipher.OCFBResync
if se.MDC {
// MDC packets use a different form of OCFB mode.
ocfbResync = cipher.OCFBNoResync
}
s := cipher.NewOCFBDecrypter(c.new(key), se.prefix, ocfbResync)
if s == nil {
return nil, error.KeyIncorrectError
}
plaintext := cipher.StreamReader{S: s, R: se.contents}
if se.MDC {
// MDC packets have an embedded hash that we need to check.
h := sha1.New()
h.Write(se.prefix)
return &seMDCReader{in: plaintext, h: h}, nil
}
// Otherwise, we just need to wrap plaintext so that it's a valid ReadCloser.
return seReader{plaintext}, nil
}
// seReader wraps an io.Reader with a no-op Close method.
type seReader struct {
in io.Reader
}
func (ser seReader) Read(buf []byte) (int, os.Error) {
return ser.in.Read(buf)
}
func (ser seReader) Close() os.Error {
return nil
}
const mdcTrailerSize = 1 /* tag byte */ + 1 /* length byte */ + sha1.Size
// An seMDCReader wraps an io.Reader, maintains a running hash and keeps hold
// of the most recent 22 bytes (mdcTrailerSize). Upon EOF, those bytes form an
// MDC packet containing a hash of the previous contents which is checked
// against the running hash. See RFC 4880, section 5.13.
type seMDCReader struct {
in io.Reader
h hash.Hash
trailer [mdcTrailerSize]byte
scratch [mdcTrailerSize]byte
trailerUsed int
error bool
eof bool
}
func (ser *seMDCReader) Read(buf []byte) (n int, err os.Error) {
if ser.error {
err = io.ErrUnexpectedEOF
return
}
if ser.eof {
err = os.EOF
return
}
// If we haven't yet filled the trailer buffer then we must do that
// first.
for ser.trailerUsed < mdcTrailerSize {
n, err = ser.in.Read(ser.trailer[ser.trailerUsed:])
ser.trailerUsed += n
if err == os.EOF {
if ser.trailerUsed != mdcTrailerSize {
n = 0
err = io.ErrUnexpectedEOF
ser.error = true
return
}
ser.eof = true
n = 0
return
}
if err != nil {
n = 0
return
}
}
// If it's a short read then we read into a temporary buffer and shift
// the data into the caller's buffer.
if len(buf) <= mdcTrailerSize {
n, err = readFull(ser.in, ser.scratch[:len(buf)])
copy(buf, ser.trailer[:n])
ser.h.Write(buf[:n])
copy(ser.trailer[:], ser.trailer[n:])
copy(ser.trailer[mdcTrailerSize-n:], ser.scratch[:])
if n < len(buf) {
ser.eof = true
err = os.EOF
}
return
}
n, err = ser.in.Read(buf[mdcTrailerSize:])
copy(buf, ser.trailer[:])
ser.h.Write(buf[:n])
copy(ser.trailer[:], buf[n:])
if err == os.EOF {
ser.eof = true
}
return
}
func (ser *seMDCReader) Close() os.Error {
if ser.error {
return error.SignatureError("error during reading")
}
for !ser.eof {
// We haven't seen EOF so we need to read to the end
var buf [1024]byte
_, err := ser.Read(buf[:])
if err == os.EOF {
break
}
if err != nil {
return error.SignatureError("error during reading")
}
}
// This is a new-format packet tag byte for a type 19 (MDC) packet.
const mdcPacketTagByte = byte(0x80) | 0x40 | 19
if ser.trailer[0] != mdcPacketTagByte || ser.trailer[1] != sha1.Size {
return error.SignatureError("MDC packet not found")
}
ser.h.Write(ser.trailer[:2])
final := ser.h.Sum()
if subtle.ConstantTimeCompare(final, ser.trailer[2:]) == 1 {
return error.SignatureError("hash mismatch")
}
return nil
}
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package packet
import (
"bytes"
"crypto/openpgp/error"
"crypto/sha1"
"encoding/hex"
"io/ioutil"
"os"
"testing"
)
// TestReader wraps a []byte and returns reads of a specific length.
type testReader struct {
data []byte
stride int
}
func (t *testReader) Read(buf []byte) (n int, err os.Error) {
n = t.stride
if n > len(t.data) {
n = len(t.data)
}
if n > len(buf) {
n = len(buf)
}
copy(buf, t.data)
t.data = t.data[n:]
if len(t.data) == 0 {
err = os.EOF
}
return
}
func testMDCReader(t *testing.T) {
mdcPlaintext, _ := hex.DecodeString(mdcPlaintextHex)
for stride := 1; stride < len(mdcPlaintext)/2; stride++ {
r := &testReader{data: mdcPlaintext, stride: stride}
mdcReader := &seMDCReader{in: r, h: sha1.New()}
body, err := ioutil.ReadAll(mdcReader)
if err != nil {
t.Errorf("stride: %d, error: %s", stride, err)
continue
}
if !bytes.Equal(body, mdcPlaintext[:len(mdcPlaintext)-22]) {
t.Errorf("stride: %d: bad contents %x", stride, body)
continue
}
err = mdcReader.Close()
if err != nil {
t.Errorf("stride: %d, error on Close: %s", stride, err)
}
}
mdcPlaintext[15] ^= 80
r := &testReader{data: mdcPlaintext, stride: 2}
mdcReader := &seMDCReader{in: r, h: sha1.New()}
_, err := ioutil.ReadAll(mdcReader)
if err != nil {
t.Errorf("corruption test, error: %s", err)
return
}
err = mdcReader.Close()
if err == nil {
t.Error("corruption: no error")
} else if _, ok := err.(*error.SignatureError); !ok {
t.Errorf("corruption: expected SignatureError, got: %s", err)
}
}
const mdcPlaintextHex = "a302789c3b2d93c4e0eb9aba22283539b3203335af44a134afb800c849cb4c4de10200aff40b45d31432c80cb384299a0655966d6939dfdeed1dddf980"
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package packet
import (
"io"
"io/ioutil"
"os"
"strings"
)
// UserId contains text that is intended to represent the name and email
// address of the key holder. See RFC 4880, section 5.11. By convention, this
// takes the form "Full Name (Comment) <email@example.com>"
type UserId struct {
Id string // By convention, this takes the form "Full Name (Comment) <email@example.com>" which is split out in the fields below.
Name, Comment, Email string
}
func (uid *UserId) parse(r io.Reader) (err os.Error) {
// RFC 4880, section 5.11
b, err := ioutil.ReadAll(r)
if err != nil {
return
}
uid.Id = string(b)
uid.Name, uid.Comment, uid.Email = parseUserId(uid.Id)
return
}
// parseUserId extracts the name, comment and email from a user id string that
// is formatted as "Full Name (Comment) <email@example.com>".
func parseUserId(id string) (name, comment, email string) {
var n, c, e struct {
start, end int
}
var state int
for offset, rune := range id {
switch state {
case 0:
// Entering name
n.start = offset
state = 1
fallthrough
case 1:
// In name
if rune == '(' {
state = 2
n.end = offset
} else if rune == '<' {
state = 5
n.end = offset
}
case 2:
// Entering comment
c.start = offset
state = 3
fallthrough
case 3:
// In comment
if rune == ')' {
state = 4
c.end = offset
}
case 4:
// Between comment and email
if rune == '<' {
state = 5
}
case 5:
// Entering email
e.start = offset
state = 6
fallthrough
case 6:
// In email
if rune == '>' {
state = 7
e.end = offset
}
default:
// After email
}
}
switch state {
case 1:
// ended in the name
n.end = len(id)
case 3:
// ended in comment
c.end = len(id)
case 6:
// ended in email
e.end = len(id)
}
name = strings.TrimSpace(id[n.start:n.end])
comment = strings.TrimSpace(id[c.start:c.end])
email = strings.TrimSpace(id[e.start:e.end])
return
}
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package packet
import (
"testing"
)
var userIdTests = []struct {
id string
name, comment, email string
}{
{"", "", "", ""},
{"John Smith", "John Smith", "", ""},
{"John Smith ()", "John Smith", "", ""},
{"John Smith () <>", "John Smith", "", ""},
{"(comment", "", "comment", ""},
{"(comment)", "", "comment", ""},
{"<email", "", "", "email"},
{"<email> sdfk", "", "", "email"},
{" John Smith ( Comment ) asdkflj < email > lksdfj", "John Smith", "Comment", "email"},
{" John Smith < email > lksdfj", "John Smith", "", "email"},
{"(<foo", "", "<foo", ""},
{"René Descartes (العربي)", "René Descartes", "العربي", ""},
}
func TestParseUserId(t *testing.T) {
for i, test := range userIdTests {
name, comment, email := parseUserId(test.id)
if name != test.name {
t.Errorf("%d: name mismatch got:%s want:%s", i, name, test.name)
}
if comment != test.comment {
t.Errorf("%d: comment mismatch got:%s want:%s", i, comment, test.comment)
}
if email != test.email {
t.Errorf("%d: email mismatch got:%s want:%s", i, email, test.email)
}
}
}
...@@ -7,15 +7,12 @@ ...@@ -7,15 +7,12 @@
package s2k package s2k
import ( import (
"crypto/md5" "crypto"
"crypto/openpgp/error" "crypto/openpgp/error"
"crypto/ripemd160"
"crypto/sha1"
"crypto/sha256"
"crypto/sha512"
"hash" "hash"
"io" "io"
"os" "os"
"strconv"
) )
// Simple writes to out the result of computing the Simple S2K function (RFC // Simple writes to out the result of computing the Simple S2K function (RFC
...@@ -87,9 +84,13 @@ func Parse(r io.Reader) (f func(out, in []byte), err os.Error) { ...@@ -87,9 +84,13 @@ func Parse(r io.Reader) (f func(out, in []byte), err os.Error) {
return return
} }
h := hashFuncFromType(buf[1]) hash, ok := HashIdToHash(buf[1])
if !ok {
return nil, error.UnsupportedError("hash for S2K function: " + strconv.Itoa(int(buf[1])))
}
h := hash.New()
if h == nil { if h == nil {
return nil, error.UnsupportedError("hash for S2K function") return nil, error.UnsupportedError("hash not availible: " + strconv.Itoa(int(hash)))
} }
switch buf[0] { switch buf[0] {
...@@ -122,25 +123,38 @@ func Parse(r io.Reader) (f func(out, in []byte), err os.Error) { ...@@ -122,25 +123,38 @@ func Parse(r io.Reader) (f func(out, in []byte), err os.Error) {
return nil, error.UnsupportedError("S2K function") return nil, error.UnsupportedError("S2K function")
} }
// hashFuncFromType returns a hash.Hash which corresponds to the given hash // hashToHashIdMapping contains pairs relating OpenPGP's hash identifier with
// type byte. See RFC 4880, section 9.4. // Go's crypto.Hash type. See RFC 4880, section 9.4.
func hashFuncFromType(hashType byte) hash.Hash { var hashToHashIdMapping = []struct {
switch hashType { id byte
case 1: hash crypto.Hash
return md5.New() }{
case 2: {1, crypto.MD5},
return sha1.New() {2, crypto.SHA1},
case 3: {3, crypto.RIPEMD160},
return ripemd160.New() {8, crypto.SHA256},
case 8: {9, crypto.SHA384},
return sha256.New() {10, crypto.SHA512},
case 9: {11, crypto.SHA224},
return sha512.New384() }
case 10:
return sha512.New() // HashIdToHash returns a crypto.Hash which corresponds to the given OpenPGP
case 11: // hash id.
return sha256.New224() func HashIdToHash(id byte) (h crypto.Hash, ok bool) {
for _, m := range hashToHashIdMapping {
if m.id == id {
return m.hash, true
}
} }
return 0, false
}
return nil // HashIdToHash returns an OpenPGP hash id which corresponds the given Hash.
func HashToHashId(h crypto.Hash) (id byte, ok bool) {
for _, m := range hashToHashIdMapping {
if m.hash == h {
return m.id, true
}
}
return 0, false
} }
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package openpgp
import (
"crypto"
"crypto/openpgp/armor"
"crypto/openpgp/error"
"crypto/openpgp/packet"
"crypto/rsa"
_ "crypto/sha256"
"io"
"os"
"strconv"
"time"
)
// DetachSign signs message with the private key from signer (which must
// already have been decrypted) and writes the signature to w.
func DetachSign(w io.Writer, signer *Entity, message io.Reader) os.Error {
return detachSign(w, signer, message, packet.SigTypeBinary)
}
// ArmoredDetachSign signs message with the private key from signer (which
// must already have been decrypted) and writes an armored signature to w.
func ArmoredDetachSign(w io.Writer, signer *Entity, message io.Reader) (err os.Error) {
return armoredDetachSign(w, signer, message, packet.SigTypeBinary)
}
// DetachSignText signs message (after canonicalising the line endings) with
// the private key from signer (which must already have been decrypted) and
// writes the signature to w.
func DetachSignText(w io.Writer, signer *Entity, message io.Reader) os.Error {
return detachSign(w, signer, message, packet.SigTypeText)
}
// ArmoredDetachSignText signs message (after canonicalising the line endings)
// with the private key from signer (which must already have been decrypted)
// and writes an armored signature to w.
func SignTextDetachedArmored(w io.Writer, signer *Entity, message io.Reader) os.Error {
return armoredDetachSign(w, signer, message, packet.SigTypeText)
}
func armoredDetachSign(w io.Writer, signer *Entity, message io.Reader, sigType packet.SignatureType) (err os.Error) {
out, err := armor.Encode(w, SignatureType, nil)
if err != nil {
return
}
err = detachSign(out, signer, message, sigType)
if err != nil {
return
}
return out.Close()
}
func detachSign(w io.Writer, signer *Entity, message io.Reader, sigType packet.SignatureType) (err os.Error) {
if signer.PrivateKey == nil {
return error.InvalidArgumentError("signing key doesn't have a private key")
}
if signer.PrivateKey.Encrypted {
return error.InvalidArgumentError("signing key is encrypted")
}
sig := new(packet.Signature)
sig.SigType = sigType
sig.PubKeyAlgo = signer.PrivateKey.PubKeyAlgo
sig.Hash = crypto.SHA256
sig.CreationTime = uint32(time.Seconds())
sig.IssuerKeyId = &signer.PrivateKey.KeyId
h, wrappedHash, err := hashForSignature(sig.Hash, sig.SigType)
if err != nil {
return
}
io.Copy(wrappedHash, message)
switch signer.PrivateKey.PubKeyAlgo {
case packet.PubKeyAlgoRSA, packet.PubKeyAlgoRSASignOnly:
priv := signer.PrivateKey.PrivateKey.(*rsa.PrivateKey)
err = sig.SignRSA(h, priv)
default:
err = error.UnsupportedError("public key algorithm: " + strconv.Itoa(int(sig.PubKeyAlgo)))
}
if err != nil {
return
}
return sig.Serialize(w)
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment