diff options
Diffstat (limited to 'vendor/github.com/stripe/krl/krl.go')
-rw-r--r-- | vendor/github.com/stripe/krl/krl.go | 372 |
1 files changed, 0 insertions, 372 deletions
diff --git a/vendor/github.com/stripe/krl/krl.go b/vendor/github.com/stripe/krl/krl.go deleted file mode 100644 index e3457f8..0000000 --- a/vendor/github.com/stripe/krl/krl.go +++ /dev/null @@ -1,372 +0,0 @@ -// 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 -} |