feat: cluster addons

This commit is contained in:
Mikaël Cluseau
2018-07-07 12:22:35 +11:00
parent 6c20c29106
commit 975f002935
78 changed files with 3226 additions and 123 deletions

View File

@ -23,6 +23,12 @@ func (b *Builder) AddASN1Int64(v int64) {
b.addASN1Signed(asn1.INTEGER, v)
}
// AddASN1Int64WithTag appends a DER-encoded ASN.1 INTEGER with the
// given tag.
func (b *Builder) AddASN1Int64WithTag(v int64, tag asn1.Tag) {
b.addASN1Signed(tag, v)
}
// AddASN1Enum appends a DER-encoded ASN.1 ENUMERATION.
func (b *Builder) AddASN1Enum(v int64) {
b.addASN1Signed(asn1.ENUM, v)
@ -224,6 +230,9 @@ func (b *Builder) AddASN1(tag asn1.Tag, f BuilderContinuation) {
// String
// ReadASN1Boolean decodes an ASN.1 INTEGER and converts it to a boolean
// representation into out and advances. It reports whether the read
// was successful.
func (s *String) ReadASN1Boolean(out *bool) bool {
var bytes String
if !s.ReadASN1(&bytes, asn1.INTEGER) || len(bytes) != 1 {
@ -245,8 +254,8 @@ func (s *String) ReadASN1Boolean(out *bool) bool {
var bigIntType = reflect.TypeOf((*big.Int)(nil)).Elem()
// ReadASN1Integer decodes an ASN.1 INTEGER into out and advances. If out does
// not point to an integer or to a big.Int, it panics. It returns true on
// success and false on error.
// not point to an integer or to a big.Int, it panics. It reports whether the
// read was successful.
func (s *String) ReadASN1Integer(out interface{}) bool {
if reflect.TypeOf(out).Kind() != reflect.Ptr {
panic("out is not a pointer")
@ -359,8 +368,16 @@ func asn1Unsigned(out *uint64, n []byte) bool {
return true
}
// ReadASN1Enum decodes an ASN.1 ENUMERATION into out and advances. It returns
// true on success and false on error.
// ReadASN1Int64WithTag decodes an ASN.1 INTEGER with the given tag into out
// and advances. It reports whether the read was successful and resulted in a
// value that can be represented in an int64.
func (s *String) ReadASN1Int64WithTag(out *int64, tag asn1.Tag) bool {
var bytes String
return s.ReadASN1(&bytes, tag) && checkASN1Integer(bytes) && asn1Signed(out, bytes)
}
// ReadASN1Enum decodes an ASN.1 ENUMERATION into out and advances. It reports
// whether the read was successful.
func (s *String) ReadASN1Enum(out *int) bool {
var bytes String
var i int64
@ -392,7 +409,7 @@ func (s *String) readBase128Int(out *int) bool {
}
// ReadASN1ObjectIdentifier decodes an ASN.1 OBJECT IDENTIFIER into out and
// advances. It returns true on success and false on error.
// advances. It reports whether the read was successful.
func (s *String) ReadASN1ObjectIdentifier(out *encoding_asn1.ObjectIdentifier) bool {
var bytes String
if !s.ReadASN1(&bytes, asn1.OBJECT_IDENTIFIER) || len(bytes) == 0 {
@ -431,7 +448,7 @@ func (s *String) ReadASN1ObjectIdentifier(out *encoding_asn1.ObjectIdentifier) b
}
// ReadASN1GeneralizedTime decodes an ASN.1 GENERALIZEDTIME into out and
// advances. It returns true on success and false on error.
// advances. It reports whether the read was successful.
func (s *String) ReadASN1GeneralizedTime(out *time.Time) bool {
var bytes String
if !s.ReadASN1(&bytes, asn1.GeneralizedTime) {
@ -449,8 +466,8 @@ func (s *String) ReadASN1GeneralizedTime(out *time.Time) bool {
return true
}
// ReadASN1BitString decodes an ASN.1 BIT STRING into out and advances. It
// returns true on success and false on error.
// ReadASN1BitString decodes an ASN.1 BIT STRING into out and advances.
// It reports whether the read was successful.
func (s *String) ReadASN1BitString(out *encoding_asn1.BitString) bool {
var bytes String
if !s.ReadASN1(&bytes, asn1.BIT_STRING) || len(bytes) == 0 {
@ -471,8 +488,8 @@ func (s *String) ReadASN1BitString(out *encoding_asn1.BitString) bool {
}
// ReadASN1BitString decodes an ASN.1 BIT STRING into out and advances. It is
// an error if the BIT STRING is not a whole number of bytes. This function
// returns true on success and false on error.
// an error if the BIT STRING is not a whole number of bytes. It reports
// whether the read was successful.
func (s *String) ReadASN1BitStringAsBytes(out *[]byte) bool {
var bytes String
if !s.ReadASN1(&bytes, asn1.BIT_STRING) || len(bytes) == 0 {
@ -489,14 +506,14 @@ func (s *String) ReadASN1BitStringAsBytes(out *[]byte) bool {
// ReadASN1Bytes reads the contents of a DER-encoded ASN.1 element (not including
// tag and length bytes) into out, and advances. The element must match the
// given tag. It returns true on success and false on error.
// given tag. It reports whether the read was successful.
func (s *String) ReadASN1Bytes(out *[]byte, tag asn1.Tag) bool {
return s.ReadASN1((*String)(out), tag)
}
// ReadASN1 reads the contents of a DER-encoded ASN.1 element (not including
// tag and length bytes) into out, and advances. The element must match the
// given tag. It returns true on success and false on error.
// given tag. It reports whether the read was successful.
//
// Tags greater than 30 are not supported (i.e. low-tag-number format only).
func (s *String) ReadASN1(out *String, tag asn1.Tag) bool {
@ -509,7 +526,7 @@ func (s *String) ReadASN1(out *String, tag asn1.Tag) bool {
// ReadASN1Element reads the contents of a DER-encoded ASN.1 element (including
// tag and length bytes) into out, and advances. The element must match the
// given tag. It returns true on success and false on error.
// given tag. It reports whether the read was successful.
//
// Tags greater than 30 are not supported (i.e. low-tag-number format only).
func (s *String) ReadASN1Element(out *String, tag asn1.Tag) bool {
@ -521,8 +538,8 @@ func (s *String) ReadASN1Element(out *String, tag asn1.Tag) bool {
}
// ReadAnyASN1 reads the contents of a DER-encoded ASN.1 element (not including
// tag and length bytes) into out, sets outTag to its tag, and advances. It
// returns true on success and false on error.
// tag and length bytes) into out, sets outTag to its tag, and advances.
// It reports whether the read was successful.
//
// Tags greater than 30 are not supported (i.e. low-tag-number format only).
func (s *String) ReadAnyASN1(out *String, outTag *asn1.Tag) bool {
@ -531,14 +548,14 @@ func (s *String) ReadAnyASN1(out *String, outTag *asn1.Tag) bool {
// ReadAnyASN1Element reads the contents of a DER-encoded ASN.1 element
// (including tag and length bytes) into out, sets outTag to is tag, and
// advances. It returns true on success and false on error.
// advances. It reports whether the read was successful.
//
// Tags greater than 30 are not supported (i.e. low-tag-number format only).
func (s *String) ReadAnyASN1Element(out *String, outTag *asn1.Tag) bool {
return s.readASN1(out, outTag, false /* include header */)
}
// PeekASN1Tag returns true if the next ASN.1 value on the string starts with
// PeekASN1Tag reports whether the next ASN.1 value on the string starts with
// the given tag.
func (s String) PeekASN1Tag(tag asn1.Tag) bool {
if len(s) == 0 {
@ -547,7 +564,8 @@ func (s String) PeekASN1Tag(tag asn1.Tag) bool {
return asn1.Tag(s[0]) == tag
}
// SkipASN1 reads and discards an ASN.1 element with the given tag.
// SkipASN1 reads and discards an ASN.1 element with the given tag. It
// reports whether the operation was successful.
func (s *String) SkipASN1(tag asn1.Tag) bool {
var unused String
return s.ReadASN1(&unused, tag)
@ -556,7 +574,7 @@ func (s *String) SkipASN1(tag asn1.Tag) bool {
// ReadOptionalASN1 attempts to read the contents of a DER-encoded ASN.1
// element (not including tag and length bytes) tagged with the given tag into
// out. It stores whether an element with the tag was found in outPresent,
// unless outPresent is nil. It returns true on success and false on error.
// unless outPresent is nil. It reports whether the read was successful.
func (s *String) ReadOptionalASN1(out *String, outPresent *bool, tag asn1.Tag) bool {
present := s.PeekASN1Tag(tag)
if outPresent != nil {
@ -569,7 +587,7 @@ func (s *String) ReadOptionalASN1(out *String, outPresent *bool, tag asn1.Tag) b
}
// SkipOptionalASN1 advances s over an ASN.1 element with the given tag, or
// else leaves s unchanged.
// else leaves s unchanged. It reports whether the operation was successful.
func (s *String) SkipOptionalASN1(tag asn1.Tag) bool {
if !s.PeekASN1Tag(tag) {
return true
@ -581,8 +599,8 @@ func (s *String) SkipOptionalASN1(tag asn1.Tag) bool {
// ReadOptionalASN1Integer attempts to read an optional ASN.1 INTEGER
// explicitly tagged with tag into out and advances. If no element with a
// matching tag is present, it writes defaultValue into out instead. If out
// does not point to an integer or to a big.Int, it panics. It returns true on
// success and false on error.
// does not point to an integer or to a big.Int, it panics. It reports
// whether the read was successful.
func (s *String) ReadOptionalASN1Integer(out interface{}, tag asn1.Tag, defaultValue interface{}) bool {
if reflect.TypeOf(out).Kind() != reflect.Ptr {
panic("out is not a pointer")
@ -619,8 +637,8 @@ func (s *String) ReadOptionalASN1Integer(out interface{}, tag asn1.Tag, defaultV
// ReadOptionalASN1OctetString attempts to read an optional ASN.1 OCTET STRING
// explicitly tagged with tag into out and advances. If no element with a
// matching tag is present, it writes defaultValue into out instead. It returns
// true on success and false on error.
// matching tag is present, it sets "out" to nil instead. It reports
// whether the read was successful.
func (s *String) ReadOptionalASN1OctetString(out *[]byte, outPresent *bool, tag asn1.Tag) bool {
var present bool
var child String
@ -644,6 +662,7 @@ func (s *String) ReadOptionalASN1OctetString(out *[]byte, outPresent *bool, tag
// ReadOptionalASN1Boolean sets *out to the value of the next ASN.1 BOOLEAN or,
// if the next bytes are not an ASN.1 BOOLEAN, to the value of defaultValue.
// It reports whether the operation was successful.
func (s *String) ReadOptionalASN1Boolean(out *bool, defaultValue bool) bool {
var present bool
var child String

View File

@ -149,6 +149,39 @@ func TestReadASN1IntegerSigned(t *testing.T) {
}
}
})
// Repeat with the implicit-tagging functions
t.Run("WithTag", func(t *testing.T) {
for i, test := range testData64 {
tag := asn1.Tag((i * 3) % 32).ContextSpecific()
testData := make([]byte, len(test.in))
copy(testData, test.in)
// Alter the tag of the test case.
testData[0] = uint8(tag)
in := String(testData)
var out int64
ok := in.ReadASN1Int64WithTag(&out, tag)
if !ok || out != test.out {
t.Errorf("#%d: in.ReadASN1Int64WithTag() = %v, want true; out = %d, want %d", i, ok, out, test.out)
}
var b Builder
b.AddASN1Int64WithTag(test.out, tag)
result, err := b.Bytes()
if err != nil {
t.Errorf("#%d: AddASN1Int64WithTag failed: %s", i, err)
continue
}
if !bytes.Equal(result, testData) {
t.Errorf("#%d: AddASN1Int64WithTag: got %x, want %x", i, result, testData)
}
}
})
}
func TestReadASN1IntegerUnsigned(t *testing.T) {

View File

@ -37,8 +37,8 @@ func (s *String) Skip(n int) bool {
return s.read(n) != nil
}
// ReadUint8 decodes an 8-bit value into out and advances over it. It
// returns true on success and false on error.
// ReadUint8 decodes an 8-bit value into out and advances over it.
// It reports whether the read was successful.
func (s *String) ReadUint8(out *uint8) bool {
v := s.read(1)
if v == nil {
@ -49,7 +49,7 @@ func (s *String) ReadUint8(out *uint8) bool {
}
// ReadUint16 decodes a big-endian, 16-bit value into out and advances over it.
// It returns true on success and false on error.
// It reports whether the read was successful.
func (s *String) ReadUint16(out *uint16) bool {
v := s.read(2)
if v == nil {
@ -60,7 +60,7 @@ func (s *String) ReadUint16(out *uint16) bool {
}
// ReadUint24 decodes a big-endian, 24-bit value into out and advances over it.
// It returns true on success and false on error.
// It reports whether the read was successful.
func (s *String) ReadUint24(out *uint32) bool {
v := s.read(3)
if v == nil {
@ -71,7 +71,7 @@ func (s *String) ReadUint24(out *uint32) bool {
}
// ReadUint32 decodes a big-endian, 32-bit value into out and advances over it.
// It returns true on success and false on error.
// It reports whether the read was successful.
func (s *String) ReadUint32(out *uint32) bool {
v := s.read(4)
if v == nil {
@ -119,28 +119,27 @@ func (s *String) readLengthPrefixed(lenLen int, outChild *String) bool {
}
// ReadUint8LengthPrefixed reads the content of an 8-bit length-prefixed value
// into out and advances over it. It returns true on success and false on
// error.
// into out and advances over it. It reports whether the read was successful.
func (s *String) ReadUint8LengthPrefixed(out *String) bool {
return s.readLengthPrefixed(1, out)
}
// ReadUint16LengthPrefixed reads the content of a big-endian, 16-bit
// length-prefixed value into out and advances over it. It returns true on
// success and false on error.
// length-prefixed value into out and advances over it. It reports whether the
// read was successful.
func (s *String) ReadUint16LengthPrefixed(out *String) bool {
return s.readLengthPrefixed(2, out)
}
// ReadUint24LengthPrefixed reads the content of a big-endian, 24-bit
// length-prefixed value into out and advances over it. It returns true on
// success and false on error.
// length-prefixed value into out and advances over it. It reports whether
// the read was successful.
func (s *String) ReadUint24LengthPrefixed(out *String) bool {
return s.readLengthPrefixed(3, out)
}
// ReadBytes reads n bytes into out and advances over them. It returns true on
// success and false and error.
// ReadBytes reads n bytes into out and advances over them. It reports
// whether the read was successful.
func (s *String) ReadBytes(out *[]byte, n int) bool {
v := s.read(n)
if v == nil {
@ -150,8 +149,8 @@ func (s *String) ReadBytes(out *[]byte, n int) bool {
return true
}
// CopyBytes copies len(out) bytes into out and advances over them. It returns
// true on success and false on error.
// CopyBytes copies len(out) bytes into out and advances over them. It reports
// whether the copy operation was successful
func (s *String) CopyBytes(out []byte) bool {
n := len(out)
v := s.read(n)

View File

@ -488,10 +488,6 @@ func ParseResponseForCert(bytes []byte, cert, issuer *x509.Certificate) (*Respon
return nil, err
}
if len(basicResp.Certificates) > 1 {
return nil, ParseError("OCSP response contains bad number of certificates")
}
if n := len(basicResp.TBSResponseData.Responses); n == 0 || cert == nil && n > 1 {
return nil, ParseError("OCSP response contains bad number of responses")
}
@ -544,6 +540,13 @@ func ParseResponseForCert(bytes []byte, cert, issuer *x509.Certificate) (*Respon
}
if len(basicResp.Certificates) > 0 {
// Responders should only send a single certificate (if they
// send any) that connects the responder's certificate to the
// original issuer. We accept responses with multiple
// certificates due to a number responders sending them[1], but
// ignore all but the first.
//
// [1] https://github.com/golang/go/issues/21527
ret.Certificate, err = x509.ParseCertificate(basicResp.Certificates[0].FullBytes)
if err != nil {
return nil, err