@@ -66,96 +66,6 @@ func Factory(ctx context.Context, conf *logical.BackendConfig) (logical.Backend,
6666// Store certificates by serial number
6767type backend struct {
6868 * framework.Backend
69- //storage logical.Storage
70- crlLifetime time.Duration
71- //tidyCASGuard *uint32
72- //store map[string][]byte
73- }
74-
75- // func (b *backend) paths() []*framework.Path {
76- // return []*framework.Path{
77- // {
78- // Pattern: "issue/" + framework.GenericNameRegex("role"),
79-
80- // Fields: addIssueAndSignCommonFields(map[string]*framework.FieldSchema{
81- // "role": {
82- // Type: framework.TypeLowerCaseString,
83- // Description: "Name of the role",
84- // Required: true,
85- // },
86- // }),
87-
88- // Callbacks: map[logical.Operation]framework.OperationFunc{
89- // logical.UpdateOperation: b.handleWrite,
90- // logical.CreateOperation: b.handleWrite,
91- // },
92-
93- // ExistenceCheck: b.handleExistenceCheck,
94- // },
95- // {
96- // Pattern: "revoke/",
97- // Fields: map[string]*framework.FieldSchema{
98- // "serial_number": {
99- // Type: framework.TypeString,
100- // Description: "The serial number of the certificate to revoke",
101- // Required: true,
102- // },
103- // },
104- // Callbacks: map[logical.Operation]framework.OperationFunc{
105- // logical.UpdateOperation: b.handleRevoke,
106- // },
107- // },
108- // {
109- // Pattern: "sign/",
110- // Fields: addIssueAndSignCommonFields(map[string]*framework.FieldSchema{}),
111- // Callbacks: map[logical.Operation]framework.OperationFunc{
112- // logical.UpdateOperation: b.handleSign,
113- // },
114- // },
115- // {
116- // Pattern: "ca/",
117- // Fields: addIssueAndSignCommonFields(map[string]*framework.FieldSchema{}),
118- // Callbacks: map[logical.Operation]framework.OperationFunc{
119- // logical.ReadOperation: b.getCACert,
120- // },
121- // },
122- // {
123- // Pattern: "ca_chain/",
124- // Fields: addIssueAndSignCommonFields(map[string]*framework.FieldSchema{}),
125- // Callbacks: map[logical.Operation]framework.OperationFunc{
126- // logical.ReadOperation: b.getCertChain,
127- // },
128- // },
129- // {
130- // Pattern: "certs/?$",
131- // Fields: addIssueAndSignCommonFields(map[string]*framework.FieldSchema{}),
132- // Callbacks: map[logical.Operation]framework.OperationFunc{
133- // logical.ListOperation: b.handleList,
134- // },
135- // },
136- // {
137- // Pattern: `cert/(?P<serial>[0-9A-Fa-f-:]+)`,
138- // Fields: map[string]*framework.FieldSchema{
139- // "serial_number": {
140- // Type: framework.TypeString,
141- // Description: "The serial number of the certificate to read",
142- // Required: true,
143- // },
144- // },
145- // Callbacks: map[logical.Operation]framework.OperationFunc{
146- // logical.ReadOperation: b.handleRead,
147- // },
148- // },
149- // }
150- // }
151-
152- func (b * backend ) handleExistenceCheck (ctx context.Context , req * logical.Request , data * framework.FieldData ) (bool , error ) {
153- out , err := req .Storage .Get (ctx , req .Path )
154- if err != nil {
155- return false , errwrap .Wrapf ("existence check failed: {{err}}" , err )
156- }
157-
158- return out != nil , nil
15969}
16070
16171// Generate keypair and CSR
@@ -249,13 +159,7 @@ func (b *backend) submitCSR(ctx context.Context, req *logical.Request, csr strin
249159 }
250160 serial := inner ["SerialNumber" ].(string )
251161 kfId := inner ["KeyfactorID" ].(float64 )
252- //caId := inner["CertificateAuthorityId"].(float64)
253- //b.Logger().Debug("CertificateAuthorityId = %d", caId)
254- // b.Logger().Debug("Serial number: ", serial)
255- // b.Logger().Debug("Keyfactor Id: ", kfId)
256- //b.store[serial] = []byte(certs[0])
257- // Retain the issuer cert for calls to "vault read keyfactor/cert/ca" - TODO Get via Keyfactor API
258- //b.save(ctx, req, serial, []byte(certs[0]))
162+
259163 if err != nil {
260164 b .Logger ().Error ("unable to parse ca_chain response" , err )
261165 }
@@ -287,255 +191,9 @@ func (b *backend) submitCSR(ctx context.Context, req *logical.Request, csr strin
287191 return nil , "" , errwrap .Wrapf ("unable to store the keyfactor ID for the certificate locally: {{err}}" , err )
288192 }
289193
290- // caIdEntry, err := logical.StorageEntryJSON("caId", caId)
291- // if err != nil {
292- // return nil, "", err
293- // }
294-
295- // err = req.Storage.Put(ctx, caIdEntry)
296- // if err != nil {
297- // return nil, "", errwrap.Wrapf("unable to store the CA ID for the certificate locally: {{err}}", err)
298- // }
299-
300194 return certs , serial , nil
301195}
302196
303- // func (b *backend) requestCert(ctx context.Context, req *logical.Request, data *framework.FieldData, role string) (*logical.Response, error) {
304- // arg, _ := json.Marshal(req.Data)
305- // b.Logger().Debug(string(arg))
306- // cn := ""
307- // var ip_sans []string
308- // var dns_sans []string
309-
310- // // Get and validate subject info from Vault command
311- // if len(req.Data) == 0 {
312- // return nil, fmt.Errorf("common_name must be provided to issue certificate")
313- // }
314- // for k, v := range req.Data {
315- // if k == "common_name" {
316- // cn = v.(string)
317- // }
318- // if k == "ip_sans" { // TODO - type switch
319- // ip_sans = strings.Split(v.(string), ",")
320- // }
321- // if k == "dns_sans" { // TODO - type switch
322- // dns_sans = strings.Split(v.(string), ",")
323- // }
324- // }
325- // b.Logger().Debug("about to check role: " + role + " against domain " + cn)
326-
327- // if !b.checkDomainAgainstRole(ctx, req, role, cn) { // <-- leaving off here.. fix this function
328- // return nil, fmt.Errorf("common name not allowed for provided role")
329- // }
330- // for u := range dns_sans {
331- // if !b.checkDomainAgainstRole(ctx, req, role, dns_sans[u]) {
332- // return nil, fmt.Errorf("Subject Alternative Name " + dns_sans[u] + " not allowed for provided role")
333- // }
334- // }
335-
336- // // Generate and submit the CSR
337- // csr, key := b.generateCSR(cn, ip_sans, dns_sans)
338- // certs, serial, err := b.submitCSR(ctx, req, csr)
339- // if err != nil {
340- // return nil, fmt.Errorf("could not enroll certificate: %s/", err)
341- // }
342-
343- // // Conform response to Vault PKI API
344- // response := &logical.Response{
345- // Data: map[string]interface{}{
346- // "certificate": certs[0],
347- // "issuing_ca": certs[1],
348- // "private_key": "-----BEGIN RSA PRIVATE KEY-----\n" + base64.StdEncoding.EncodeToString(key) + "\n-----END RSA PRIVATE KEY-----",
349- // "private_key_type": "rsa",
350- // "revocation_time": 0,
351- // "serial_number": serial,
352- // },
353- // }
354-
355- // return response, nil
356- // }
357-
358- // func (b *backend) getCACert(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
359- // if len(issuer_chain) == 0 {
360- // return nil, fmt.Errorf("CA certificate unknown")
361- // }
362- // b.Logger().Debug("issuer: " + issuer_chain[0])
363- // response := &logical.Response{
364- // Data: map[string]interface{}{
365- // "certificate": issuer_chain[0],
366- // },
367- // }
368- // return response, nil
369- // }
370-
371- // func (b *backend) getCertChain(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
372- // chain := ""
373- // for c := range issuer_chain {
374- // chain += issuer_chain[c]
375- // }
376- // b.Logger().Debug("issuer chain: " + chain)
377- // response := &logical.Response{
378- // Data: map[string]interface{}{
379- // "certificate": chain,
380- // },
381- // }
382- // return response, nil
383- // }
384-
385- // Check if a domain is allowed for a given role based on allowed domains and whether subdomains are allowed
386- func (b * backend ) checkDomainAgainstRole (ctx context.Context , req * logical.Request , role string , domain string ) bool {
387- b .Logger ().Debug ("checking role: " + role + " against domain " + domain )
388-
389- roleEntry , err := b .getRole (ctx , req .Storage , role )
390- if err != nil {
391- b .Logger ().Error ("Error retrieving role " + role )
392- return false
393- }
394-
395- if roleEntry .AllowedBaseDomain == domain {
396- return true
397- }
398-
399- if strings .Contains (domain , roleEntry .AllowedBaseDomain ) && roleEntry .AllowSubdomains {
400- return true
401- }
402-
403- return false
404- }
405-
406- // Add role or enroll certificate
407- // func (b *backend) handleWrite(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
408- // b.load(ctx, req)
409- // role := data.Get("role").(string)
410-
411- // b.Logger().Debug("parsing role: " + role)
412-
413- // // look up role then request certificate
414-
415- // entry, err := req.Storage.Get(ctx, "role/"+role)
416- // if err != nil || entry == nil {
417- // return nil, fmt.Errorf("cannot find provided role")
418- // }
419-
420- // return b.requestCert(ctx, req, data, role)
421- // }
422-
423- // func (b *backend) handleRevoke(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
424- // sn := data.Get("serial_number").(string)
425-
426- // if sn == "" {
427- // return nil, fmt.Errorf("must supply serial_number parameter to revoke")
428- // }
429-
430- // return b.revoke(ctx, req, data, sn)
431- // }
432-
433- func (b * backend ) handleSign (ctx context.Context , req * logical.Request , data * framework.FieldData ) (* logical.Response , error ) {
434- role := data .Get ("role" ).(string )
435- csr := data .Get ("csr" ).(string )
436- if csr == "" {
437- return nil , fmt .Errorf ("must supply csr parameter to sign" )
438- }
439- return b .sign (ctx , req , csr , role )
440- }
441-
442- func (b * backend ) sign (ctx context.Context , req * logical.Request , csrString string , role string ) (* logical.Response , error ) {
443- // TODO - Get CSR to parse from CLI
444- // csr, err := x509.ParseCertificateRequest([]byte(csrString))
445- // if err != nil {
446- // return nil, fmt.Errorf("Could not parse CSR: {{err}}",err)
447- // }
448- // cn := csr.Subject.CommonName
449- // b.Logger().Debug("Got CSR with CN="+cn)
450- // if !b.checkDomainAgainstRole(role, cn) {
451- // return nil, fmt.Errorf("Common name {{cn}} is not allowed for provided role", cn)
452- // }
453- // TODO - check SANs
454-
455- certs , serial , err := b .submitCSR (ctx , req , csrString )
456-
457- if err != nil {
458- b .Logger ().Info ("Error signing certificate: {{err}}" , err )
459- return nil , err
460- }
461-
462- response := & logical.Response {
463- Data : map [string ]interface {}{
464- "certificate" : certs [0 ],
465- "issuing_ca" : certs [1 ],
466- "ca_chain" : certs [1 :],
467- "serial_number" : serial ,
468- "revocation_time" : 0 ,
469- },
470- }
471- // err = req.Storage.Put(ctx, &logical.StorageEntry{
472- // Key: "certs/" + normalizeSerial(serial),
473- // Value: certs[0],
474- // })
475- // if err != nil {
476- // return nil, errwrap.Wrapf("unable to store certificate locally: {{err}}", err)
477- // }
478- return response , nil
479-
480- }
481-
482- // Revoke certificate.
483- // func (b *backend) revoke(ctx context.Context, req *logical.Request, data *framework.FieldData, serial string) (*logical.Response, error) {
484- // serial = strings.ReplaceAll(serial, "-", "")
485- // serial = strings.ReplaceAll(serial, ":", "")
486- // fmt.Println("Revoking serial number " + serial)
487-
488- // //b.Logger().Info(string(b.store[path]))
489-
490- // // set up keyfactor api request
491- // url := config["protocol"] + "://" + config["host"] + "/CMSAPI/Certificates/3/Revoke"
492- // payload := `{"Lookup":{"Type":"Serial","SerialNumber":"` + serial + `","IssuerDN":"CN=jdk-CA1,DC=jdk,DC=cms"},"Details":{"Reason":4, "EffectiveDate": "2020-5-5", "Comment":"" }}`
493-
494- // httpReq, _ := http.NewRequest("POST", url, strings.NewReader(payload))
495-
496- // httpReq.Header.Add("content-type", "application/json")
497- // httpReq.Header.Add("authorization", "Basic "+config["creds"])
498-
499- // res, err := http.DefaultClient.Do(httpReq)
500- // if err != nil {
501- // b.Logger().Error("Revoke failed: {{err}}", err)
502- // }
503-
504- // defer res.Body.Close()
505- // _, _ = ioutil.ReadAll(res.Body)
506-
507- // // Remove entry for specified path
508- // //delete(b.store, path)
509- // certEntry, err := fetchCertBySerial(ctx, req, "certs/", serial)
510- // var revInfo revocationInfo
511- // revEntry, err := fetchCertBySerial(ctx, req, "revoked/", serial)
512- // if err != nil {
513- // switch err.(type) {
514- // case errutil.UserError:
515- // return logical.ErrorResponse(err.Error()), nil
516- // case errutil.InternalError:
517- // return nil, err
518- // }
519- // }
520-
521- // currTime := time.Now()
522- // revInfo.CertificateBytes = certEntry.Value
523- // revInfo.RevocationTime = currTime.Unix()
524- // revInfo.RevocationTimeUTC = currTime.UTC()
525-
526- // revEntry, err = logical.StorageEntryJSON("revoked/"+normalizeSerial(serial), revInfo)
527- // if err != nil {
528- // return nil, fmt.Errorf("error creating revocation entry")
529- // }
530-
531- // err = req.Storage.Put(ctx, revEntry)
532- // if err != nil {
533- // return nil, fmt.Errorf("error saving revoked certificate to new location")
534- // }
535-
536- // return nil, nil
537- // }
538-
539197const keyfactorHelp = `
540198The Keyfactor backend is a pki service that issues and manages certificates.
541199`
0 commit comments