mirror of https://github.com/docker/docs.git
Adding Cert retrieval by common name, and renaming KeyID to CertID
Signed-off-by: Diogo Monica <diogo@docker.com>
This commit is contained in:
parent
0313aa5958
commit
58e6544d0a
|
@ -64,7 +64,7 @@ func keysRemove(cmd *cobra.Command, args []string) {
|
|||
gunOrID := args[0]
|
||||
|
||||
// Try to retrieve the ID from the CA store.
|
||||
cert, err := caStore.GetCertificateByKeyID(gunOrID)
|
||||
cert, err := caStore.GetCertificateByCertID(gunOrID)
|
||||
if err == nil {
|
||||
fmt.Printf("Removing: ")
|
||||
printCert(cert)
|
||||
|
@ -78,7 +78,7 @@ func keysRemove(cmd *cobra.Command, args []string) {
|
|||
}
|
||||
|
||||
// Try to retrieve the ID from the Certificate store.
|
||||
cert, err = certificateStore.GetCertificateByKeyID(gunOrID)
|
||||
cert, err = certificateStore.GetCertificateByCertID(gunOrID)
|
||||
if err == nil {
|
||||
fmt.Printf("Removing: ")
|
||||
printCert(cert)
|
||||
|
@ -216,12 +216,12 @@ func keysGenerate(cmd *cobra.Command, args []string) {
|
|||
|
||||
func printCert(cert *x509.Certificate) {
|
||||
timeDifference := cert.NotAfter.Sub(time.Now())
|
||||
keyID, err := trustmanager.FingerprintCert(cert)
|
||||
certID, err := trustmanager.FingerprintCert(cert)
|
||||
if err != nil {
|
||||
fatalf("could not fingerprint certificate: %v", err)
|
||||
}
|
||||
|
||||
fmt.Printf("%s %s (expires in: %v days)\n", cert.Subject.CommonName, keyID, math.Floor(timeDifference.Hours()/24))
|
||||
fmt.Printf("%s %s (expires in: %v days)\n", cert.Subject.CommonName, certID, math.Floor(timeDifference.Hours()/24))
|
||||
}
|
||||
|
||||
func printKey(keyPath string) {
|
||||
|
|
|
@ -70,14 +70,14 @@ func (s X509FileStore) AddCert(cert *x509.Certificate) error {
|
|||
// addNamedCert allows adding a certificate while controling the filename it gets
|
||||
// stored under. If the file does not exist on disk, saves it.
|
||||
func (s X509FileStore) addNamedCert(cert *x509.Certificate) error {
|
||||
fileName, keyID, err := fileName(cert)
|
||||
fileName, certID, err := fileName(cert)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logrus.Debug("Adding cert with keyID: ", keyID)
|
||||
logrus.Debug("Adding cert with certID: ", certID)
|
||||
// Validate if we already loaded this certificate before
|
||||
if _, ok := s.fingerprintMap[keyID]; ok {
|
||||
if _, ok := s.fingerprintMap[certID]; ok {
|
||||
return errors.New("certificate already in the store")
|
||||
}
|
||||
|
||||
|
@ -98,11 +98,11 @@ func (s X509FileStore) addNamedCert(cert *x509.Certificate) error {
|
|||
}
|
||||
|
||||
// We wrote the certificate succcessfully, add it to our in-memory storage
|
||||
s.fingerprintMap[keyID] = cert
|
||||
s.fileMap[keyID] = fileName
|
||||
s.fingerprintMap[certID] = cert
|
||||
s.fileMap[certID] = fileName
|
||||
|
||||
name := string(cert.RawSubject)
|
||||
s.nameMap[name] = append(s.nameMap[name], keyID)
|
||||
name := string(cert.Subject.CommonName)
|
||||
s.nameMap[name] = append(s.nameMap[name], certID)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -113,13 +113,13 @@ func (s X509FileStore) RemoveCert(cert *x509.Certificate) error {
|
|||
return errors.New("removing nil Certificate from X509Store")
|
||||
}
|
||||
|
||||
keyID, err := fingerprintCert(cert)
|
||||
certID, err := fingerprintCert(cert)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
delete(s.fingerprintMap, keyID)
|
||||
filename := s.fileMap[keyID]
|
||||
delete(s.fileMap, keyID)
|
||||
delete(s.fingerprintMap, certID)
|
||||
filename := s.fileMap[certID]
|
||||
delete(s.fileMap, certID)
|
||||
|
||||
name := string(cert.RawSubject)
|
||||
|
||||
|
@ -127,7 +127,7 @@ func (s X509FileStore) RemoveCert(cert *x509.Certificate) error {
|
|||
fpList := s.nameMap[name]
|
||||
newfpList := fpList[:0]
|
||||
for _, x := range fpList {
|
||||
if x != keyID {
|
||||
if x != certID {
|
||||
newfpList = append(newfpList, x)
|
||||
}
|
||||
}
|
||||
|
@ -183,21 +183,48 @@ func (s X509FileStore) GetCertificatePool() *x509.CertPool {
|
|||
return pool
|
||||
}
|
||||
|
||||
// GetCertificateByKeyID returns the certificate that matches a certain keyID or error
|
||||
func (s X509FileStore) GetCertificateByKeyID(keyID string) (*x509.Certificate, error) {
|
||||
// GetCertificateByCertID returns the certificate that matches a certain certID
|
||||
func (s X509FileStore) GetCertificateByCertID(certID string) (*x509.Certificate, error) {
|
||||
return s.getCertificateByCertID(CertID(certID))
|
||||
}
|
||||
|
||||
// getCertificateByCertID returns the certificate that matches a certain certID
|
||||
func (s X509FileStore) getCertificateByCertID(certID CertID) (*x509.Certificate, error) {
|
||||
// If it does not look like a hex encoded sha256 hash, error
|
||||
if len(keyID) != 64 {
|
||||
if len(certID) != 64 {
|
||||
return nil, errors.New("invalid Subject Key Identifier")
|
||||
}
|
||||
|
||||
// Check to see if this subject key identifier exists
|
||||
if cert, ok := s.fingerprintMap[CertID(keyID)]; ok {
|
||||
if cert, ok := s.fingerprintMap[CertID(certID)]; ok {
|
||||
return cert, nil
|
||||
|
||||
}
|
||||
return nil, errors.New("certificate not found in Key Store")
|
||||
}
|
||||
|
||||
// GetCertificatesByCN returns all the certificates that match a specific
|
||||
// CommonName
|
||||
func (s X509FileStore) GetCertificatesByCN(cn string) ([]*x509.Certificate, error) {
|
||||
var certs []*x509.Certificate
|
||||
if ids, ok := s.nameMap[cn]; ok {
|
||||
for _, v := range ids {
|
||||
cert, err := s.getCertificateByCertID(v)
|
||||
if err != nil {
|
||||
// This error should never happen. This would mean that we have
|
||||
// an inconsistent X509FileStore
|
||||
return nil, err
|
||||
}
|
||||
certs = append(certs, cert)
|
||||
}
|
||||
}
|
||||
if len(certs) == 0 {
|
||||
return nil, errors.New("common name not found in Key Store")
|
||||
}
|
||||
|
||||
return certs, nil
|
||||
}
|
||||
|
||||
// GetVerifyOptions returns VerifyOptions with the certificates within the KeyStore
|
||||
// as part of the roots list. This never allows the use of system roots, returning
|
||||
// an error if there are no root CAs.
|
||||
|
@ -217,10 +244,10 @@ func (s X509FileStore) GetVerifyOptions(dnsName string) (x509.VerifyOptions, err
|
|||
}
|
||||
|
||||
func fileName(cert *x509.Certificate) (string, CertID, error) {
|
||||
keyID, err := fingerprintCert(cert)
|
||||
certID, err := fingerprintCert(cert)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
return path.Join(cert.Subject.CommonName, string(keyID)), keyID, nil
|
||||
return path.Join(cert.Subject.CommonName, string(certID)), certID, nil
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ func NewX509MemStore() *X509MemStore {
|
|||
}
|
||||
}
|
||||
|
||||
// NewX509FilteredMemStore returns a new X509FileStore that validates certificates
|
||||
// NewX509FilteredMemStore returns a new X509Memstore that validates certificates
|
||||
// that are added.
|
||||
func NewX509FilteredMemStore(validate func(*x509.Certificate) bool) *X509MemStore {
|
||||
s := &X509MemStore{
|
||||
|
@ -46,14 +46,14 @@ func (s X509MemStore) AddCert(cert *x509.Certificate) error {
|
|||
return errors.New("certificate failed validation")
|
||||
}
|
||||
|
||||
keyID, err := fingerprintCert(cert)
|
||||
certID, err := fingerprintCert(cert)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.fingerprintMap[keyID] = cert
|
||||
s.fingerprintMap[certID] = cert
|
||||
name := string(cert.RawSubject)
|
||||
s.nameMap[name] = append(s.nameMap[name], keyID)
|
||||
s.nameMap[name] = append(s.nameMap[name], certID)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -64,18 +64,18 @@ func (s X509MemStore) RemoveCert(cert *x509.Certificate) error {
|
|||
return errors.New("removing nil Certificate to X509Store")
|
||||
}
|
||||
|
||||
keyID, err := fingerprintCert(cert)
|
||||
certID, err := fingerprintCert(cert)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
delete(s.fingerprintMap, keyID)
|
||||
delete(s.fingerprintMap, certID)
|
||||
name := string(cert.RawSubject)
|
||||
|
||||
// Filter the fingerprint out of this name entry
|
||||
fpList := s.nameMap[name]
|
||||
newfpList := fpList[:0]
|
||||
for _, x := range fpList {
|
||||
if x != keyID {
|
||||
if x != certID {
|
||||
newfpList = append(newfpList, x)
|
||||
}
|
||||
}
|
||||
|
@ -125,21 +125,48 @@ func (s X509MemStore) GetCertificatePool() *x509.CertPool {
|
|||
return pool
|
||||
}
|
||||
|
||||
// GetCertificateByKeyID returns the certificate that matches a certain keyID or error
|
||||
func (s X509MemStore) GetCertificateByKeyID(keyID string) (*x509.Certificate, error) {
|
||||
// GetCertificateByCertID returns the certificate that matches a certain certID
|
||||
func (s X509MemStore) GetCertificateByCertID(certID string) (*x509.Certificate, error) {
|
||||
return s.getCertificateByCertID(CertID(certID))
|
||||
}
|
||||
|
||||
// getCertificateByCertID returns the certificate that matches a certain certID or error
|
||||
func (s X509MemStore) getCertificateByCertID(certID CertID) (*x509.Certificate, error) {
|
||||
// If it does not look like a hex encoded sha256 hash, error
|
||||
if len(keyID) != 64 {
|
||||
if len(certID) != 64 {
|
||||
return nil, errors.New("invalid Subject Key Identifier")
|
||||
}
|
||||
|
||||
// Check to see if this subject key identifier exists
|
||||
if cert, ok := s.fingerprintMap[CertID(keyID)]; ok {
|
||||
if cert, ok := s.fingerprintMap[CertID(certID)]; ok {
|
||||
return cert, nil
|
||||
|
||||
}
|
||||
return nil, errors.New("certificate not found in Key Store")
|
||||
}
|
||||
|
||||
// GetCertificatesByCN returns all the certificates that match a specific
|
||||
// CommonName
|
||||
func (s X509MemStore) GetCertificatesByCN(cn string) ([]*x509.Certificate, error) {
|
||||
var certs []*x509.Certificate
|
||||
if ids, ok := s.nameMap[cn]; ok {
|
||||
for _, v := range ids {
|
||||
cert, err := s.getCertificateByCertID(v)
|
||||
if err != nil {
|
||||
// This error should never happen. This would mean that we have
|
||||
// an inconsistent X509MemStore
|
||||
return nil, err
|
||||
}
|
||||
certs = append(certs, cert)
|
||||
}
|
||||
}
|
||||
if len(certs) == 0 {
|
||||
return nil, errors.New("common name not found in Key Store")
|
||||
}
|
||||
|
||||
return certs, nil
|
||||
}
|
||||
|
||||
// GetVerifyOptions returns VerifyOptions with the certificates within the KeyStore
|
||||
// as part of the roots list. This never allows the use of system roots, returning
|
||||
// an error if there are no root CAs.
|
||||
|
|
|
@ -106,14 +106,14 @@ func TestRemoveCert(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestInexistentGetCertificateByKeyID(t *testing.T) {
|
||||
func TestInexistentGetCertificateByCertID(t *testing.T) {
|
||||
store := NewX509MemStore()
|
||||
err := store.AddCertFromFile("../fixtures/root-ca.crt")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load certificate from file: %v", err)
|
||||
}
|
||||
|
||||
_, err = store.GetCertificateByKeyID("4d06afd30b8bed131d2a84c97d00b37f422021598bfae34285ce98e77b708b5a")
|
||||
_, err = store.GetCertificateByCertID("4d06afd30b8bed131d2a84c97d00b37f422021598bfae34285ce98e77b708b5a")
|
||||
if err == nil {
|
||||
t.Fatalf("no error returned for inexistent certificate")
|
||||
}
|
||||
|
@ -138,15 +138,15 @@ func TestGetCertificateByKeyID(t *testing.T) {
|
|||
t.Fatalf("failed to load certificate from PEM: %v", err)
|
||||
}
|
||||
|
||||
keyID, err := FingerprintCert(cert)
|
||||
certID, err := FingerprintCert(cert)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to fingerprint the certificate: %v", err)
|
||||
}
|
||||
|
||||
// Tries to retrieve cert by Subject Key IDs
|
||||
_, err = store.GetCertificateByKeyID(keyID)
|
||||
_, err = store.GetCertificateByCertID(certID)
|
||||
if err != nil {
|
||||
t.Fatalf("expected certificate in store: %s", keyID)
|
||||
t.Fatalf("expected certificate in store: %s", certID)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,8 @@ type X509Store interface {
|
|||
AddCertFromPEM(pemCerts []byte) error
|
||||
AddCertFromFile(filename string) error
|
||||
RemoveCert(cert *x509.Certificate) error
|
||||
GetCertificateByKeyID(keyID string) (*x509.Certificate, error)
|
||||
GetCertificateByCertID(certID string) (*x509.Certificate, error)
|
||||
GetCertificatesByCN(cn string) ([]*x509.Certificate, error)
|
||||
GetCertificates() []*x509.Certificate
|
||||
GetCertificatePool() *x509.CertPool
|
||||
GetVerifyOptions(dnsName string) (x509.VerifyOptions, error)
|
||||
|
|
Loading…
Reference in New Issue