]>
git.siccegge.de Git - tooling/letool.git/blob - bin/newcert
6817b704518de9bb13519a83b2535018c9d8bb0c
2 # -*- coding: utf-8 -*-
3 # (C) Christoph Egger <christoph@christoph-egger.org>
5 from __future__
import print_function
7 from socket
import getfqdn
14 from acme
import client
16 from acme
import messages
17 from acme
import challenges
19 from cryptography
.hazmat
.backends
import default_backend
20 from cryptography
.hazmat
.primitives
.asymmetric
import rsa
21 from cryptography
.hazmat
.primitives
import serialization
22 from cryptography
.hazmat
.primitives
import hashes
23 from cryptography
import x509
24 from cryptography
.x509
.oid
import NameOID
30 from sicceggetools
.acme
import constants
34 logging
.info("Loading account key")
35 with
open("data/account.key.pem", "rb") as keyfd
:
36 private_key
= serialization
.load_pem_private_key(
39 backend
=default_backend()
42 logging
.info("Loading account registration")
43 with
open("data/registration.json", "rb") as regfd
:
44 registration
= messages
.RegistrationResource
.json_loads(regfd
.read())
46 account_key
= jose
.JWKRSA(key
=private_key
)
47 acme_client
= client
.Client(constants
.DIRECTORY_URL
, account_key
)
49 return registration
, acme_client
, account_key
53 registration
, acme_client
, account_key
= get_client()
56 authzr
= acme_client
.request_challenges(
57 identifier
=messages
.Identifier(typ
=messages
.IDENTIFIER_FQDN
, value
=san
),
58 new_authzr_uri
=registration
.new_authzr_uri
)
59 authorizations
.append(authzr
)
60 for challenge
in authzr
.body
.challenges
:
61 if isinstance(challenge
.chall
, challenges
.DNS01
):
63 print(challenge
.validation(account_key
))
64 print(challenge
.key_authorization(account_key
))
65 ssh
= pexpect
.spawn("ssh _tls@ns1.siccegge.de acme")
66 ssh
.expect("Hostname:")
69 ssh
.sendline(challenge
.validation(account_key
))
77 for authorization
in authorizations
:
78 for challenge
in authorization
.body
.challenges
:
79 if isinstance(challenge
.chall
, challenges
.DNS01
):
80 response
= challenges
.DNS01Response(key_authorization
=challenge
.key_authorization(account_key
))
81 acme_client
.answer_challenge(challenge
, response
)
86 new_authorizations
= []
87 for authorization
in authorizations
:
88 new_auth
, response
= acme_client
.poll(authorization
)
89 new_authorizations
.append(new_auth
)
90 if new_auth
.body
.status
!= messages
.Status("valid"):
93 return new_authorizations
96 def get_certificate(cname
, sans
):
97 registration
, acme_client
, account_key
= get_client()
98 authorizations
= authorize(sans
)
100 with
open(os
.path
.join("certs", cname
, "key.pem"), "rb") as keyfd
:
101 private_key
= serialization
.load_pem_private_key(
104 backend
=default_backend())
106 builder
= x509
.CertificateSigningRequestBuilder()
107 builder
= builder
.subject_name(x509
.Name([
108 x509
.NameAttribute(NameOID
.COMMON_NAME
, cname
.decode()),
110 builder
= builder
.add_extension(
111 x509
.SubjectAlternativeName([x509
.DNSName(x
.decode()) for x
in sans
]),
114 request
= builder
.sign(private_key
, hashes
.SHA512(), default_backend())
115 orequest
= OpenSSL
.crypto
.load_certificate_request(
116 OpenSSL
.crypto
.FILETYPE_PEM
,
117 request
.public_bytes(serialization
.Encoding
.PEM
))
119 jrequest
= jose
.util
.ComparableX509(orequest
)
120 cert
= acme_client
.request_issuance(jrequest
, authorizations
)
121 certs
= acme_client
.fetch_chain(cert
)
123 with
open(os
.path
.join("certs", cname
, "cert.pem"), "wb") as certfd
:
124 certfd
.write(cert
.body
._dump
(OpenSSL
.crypto
.FILETYPE_PEM
))
126 certfd
.write(cert
._dump
(OpenSSL
.crypto
.FILETYPE_PEM
))
134 parser
= argparse
.ArgumentParser()
136 parser
.add_argument('--servicetype', '-s', type=str)
137 parser
.add_argument('certificate', type=str)
138 args
= parser
.parse_args()
140 with
open("config/inventory.yaml") as invfd
:
141 inventory
= yaml
.load(invfd
.read())
143 certificate_list
= inventory
[getfqdn()][args
.servicetype
]
144 if type(certificate_list
) is list:
145 if args
.certificate
in certificate_list
:
146 get_certificate(args
.certificate
, [args
.certificate
])
147 elif type(certificate_list
) is dict:
148 if args
.certificate
in certificate_list
.keys():
149 get_certificate(args
.certificate
, certificate_list
[args
.certificate
])
151 print("unexpected type: %s", type(certificate_list
))
154 if __name__
== '__main__':