@@ -2,6 +2,7 @@ package scep
2
2
3
3
import (
4
4
"context"
5
+ "crypto"
5
6
"crypto/x509"
6
7
"errors"
7
8
"fmt"
@@ -18,12 +19,10 @@ import (
18
19
19
20
// Authority is the layer that handles all SCEP interactions.
20
21
type Authority struct {
21
- prefix string
22
- dns string
23
- intermediateCertificate * x509.Certificate
24
- caCerts []* x509.Certificate // TODO(hs): change to use these instead of root and intermediate
25
- service * Service
26
- signAuth SignAuthority
22
+ prefix string
23
+ dns string
24
+ service * Service
25
+ signAuth SignAuthority
27
26
}
28
27
29
28
type authorityKey struct {}
@@ -74,18 +73,8 @@ func New(signAuth SignAuthority, ops AuthorityOptions) (*Authority, error) {
74
73
prefix : ops .Prefix ,
75
74
dns : ops .DNS ,
76
75
signAuth : signAuth ,
76
+ service : ops .Service ,
77
77
}
78
-
79
- // TODO: this is not really nice to do; the Service should be removed
80
- // in its entirety to make this more interoperable with the rest of
81
- // step-ca, I think.
82
- if ops .Service != nil {
83
- authority .caCerts = ops .Service .certificateChain
84
- // TODO(hs): look into refactoring SCEP into using just caCerts everywhere, if it makes sense for more elaborate SCEP configuration. Keeping it like this for clarity (for now).
85
- authority .intermediateCertificate = ops .Service .certificateChain [0 ]
86
- authority .service = ops .Service
87
- }
88
-
89
78
return authority , nil
90
79
}
91
80
@@ -165,30 +154,46 @@ func (a *Authority) GetCACertificates(ctx context.Context) ([]*x509.Certificate,
165
154
return nil , err
166
155
}
167
156
168
- if len (a .caCerts ) == 0 {
157
+ if len (a .service . certificateChain ) == 0 {
169
158
return nil , errors .New ("no intermediate certificate available in SCEP authority" )
170
159
}
171
160
172
161
certs := []* x509.Certificate {}
173
- certs = append (certs , a .caCerts [0 ])
162
+ if decrypterCertificate , _ := p .GetDecrypter (); decrypterCertificate != nil {
163
+ certs = append (certs , decrypterCertificate )
164
+ certs = append (certs , a .service .signerCertificate )
165
+ } else {
166
+ certs = append (certs , a .service .defaultDecrypterCertificate )
167
+ }
174
168
175
169
// NOTE: we're adding the CA roots here, but they are (highly likely) different than what the RFC means.
176
170
// Clients are responsible to select the right cert(s) to use, though.
177
- if p .ShouldIncludeRootInChain () && len (a .caCerts ) > 1 {
178
- certs = append (certs , a .caCerts [1 ])
171
+ if p .ShouldIncludeRootInChain () && len (a .service . certificateChain ) > 1 {
172
+ certs = append (certs , a .service . certificateChain [1 ])
179
173
}
180
174
181
175
return certs , nil
182
176
}
183
177
184
178
// DecryptPKIEnvelope decrypts an enveloped message
185
- func (a * Authority ) DecryptPKIEnvelope (_ context.Context , msg * PKIMessage ) error {
179
+ func (a * Authority ) DecryptPKIEnvelope (ctx context.Context , msg * PKIMessage ) error {
186
180
p7c , err := pkcs7 .Parse (msg .P7 .Content )
187
181
if err != nil {
188
182
return fmt .Errorf ("error parsing pkcs7 content: %w" , err )
189
183
}
190
184
191
- envelope , err := p7c .Decrypt (a .intermediateCertificate , a .service .decrypter )
185
+ fmt .Println (fmt .Sprintf ("%#+v" , a .service .defaultDecrypterCertificate ))
186
+ fmt .Println (fmt .Sprintf ("%#+v" , a .service .defaultDecrypter ))
187
+
188
+ cert , pkey , err := a .selectDecrypter (ctx )
189
+ if err != nil {
190
+ return fmt .Errorf ("failed selecting decrypter: %w" , err )
191
+ }
192
+
193
+ fmt .Println (fmt .Sprintf ("%#+v" , cert ))
194
+ fmt .Println (fmt .Sprintf ("%#+v" , pkey ))
195
+
196
+ envelope , err := p7c .Decrypt (cert , pkey )
192
197
if err != nil {
193
198
return fmt .Errorf ("error decrypting encrypted pkcs7 content: %w" , err )
194
199
}
@@ -208,6 +213,9 @@ func (a *Authority) DecryptPKIEnvelope(_ context.Context, msg *PKIMessage) error
208
213
if err != nil {
209
214
return fmt .Errorf ("parse CSR from pkiEnvelope: %w" , err )
210
215
}
216
+ if err := csr .CheckSignature (); err != nil {
217
+ return fmt .Errorf ("invalid CSR signature; %w" , err )
218
+ }
211
219
// check for challengePassword
212
220
cp , err := microx509util .ParseChallengePassword (msg .pkiEnvelope )
213
221
if err != nil {
@@ -226,6 +234,24 @@ func (a *Authority) DecryptPKIEnvelope(_ context.Context, msg *PKIMessage) error
226
234
return nil
227
235
}
228
236
237
+ func (a * Authority ) selectDecrypter (ctx context.Context ) (cert * x509.Certificate , pkey crypto.PrivateKey , err error ) {
238
+ p , err := provisionerFromContext (ctx )
239
+ if err != nil {
240
+ return nil , nil , err
241
+ }
242
+
243
+ // return provisioner specific decrypter, if available
244
+ if cert , pkey = p .GetDecrypter (); cert != nil && pkey != nil {
245
+ return
246
+ }
247
+
248
+ // fallback to the CA wide decrypter
249
+ cert = a .service .defaultDecrypterCertificate
250
+ pkey = a .service .defaultDecrypter
251
+
252
+ return
253
+ }
254
+
229
255
// SignCSR creates an x509.Certificate based on a CSR template and Cert Authority credentials
230
256
// returns a new PKIMessage with CertRep data
231
257
func (a * Authority ) SignCSR (ctx context.Context , csr * x509.CertificateRequest , msg * PKIMessage ) (* PKIMessage , error ) {
@@ -358,10 +384,11 @@ func (a *Authority) SignCSR(ctx context.Context, csr *x509.CertificateRequest, m
358
384
// as the first certificate in the array
359
385
signedData .AddCertificate (cert )
360
386
361
- authCert := a .intermediateCertificate
387
+ authCert := a .service .signerCertificate
388
+ signer := a .service .signer
362
389
363
390
// sign the attributes
364
- if err := signedData .AddSigner (authCert , a . service . signer , config ); err != nil {
391
+ if err := signedData .AddSigner (authCert , signer , config ); err != nil {
365
392
return nil , err
366
393
}
367
394
@@ -429,7 +456,7 @@ func (a *Authority) CreateFailureResponse(_ context.Context, _ *x509.Certificate
429
456
}
430
457
431
458
// sign the attributes
432
- if err := signedData .AddSigner (a .intermediateCertificate , a .service .signer , config ); err != nil {
459
+ if err := signedData .AddSigner (a .service . signerCertificate , a .service .signer , config ); err != nil {
433
460
return nil , err
434
461
}
435
462
0 commit comments