@@ -10,14 +10,15 @@ import (
10
10
"crypto/x509/pkix"
11
11
"encoding/json"
12
12
"encoding/pem"
13
+ "errors"
14
+ "fmt"
13
15
"os"
14
16
"path"
15
17
"strings"
16
18
"sync"
17
19
"time"
18
20
19
21
"github.com/eggsampler/acme/v3"
20
- "github.com/pkg/errors"
21
22
)
22
23
23
24
type CertManager struct {
@@ -64,7 +65,7 @@ func New(conf Config) (*CertManager, error) {
64
65
}
65
66
client , err := acme .NewClient (conf .Directory , acme .WithHTTPTimeout (time .Second * 10 ))
66
67
if err != nil {
67
- return nil , errors . Wrap ( err , "initializing acme client" )
68
+ return nil , fmt . Errorf ( "initializing acme client: %w" , err )
68
69
}
69
70
c := & CertManager {
70
71
client : client ,
@@ -84,17 +85,17 @@ func (c *CertManager) CreateAccount() error {
84
85
var err error
85
86
c .accKey , err = ecdsa .GenerateKey (elliptic .P256 (), rand .Reader )
86
87
if err != nil {
87
- return errors . Wrap ( err , "generating new account private key" )
88
+ return fmt . Errorf ( "generating new account private key: %w" , err )
88
89
}
89
90
c .account , err = c .client .NewAccountOptions (c .accKey , acme .NewAcctOptAgreeTOS (), acme .NewAcctOptWithContacts (c .config .Contact ))
90
91
if err != nil {
91
- return errors . Wrap ( err , "creating account with CA" )
92
+ return fmt . Errorf ( "creating account with CA: %w" , err )
92
93
}
93
94
c .hasAcc = true
94
95
95
96
pem , err := keyToPEM (c .accKey )
96
97
if err != nil {
97
- return errors . Wrap ( err , "converting pkey to pem" )
98
+ return fmt . Errorf ( "converting pkey to pem: %w" , err )
98
99
}
99
100
af := AccountFile {
100
101
PrivateKey : string (pem ),
@@ -106,25 +107,25 @@ func (c *CertManager) CreateAccount() error {
106
107
func (c * CertManager ) persistAccount (af AccountFile ) error {
107
108
w , err := os .Create (path .Join (c .config .DataDir , "accounts.json" ))
108
109
if err != nil {
109
- return errors . Wrap ( err , "opening accounts.json for writing" )
110
+ return fmt . Errorf ( "opening accounts.json for writing: %w" , err )
110
111
}
111
112
defer w .Close ()
112
113
err = json .NewEncoder (w ).Encode (& af )
113
114
if err != nil {
114
- return errors . Wrap ( err , "writing to accounts.json" )
115
+ return fmt . Errorf ( "writing to accounts.json: %w" , err )
115
116
}
116
117
return nil
117
118
}
118
119
119
120
func (c * CertManager ) persisCerts (bundle Bundle ) error {
120
121
w , err := os .Create (path .Join (c .config .DataDir , "bundle.json" ))
121
122
if err != nil {
122
- return errors . Wrap ( err , "opening bundle.json for writing" )
123
+ return fmt . Errorf ( "opening bundle.json for writing: %w" , err )
123
124
}
124
125
defer w .Close ()
125
126
err = json .NewEncoder (w ).Encode (& bundle )
126
127
if err != nil {
127
- return errors . Wrap ( err , "writing to bundle.json" )
128
+ return fmt . Errorf ( "writing to bundle.json: %w" , err )
128
129
}
129
130
return nil
130
131
}
@@ -138,7 +139,7 @@ func (c *CertManager) ExportAccount() (*AccountFile, error) {
138
139
}
139
140
pem , err := keyToPEM (c .accKey )
140
141
if err != nil {
141
- return nil , errors . Wrap ( err , "converting pkey to pem" )
142
+ return nil , fmt . Errorf ( "converting pkey to pem: %w" , err )
142
143
}
143
144
af := AccountFile {
144
145
PrivateKey : string (pem ),
@@ -153,14 +154,14 @@ func (c *CertManager) LoadAccountFromFile() error {
153
154
if errors .Is (err , os .ErrNotExist ) {
154
155
return ErrNoAccount
155
156
}
156
- return errors . Wrap ( err , "loading accounts.json" )
157
+ return fmt . Errorf ( "loading accounts.json: %w" , err )
157
158
}
158
159
defer f .Close ()
159
160
160
161
var af AccountFile
161
162
err = json .NewDecoder (f ).Decode (& af )
162
163
if err != nil {
163
- return errors . Wrap ( err , "decoding accounts.json" )
164
+ return fmt . Errorf ( "decoding accounts.json: %w" , err )
164
165
}
165
166
166
167
return c .ImportAccount (af , false )
@@ -172,14 +173,14 @@ func (c *CertManager) LoadBundleFromFile() error {
172
173
if errors .Is (err , os .ErrNotExist ) {
173
174
return ErrNoCert
174
175
}
175
- return errors . Wrap ( err , "loading bundle.json" )
176
+ return fmt . Errorf ( "loading bundle.json: %w" , err )
176
177
}
177
178
defer f .Close ()
178
179
179
180
var bundle Bundle
180
181
err = json .NewDecoder (f ).Decode (& bundle )
181
182
if err != nil {
182
- return errors . Wrap ( err , "decoding bundle.json" )
183
+ return fmt . Errorf ( "decoding bundle.json: %w" , err )
183
184
}
184
185
185
186
return c .ImportBundle (bundle , false )
@@ -195,15 +196,15 @@ func (c *CertManager) ImportAccount(af AccountFile, persist bool) error {
195
196
196
197
pKey , err := pemToKey ([]byte (af .PrivateKey ))
197
198
if err != nil {
198
- return errors . Wrap ( err , "converting pem to pkey" )
199
+ return fmt . Errorf ( "converting pem to pkey: %w" , err )
199
200
}
200
201
c .account , err = c .client .UpdateAccount (acme.Account {
201
202
PrivateKey : pKey ,
202
203
URL : af .URL ,
203
204
}, c .config .Contact )
204
205
205
206
if err != nil {
206
- return errors . Wrap ( err , "reloading accounts" )
207
+ return fmt . Errorf ( "reloading accounts: %w" , err )
207
208
}
208
209
209
210
c .hasAcc = true
@@ -226,7 +227,7 @@ func (c *CertManager) ImportPrivateKey(keyPem string) error {
226
227
var err error
227
228
c .certPKey , err = pemToKey ([]byte (keyPem ))
228
229
if err != nil {
229
- return errors . Wrap ( err , "decoding private key from pem" )
230
+ return fmt . Errorf ( "decoding private key from pem: %w" , err )
230
231
}
231
232
return nil
232
233
}
@@ -241,22 +242,22 @@ func (c *CertManager) ExportPrivateKey() ([]byte, error) {
241
242
242
243
pKey , err := keyToPEM (c .certPKey )
243
244
if err != nil {
244
- return nil , errors . Wrap ( err , "encoding private key to pem" )
245
+ return nil , fmt . Errorf ( "encoding private key to pem: %w" , err )
245
246
}
246
247
return pKey , nil
247
248
}
248
249
249
250
func (c * CertManager ) ImportBundle (bundle Bundle , persist bool ) error {
250
251
pKey , err := pemToKey ([]byte (bundle .PrivateKey ))
251
252
if err != nil {
252
- return errors . Wrap ( err , "decoding private key" )
253
+ return fmt . Errorf ( "decoding private key: %w" , err )
253
254
}
254
255
cert , err := tls .X509KeyPair (
255
256
[]byte (strings .Join (bundle .Chain , "\n " )),
256
257
[]byte (bundle .PrivateKey ),
257
258
)
258
259
if err != nil {
259
- return errors . Wrap ( err , "generating x509 key pair" )
260
+ return fmt . Errorf ( "generating x509 key pair: %w" , err )
260
261
}
261
262
c .certPKeyMu .Lock ()
262
263
c .certMu .Lock ()
@@ -300,6 +301,7 @@ func (c *CertManager) RequestCertificate() error {
300
301
common := c .config .RootZone
301
302
apex := strings .TrimSuffix (c .config .Domain , c .config .RootZone )
302
303
apex = strings .TrimSuffix (apex , "." )
304
+ // TODO: the following routine is not robust
303
305
switch {
304
306
case apex == "" :
305
307
case apex [0 ] == 0x2a : // the "*" character
@@ -323,7 +325,7 @@ func (c *CertManager) RequestCertificate() error {
323
325
c .certPKey , err = ecdsa .GenerateKey (elliptic .P256 (), rand .Reader )
324
326
if err != nil {
325
327
c .certPKeyMu .Unlock ()
326
- return errors . Wrap ( err , "generating certificate private key" )
328
+ return fmt . Errorf ( "generating certificate private key: %w" , err )
327
329
}
328
330
c .hasCertPKey = true
329
331
}
@@ -339,29 +341,29 @@ func (c *CertManager) RequestCertificate() error {
339
341
c .certPKeyMu .Unlock ()
340
342
341
343
if err != nil {
342
- return errors . Wrap ( err , "generating csr" )
344
+ return fmt . Errorf ( "generating csr: %w" , err )
343
345
}
344
346
csr , err := x509 .ParseCertificateRequest (csrDer )
345
347
if err != nil {
346
- return errors . Wrap ( err , "parsing csr" )
348
+ return fmt . Errorf ( "parsing csr: %w" , err )
347
349
}
348
350
349
351
var pKey []byte
350
352
pKey , err = c .ExportPrivateKey ()
351
353
if err != nil {
352
- return errors . Wrap ( err , "encoding private key to pem" )
354
+ return fmt . Errorf ( "encoding private key to pem: %w" , err )
353
355
}
354
356
355
357
// now we can create a order
356
358
o , err := c .client .NewOrderDomains (c .account , names ... )
357
359
if err != nil {
358
- return errors . Wrap ( err , "creating order" )
360
+ return fmt . Errorf ( "creating order: %w" , err )
359
361
}
360
362
361
363
for _ , authURL := range o .Authorizations {
362
364
auth , err := c .client .FetchAuthorization (c .account , authURL )
363
365
if err != nil {
364
- return errors . Wrap ( err , "fetching authorization" )
366
+ return fmt . Errorf ( "fetching authoriztion: %w" , err )
365
367
}
366
368
chal , ok := auth .ChallengeMap [acme .ChallengeTypeDNS01 ]
367
369
if ! ok {
@@ -376,15 +378,15 @@ func (c *CertManager) RequestCertificate() error {
376
378
377
379
ok , err = c .config .DNSProvider .Update (ctx , host , "TXT" , txt )
378
380
if err != nil {
379
- return errors . Wrap ( err , "updating dns record" )
381
+ return fmt . Errorf ( "updating dns record: %w" , err )
380
382
}
381
383
if ! ok {
382
384
return errors .New ("dns update failed" )
383
385
}
384
386
385
387
chal , err = c .client .UpdateChallenge (c .account , chal )
386
388
if err != nil {
387
- return errors . Wrap ( err , "updating challenge" )
389
+ return fmt . Errorf ( "updating challenge: %w" , err )
388
390
}
389
391
return nil
390
392
}()
@@ -398,12 +400,12 @@ func (c *CertManager) RequestCertificate() error {
398
400
399
401
o , err = c .client .FinalizeOrder (c .account , o , csr )
400
402
if err != nil {
401
- return errors . Wrap ( err , "finalizing order" )
403
+ return fmt . Errorf ( "finalizing order: %w" , err )
402
404
}
403
405
404
406
certs , err := c .client .FetchCertificates (c .account , o .Certificate )
405
407
if err != nil {
406
- return errors . Wrap ( err , "fetching certificates" )
408
+ return fmt . Errorf ( "fetching certificates: %w" , err )
407
409
}
408
410
409
411
var pemData []string
@@ -420,7 +422,7 @@ func (c *CertManager) RequestCertificate() error {
420
422
}
421
423
422
424
if err := c .ImportBundle (bundle , true ); err != nil {
423
- return errors . Wrap ( err , "re-importing exported certificate" )
425
+ return fmt . Errorf ( "re-importing exported certificate: %w" , err )
424
426
}
425
427
426
428
return nil
@@ -438,7 +440,7 @@ func (c *CertManager) GetCertificatesFunc(chi *tls.ClientHelloInfo) (*tls.Certif
438
440
func keyToPEM (pKey * ecdsa.PrivateKey ) ([]byte , error ) {
439
441
enc , err := x509 .MarshalECPrivateKey (pKey )
440
442
if err != nil {
441
- return nil , errors . Wrap ( err , "marshaling private key to pem" )
443
+ return nil , fmt . Errorf ( "marshalling private key to pem: %w" , err )
442
444
}
443
445
return pem .EncodeToMemory (& pem.Block {
444
446
Type : "EC PRIVATE KEY" ,
@@ -450,7 +452,7 @@ func pemToKey(b []byte) (*ecdsa.PrivateKey, error) {
450
452
blk , _ := pem .Decode (b )
451
453
pKey , err := x509 .ParseECPrivateKey (blk .Bytes )
452
454
if err != nil {
453
- return nil , errors . Wrap ( err , "parsing private key from pem" )
455
+ return nil , fmt . Errorf ( "parsing private key from pem: %w" , err )
454
456
}
455
457
return pKey , nil
456
458
}
0 commit comments