Add a function to check cert expiration dates.

This commit is contained in:
xenolf 2015-10-16 21:05:16 +02:00
parent 9160122ebe
commit 34910bd541
3 changed files with 74 additions and 32 deletions

View file

@ -6,6 +6,8 @@ import (
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"math/big"
"time"
)
func generatePrivateKey(keyLength int) (*rsa.PrivateKey, error) {
@ -31,3 +33,49 @@ func pemEncode(data interface{}) []byte {
return pem.EncodeToMemory(pemBlock)
}
func GetCertExpiration(cert []byte) (time.Time, error) {
pCert, err := x509.ParseCertificate(cert)
if err != nil {
return time.Time{}, err
}
return pCert.NotAfter, nil
}
func generatePemCert(privKey *rsa.PrivateKey, domain string) ([]byte, error) {
derBytes, err := generateDerCert(privKey, time.Time{}, domain)
if err != nil {
return nil, err
}
return pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: derBytes}), nil
}
func generateDerCert(privKey *rsa.PrivateKey, expiration time.Time, domain string) ([]byte, error) {
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
if err != nil {
return nil, err
}
zero := time.Time{}
if expiration == zero {
expiration = time.Now().Add(365)
}
template := x509.Certificate{
SerialNumber: serialNumber,
Subject: pkix.Name{
CommonName: "ACME Challenge TEMP",
},
NotBefore: time.Now(),
NotAfter: expiration,
KeyUsage: x509.KeyUsageKeyEncipherment,
BasicConstraintsValid: true,
DNSNames: []string{domain},
}
return x509.CreateCertificate(rand.Reader, &template, &template, &privKey.PublicKey, privKey)
}

View file

@ -4,6 +4,7 @@ import (
"bytes"
"crypto/rsa"
"testing"
"time"
)
func TestGeneratePrivateKey(t *testing.T) {
@ -50,6 +51,30 @@ func TestPEMEncode(t *testing.T) {
}
}
func TestCertExpiration(t *testing.T) {
privKey, err := generatePrivateKey(2048)
if err != nil {
t.Fatal("Error generating private key:", err)
}
expiration := time.Now().Add(365)
expiration = expiration.Round(time.Second)
certBytes, err := generateDerCert(privKey, expiration, "test.com")
if err != nil {
t.Fatal("Error generating cert:", err)
}
buf := bytes.NewBufferString("TestingRSAIsSoMuchFun")
if ctime, err := GetCertExpiration(buf.Bytes()); err == nil {
t.Errorf("Expected getCertExpiration to return an error for garbage string but returned %v", ctime)
}
if ctime, err := GetCertExpiration(certBytes); err != nil || ctime != expiration.UTC() {
t.Errorf("Expected getCertExpiration to return %v but returned: %v, err: %v", expiration.UTC(), ctime, err)
}
}
type MockRandReader struct {
b *bytes.Buffer
}

View file

@ -2,16 +2,13 @@ package acme
import (
"crypto/rand"
"crypto/rsa"
"crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
"encoding/json"
"encoding/pem"
"errors"
"fmt"
"io/ioutil"
"math/big"
"net"
"net/http"
"strings"
@ -122,7 +119,7 @@ func (s *simpleHTTPChallenge) startHTTPSServer(domain string, token string) (net
if err != nil {
return nil, err
}
tempCertPEM, err := generateCert(tempPrivKey, domain)
tempCertPEM, err := generatePemCert(tempPrivKey, domain)
if err != nil {
return nil, err
}
@ -190,31 +187,3 @@ func getRandomString(length int) string {
}
return string(bytes)
}
func generateCert(privKey *rsa.PrivateKey, domain string) ([]byte, error) {
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
if err != nil {
return nil, err
}
template := x509.Certificate{
SerialNumber: serialNumber,
Subject: pkix.Name{
CommonName: "ACME Challenge TEMP",
},
NotBefore: time.Now(),
NotAfter: time.Now().Add(365),
KeyUsage: x509.KeyUsageKeyEncipherment,
BasicConstraintsValid: true,
DNSNames: []string{domain},
}
derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &privKey.PublicKey, privKey)
if err != nil {
return nil, err
}
return pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: derBytes}), nil
}