func (b *backend) pathCAWrite( req *logical.Request, data *framework.FieldData) (*logical.Response, error) { pemBundle := data.Get("pem_bundle").(string) parsedBundle, err := certutil.ParsePEMBundle(pemBundle) if err != nil { switch err.(type) { case errutil.InternalError: return nil, err default: return logical.ErrorResponse(err.Error()), nil } } if parsedBundle.PrivateKey == nil || parsedBundle.PrivateKeyType == certutil.UnknownPrivateKey { return logical.ErrorResponse("private key not found in the PEM bundle"), nil } if parsedBundle.Certificate == nil { return logical.ErrorResponse("no certificate found in the PEM bundle"), nil } if !parsedBundle.Certificate.IsCA { return logical.ErrorResponse("the given certificate is not marked for CA use and cannot be used with this backend"), nil } cb, err := parsedBundle.ToCertBundle() if err != nil { return nil, fmt.Errorf("error converting raw values into cert bundle: %s", err) } entry, err := logical.StorageEntryJSON("config/ca_bundle", cb) if err != nil { return nil, err } err = req.Storage.Put(entry) if err != nil { return nil, err } // For ease of later use, also store just the certificate at a known // location, plus a fresh CRL entry.Key = "ca" entry.Value = parsedBundle.CertificateBytes err = req.Storage.Put(entry) if err != nil { return nil, err } err = buildCRL(b, req) return nil, err }
func (b *backend) pathSetSignedIntermediate( req *logical.Request, data *framework.FieldData) (*logical.Response, error) { cert := data.Get("certificate").(string) if cert == "" { return logical.ErrorResponse("no certificate provided in the \"certficate\" parameter"), nil } inputBundle, err := certutil.ParsePEMBundle(cert) if err != nil { switch err.(type) { case certutil.InternalError: return nil, err default: return logical.ErrorResponse(err.Error()), nil } } // If only one certificate is provided and it's a CA // the parsing will assign it to the IssuingCA, so move it over if inputBundle.Certificate == nil && inputBundle.IssuingCA != nil { inputBundle.Certificate = inputBundle.IssuingCA inputBundle.IssuingCA = nil inputBundle.CertificateBytes = inputBundle.IssuingCABytes inputBundle.IssuingCABytes = nil } if inputBundle.Certificate == nil { return logical.ErrorResponse("supplied certificate could not be successfully parsed"), nil } cb := &certutil.CertBundle{} entry, err := req.Storage.Get("config/ca_bundle") if err != nil { return nil, err } if entry == nil { return logical.ErrorResponse("could not find any existing entry with a private key"), nil } err = entry.DecodeJSON(cb) if err != nil { return nil, err } if len(cb.PrivateKey) == 0 || cb.PrivateKeyType == "" { return logical.ErrorResponse("could not find an existing private key"), nil } parsedCB, err := cb.ToParsedCertBundle() if err != nil { return nil, err } if parsedCB.PrivateKey == nil { return nil, fmt.Errorf("saved key could not be parsed successfully") } equal, err := certutil.ComparePublicKeys(parsedCB.PrivateKey.Public(), inputBundle.Certificate.PublicKey) if err != nil { return logical.ErrorResponse(fmt.Sprintf( "error matching public keys: %v", err)), nil } if !equal { return logical.ErrorResponse("key in certificate does not match stored key"), nil } inputBundle.PrivateKey = parsedCB.PrivateKey inputBundle.PrivateKeyType = parsedCB.PrivateKeyType inputBundle.PrivateKeyBytes = parsedCB.PrivateKeyBytes if !inputBundle.Certificate.IsCA { return logical.ErrorResponse("the given certificate is not marked for CA use and cannot be used with this backend"), nil } cb, err = inputBundle.ToCertBundle() if err != nil { return nil, fmt.Errorf("error converting raw values into cert bundle: %s", err) } entry, err = logical.StorageEntryJSON("config/ca_bundle", cb) if err != nil { return nil, err } err = req.Storage.Put(entry) if err != nil { return nil, err } entry.Key = "certs/" + cb.SerialNumber entry.Value = inputBundle.CertificateBytes err = req.Storage.Put(entry) if err != nil { return nil, err } // For ease of later use, also store just the certificate at a known // location entry.Key = "ca" entry.Value = inputBundle.CertificateBytes err = req.Storage.Put(entry) if err != nil { return nil, err } // Build a fresh CRL err = buildCRL(b, req) return nil, err }
func (b *backend) pathConnectionWrite( req *logical.Request, data *framework.FieldData) (*logical.Response, error) { hosts := data.Get("hosts").(string) username := data.Get("username").(string) password := data.Get("password").(string) switch { case len(hosts) == 0: return logical.ErrorResponse("Hosts cannot be empty"), nil case len(username) == 0: return logical.ErrorResponse("Username cannot be empty"), nil case len(password) == 0: return logical.ErrorResponse("Password cannot be empty"), nil } config := &sessionConfig{ Hosts: hosts, Username: username, Password: password, TLS: data.Get("tls").(bool), InsecureTLS: data.Get("insecure_tls").(bool), ProtocolVersion: data.Get("protocol_version").(int), ConnectTimeout: data.Get("connect_timeout").(int), } config.TLSMinVersion = data.Get("tls_min_version").(string) if config.TLSMinVersion == "" { return logical.ErrorResponse("failed to get 'tls_min_version' value"), nil } var ok bool _, ok = tlsutil.TLSLookup[config.TLSMinVersion] if !ok { return logical.ErrorResponse("invalid 'tls_min_version'"), nil } if config.InsecureTLS { config.TLS = true } pemBundle := data.Get("pem_bundle").(string) pemJSON := data.Get("pem_json").(string) var certBundle *certutil.CertBundle var parsedCertBundle *certutil.ParsedCertBundle var err error switch { case len(pemJSON) != 0: parsedCertBundle, err = certutil.ParsePKIJSON([]byte(pemJSON)) if err != nil { return logical.ErrorResponse(fmt.Sprintf("Could not parse given JSON; it must be in the format of the output of the PKI backend certificate issuing command: %s", err)), nil } certBundle, err = parsedCertBundle.ToCertBundle() if err != nil { return logical.ErrorResponse(fmt.Sprintf("Error marshaling PEM information: %s", err)), nil } config.Certificate = certBundle.Certificate config.PrivateKey = certBundle.PrivateKey config.IssuingCA = certBundle.IssuingCA config.TLS = true case len(pemBundle) != 0: parsedCertBundle, err = certutil.ParsePEMBundle(pemBundle) if err != nil { return logical.ErrorResponse(fmt.Sprintf("Error parsing the given PEM information: %s", err)), nil } certBundle, err = parsedCertBundle.ToCertBundle() if err != nil { return logical.ErrorResponse(fmt.Sprintf("Error marshaling PEM information: %s", err)), nil } config.Certificate = certBundle.Certificate config.PrivateKey = certBundle.PrivateKey config.IssuingCA = certBundle.IssuingCA config.TLS = true } session, err := createSession(config, req.Storage) if err != nil { return logical.ErrorResponse(err.Error()), nil } // Store it entry, err := logical.StorageEntryJSON("config/connection", config) if err != nil { return nil, err } if err := req.Storage.Put(entry); err != nil { return nil, err } // Reset the DB connection b.ResetDB(session) return nil, nil }
func (b *backend) pathCAWrite( req *logical.Request, d *framework.FieldData) (*logical.Response, error) { pemBundle := d.Get("pem_bundle").(string) parsedBundle, err := certutil.ParsePEMBundle(pemBundle) if err != nil { switch err.(type) { case certutil.InternalError: return nil, err default: return logical.ErrorResponse(err.Error()), nil } } // Handle the case of a self-signed certificate if parsedBundle.Certificate == nil && parsedBundle.IssuingCA != nil { parsedBundle.Certificate = parsedBundle.IssuingCA parsedBundle.CertificateBytes = parsedBundle.IssuingCABytes } // TODO?: CRLs can only be generated with RSA keys right now, in the // Go standard library. The plubming is here to support non-RSA keys // if the library gets support if parsedBundle.PrivateKeyType != certutil.RSAPrivateKey { return logical.ErrorResponse("Currently, only RSA keys are supported for the CA certificate"), nil } if !parsedBundle.Certificate.IsCA { return logical.ErrorResponse("The given certificate is not marked for CA use and cannot be used with this backend"), nil } cb, err := parsedBundle.ToCertBundle() if err != nil { return nil, fmt.Errorf("Error converting raw values into cert bundle: %s", err) } entry, err := logical.StorageEntryJSON("config/ca_bundle", cb) if err != nil { return nil, err } err = req.Storage.Put(entry) if err != nil { return nil, err } // For ease of later use, also store just the certificate at a known // location, plus a blank CRL entry.Key = "ca" entry.Value = parsedBundle.CertificateBytes err = req.Storage.Put(entry) if err != nil { return nil, err } entry.Key = "crl" entry.Value = []byte{} err = req.Storage.Put(entry) if err != nil { return nil, err } return nil, nil }
func (b *backend) pathCAWrite( req *logical.Request, data *framework.FieldData) (*logical.Response, error) { pemBundle := data.Get("pem_bundle").(string) parsedBundle, err := certutil.ParsePEMBundle(pemBundle) if err != nil { switch err.(type) { case certutil.InternalError: return nil, err default: return logical.ErrorResponse(err.Error()), nil } } if parsedBundle.PrivateKey == nil || parsedBundle.PrivateKeyType == certutil.UnknownPrivateKey { return logical.ErrorResponse("private key not found in the PEM bundle"), nil } // Handle the case of a self-signed certificate; the parsing function will // see the CA and put it into the issuer if parsedBundle.Certificate == nil && parsedBundle.IssuingCA != nil { equal, err := certutil.ComparePublicKeys(parsedBundle.IssuingCA.PublicKey, parsedBundle.PrivateKey.Public()) if err != nil { return logical.ErrorResponse(fmt.Sprintf( "got only a CA and private key but could not verify the public keys match: %v", err)), nil } if !equal { return logical.ErrorResponse( "got only a CA and private key but keys do not match"), nil } parsedBundle.Certificate = parsedBundle.IssuingCA parsedBundle.CertificateBytes = parsedBundle.IssuingCABytes } if parsedBundle.Certificate == nil { return logical.ErrorResponse("no certificate found in the PEM bundle"), nil } if !parsedBundle.Certificate.IsCA { return logical.ErrorResponse("the given certificate is not marked for CA use and cannot be used with this backend"), nil } cb, err := parsedBundle.ToCertBundle() if err != nil { return nil, fmt.Errorf("error converting raw values into cert bundle: %s", err) } entry, err := logical.StorageEntryJSON("config/ca_bundle", cb) if err != nil { return nil, err } err = req.Storage.Put(entry) if err != nil { return nil, err } // For ease of later use, also store just the certificate at a known // location, plus a fresh CRL entry.Key = "ca" entry.Value = parsedBundle.CertificateBytes err = req.Storage.Put(entry) if err != nil { return nil, err } err = buildCRL(b, req) return nil, err }