diff options
author | Ondřej Surý <ondrej@sury.org> | 2011-06-30 15:34:22 +0200 |
---|---|---|
committer | Ondřej Surý <ondrej@sury.org> | 2011-06-30 15:34:22 +0200 |
commit | d39f5aa373a4422f7a5f3ee764fb0f6b0b719d61 (patch) | |
tree | 1833f8b72a4b3a8f00d0d143b079a8fcad01c6ae /src/pkg/asn1/asn1.go | |
parent | 8652e6c371b8905498d3d314491d36c58d5f68d5 (diff) | |
download | golang-upstream/58.tar.gz |
Imported Upstream version 58upstream/58
Diffstat (limited to 'src/pkg/asn1/asn1.go')
-rw-r--r-- | src/pkg/asn1/asn1.go | 35 |
1 files changed, 31 insertions, 4 deletions
diff --git a/src/pkg/asn1/asn1.go b/src/pkg/asn1/asn1.go index 5f470aed7..2650ef2a2 100644 --- a/src/pkg/asn1/asn1.go +++ b/src/pkg/asn1/asn1.go @@ -20,6 +20,7 @@ package asn1 // everything by any means. import ( + "big" "fmt" "os" "reflect" @@ -88,6 +89,27 @@ func parseInt(bytes []byte) (int, os.Error) { return int(ret64), nil } +var bigOne = big.NewInt(1) + +// parseBigInt treats the given bytes as a big-endian, signed integer and returns +// the result. +func parseBigInt(bytes []byte) *big.Int { + ret := new(big.Int) + if len(bytes) > 0 && bytes[0]&0x80 == 0x80 { + // This is a negative number. + notBytes := make([]byte, len(bytes)) + for i := range notBytes { + notBytes[i] = ^bytes[i] + } + ret.SetBytes(notBytes) + ret.Add(ret, bigOne) + ret.Neg(ret) + return ret + } + ret.SetBytes(bytes) + return ret +} + // BIT STRING // BitString is the structure to use when you want an ASN.1 BIT STRING type. A @@ -164,9 +186,9 @@ func (oi ObjectIdentifier) Equal(other ObjectIdentifier) bool { return true } -// parseObjectIdentifier parses an OBJECT IDENTIFER from the given bytes and -// returns it. An object identifer is a sequence of variable length integers -// that are assigned in a hierarachy. +// parseObjectIdentifier parses an OBJECT IDENTIFIER from the given bytes and +// returns it. An object identifier is a sequence of variable length integers +// that are assigned in a hierarchy. func parseObjectIdentifier(bytes []byte) (s []int, err os.Error) { if len(bytes) == 0 { err = SyntaxError{"zero length OBJECT IDENTIFIER"} @@ -269,7 +291,7 @@ func isPrintable(b byte) bool { b == ':' || b == '=' || b == '?' || - // This is techincally not allowed in a PrintableString. + // This is technically not allowed in a PrintableString. // However, x509 certificates with wildcard strings don't // always use the correct string type so we permit it. b == '*' @@ -425,6 +447,7 @@ var ( timeType = reflect.TypeOf(&time.Time{}) rawValueType = reflect.TypeOf(RawValue{}) rawContentsType = reflect.TypeOf(RawContent(nil)) + bigIntType = reflect.TypeOf(new(big.Int)) ) // invalidLength returns true iff offset + length > sliceLength, or if the @@ -639,6 +662,10 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam case flagType: v.SetBool(true) return + case bigIntType: + parsedInt := parseBigInt(innerBytes) + v.Set(reflect.ValueOf(parsedInt)) + return } switch val := v; val.Kind() { case reflect.Bool: |