Ejemplo n.º 1
0
func TestAuthSign(t *testing.T) {
	s := NewServer("1.1")
	testProvider, _ = auth.New(testKey, nil)
	testRequest := []byte(`testing 1 2 3`)
	as, _ := s.AuthSign(testRequest, testAD, testProvider)
	if as != nil {
		t.Fatal("fatal error with auth sign function")
	}
}
Ejemplo n.º 2
0
func TestMain(m *testing.M) {
	caKeyPEM, _ := ioutil.ReadFile(caKeyFile)
	caKey, _ := helpers.ParsePrivateKeyPEM(caKeyPEM)

	caCertPEM, _ := ioutil.ReadFile(caCertFile)
	caCert, _ := helpers.ParseCertificatePEM(caCertPEM)

	// Create an online CFSSL instance
	// This is designed to mimic what LE plans to do
	authHandler, _ := auth.New(authKey, nil)
	policy := &cfsslConfig.Signing{
		Profiles: map[string]*cfsslConfig.SigningProfile{
			profileName: &cfsslConfig.SigningProfile{
				Usage:     []string{"server auth"},
				CA:        false,
				IssuerURL: []string{"http://not-example.com/issuer-url"},
				OCSP:      "http://not-example.com/ocsp",
				CRL:       "http://not-example.com/crl",

				Policies: []asn1.ObjectIdentifier{
					asn1.ObjectIdentifier{2, 23, 140, 1, 2, 1},
				},
				Expiry:   8760 * time.Hour,
				Backdate: time.Hour,
				Provider: authHandler,
				CSRWhitelist: &cfsslConfig.CSRWhitelist{
					PublicKeyAlgorithm: true,
					PublicKey:          true,
					SignatureAlgorithm: true,
				},
			},
		},
		Default: &cfsslConfig.SigningProfile{
			Expiry: time.Hour,
		},
	}
	cfsslSigner, _ = local.NewSigner(caKey, caCert, x509.SHA256WithRSA, policy)
	signHandler, _ := apisign.NewAuthHandlerFromSigner(cfsslSigner)
	http.Handle("/api/v1/cfssl/authsign", signHandler)
	// This goroutine should get killed when main() return
	go (func() { http.ListenAndServe(hostPort, nil) })()

	os.Exit(m.Run())
}
Ejemplo n.º 3
0
// populate is used to fill in the fields that are not in JSON
//
// First, the ExpiryString parameter is needed to parse
// expiration timestamps from JSON. The JSON decoder is not able to
// decode a string time duration to a time.Duration, so this is called
// when loading the configuration to properly parse and fill out the
// Expiry parameter.
// This function is also used to create references to the auth key
// and default remote for the profile.
// It returns true if ExpiryString is a valid representation of a
// time.Duration, and the AuthKeyString and RemoteName point to
// valid objects. It returns false otherwise.
func (p *SigningProfile) populate(cfg *Config) error {
	if p == nil {
		return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, errors.New("can't parse nil profile"))
	}

	var err error
	if p.RemoteName == "" && p.AuthRemote.RemoteName == "" {
		log.Debugf("parse expiry in profile")
		if p.ExpiryString == "" {
			return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, errors.New("empty expiry string"))
		}

		dur, err := time.ParseDuration(p.ExpiryString)
		if err != nil {
			return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, err)
		}

		log.Debugf("expiry is valid")
		p.Expiry = dur

		if p.BackdateString != "" {
			dur, err = time.ParseDuration(p.BackdateString)
			if err != nil {
				return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, err)
			}

			p.Backdate = dur
		}

		if !p.NotBefore.IsZero() && !p.NotAfter.IsZero() && p.NotAfter.Before(p.NotBefore) {
			return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, err)
		}

		if len(p.Policies) > 0 {
			for _, policy := range p.Policies {
				for _, qualifier := range policy.Qualifiers {
					if qualifier.Type != "" && qualifier.Type != "id-qt-unotice" && qualifier.Type != "id-qt-cps" {
						return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy,
							errors.New("invalid policy qualifier type"))
					}
				}
			}
		}
	} else if p.RemoteName != "" {
		log.Debug("match remote in profile to remotes section")
		if p.AuthRemote.RemoteName != "" {
			log.Error("profile has both a remote and an auth remote specified")
			return cferr.New(cferr.PolicyError, cferr.InvalidPolicy)
		}
		if remote := cfg.Remotes[p.RemoteName]; remote != "" {
			if err := p.updateRemote(remote); err != nil {
				return err
			}
		} else {
			return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy,
				errors.New("failed to find remote in remotes section"))
		}
	} else {
		log.Debug("match auth remote in profile to remotes section")
		if remote := cfg.Remotes[p.AuthRemote.RemoteName]; remote != "" {
			if err := p.updateRemote(remote); err != nil {
				return err
			}
		} else {
			return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy,
				errors.New("failed to find remote in remotes section"))
		}
	}

	if p.AuthKeyName != "" {
		log.Debug("match auth key in profile to auth_keys section")
		if key, ok := cfg.AuthKeys[p.AuthKeyName]; ok == true {
			if key.Type == "standard" {
				p.Provider, err = auth.New(key.Key, nil)
				if err != nil {
					log.Debugf("failed to create new standard auth provider: %v", err)
					return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy,
						errors.New("failed to create new standard auth provider"))
				}
			} else {
				log.Debugf("unknown authentication type %v", key.Type)
				return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy,
					errors.New("unknown authentication type"))
			}
		} else {
			return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy,
				errors.New("failed to find auth_key in auth_keys section"))
		}
	}

	if p.AuthRemote.AuthKeyName != "" {
		log.Debug("match auth remote key in profile to auth_keys section")
		if key, ok := cfg.AuthKeys[p.AuthRemote.AuthKeyName]; ok == true {
			if key.Type == "standard" {
				p.RemoteProvider, err = auth.New(key.Key, nil)
				if err != nil {
					log.Debugf("failed to create new standard auth provider: %v", err)
					return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy,
						errors.New("failed to create new standard auth provider"))
				}
			} else {
				log.Debugf("unknown authentication type %v", key.Type)
				return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy,
					errors.New("unknown authentication type"))
			}
		} else {
			return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy,
				errors.New("failed to find auth_remote's auth_key in auth_keys section"))
		}
	}

	if p.NameWhitelistString != "" {
		log.Debug("compiling whitelist regular expression")
		rule, err := regexp.Compile(p.NameWhitelistString)
		if err != nil {
			return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy,
				errors.New("failed to compile name whitelist section"))
		}
		p.NameWhitelist = rule
	}

	return nil
}
Ejemplo n.º 4
0
// NewCertificateAuthorityImpl creates a CA that talks to a remote CFSSL
// instance.  (To use a local signer, simply instantiate CertificateAuthorityImpl
// directly.)  Communications with the CA are authenticated with MACs,
// using CFSSL's authenticated signature scheme.  A CA created in this way
// issues for a single profile on the remote signer, which is indicated
// by name in this constructor.
func NewCertificateAuthorityImpl(cadb core.CertificateAuthorityDatabase, config Config) (*CertificateAuthorityImpl, error) {
	var ca *CertificateAuthorityImpl
	var err error
	logger := blog.GetAuditLogger()
	logger.Notice("Certificate Authority Starting")

	if config.SerialPrefix <= 0 || config.SerialPrefix >= 256 {
		err = errors.New("Must have a positive non-zero serial prefix less than 256 for CA.")
		return nil, err
	}

	// Create the remote signer
	localProfile := cfsslConfig.SigningProfile{
		Expiry:       time.Hour,     // BOGUS: Required by CFSSL, but not used
		RemoteName:   config.Server, // BOGUS: Only used as a flag by CFSSL
		RemoteServer: config.Server,
		UseSerialSeq: true,
	}

	localProfile.Provider, err = auth.New(config.AuthKey, nil)
	if err != nil {
		return nil, err
	}

	signer, err := remote.NewSigner(&cfsslConfig.Signing{Default: &localProfile})
	if err != nil {
		return nil, err
	}

	issuer, err := loadIssuer(config.IssuerCert)
	if err != nil {
		return nil, err
	}

	// In test mode, load a private key from a file.
	// TODO: This should rely on the CFSSL config, to make it easy to use a key
	// from a file vs an HSM. https://github.com/letsencrypt/boulder/issues/163
	issuerKey, err := loadIssuerKey(config.IssuerKey)
	if err != nil {
		return nil, err
	}

	// Set up our OCSP signer. Note this calls for both the issuer cert and the
	// OCSP signing cert, which are the same in our case.
	ocspSigner, err := ocsp.NewSigner(issuer, issuer, issuerKey,
		time.Hour*24*4)
	if err != nil {
		return nil, err
	}

	pa := policy.NewPolicyAuthorityImpl()

	ca = &CertificateAuthorityImpl{
		Signer:     signer,
		OCSPSigner: ocspSigner,
		profile:    config.Profile,
		PA:         pa,
		DB:         cadb,
		Prefix:     config.SerialPrefix,
		log:        logger,
		NotAfter:   issuer.NotAfter,
	}

	ca.ValidityPeriod, err = time.ParseDuration(config.Expiry)
	if err != nil {
		return nil, err
	}

	return ca, nil
}
Ejemplo n.º 5
0
// populate is used to fill in the fields that are not in JSON
//
// First, the ExpiryString parameter is needed to parse
// expiration timestamps from JSON. The JSON decoder is not able to
// decode a string time duration to a time.Duration, so this is called
// when loading the configuration to properly parse and fill out the
// Expiry parameter.
// This function is also used to create references to the auth key
// and default remote for the profile.
// It returns true if ExpiryString is a valid representation of a
// time.Duration, and the AuthKeyString and RemoteName point to
// valid objects. It returns false otherwise.
func (p *SigningProfile) populate(cfg *Config) error {
	if p == nil {
		return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, errors.New("can't parse nil profile"))
	}

	var err error
	if p.RemoteName == "" {
		log.Debugf("parse expiry in profile")
		if p.ExpiryString == "" {
			return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, errors.New("empty expiry string"))
		}

		dur, err := time.ParseDuration(p.ExpiryString)
		if err != nil {
			return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, err)
		}

		log.Debugf("expiry is valid")
		p.Expiry = dur

		if p.BackdateString != "" {
			dur, err = time.ParseDuration(p.BackdateString)
			if err != nil {
				return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, err)
			}

			p.Backdate = dur
		}

		if !p.NotBefore.IsZero() && !p.NotAfter.IsZero() && p.NotAfter.Before(p.NotBefore) {
			return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, err)
		}

		if len(p.PolicyStrings) > 0 {
			p.Policies = make([]asn1.ObjectIdentifier, len(p.PolicyStrings))
			for i, oidString := range p.PolicyStrings {
				p.Policies[i], err = parseObjectIdentifier(oidString)
				if err != nil {
					return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, err)
				}
			}
		}
	} else {
		log.Debug("match remote in profile to remotes section")
		if remote := cfg.Remotes[p.RemoteName]; remote != "" {
			if err := p.updateRemote(remote); err != nil {
				return err
			}
		} else {
			return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy,
				errors.New("failed to find remote in remotes section"))
		}
	}

	if p.AuthKeyName != "" {
		log.Debug("match auth key in profile to auth_keys section")
		if key, ok := cfg.AuthKeys[p.AuthKeyName]; ok == true {
			if key.Type == "standard" {
				p.Provider, err = auth.New(key.Key, nil)
				if err != nil {
					log.Debugf("failed to create new standard auth provider: %v", err)
					return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy,
						errors.New("failed to create new standard auth provider"))
				}
			} else {
				log.Debugf("unknown authentication type %v", key.Type)
				return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy,
					errors.New("unknown authentication type"))
			}
		} else {
			return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy,
				errors.New("failed to find auth_key in auth_keys section"))
		}
	}

	return nil
}