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) pathIssueSignCert( req *logical.Request, data *framework.FieldData, role *roleEntry, useCSR, useCSRValues bool) (*logical.Response, error) { format := getFormat(data) if format == "" { return logical.ErrorResponse( `The "format" path parameter must be "pem", "der", or "pem_bundle"`), nil } var caErr error signingBundle, caErr := fetchCAInfo(req) switch caErr.(type) { case certutil.UserError: return nil, certutil.UserError{Err: fmt.Sprintf( "Could not fetch the CA certificate (was one set?): %s", caErr)} case certutil.InternalError: return nil, certutil.InternalError{Err: fmt.Sprintf( "Error fetching CA certificate: %s", caErr)} } var parsedBundle *certutil.ParsedCertBundle var err error if useCSR { parsedBundle, err = signCert(b, role, signingBundle, false, useCSRValues, req, data) } else { parsedBundle, err = generateCert(b, role, signingBundle, false, req, data) } if err != nil { switch err.(type) { case certutil.UserError: return logical.ErrorResponse(err.Error()), nil case certutil.InternalError: return nil, err } } cb, err := parsedBundle.ToCertBundle() if err != nil { return nil, fmt.Errorf("Error converting raw cert bundle to cert bundle: %s", err) } resp := b.Secret(SecretCertsType).Response( map[string]interface{}{ "certificate": cb.Certificate, "issuing_ca": cb.IssuingCA, }, map[string]interface{}{ "serial_number": cb.SerialNumber, }) switch format { case "pem": resp.Data["issuing_ca"] = cb.IssuingCA resp.Data["certificate"] = cb.Certificate if !useCSR { resp.Data["private_key"] = cb.PrivateKey resp.Data["private_key_type"] = cb.PrivateKeyType } case "pem_bundle": resp.Data["issuing_ca"] = cb.IssuingCA resp.Data["certificate"] = fmt.Sprintf("%s\n%s", cb.Certificate, cb.IssuingCA) if !useCSR { resp.Data["private_key"] = cb.PrivateKey resp.Data["private_key_type"] = cb.PrivateKeyType resp.Data["certificate"] = fmt.Sprintf("%s\n%s\n%s", cb.PrivateKey, cb.Certificate, cb.IssuingCA) } case "der": resp.Data["certificate"] = base64.StdEncoding.EncodeToString(parsedBundle.CertificateBytes) resp.Data["issuing_ca"] = base64.StdEncoding.EncodeToString(parsedBundle.IssuingCABytes) if !useCSR { resp.Data["private_key"] = base64.StdEncoding.EncodeToString(parsedBundle.PrivateKeyBytes) } } resp.Secret.TTL = parsedBundle.Certificate.NotAfter.Sub(time.Now()) err = req.Storage.Put(&logical.StorageEntry{ Key: "certs/" + cb.SerialNumber, Value: parsedBundle.CertificateBytes, }) if err != nil { return nil, fmt.Errorf("Unable to store certificate locally") } return resp, nil }