Merge pull request #1481 from letsencrypt/update_cfssl

update cfssl mostly for the Subject.SerialName
This commit is contained in:
Jeff Hodges 2016-02-11 11:31:42 -08:00
commit 7176ac1b2d
5 changed files with 105 additions and 47 deletions

48
Godeps/Godeps.json generated
View File

@ -12,63 +12,63 @@
}, },
{ {
"ImportPath": "github.com/cloudflare/cfssl/auth", "ImportPath": "github.com/cloudflare/cfssl/auth",
"Comment": "1.1.0-345-g3cc473b", "Comment": "1.1.0-355-g3f3fa68",
"Rev": "3cc473b970536c9c35099bc46be861cd33f8bda2" "Rev": "3f3fa68e8d6ce6ceace60ea86461f8be41fa477b"
}, },
{ {
"ImportPath": "github.com/cloudflare/cfssl/certdb", "ImportPath": "github.com/cloudflare/cfssl/certdb",
"Comment": "1.1.0-345-g3cc473b", "Comment": "1.1.0-355-g3f3fa68",
"Rev": "3cc473b970536c9c35099bc46be861cd33f8bda2" "Rev": "3f3fa68e8d6ce6ceace60ea86461f8be41fa477b"
}, },
{ {
"ImportPath": "github.com/cloudflare/cfssl/config", "ImportPath": "github.com/cloudflare/cfssl/config",
"Comment": "1.1.0-345-g3cc473b", "Comment": "1.1.0-355-g3f3fa68",
"Rev": "3cc473b970536c9c35099bc46be861cd33f8bda2" "Rev": "3f3fa68e8d6ce6ceace60ea86461f8be41fa477b"
}, },
{ {
"ImportPath": "github.com/cloudflare/cfssl/crypto/pkcs11key", "ImportPath": "github.com/cloudflare/cfssl/crypto/pkcs11key",
"Comment": "1.1.0-345-g3cc473b", "Comment": "1.1.0-355-g3f3fa68",
"Rev": "3cc473b970536c9c35099bc46be861cd33f8bda2" "Rev": "3f3fa68e8d6ce6ceace60ea86461f8be41fa477b"
}, },
{ {
"ImportPath": "github.com/cloudflare/cfssl/crypto/pkcs7", "ImportPath": "github.com/cloudflare/cfssl/crypto/pkcs7",
"Comment": "1.1.0-345-g3cc473b", "Comment": "1.1.0-355-g3f3fa68",
"Rev": "3cc473b970536c9c35099bc46be861cd33f8bda2" "Rev": "3f3fa68e8d6ce6ceace60ea86461f8be41fa477b"
}, },
{ {
"ImportPath": "github.com/cloudflare/cfssl/csr", "ImportPath": "github.com/cloudflare/cfssl/csr",
"Comment": "1.1.0-345-g3cc473b", "Comment": "1.1.0-355-g3f3fa68",
"Rev": "3cc473b970536c9c35099bc46be861cd33f8bda2" "Rev": "3f3fa68e8d6ce6ceace60ea86461f8be41fa477b"
}, },
{ {
"ImportPath": "github.com/cloudflare/cfssl/errors", "ImportPath": "github.com/cloudflare/cfssl/errors",
"Comment": "1.1.0-345-g3cc473b", "Comment": "1.1.0-355-g3f3fa68",
"Rev": "3cc473b970536c9c35099bc46be861cd33f8bda2" "Rev": "3f3fa68e8d6ce6ceace60ea86461f8be41fa477b"
}, },
{ {
"ImportPath": "github.com/cloudflare/cfssl/helpers", "ImportPath": "github.com/cloudflare/cfssl/helpers",
"Comment": "1.1.0-345-g3cc473b", "Comment": "1.1.0-355-g3f3fa68",
"Rev": "3cc473b970536c9c35099bc46be861cd33f8bda2" "Rev": "3f3fa68e8d6ce6ceace60ea86461f8be41fa477b"
}, },
{ {
"ImportPath": "github.com/cloudflare/cfssl/info", "ImportPath": "github.com/cloudflare/cfssl/info",
"Comment": "1.1.0-345-g3cc473b", "Comment": "1.1.0-355-g3f3fa68",
"Rev": "3cc473b970536c9c35099bc46be861cd33f8bda2" "Rev": "3f3fa68e8d6ce6ceace60ea86461f8be41fa477b"
}, },
{ {
"ImportPath": "github.com/cloudflare/cfssl/log", "ImportPath": "github.com/cloudflare/cfssl/log",
"Comment": "1.1.0-345-g3cc473b", "Comment": "1.1.0-355-g3f3fa68",
"Rev": "3cc473b970536c9c35099bc46be861cd33f8bda2" "Rev": "3f3fa68e8d6ce6ceace60ea86461f8be41fa477b"
}, },
{ {
"ImportPath": "github.com/cloudflare/cfssl/ocsp", "ImportPath": "github.com/cloudflare/cfssl/ocsp",
"Comment": "1.1.0-345-g3cc473b", "Comment": "1.1.0-355-g3f3fa68",
"Rev": "3cc473b970536c9c35099bc46be861cd33f8bda2" "Rev": "3f3fa68e8d6ce6ceace60ea86461f8be41fa477b"
}, },
{ {
"ImportPath": "github.com/cloudflare/cfssl/signer", "ImportPath": "github.com/cloudflare/cfssl/signer",
"Comment": "1.1.0-345-g3cc473b", "Comment": "1.1.0-355-g3f3fa68",
"Rev": "3cc473b970536c9c35099bc46be861cd33f8bda2" "Rev": "3f3fa68e8d6ce6ceace60ea86461f8be41fa477b"
}, },
{ {
"ImportPath": "github.com/codegangsta/cli", "ImportPath": "github.com/codegangsta/cli",

View File

@ -327,7 +327,14 @@ func LoadPEMCertPool(certsFile string) (*x509.CertPool, error) {
// key. The private key may be either an unencrypted PKCS#8, PKCS#1, // key. The private key may be either an unencrypted PKCS#8, PKCS#1,
// or elliptic private key. // or elliptic private key.
func ParsePrivateKeyPEM(keyPEM []byte) (key crypto.Signer, err error) { func ParsePrivateKeyPEM(keyPEM []byte) (key crypto.Signer, err error) {
keyDER, err := GetKeyDERFromPEM(keyPEM) return ParsePrivateKeyPEMWithPassword(keyPEM, nil)
}
// ParsePrivateKeyPEMWithPassword parses and returns a PEM-encoded private
// key. The private key may be a potentially encrypted PKCS#8, PKCS#1,
// or elliptic private key.
func ParsePrivateKeyPEMWithPassword(keyPEM []byte, password []byte) (key crypto.Signer, err error) {
keyDER, err := GetKeyDERFromPEM(keyPEM, password)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -336,11 +343,14 @@ func ParsePrivateKeyPEM(keyPEM []byte) (key crypto.Signer, err error) {
} }
// GetKeyDERFromPEM parses a PEM-encoded private key and returns DER-format key bytes. // GetKeyDERFromPEM parses a PEM-encoded private key and returns DER-format key bytes.
func GetKeyDERFromPEM(in []byte) ([]byte, error) { func GetKeyDERFromPEM(in []byte, password []byte) ([]byte, error) {
keyDER, _ := pem.Decode(in) keyDER, _ := pem.Decode(in)
if keyDER != nil { if keyDER != nil {
if procType, ok := keyDER.Headers["Proc-Type"]; ok { if procType, ok := keyDER.Headers["Proc-Type"]; ok {
if strings.Contains(procType, "ENCRYPTED") { if strings.Contains(procType, "ENCRYPTED") {
if password != nil {
return x509.DecryptPEMBlock(keyDER, password)
}
return nil, cferr.New(cferr.PrivateKeyError, cferr.Encrypted) return nil, cferr.New(cferr.PrivateKeyError, cferr.Encrypted)
} }
} }

View File

@ -6,43 +6,82 @@
package log package log
import ( import (
"flag"
"fmt" "fmt"
golog "log" "log"
"log/syslog"
"os" "os"
) )
// The following constants represent logging levels in increasing levels of seriousness. // The following constants represent logging levels in increasing levels of seriousness.
const ( const (
// LevelDebug is the log level for Debug statements.
LevelDebug = iota LevelDebug = iota
// LevelInfo is the log level for Info statements.
LevelInfo LevelInfo
// LevelWarning is the log level for Warning statements.
LevelWarning LevelWarning
// LevelError is the log level for Error statements.
LevelError LevelError
// LevelCritical is the log level for Critical statements.
LevelCritical LevelCritical
// LevelFatal is the log level for Fatal statements.
LevelFatal LevelFatal
) )
var levelPrefix = [...]string{ var levelPrefix = [...]string{
LevelDebug: "[DEBUG] ", LevelDebug: "DEBUG",
LevelInfo: "[INFO] ", LevelInfo: "INFO",
LevelWarning: "[WARNING] ", LevelWarning: "WARNING",
LevelError: "[ERROR] ", LevelError: "ERROR",
LevelCritical: "[CRITICAL] ", LevelCritical: "CRITICAL",
LevelFatal: "[FATAL] ", LevelFatal: "FATAL",
} }
// Level stores the current logging level. var (
var Level = LevelDebug // Level stores the current logging level.
Level = LevelInfo
// SysLogger is a syslog Writer to be used if not nil.
SysLogger *syslog.Writer
)
func init() {
flag.IntVar(&Level, "loglevel", LevelInfo, "Log level (0 = DEBUG, 5 = FATAL)")
}
func print(l int, msg string) {
if l >= Level {
if SysLogger != nil {
var err error
switch l {
case LevelDebug:
err = SysLogger.Debug(msg)
case LevelInfo:
err = SysLogger.Info(msg)
case LevelWarning:
err = SysLogger.Warning(msg)
case LevelError:
err = SysLogger.Err(msg)
case LevelCritical:
err = SysLogger.Crit(msg)
case LevelFatal:
err = SysLogger.Emerg(msg)
}
if err != nil {
log.Printf("Unable to write syslog: %v for msg: %s\n", err, msg)
}
} else {
log.Printf("[%s] %s", levelPrefix[l], msg)
}
}
}
func outputf(l int, format string, v []interface{}) { func outputf(l int, format string, v []interface{}) {
if l >= Level { print(l, fmt.Sprintf(format, v...))
golog.Printf(fmt.Sprint(levelPrefix[l], format), v...)
}
} }
func output(l int, v []interface{}) { func output(l int, v []interface{}) {
if l >= Level { print(l, fmt.Sprint(v...))
golog.Print(levelPrefix[l], fmt.Sprint(v...))
}
} }
// Fatalf logs a formatted message at the "fatal" level and then exits. The // Fatalf logs a formatted message at the "fatal" level and then exits. The

View File

@ -12,12 +12,12 @@ import (
"encoding/hex" "encoding/hex"
"encoding/pem" "encoding/pem"
"errors" "errors"
"fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"math/big" "math/big"
"net" "net"
"net/mail" "net/mail"
"os"
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/certdb" "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/certdb"
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/config" "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/config"
@ -80,7 +80,13 @@ func NewSignerFromFile(caFile, caKeyFile string, policy *config.Signing) (*Signe
return nil, err return nil, err
} }
priv, err := helpers.ParsePrivateKeyPEM(cakey) strPassword := os.Getenv("CFSSL_CA_PK_PASSWORD")
password := []byte(strPassword)
if strPassword == "" {
password = nil
}
priv, err := helpers.ParsePrivateKeyPEMWithPassword(cakey, password)
if err != nil { if err != nil {
log.Debug("Malformed private key %v", err) log.Debug("Malformed private key %v", err)
return nil, err return nil, err
@ -156,7 +162,9 @@ func PopulateSubjectFromCSR(s *signer.Subject, req pkix.Name) pkix.Name {
replaceSliceIfEmpty(&name.Locality, &req.Locality) replaceSliceIfEmpty(&name.Locality, &req.Locality)
replaceSliceIfEmpty(&name.Organization, &req.Organization) replaceSliceIfEmpty(&name.Organization, &req.Organization)
replaceSliceIfEmpty(&name.OrganizationalUnit, &req.OrganizationalUnit) replaceSliceIfEmpty(&name.OrganizationalUnit, &req.OrganizationalUnit)
if name.SerialNumber == "" {
name.SerialNumber = req.SerialNumber
}
return name return name
} }
@ -259,7 +267,6 @@ func (s *Signer) Sign(req signer.SignRequest) (cert []byte, err error) {
if profile.ClientProvidesSerialNumbers { if profile.ClientProvidesSerialNumbers {
if req.Serial == nil { if req.Serial == nil {
fmt.Printf("xx %#v\n", profile)
return nil, cferr.New(cferr.CertificateError, cferr.MissingSerial) return nil, cferr.New(cferr.CertificateError, cferr.MissingSerial)
} }
safeTemplate.SerialNumber = req.Serial safeTemplate.SerialNumber = req.Serial

View File

@ -29,8 +29,9 @@ var MaxPathLen = 2
// Subject contains the information that should be used to override the // Subject contains the information that should be used to override the
// subject information when signing a certificate. // subject information when signing a certificate.
type Subject struct { type Subject struct {
CN string CN string
Names []csr.Name `json:"names"` Names []csr.Name `json:"names"`
SerialNumber string
} }
// Extension represents a raw extension to be included in the certificate. The // Extension represents a raw extension to be included in the certificate. The
@ -77,6 +78,7 @@ func (s *Subject) Name() pkix.Name {
appendIf(n.O, &name.Organization) appendIf(n.O, &name.Organization)
appendIf(n.OU, &name.OrganizationalUnit) appendIf(n.OU, &name.OrganizationalUnit)
} }
name.SerialNumber = s.SerialNumber
return name return name
} }