diff options
Diffstat (limited to 'vendor')
-rw-r--r-- | vendor/github.com/stripe/krl/LICENSE | 20 | ||||
-rw-r--r-- | vendor/github.com/stripe/krl/README.md | 7 | ||||
-rw-r--r-- | vendor/github.com/stripe/krl/format.go | 163 | ||||
-rw-r--r-- | vendor/github.com/stripe/krl/krl.go | 372 | ||||
-rw-r--r-- | vendor/github.com/stripe/krl/parse.go | 237 | ||||
-rw-r--r-- | vendor/vendor.json | 6 |
6 files changed, 805 insertions, 0 deletions
diff --git a/vendor/github.com/stripe/krl/LICENSE b/vendor/github.com/stripe/krl/LICENSE new file mode 100644 index 0000000..f3241a2 --- /dev/null +++ b/vendor/github.com/stripe/krl/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2015, 2016 Stripe, Inc. + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/stripe/krl/README.md b/vendor/github.com/stripe/krl/README.md new file mode 100644 index 0000000..6402e63 --- /dev/null +++ b/vendor/github.com/stripe/krl/README.md @@ -0,0 +1,7 @@ +krl +=== + +[![GoDoc](https://godoc.org/github.com/stripe/krl?status.svg)](https://godoc.org/github.com/stripe/krl) + +Package krl provides functionality for reading and writing SSH Key Revocation +Lists (KRLs). diff --git a/vendor/github.com/stripe/krl/format.go b/vendor/github.com/stripe/krl/format.go new file mode 100644 index 0000000..4a4b822 --- /dev/null +++ b/vendor/github.com/stripe/krl/format.go @@ -0,0 +1,163 @@ +package krl + +import "math/big" + +// We (unfortunately) make extensive use of x/crypto/ssh.Unmarshal's "rest" +// parameter here. The KRL specification makes extensive use of sections placed +// back-to-back, and there's no other way to get x/crypto/ssh.Unmarshal to emit +// the portion of the input that has not yet been parsed. + +const krlMagic = 0x5353484b524c0a00 + +/* +#define KRL_MAGIC 0x5353484b524c0a00ULL /* "SSHKRL\n\0" * / +#define KRL_FORMAT_VERSION 1 + + uint64 KRL_MAGIC + uint32 KRL_FORMAT_VERSION + uint64 krl_version + uint64 generated_date + uint64 flags + string reserved + string comment +*/ +type krlHeader struct { + KRLMagic uint64 + KRLFormatVersion uint32 + KRLVersion uint64 + GeneratedDate uint64 + Flags uint64 + Reserved []byte + Comment string + + Rest []byte `ssh:"rest"` +} + +/* + byte section_type + string section_data + +#define KRL_SECTION_CERTIFICATES 1 +#define KRL_SECTION_EXPLICIT_KEY 2 +#define KRL_SECTION_FINGERPRINT_SHA1 3 +#define KRL_SECTION_SIGNATURE 4 +*/ +type krlSection struct { + SectionType byte + SectionData []byte + + Rest []byte `ssh:"rest"` +} + +/* + string ca_key + string reserved +*/ +type krlCertificateSectionHeader struct { + CAKey []byte + Reserved []byte + + Rest []byte `ssh:"rest"` +} + +/* + byte cert_section_type + string cert_section_data + +#define KRL_SECTION_CERT_SERIAL_LIST 0x20 +#define KRL_SECTION_CERT_SERIAL_RANGE 0x21 +#define KRL_SECTION_CERT_SERIAL_BITMAP 0x22 +#define KRL_SECTION_CERT_KEY_ID 0x23 +*/ +type krlCertificateSection struct { + CertSectionType byte + CertSectionData []byte + + Rest []byte `ssh:"rest"` +} + +const ( + krlSectionCertSerialList = 0x20 + krlSectionCertSerialRange = 0x21 + krlSectionCertSerialBitmap = 0x22 + krlSectionCertKeyId = 0x23 +) + +/* + uint64 revoked_cert_serial + uint64 ... +*/ +type krlSerialList struct { + RevokedCertSerial uint64 + + Rest []byte `ssh:"rest"` +} + +/* + uint64 serial_min + uint64 serial_max +*/ +type krlSerialRange struct { + SerialMin uint64 + SerialMax uint64 +} + +/* + uint64 serial_offset + mpint revoked_keys_bitmap +*/ +type krlSerialBitmap struct { + SerialOffset uint64 + RevokedKeysBitmap *big.Int +} + +/* + string key_id[0] + ... +*/ +type krlKeyID struct { + KeyID string + + Rest []byte `ssh:"rest"` +} + +/* + string public_key_blob[0] + .... +*/ +type krlExplicitKey struct { + PublicKeyBlob []byte + + Rest []byte `ssh:"rest"` +} + +/* + string public_key_hash[0] + .... +*/ +type krlFingerprintSHA1 struct { + PublicKeyHash []byte + + Rest []byte `ssh:"rest"` +} + +/* + byte KRL_SECTION_SIGNATURE + string signature_key + string signature + +We split this struct into two parts: krlSignatureHeader is included in the +signature, and so the inverse of its "Rest" key is the data coverd by the +signature. +*/ +type krlSignatureHeader struct { + SignatureKey []byte `sshtype:"4"` + + Rest []byte `ssh:"rest"` +} + +type krlSignature struct { + Signature []byte + + Rest []byte `ssh:"rest"` +} diff --git a/vendor/github.com/stripe/krl/krl.go b/vendor/github.com/stripe/krl/krl.go new file mode 100644 index 0000000..e3457f8 --- /dev/null +++ b/vendor/github.com/stripe/krl/krl.go @@ -0,0 +1,372 @@ +// Package krl provides functionality for reading and writing SSH Key Revocation +// Lists (KRLs). +// +// References: +// https://raw.githubusercontent.com/openssh/openssh-portable/master/PROTOCOL.krl +package krl + +import ( + "bytes" + "crypto/sha1" + "io" + "math/big" + "sort" + "time" + + "golang.org/x/crypto/ssh" +) + +// KRL, or Key Revocation List, is a list of revoked keys, certificates, and +// identities, possibly signed by some authority. The zero value of KRL is +// appropriate for use, and represents an empty list. +type KRL struct { + // Version is a number that increases every time the KRL is modified. + // When marshaling a KRL, if Version is zero GeneratedDate will be used + // instead. + Version uint64 + // GeneratedDate is the Unix timestamp the KRL was generated at. When + // marshaling a KRL, if GeneratedDate is zero the current Unix timestamp + // will be used instead. + GeneratedDate uint64 + // Comment is an optional comment for the KRL. + Comment string + // Sections is a list of public key and certificate selectors that this + // KRL applies to. + Sections []KRLSection + // SigningKeys is set by ParseKRL and Marshal to the list of Signers + // that signed (or which claimed to sign) the KRL in the order they + // appeared (i.e., innermost-first). + SigningKeys []ssh.PublicKey +} + +/* +KRLSection describes a section of a KRL, which selects certain certificates and +keys for revocation. The concrete types KRLCertificateSection, +KRLExplicitKeySection, and KRLFingerprintSection satisfy this interface, and +correspond to the three types of KRL sections currently defined. +*/ +type KRLSection interface { + isRevoked(key ssh.PublicKey) bool + marshal() []byte +} + +/* +KRLCertificateSection revokes SSH certificates by certificate authority and +either serial numbers or key ids. +*/ +type KRLCertificateSection struct { + // CA is the certificate authority whose keys are being revoked by this + // section. If CA is nil, this section applies to keys signed by any + // certificate authority. + CA ssh.PublicKey + // Sections is a list of certificate selectors. + Sections []KRLCertificateSubsection +} + +func (k *KRLCertificateSection) isRevoked(key ssh.PublicKey) bool { + cert, ok := key.(*ssh.Certificate) + if !ok { + return false + } + + if k.CA != nil { + sk := cert.SignatureKey.Marshal() + ca := k.CA.Marshal() + if !bytes.Equal(sk, ca) { + return false + } + } + + for _, section := range k.Sections { + if section.isRevoked(cert) { + return true + } + } + return false +} + +func (k *KRLCertificateSection) marshal() []byte { + var buf bytes.Buffer + var ca []byte + if k.CA != nil { + ca = k.CA.Marshal() + } + buf.Write(ssh.Marshal(krlCertificateSectionHeader{CAKey: ca})) + headerLen := buf.Len() + for _, section := range k.Sections { + buf.Write(section.marshal()) + } + // All subsections were empty; we should be empty too. + if buf.Len() == headerLen { + return nil + } + return ssh.Marshal(krlSection{ + SectionType: 1, + SectionData: buf.Bytes(), + }) +} + +/* +KRLCertificateSubsection describes a subsection of a KRL certificate selection, +and selects certain certificates for revocation. The concrete types +KRLCertificateSerialList, KRLCertificateSerialRange, KRLCertificateSerialBitmap, +and KRLCertificateSerialBitmap satisfy this interface, and correspond to the +four subsections currently defined. +*/ +type KRLCertificateSubsection interface { + isRevoked(cert *ssh.Certificate) bool + marshal() []byte +} + +// KRLCertificateSerialList revokes certificates by listing their serial +// numbers. +type KRLCertificateSerialList []uint64 + +func (k *KRLCertificateSerialList) isRevoked(cert *ssh.Certificate) bool { + for _, serial := range *k { + if serial == cert.Serial { + return true + } + } + return false +} + +func (k *KRLCertificateSerialList) marshal() []byte { + if len(*k) == 0 { + return nil + } + + var buf bytes.Buffer + for _, serial := range *k { + buf.Write(ssh.Marshal(krlSerialList{ + RevokedCertSerial: serial, + })) + } + return ssh.Marshal(krlCertificateSection{ + CertSectionType: krlSectionCertSerialList, + CertSectionData: buf.Bytes(), + }) +} + +// KRLCertificateSerialRange revokes all certificates with serial numbers in the +// range between Min and Max, inclusive. +type KRLCertificateSerialRange struct { + Min, Max uint64 +} + +func (k *KRLCertificateSerialRange) isRevoked(cert *ssh.Certificate) bool { + return k.Min <= cert.Serial && cert.Serial <= k.Max +} + +func (k *KRLCertificateSerialRange) marshal() []byte { + return ssh.Marshal(krlCertificateSection{ + CertSectionType: krlSectionCertSerialRange, + CertSectionData: ssh.Marshal(krlSerialRange{ + SerialMin: k.Min, + SerialMax: k.Max, + }), + }) +} + +// KRLCertificateSerialBitmap revokes certificates densely using a bitmap. If +// bit N of the bitmap is set, the certificate with serial Offset + N is +// revoked. +type KRLCertificateSerialBitmap struct { + Offset uint64 + Bitmap *big.Int +} + +func (k *KRLCertificateSerialBitmap) isRevoked(cert *ssh.Certificate) bool { + if cert.Serial < k.Offset { + return false + } + if cert.Serial-k.Offset > krlMaxBitmapSize { + return false + } + return k.Bitmap.Bit(int(cert.Serial-k.Offset)) == 1 +} + +func (k *KRLCertificateSerialBitmap) marshal() []byte { + return ssh.Marshal(krlCertificateSection{ + CertSectionType: krlSectionCertSerialBitmap, + CertSectionData: ssh.Marshal(krlSerialBitmap{ + SerialOffset: k.Offset, + RevokedKeysBitmap: k.Bitmap, + }), + }) +} + +// KRLCertificateKeyID revokes certificates by listing key ids. This may be +// useful in revoking all certificates associated with a particular identity, +// for instance hosts or users. +type KRLCertificateKeyID []string + +func (k *KRLCertificateKeyID) isRevoked(cert *ssh.Certificate) bool { + for _, id := range *k { + if id == cert.KeyId { + return true + } + } + return false +} + +func (k *KRLCertificateKeyID) marshal() []byte { + if len(*k) == 0 { + return nil + } + + var buf bytes.Buffer + for _, id := range *k { + buf.Write(ssh.Marshal(krlKeyID{ + KeyID: id, + })) + } + return ssh.Marshal(krlCertificateSection{ + CertSectionType: krlSectionCertKeyId, + CertSectionData: buf.Bytes(), + }) +} + +// ssh.PublicKey objects might be certificates, which have a different wire +// format. +func marshalPubkey(key ssh.PublicKey) []byte { + switch v := key.(type) { + case *ssh.Certificate: + return marshalPubkey(v.Key) + default: + return key.Marshal() + } +} + +// KRLExplicitKeySection revokes keys by explicitly listing them. +type KRLExplicitKeySection []ssh.PublicKey + +func (k *KRLExplicitKeySection) isRevoked(key ssh.PublicKey) bool { + kbuf := marshalPubkey(key) + for _, key := range *k { + if bytes.Equal(kbuf, marshalPubkey(key)) { + return true + } + } + return false +} + +func (k *KRLExplicitKeySection) marshal() []byte { + if len(*k) == 0 { + return nil + } + + var buf bytes.Buffer + for _, key := range *k { + buf.Write(ssh.Marshal(krlExplicitKey{ + PublicKeyBlob: marshalPubkey(key), + })) + } + return ssh.Marshal(krlSection{ + SectionType: 2, + SectionData: buf.Bytes(), + }) +} + +// KRLFingerprintSection revokes keys by their SHA1 fingerprints. It is +// semantically equivalent to--but is more space efficient than-- +// KRLExplicitKeySection. +type KRLFingerprintSection [][sha1.Size]byte + +func (k *KRLFingerprintSection) isRevoked(key ssh.PublicKey) bool { + sha := sha1.Sum(marshalPubkey(key)) + for _, hash := range *k { + if hash == sha { + return true + } + } + return false +} + +type bigEndian [][sha1.Size]byte + +func (b bigEndian) Len() int { + return len(b) +} +func (b bigEndian) Less(i, j int) bool { + return bytes.Compare(b[i][:], b[j][:]) == -1 +} +func (b bigEndian) Swap(i, j int) { + b[i], b[j] = b[j], b[i] +} + +func (k *KRLFingerprintSection) marshal() []byte { + if len(*k) == 0 { + return nil + } + + // For some reason SSH insists that keys revoked by fingerprint must be + // sorted as if they were big-endian integers (i.e., lexicographically). + be := make(bigEndian, len(*k)) + for i, hash := range *k { + be[i] = hash + } + sort.Sort(be) + + var buf bytes.Buffer + for _, hash := range be { + buf.Write(ssh.Marshal(krlFingerprintSHA1{ + PublicKeyHash: hash[:], + })) + } + return ssh.Marshal(krlSection{ + SectionType: 3, + SectionData: buf.Bytes(), + }) +} + +// Marshal serializes the KRL and optionally signs it with one or more authority +// keys. +func (k *KRL) Marshal(rand io.Reader, keys ...ssh.Signer) ([]byte, error) { + if k.GeneratedDate == 0 { + k.GeneratedDate = uint64(time.Now().Unix()) + } + if k.Version == 0 { + k.Version = k.GeneratedDate + } + k.SigningKeys = nil + + var buf bytes.Buffer + buf.Write(ssh.Marshal(krlHeader{ + KRLMagic: krlMagic, + KRLFormatVersion: 1, + KRLVersion: k.Version, + GeneratedDate: k.GeneratedDate, + Comment: k.Comment, + })) + + for _, section := range k.Sections { + buf.Write(section.marshal()) + } + + for _, key := range keys { + buf.Write(ssh.Marshal(krlSignatureHeader{ + SignatureKey: key.PublicKey().Marshal(), + })) + sig, err := key.Sign(rand, buf.Bytes()) + if err != nil { + return nil, err + } + buf.Write(ssh.Marshal(krlSignature{ + Signature: ssh.Marshal(sig), + })) + k.SigningKeys = append(k.SigningKeys, key.PublicKey()) + } + + return buf.Bytes(), nil +} + +// IsRevoked returns true if the given key has been revoked by this KRL. +func (k *KRL) IsRevoked(key ssh.PublicKey) bool { + for _, section := range k.Sections { + if section.isRevoked(key) { + return true + } + } + return false +} diff --git a/vendor/github.com/stripe/krl/parse.go b/vendor/github.com/stripe/krl/parse.go new file mode 100644 index 0000000..75f2551 --- /dev/null +++ b/vendor/github.com/stripe/krl/parse.go @@ -0,0 +1,237 @@ +package krl + +import ( + "crypto/sha1" + "fmt" + + "golang.org/x/crypto/ssh" +) + +// Hundreds of millions, or 32MB of bitmap +const krlMaxBitmapSize = 0x10000000 + +// KRLSigningErrors is a slice of error messages which correspond one-to-one +// with KRL.SigningKeys. +type KRLSigningErrors []error + +func (k KRLSigningErrors) Error() string { + return fmt.Sprintf("krl: bad signatures: %v", []error(k)) +} + +func (k KRLSigningErrors) err() error { + for _, err := range k { + if err != nil { + return k + } + } + return nil +} + +// ParseKRL parses a KRL. If the KRL was signed by one or more authorities, +// those signatures will be checked, and any verification errors will be +// returned. +func ParseKRL(in []byte) (*KRL, error) { + orig := in + + var header krlHeader + if err := ssh.Unmarshal(in, &header); err != nil { + return nil, fmt.Errorf("krl: while parsing header: %v", err) + } + if header.KRLMagic != krlMagic { + return nil, fmt.Errorf("krl: bad magic value %x", header.KRLMagic) + } + if header.KRLFormatVersion != 1 { + return nil, fmt.Errorf("krl: bad format version %v", header.KRLFormatVersion) + } + krl := &KRL{ + Version: header.KRLVersion, + GeneratedDate: header.GeneratedDate, + Comment: header.Comment, + } + in = header.Rest + + for len(in) > 0 && in[0] != 4 { // // KRL_SECTION_SIGNATURE + var sdata krlSection + if err := ssh.Unmarshal(in, &sdata); err != nil { + return nil, fmt.Errorf("krl: malformed section: %v", err) + } + in = sdata.Rest + + var err error + var section KRLSection + switch sdata.SectionType { + case 1: // KRL_SECTION_CERTIFICATES + section, err = parseCertificateSection(sdata.SectionData) + case 2: // KRL_SECTION_EXPLICIT_KEY + section, err = parseExplicitKeySection(sdata.SectionData) + case 3: // KRL_SECTION_FINGERPRINT_SHA1 + section, err = parseFingerprintSection(sdata.SectionData) + default: + return nil, fmt.Errorf("krl: unexpected section type %d", sdata.SectionType) + } + if err != nil { + return nil, err + } + krl.Sections = append(krl.Sections, section) + } + + var signingErrors KRLSigningErrors + for len(in) > 0 { + var sigHeader krlSignatureHeader + if err := ssh.Unmarshal(in, &sigHeader); err != nil { + return nil, fmt.Errorf("krl: malfored signature header: %v", err) + } + in = sigHeader.Rest + + key, err := ssh.ParsePublicKey(sigHeader.SignatureKey) + if err != nil { + return nil, fmt.Errorf("krl: malformed signing key: %v", err) + } + + var sig krlSignature + if err := ssh.Unmarshal(in, &sig); err != nil { + return nil, fmt.Errorf("krl: malfored signature wrapper: %v", err) + } + in = sig.Rest + + sshsig := new(ssh.Signature) + if err := ssh.Unmarshal(sig.Signature, sshsig); err != nil { + return nil, fmt.Errorf("krl: malformed signature: %v", err) + } + + // The entire KRL up until immediately after the signature + // header is signed. + data := orig[:len(orig)-len(sigHeader.Rest)] + + krl.SigningKeys = append(krl.SigningKeys, key) + signingErrors = append(signingErrors, key.Verify(data, sshsig)) + } + + return krl, signingErrors.err() +} + +func parseCertificateSection(in []byte) (*KRLCertificateSection, error) { + var header krlCertificateSectionHeader + if err := ssh.Unmarshal(in, &header); err != nil { + return nil, fmt.Errorf("krl: while parsing certificate section header: %v", err) + } + ca, err := ssh.ParsePublicKey(header.CAKey) + if err != nil { + return nil, fmt.Errorf("krl: while parsing CA key: %v", err) + } + k := &KRLCertificateSection{CA: ca} + in = header.Rest + for len(in) > 0 { + var section krlCertificateSection + if err := ssh.Unmarshal(in, §ion); err != nil { + return nil, fmt.Errorf("krl: malformed certificate section: %v", err) + } + in = section.Rest + var err error + var subsection KRLCertificateSubsection + switch section.CertSectionType { + case krlSectionCertSerialList: + subsection, err = parseCertSerialList(section.CertSectionData) + case krlSectionCertSerialRange: + subsection, err = parseCertSerialRange(section.CertSectionData) + case krlSectionCertSerialBitmap: + subsection, err = parseCertSerialBitmap(section.CertSectionData) + case krlSectionCertKeyId: + subsection, err = parseCertKeyID(section.CertSectionData) + default: + return nil, fmt.Errorf("krl: unexpected cert section type %x", in[0]) + } + if err != nil { + return nil, err + } + k.Sections = append(k.Sections, subsection) + } + + return k, nil +} + +func parseCertSerialList(in []byte) (*KRLCertificateSerialList, error) { + s := &KRLCertificateSerialList{} + for len(in) > 0 { + var list krlSerialList + if err := ssh.Unmarshal(in, &list); err != nil { + return nil, fmt.Errorf("krl: while parsing serial in list: %v", err) + } + in = list.Rest + *s = append(*s, list.RevokedCertSerial) + } + return s, nil +} + +func parseCertSerialRange(in []byte) (*KRLCertificateSerialRange, error) { + var s krlSerialRange + if err := ssh.Unmarshal(in, &s); err != nil { + return nil, fmt.Errorf("krl: while parsing serial range: %v", err) + } + return &KRLCertificateSerialRange{ + Min: s.SerialMin, + Max: s.SerialMax, + }, nil +} + +func parseCertSerialBitmap(in []byte) (*KRLCertificateSerialBitmap, error) { + var s krlSerialBitmap + if err := ssh.Unmarshal(in, &s); err != nil { + return nil, fmt.Errorf("krl: while parsing serial bitmap: %v", err) + } + if bl := s.RevokedKeysBitmap.BitLen(); bl > krlMaxBitmapSize { + return nil, fmt.Errorf("krl: serial bitmap too wide: %v", bl) + } + return &KRLCertificateSerialBitmap{ + Offset: s.SerialOffset, + Bitmap: s.RevokedKeysBitmap, + }, nil +} + +func parseCertKeyID(in []byte) (*KRLCertificateKeyID, error) { + s := &KRLCertificateKeyID{} + for len(in) > 0 { + var list krlKeyID + if err := ssh.Unmarshal(in, &list); err != nil { + return nil, fmt.Errorf("krl: while parsing key id in list: %v", err) + } + in = list.Rest + *s = append(*s, list.KeyID) + } + return s, nil +} + +func parseExplicitKeySection(in []byte) (*KRLExplicitKeySection, error) { + s := &KRLExplicitKeySection{} + for len(in) > 0 { + var list krlExplicitKey + if err := ssh.Unmarshal(in, &list); err != nil { + return nil, fmt.Errorf("krl: while parsing explicit key in list: %v", err) + } + in = list.Rest + key, err := ssh.ParsePublicKey(list.PublicKeyBlob) + if err != nil { + return nil, fmt.Errorf("krl: while parsing explicit key: %v", err) + } + *s = append(*s, key) + } + return s, nil +} + +func parseFingerprintSection(in []byte) (*KRLFingerprintSection, error) { + s := &KRLFingerprintSection{} + for len(in) > 0 { + var list krlFingerprintSHA1 + if err := ssh.Unmarshal(in, &list); err != nil { + return nil, fmt.Errorf("krl: while parsing fingerprint in list: %v", err) + } + in = list.Rest + if len(list.PublicKeyHash) != sha1.Size { + return nil, fmt.Errorf("krl: key fingerprint wrong length for SHA1: %x", list.PublicKeyHash) + } + var sha [sha1.Size]byte + copy(sha[:], list.PublicKeyHash) + *s = append(*s, sha) + } + return s, nil +} diff --git a/vendor/vendor.json b/vendor/vendor.json index 4e31773..a687a53 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -377,6 +377,12 @@ "revisionTime": "2016-06-15T09:26:46Z" }, { + "checksumSHA1": "Mqb+Cn1S2ZN/nOfn8FDaAiXTdhU=", + "path": "github.com/stripe/krl", + "revision": "fd565ec6f8e236d6b63b953f3aecb2f2cca80605", + "revisionTime": "2016-07-21T22:16:07Z" + }, + { "checksumSHA1": "BS9oue0y6JjMzz3spKlMTVmxZxo=", "path": "go4.org/wkfs", "revision": "85455cb60c902182109ca27131042a41bc4cb85d", |