Пример #1
0
func TestCreateSelfSignedCert(t *testing.T) {

	// --- TEST: Create a self-signed certificate from a CSR. --- //

	// Generate a self-signed certificate from the request.
	encodedCertFromCode, _, err := CreateSelfSignedCert(CARequest)
	if err != nil {
		t.Fatal(err.Error())
	}

	// Now compare to a pre-made certificate made using a JSON file with the
	// same request information. This JSON file is located in testdata/initCA
	// and is called ca_csr.json.

	CLIOutputFile := preMadeOutput
	CLIOutput, err := ioutil.ReadFile(CLIOutputFile)
	if err != nil {
		t.Fatal(err.Error())
	}
	encodedCertFromCLI, err := cleanCLIOutput(CLIOutput, "cert")
	if err != nil {
		t.Fatal(err.Error())
	}

	certFromCode, err := helpers.ParseSelfSignedCertificatePEM(encodedCertFromCode)
	if err != nil {
		t.Fatal(err.Error())
	}
	certFromCLI, err := helpers.ParseSelfSignedCertificatePEM(encodedCertFromCLI)
	if err != nil {
		t.Fatal(err.Error())
	}

	// Nullify any fields of the certificates which are dependent upon the time
	// of the certificate's creation.
	nullifyTimeDependency(certFromCode)
	nullifyTimeDependency(certFromCLI)

	if !reflect.DeepEqual(certFromCode, certFromCLI) {
		unequalFields := checkFields(
			*certFromCode, *certFromCLI, reflect.TypeOf(*certFromCode))
		t.Log("The following fields were unequal:")
		for _, field := range unequalFields {
			t.Log(field)
		}
		t.Fatal("Certificates unequal.")
	}

}
Пример #2
0
// Sign signs a new certificate based on the PEM-encoded client
// certificate or certificate request with the signing profile, specified by profileName.
// The certificate will be valid for the host named in  the hostName parameter.
func (s *Signer) Sign(hostName string, in []byte, profileName string) (cert []byte, err error) {
	profile := s.Policy.Profiles[profileName]

	block, _ := pem.Decode(in)
	if block == nil {
		return nil, cferr.New(cferr.CertificateError, cferr.DecodeFailed, err)
	}

	var template *x509.Certificate
	switch block.Type {
	case "CERTIFICATE":
		template, err = helpers.ParseSelfSignedCertificatePEM(in)
	case "CERTIFICATE REQUEST":
		template, err = s.parseCertificateRequest(block.Bytes)
	default:
		return nil, cferr.New(cferr.CertificateError, cferr.ParseFailed, errors.New("Not a certificate or csr."))
	}
	if err != nil {
		return
	}

	if ip := net.ParseIP(hostName); ip != nil {
		template.IPAddresses = []net.IP{ip}
	} else {
		template.DNSNames = []string{hostName}
	}
	return s.sign(template, profile)
}
Пример #3
0
// NewRootCA creates a new RootCA object from unparsed cert and key byte
// slices. key may be nil, and in this case NewRootCA will return a RootCA
// without a signer.
func NewRootCA(cert, key []byte, certExpiry time.Duration) (RootCA, error) {
	// Check to see if the Certificate file is a valid, self-signed Cert
	parsedCA, err := helpers.ParseSelfSignedCertificatePEM(cert)
	if err != nil {
		return RootCA{}, err
	}

	// Calculate the digest for our RootCACertificate
	digest := digest.FromBytes(cert)

	// Create a Pool with our RootCACertificate
	pool := x509.NewCertPool()
	if !pool.AppendCertsFromPEM(cert) {
		return RootCA{}, fmt.Errorf("error while adding root CA cert to Cert Pool")
	}

	if len(key) == 0 {
		// This RootCA does not have a valid signer.
		return RootCA{Cert: cert, Digest: digest, Pool: pool}, nil
	}

	var (
		passphraseStr              string
		passphrase, passphrasePrev []byte
		priv                       crypto.Signer
	)

	// Attempt two distinct passphrases, so we can do a hitless passphrase rotation
	if passphraseStr = os.Getenv(PassphraseENVVar); passphraseStr != "" {
		passphrase = []byte(passphraseStr)
	}

	if p := os.Getenv(PassphraseENVVarPrev); p != "" {
		passphrasePrev = []byte(p)
	}

	// Attempt to decrypt the current private-key with the passphrases provided
	priv, err = helpers.ParsePrivateKeyPEMWithPassword(key, passphrase)
	if err != nil {
		priv, err = helpers.ParsePrivateKeyPEMWithPassword(key, passphrasePrev)
		if err != nil {
			log.Debug("Malformed private key %v", err)
			return RootCA{}, err
		}
	}

	if err := ensureCertKeyMatch(parsedCA, priv.Public()); err != nil {
		return RootCA{}, err
	}

	signer, err := local.NewSigner(priv, parsedCA, cfsigner.DefaultSigAlgo(priv), SigningPolicy(certExpiry))
	if err != nil {
		return RootCA{}, err
	}

	// If the key was loaded from disk unencrypted, but there is a passphrase set,
	// ensure it is encrypted, so it doesn't hit raft in plain-text
	keyBlock, _ := pem.Decode(key)
	if keyBlock == nil {
		// This RootCA does not have a valid signer.
		return RootCA{Cert: cert, Digest: digest, Pool: pool}, nil
	}
	if passphraseStr != "" && !x509.IsEncryptedPEMBlock(keyBlock) {
		key, err = EncryptECPrivateKey(key, passphraseStr)
		if err != nil {
			return RootCA{}, err
		}
	}

	return RootCA{Signer: signer, Key: key, Digest: digest, Cert: cert, Pool: pool}, nil
}
Пример #4
0
func TestCreateSelfSignedCert(t *testing.T) {

	// --- TEST: Create a self-signed certificate from a CSR. --- //

	// Make the request we will use to generate the certificate.
	keyRequest := csr.KeyRequest{
		Algo: "rsa",
		Size: 2048,
	}
	CAConfig := csr.CAConfig{
		PathLength: 1,
		Expiry:     "1/1/2015",
	}
	request := csr.CertificateRequest{
		CN: "example.com",
		Names: []csr.Name{
			{
				C:  "US",
				ST: "California",
				L:  "San Francisco",
				O:  "Internet Widgets, LLC",
				OU: "Certificate Authority",
			},
		},
		Hosts:      []string{"ca.example.com"},
		KeyRequest: &keyRequest,
		CA:         &CAConfig,
	}

	// Generate a self-signed certificate from the request.
	encodedCertFromCode, _, err := CreateSelfSignedCert(request)
	checkError(err, t)

	// Now compare to a pre-made certificate made using a JSON file with the
	// same request information. This JSON file is located in testdata/initCA
	// and is called ca_csr.json.

	CLIOutputFile := preMadeOutput
	CLIOutput, err := ioutil.ReadFile(CLIOutputFile)
	checkError(err, t)
	encodedCertFromCLI, err := cleanCLIOutput(CLIOutput, "cert")
	checkError(err, t)

	certFromCode, err := helpers.ParseSelfSignedCertificatePEM(encodedCertFromCode)
	checkError(err, t)
	certFromCLI, err := helpers.ParseSelfSignedCertificatePEM(encodedCertFromCLI)
	checkError(err, t)

	// Nullify any fields of the certificates which are dependent upon the time
	// of the certificate's creation.
	nullifyTimeDependency(certFromCode)
	nullifyTimeDependency(certFromCLI)

	if !reflect.DeepEqual(certFromCode, certFromCLI) {
		unequalFields := checkFields(
			*certFromCode, *certFromCLI, reflect.TypeOf(*certFromCode))
		t.Log("The following fields were unequal:")
		for _, field := range unequalFields {
			t.Log(field)
		}
		t.Fatal("Certificates unequal.")
	}

}