Skip to content

Commit

Permalink
implement HasCN for boltdepot
Browse files Browse the repository at this point in the history
Closes #30
  • Loading branch information
groob committed Jul 16, 2017
1 parent ba005a1 commit e6079f0
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 18 deletions.
25 changes: 22 additions & 3 deletions depot/bolt/depot.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package bolt

import (
"bytes"
"crypto"
"crypto/rand"
"crypto/rsa"
Expand Down Expand Up @@ -169,9 +170,27 @@ func (db *Depot) incrementSerial(s *big.Int) error {
return err
}

func (db *Depot) HasCN(cn string, allowTime int, cert *x509.Certificate, revokeOldCertificate bool) error {
// FIXME: not implemented.
return nil
func (db *Depot) HasCN(cn string, allowTime int, cert *x509.Certificate, revokeOldCertificate bool) (bool, error) {
// TODO: implement allowTime
// TODO: implement revocation
if cert == nil {
return false, errors.New("nil certificate provided")
}
var hasCN bool
err := db.View(func(tx *bolt.Tx) error {
// TODO: "scep_certificates" is internal const in micromdm/scep
curs := tx.Bucket([]byte("scep_certificates")).Cursor()
prefix := []byte(cert.Subject.CommonName)
for k, v := curs.Seek(prefix); k != nil && bytes.HasPrefix(k, prefix); k, v = curs.Next() {
if bytes.Compare(v, cert.Raw) == 0 {
hasCN = true
return nil
}
}

return nil
})
return hasCN, err
}

func (db *Depot) CreateOrLoadKey(bits int) (*rsa.PrivateKey, error) {
Expand Down
2 changes: 1 addition & 1 deletion depot/depot.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ type Depot interface {
CA(pass []byte) ([]*x509.Certificate, *rsa.PrivateKey, error)
Put(name string, crt *x509.Certificate) error
Serial() (*big.Int, error)
HasCN(cn string, allowTime int, cert *x509.Certificate, revokeOldCertificate bool) error
HasCN(cn string, allowTime int, cert *x509.Certificate, revokeOldCertificate bool) (bool, error)
}
25 changes: 12 additions & 13 deletions depot/file/depot.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,22 +165,21 @@ func makeDn(cert *x509.Certificate) string {
}

// Determine if the cadb already has a valid certificate with the same name
func (d *fileDepot) HasCN(cn string, allowTime int, cert *x509.Certificate, revokeOldCertificate bool) error {
func (d *fileDepot) HasCN(cn string, allowTime int, cert *x509.Certificate, revokeOldCertificate bool) (bool, error) {

var addDB bytes.Buffer
var candidates map[string]string
candidates = make(map[string]string)
candidates := make(map[string]string)

dn := makeDn(cert)

if err := os.MkdirAll(d.dirPath, 0755); err != nil {
return err
return false, err
}

name := d.path("index.txt")
file, err := os.Open(name)
if err != nil {
return err
return false, err
}
defer file.Close()

Expand All @@ -201,11 +200,11 @@ func (d *fileDepot) HasCN(cn string, allowTime int, cert *x509.Certificate, revo
} else if strings.HasPrefix(line, "V\t") {
issueDate, err := strconv.Atoi(strings.Replace(strings.Split(line, "\t")[1], "Z", "", 1))
if err != nil {
return errors.New("Could not get expiry date from ca db")
return false, errors.New("Could not get expiry date from ca db")
}
minimalRenewDate, err := strconv.Atoi(strings.Replace(makeOpenSSLTime(time.Now().AddDate(0, 0, allowTime).UTC()), "Z", "", 1))
if err != nil {
return errors.New("Could not calculate expiry date")
return false, errors.New("Could not calculate expiry date")
}
entries := strings.Split(line, "\t")
serial := strings.ToUpper(entries[3])
Expand All @@ -224,7 +223,7 @@ func (d *fileDepot) HasCN(cn string, allowTime int, cert *x509.Certificate, revo
file.Close()
for key, value := range candidates {
if value == "no" {
return errors.New("DN " + dn + " already exists")
return false, errors.New("DN " + dn + " already exists")
}
if revokeOldCertificate {
fmt.Println("Revoking certificate with serial " + key + " from DB. Recreation of CRL needed.")
Expand All @@ -233,26 +232,26 @@ func (d *fileDepot) HasCN(cn string, allowTime int, cert *x509.Certificate, revo
}
}
if err := scanner.Err(); err != nil {
return err
return false, err
}
if revokeOldCertificate {
file, err := os.OpenFile(name, os.O_CREATE|os.O_RDWR, dbPerm)
if err != nil {
return err
return false, err
}
if _, err := file.Write(addDB.Bytes()); err != nil {
return err
return false, err
}
}
return nil
return true, nil
}

func (d *fileDepot) writeDB(cn string, serial *big.Int, filename string, cert *x509.Certificate) error {

var dbEntry bytes.Buffer

// Revoke old certificate
if err := d.HasCN(cn, 0, cert, true); err != nil {
if _, err := d.HasCN(cn, 0, cert, true); err != nil {
return err
}
if err := os.MkdirAll(d.dirPath, 0755); err != nil {
Expand Down
6 changes: 5 additions & 1 deletion server/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"crypto/x509"
"encoding/asn1"
"errors"
"fmt"
"math/big"
"time"

Expand Down Expand Up @@ -121,10 +122,13 @@ func (svc service) PKIOperation(ctx context.Context, data []byte) ([]byte, error
// Test if this certificate is already in the CADB, revoke if needed
// revocation is done if the validity of the existing certificate is
// less than allowRenewal (14 days by default)
err = svc.depot.HasCN(name, svc.allowRenewal, crt, false)
hasCN, err := svc.depot.HasCN(name, svc.allowRenewal, crt, false)
if err != nil {
return nil, err
}
if !hasCN {
return nil, fmt.Errorf("scep service: no certificate %s", name)
}

if err := svc.depot.Put(name, crt); err != nil {
return nil, err
Expand Down

0 comments on commit e6079f0

Please sign in to comment.