Example #1
0
// validRootLeafCerts returns a list of possibly (if checkExpiry is true) non-expired, non-sha1 certificates
// found in root whose Common-Names match the provided GUN. Note that this
// "validity" alone does not imply any measure of trust.
func validRootLeafCerts(allLeafCerts map[string]*x509.Certificate, gun string, checkExpiry bool) (map[string]*x509.Certificate, error) {
	validLeafCerts := make(map[string]*x509.Certificate)

	// Go through every leaf certificate and check that the CN matches the gun
	for id, cert := range allLeafCerts {
		// Validate that this leaf certificate has a CN that matches the exact gun
		if cert.Subject.CommonName != gun {
			logrus.Debugf("error leaf certificate CN: %s doesn't match the given GUN: %s",
				cert.Subject.CommonName, gun)
			continue
		}
		// Make sure the certificate is not expired if checkExpiry is true
		// and warn if it hasn't expired yet but is within 6 months of expiry
		if err := utils.ValidateCertificate(cert, checkExpiry); err != nil {
			logrus.Debugf("%s is invalid: %s", id, err.Error())
			continue
		}

		validLeafCerts[id] = cert
	}

	if len(validLeafCerts) < 1 {
		logrus.Debugf("didn't find any valid leaf certificates for %s", gun)
		return nil, errors.New("no valid leaf certificates found in any of the root keys")
	}

	logrus.Debugf("found %d valid leaf certificates for %s: %s", len(validLeafCerts), gun,
		prettyFormatCertIDs(validLeafCerts))
	return validLeafCerts, nil
}
Example #2
0
// validRootIntCerts filters the passed in structure of intermediate certificates to only include non-expired, non-sha1 certificates
// Note that this "validity" alone does not imply any measure of trust.
func validRootIntCerts(allIntCerts map[string][]*x509.Certificate) map[string][]*x509.Certificate {
	validIntCerts := make(map[string][]*x509.Certificate)

	// Go through every leaf cert ID, and build its valid intermediate certificate list
	for leafID, intCertList := range allIntCerts {
		for _, intCert := range intCertList {
			if err := utils.ValidateCertificate(intCert, true); err != nil {
				continue
			}
			validIntCerts[leafID] = append(validIntCerts[leafID], intCert)
		}

	}
	return validIntCerts
}
Example #3
0
// NewTrustPinChecker returns a new certChecker function from a TrustPinConfig for a GUN
func NewTrustPinChecker(trustPinConfig TrustPinConfig, gun string, firstBootstrap bool) (CertChecker, error) {
	t := trustPinChecker{gun: gun, config: trustPinConfig}
	// Determine the mode, and if it's even valid
	if pinnedCerts, ok := trustPinConfig.Certs[gun]; ok {
		logrus.Debugf("trust-pinning using Cert IDs")
		t.pinnedCertIDs = pinnedCerts
		return t.certsCheck, nil
	}

	if caFilepath, err := getPinnedCAFilepathByPrefix(gun, trustPinConfig); err == nil {
		logrus.Debugf("trust-pinning using root CA bundle at: %s", caFilepath)

		// Try to add the CA certs from its bundle file to our certificate store,
		// and use it to validate certs in the root.json later
		caCerts, err := utils.LoadCertBundleFromFile(caFilepath)
		if err != nil {
			return nil, fmt.Errorf("could not load root cert from CA path")
		}
		// Now only consider certificates that are direct children from this CA cert chain
		caRootPool := x509.NewCertPool()
		for _, caCert := range caCerts {
			if err = utils.ValidateCertificate(caCert, true); err != nil {
				logrus.Debugf("ignoring root CA certificate with CN %s in bundle: %s", caCert.Subject.CommonName, err)
				continue
			}
			caRootPool.AddCert(caCert)
		}
		// If we didn't have any valid CA certs, error out
		if len(caRootPool.Subjects()) == 0 {
			return nil, fmt.Errorf("invalid CA certs provided")
		}
		t.pinnedCAPool = caRootPool
		return t.caCheck, nil
	}

	// If TOFUs is disabled and we don't have any previous trusted root data for this GUN, we error out
	if trustPinConfig.DisableTOFU && firstBootstrap {
		return nil, fmt.Errorf("invalid trust pinning specified")

	}
	return t.tofusCheck, nil
}
Example #4
0
File: tuf.go Project: Mic92/docker
// GetDelegationRole gets a delegation role from this repo's metadata, walking from the targets role down to the delegation itself
func (tr *Repo) GetDelegationRole(name string) (data.DelegationRole, error) {
	if !data.IsDelegation(name) {
		return data.DelegationRole{}, data.ErrInvalidRole{Role: name, Reason: "invalid delegation name"}
	}
	if tr.Root == nil {
		return data.DelegationRole{}, ErrNotLoaded{data.CanonicalRootRole}
	}
	_, ok := tr.Root.Signed.Roles[data.CanonicalTargetsRole]
	if !ok {
		return data.DelegationRole{}, ErrNotLoaded{data.CanonicalTargetsRole}
	}
	// Traverse target metadata, down to delegation itself
	// Get all public keys for the base role from TUF metadata
	_, ok = tr.Targets[data.CanonicalTargetsRole]
	if !ok {
		return data.DelegationRole{}, ErrNotLoaded{data.CanonicalTargetsRole}
	}

	// Start with top level roles in targets. Walk the chain of ancestors
	// until finding the desired role, or we run out of targets files to search.
	var foundRole *data.DelegationRole
	buildDelegationRoleVisitor := func(tgt *data.SignedTargets, validRole data.DelegationRole) interface{} {
		// Try to find the delegation and build a DelegationRole structure
		for _, role := range tgt.Signed.Delegations.Roles {
			if role.Name == name {
				delgRole, err := tgt.BuildDelegationRole(name)
				if err != nil {
					return err
				}
				// Check all public key certificates in the role for expiry
				// Currently we do not reject expired delegation keys but warn if they might expire soon or have already
				for keyID, pubKey := range delgRole.Keys {
					certFromKey, err := utils.LoadCertFromPEM(pubKey.Public())
					if err != nil {
						continue
					}
					if err := utils.ValidateCertificate(certFromKey, true); err != nil {
						if _, ok := err.(data.ErrCertExpired); !ok {
							// do not allow other invalid cert errors
							return err
						}
						logrus.Warnf("error with delegation %s key ID %d: %s", delgRole.Name, keyID, err)
					}
				}
				foundRole = &delgRole
				return StopWalk{}
			}
		}
		return nil
	}

	// Walk to the parent of this delegation, since that is where its role metadata exists
	err := tr.WalkTargets("", path.Dir(name), buildDelegationRoleVisitor)
	if err != nil {
		return data.DelegationRole{}, err
	}

	// We never found the delegation. In the context of this repo it is considered
	// invalid. N.B. it may be that it existed at one point but an ancestor has since
	// been modified/removed.
	if foundRole == nil {
		return data.DelegationRole{}, data.ErrInvalidRole{Role: name, Reason: "delegation does not exist"}
	}

	return *foundRole, nil
}