forked from TrueCloudLab/lego
tls-alpn: add a function to return PEM blocks. (#579)
* feature(tls-alpn): add function to return PEM blocks.
This commit is contained in:
parent
d457f70ae0
commit
57782ac3c1
2 changed files with 35 additions and 26 deletions
|
@ -11,9 +11,8 @@ import (
|
||||||
"github.com/xenolf/lego/log"
|
"github.com/xenolf/lego/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// idPeAcmeIdentifierV1 is the SMI Security for PKIX Certification Extension
|
// idPeAcmeIdentifierV1 is the SMI Security for PKIX Certification Extension OID referencing the ACME extension.
|
||||||
// OID referencing the ACME extension. Reference:
|
// Reference: https://tools.ietf.org/html/draft-ietf-acme-tls-alpn-01#section-5.1
|
||||||
// https://tools.ietf.org/html/draft-ietf-acme-tls-alpn-01#section-5.1
|
|
||||||
var idPeAcmeIdentifierV1 = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 30, 1}
|
var idPeAcmeIdentifierV1 = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 30, 1}
|
||||||
|
|
||||||
type tlsALPNChallenge struct {
|
type tlsALPNChallenge struct {
|
||||||
|
@ -46,31 +45,20 @@ func (t *tlsALPNChallenge) Solve(chlng challenge, domain string) error {
|
||||||
return t.validate(t.jws, domain, chlng.URL, challenge{Type: chlng.Type, Token: chlng.Token, KeyAuthorization: keyAuth})
|
return t.validate(t.jws, domain, chlng.URL, challenge{Type: chlng.Type, Token: chlng.Token, KeyAuthorization: keyAuth})
|
||||||
}
|
}
|
||||||
|
|
||||||
// TLSALPNChallengeCert returns a certificate with the acmeValidation-v1
|
// TLSALPNChallengeBlocks returns PEM blocks (certPEMBlock, keyPEMBlock) with the acmeValidation-v1 extension
|
||||||
// extension and domain name for the `tls-alpn-01` challenge.
|
// and domain name for the `tls-alpn-01` challenge.
|
||||||
func TLSALPNChallengeCert(domain, keyAuth string) (*tls.Certificate, error) {
|
func TLSALPNChallengeBlocks(domain, keyAuth string) ([]byte, []byte, error) {
|
||||||
// Generate a new RSA key for the certificates.
|
|
||||||
tempPrivKey, err := generatePrivateKey(RSA2048)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encode the private key into a PEM format. We'll need to use it to
|
|
||||||
// generate the x509 keypair.
|
|
||||||
rsaPrivKey := tempPrivKey.(*rsa.PrivateKey)
|
|
||||||
rsaPrivPEM := pemEncode(rsaPrivKey)
|
|
||||||
|
|
||||||
// Compute the SHA-256 digest of the key authorization.
|
// Compute the SHA-256 digest of the key authorization.
|
||||||
zBytes := sha256.Sum256([]byte(keyAuth))
|
zBytes := sha256.Sum256([]byte(keyAuth))
|
||||||
|
|
||||||
value, err := asn1.Marshal(zBytes[:sha256.Size])
|
value, err := asn1.Marshal(zBytes[:sha256.Size])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the keyAuth digest as the acmeValidation-v1 extension (marked as
|
// Add the keyAuth digest as the acmeValidation-v1 extension
|
||||||
// critical such that it won't be used by non-ACME software). Reference:
|
// (marked as critical such that it won't be used by non-ACME software).
|
||||||
// https://tools.ietf.org/html/draft-ietf-acme-tls-alpn-01#section-3
|
// Reference: https://tools.ietf.org/html/draft-ietf-acme-tls-alpn-01#section-3
|
||||||
extensions := []pkix.Extension{
|
extensions := []pkix.Extension{
|
||||||
{
|
{
|
||||||
Id: idPeAcmeIdentifierV1,
|
Id: idPeAcmeIdentifierV1,
|
||||||
|
@ -79,9 +67,30 @@ func TLSALPNChallengeCert(domain, keyAuth string) (*tls.Certificate, error) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate the PEM certificate using the provided private key, domain, and
|
// Generate a new RSA key for the certificates.
|
||||||
// extra extensions.
|
tempPrivKey, err := generatePrivateKey(RSA2048)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
rsaPrivKey := tempPrivKey.(*rsa.PrivateKey)
|
||||||
|
|
||||||
|
// Generate the PEM certificate using the provided private key, domain, and extra extensions.
|
||||||
tempCertPEM, err := generatePemCert(rsaPrivKey, domain, extensions)
|
tempCertPEM, err := generatePemCert(rsaPrivKey, domain, extensions)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode the private key into a PEM format. We'll need to use it to generate the x509 keypair.
|
||||||
|
rsaPrivPEM := pemEncode(rsaPrivKey)
|
||||||
|
|
||||||
|
return tempCertPEM, rsaPrivPEM, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// TLSALPNChallengeCert returns a certificate with the acmeValidation-v1 extension
|
||||||
|
// and domain name for the `tls-alpn-01` challenge.
|
||||||
|
func TLSALPNChallengeCert(domain, keyAuth string) (*tls.Certificate, error) {
|
||||||
|
tempCertPEM, rsaPrivPEM, err := TLSALPNChallengeBlocks(domain, keyAuth)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// acmeTLS1Protocol is the ALPN Protocol ID for the ACME-TLS/1 Protocol.
|
// ACMETLS1Protocol is the ALPN Protocol ID for the ACME-TLS/1 Protocol.
|
||||||
acmeTLS1Protocol = "acme-tls/1"
|
ACMETLS1Protocol = "acme-tls/1"
|
||||||
|
|
||||||
// defaultTLSPort is the port that the TLSALPNProviderServer will default to
|
// defaultTLSPort is the port that the TLSALPNProviderServer will default to
|
||||||
// when no other port is provided.
|
// when no other port is provided.
|
||||||
|
@ -55,7 +55,7 @@ func (t *TLSALPNProviderServer) Present(domain, token, keyAuth string) error {
|
||||||
// We must set that the `acme-tls/1` application level protocol is supported
|
// We must set that the `acme-tls/1` application level protocol is supported
|
||||||
// so that the protocol negotiation can succeed. Reference:
|
// so that the protocol negotiation can succeed. Reference:
|
||||||
// https://tools.ietf.org/html/draft-ietf-acme-tls-alpn-01#section-5.2
|
// https://tools.ietf.org/html/draft-ietf-acme-tls-alpn-01#section-5.2
|
||||||
tlsConf.NextProtos = []string{acmeTLS1Protocol}
|
tlsConf.NextProtos = []string{ACMETLS1Protocol}
|
||||||
|
|
||||||
// Create the listener with the created tls.Config.
|
// Create the listener with the created tls.Config.
|
||||||
t.listener, err = tls.Listen("tcp", net.JoinHostPort(t.iface, t.port), tlsConf)
|
t.listener, err = tls.Listen("tcp", net.JoinHostPort(t.iface, t.port), tlsConf)
|
||||||
|
|
Loading…
Reference in a new issue