1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #include "nss.h"
8 #include "pk11func.h"
9 #include "secder.h"
10 #include "sechash.h"
11 #include "ssl.h"
12 #include "sslproto.h"
13 #include "sslimpl.h"
14 #include "ssl3exthandle.h"
15 #include "tls13exthandle.h"
16 #include "tls13hkdf.h"
17 #include "tls13subcerts.h"
18 
19 /* Parses the delegated credential (DC) from the raw extension |b| of length
20  * |length|. Memory for the DC is allocated and set to |*dcp|.
21  *
22  * It's the caller's responsibility to invoke |tls13_DestroyDelegatedCredential|
23  * when this data is no longer needed.
24  */
25 SECStatus
tls13_ReadDelegatedCredential(PRUint8 * b,PRUint32 length,sslDelegatedCredential ** dcp)26 tls13_ReadDelegatedCredential(PRUint8 *b, PRUint32 length,
27                               sslDelegatedCredential **dcp)
28 {
29     sslDelegatedCredential *dc = NULL;
30     SECStatus rv;
31     PRUint64 n;
32     sslReadBuffer tmp;
33     sslReader rdr = SSL_READER(b, length);
34 
35     PORT_Assert(!*dcp);
36 
37     dc = PORT_ZNew(sslDelegatedCredential);
38     if (!dc) {
39         PORT_SetError(SEC_ERROR_NO_MEMORY);
40         goto loser;
41     }
42 
43     /* Read the valid_time field of DelegatedCredential.cred. */
44     rv = sslRead_ReadNumber(&rdr, 4, &n);
45     if (rv != SECSuccess) {
46         goto loser;
47     }
48     dc->validTime = n;
49 
50     /* Read the expected_cert_verify_algorithm field of
51      * DelegatedCredential.cred. */
52     rv = sslRead_ReadNumber(&rdr, 2, &n);
53     if (rv != SECSuccess) {
54         goto loser;
55     }
56     dc->expectedCertVerifyAlg = n;
57 
58     /* Read the ASN1_subjectPublicKeyInfo field of DelegatedCredential.cred. */
59     rv = sslRead_ReadVariable(&rdr, 3, &tmp);
60     if (rv != SECSuccess) {
61         goto loser;
62     }
63     rv = SECITEM_MakeItem(NULL, &dc->derSpki, tmp.buf, tmp.len);
64     if (rv != SECSuccess) {
65         goto loser;
66     }
67 
68     /* Parse the DER-encoded SubjectPublicKeyInfo. */
69     dc->spki = SECKEY_DecodeDERSubjectPublicKeyInfo(&dc->derSpki);
70     if (!dc->spki) {
71         goto loser;
72     }
73 
74     /* Read the algorithm field of the DelegatedCredential. */
75     rv = sslRead_ReadNumber(&rdr, 2, &n);
76     if (rv != SECSuccess) {
77         goto loser;
78     }
79     dc->alg = n;
80 
81     /* Read the signature field of the DelegatedCredential. */
82     rv = sslRead_ReadVariable(&rdr, 2, &tmp);
83     if (rv != SECSuccess) {
84         goto loser;
85     }
86     rv = SECITEM_MakeItem(NULL, &dc->signature, tmp.buf, tmp.len);
87     if (rv != SECSuccess) {
88         goto loser;
89     }
90 
91     /* There should be nothing left to read. */
92     if (SSL_READER_REMAINING(&rdr) > 0) {
93         goto loser;
94     }
95 
96     *dcp = dc;
97     return SECSuccess;
98 
99 loser:
100     tls13_DestroyDelegatedCredential(dc);
101     *dcp = NULL;
102     return SECFailure;
103 }
104 
105 /* Frees |dc| from the heap. */
106 void
tls13_DestroyDelegatedCredential(sslDelegatedCredential * dc)107 tls13_DestroyDelegatedCredential(sslDelegatedCredential *dc)
108 {
109     if (!dc) {
110         return;
111     }
112 
113     SECKEY_DestroySubjectPublicKeyInfo(dc->spki);
114     SECITEM_FreeItem(&dc->derSpki, PR_FALSE);
115     SECITEM_FreeItem(&dc->signature, PR_FALSE);
116     PORT_ZFree(dc, sizeof(sslDelegatedCredential));
117 }
118 
119 /* Sets |*certVerifyAlg| to the expected_cert_verify_algorithm field from the
120  * serialized DC |in|. Returns SECSuccess upon success; SECFailure indicates a
121  * decoding failure or the input wasn't long enough.
122  */
123 static SECStatus
tls13_GetExpectedCertVerifyAlg(SECItem in,SSLSignatureScheme * certVerifyAlg)124 tls13_GetExpectedCertVerifyAlg(SECItem in, SSLSignatureScheme *certVerifyAlg)
125 {
126     SECStatus rv;
127     PRUint64 n;
128     sslReader rdr = SSL_READER(in.data, in.len);
129 
130     if (in.len < 6) { /* Buffer too short to contain the first two params. */
131         return SECFailure;
132     }
133 
134     rv = sslRead_ReadNumber(&rdr, 4, &n);
135     if (rv != SECSuccess) {
136         return SECFailure;
137     }
138 
139     rv = sslRead_ReadNumber(&rdr, 2, &n);
140     if (rv != SECSuccess) {
141         return SECFailure;
142     }
143     *certVerifyAlg = n;
144 
145     return SECSuccess;
146 }
147 
148 /* Returns PR_TRUE if the host is verifying the handshake with a DC. */
149 PRBool
tls13_IsVerifyingWithDelegatedCredential(const sslSocket * ss)150 tls13_IsVerifyingWithDelegatedCredential(const sslSocket *ss)
151 {
152     /* We currently do not support client-delegated credentials. */
153     if (ss->sec.isServer ||
154         !ss->opt.enableDelegatedCredentials ||
155         !ss->xtnData.peerDelegCred) {
156         return PR_FALSE;
157     }
158 
159     return PR_TRUE;
160 }
161 
162 /* Returns PR_TRUE if the host is signing the handshake with a DC. */
163 PRBool
tls13_IsSigningWithDelegatedCredential(const sslSocket * ss)164 tls13_IsSigningWithDelegatedCredential(const sslSocket *ss)
165 {
166     if (!ss->sec.isServer ||
167         !ss->xtnData.sendingDelegCredToPeer ||
168         !ss->xtnData.peerRequestedDelegCred) {
169         return PR_FALSE;
170     }
171 
172     return PR_TRUE;
173 }
174 
175 /* Commits to authenticating with a DC if all of the following conditions hold:
176  *  - the negotiated protocol is TLS 1.3 or newer;
177  *  - the selected certificate has a DC configured;
178  *  - the peer has indicated support for this extension;
179  *  - the peer has indicated support for the DC signature scheme; and
180  *  - the host supports the DC signature scheme.
181  *
182  * It's the caller's responsibility to ensure that the version has been
183  * negotiated and the certificate has been selected.
184  */
185 SECStatus
tls13_MaybeSetDelegatedCredential(sslSocket * ss)186 tls13_MaybeSetDelegatedCredential(sslSocket *ss)
187 {
188     SECStatus rv;
189     PRBool doesRsaPss;
190     SECKEYPrivateKey *priv;
191     SSLSignatureScheme scheme;
192 
193     /* Assert that the host is the server (we do not currently support
194      * client-delegated credentials), the certificate has been
195      * chosen, TLS 1.3 or higher has been negotiated, and that the set of
196      * signature schemes supported by the client is known.
197      */
198     PORT_Assert(ss->sec.isServer);
199     PORT_Assert(ss->sec.serverCert);
200     PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3);
201     PORT_Assert(ss->xtnData.peerRequestedDelegCred == !!ss->xtnData.delegCredSigSchemes);
202 
203     /* Check that the peer has indicated support and that a DC has been
204      * configured for the selected certificate.
205      */
206     if (!ss->xtnData.peerRequestedDelegCred ||
207         !ss->xtnData.delegCredSigSchemes ||
208         !ss->sec.serverCert->delegCred.len ||
209         !ss->sec.serverCert->delegCredKeyPair) {
210         return SECSuccess;
211     }
212 
213     /* Check that the host and peer both support the signing algorithm used with
214      * the DC.
215      */
216     rv = tls13_GetExpectedCertVerifyAlg(ss->sec.serverCert->delegCred,
217                                         &scheme);
218     if (rv != SECSuccess) {
219         return SECFailure;
220     }
221 
222     priv = ss->sec.serverCert->delegCredKeyPair->privKey;
223     rv = ssl_PrivateKeySupportsRsaPss(priv, &doesRsaPss);
224     if (rv != SECSuccess) {
225         return SECFailure;
226     }
227 
228     if (!ssl_SignatureSchemeEnabled(ss, scheme) ||
229         !ssl_CanUseSignatureScheme(scheme,
230                                    ss->xtnData.delegCredSigSchemes,
231                                    ss->xtnData.numDelegCredSigSchemes,
232                                    PR_FALSE /* requireSha1 */,
233                                    doesRsaPss)) {
234         return SECSuccess;
235     }
236 
237     /* Commit to sending a DC and set the handshake signature scheme to the
238      * indicated algorithm.
239      */
240     ss->xtnData.sendingDelegCredToPeer = PR_TRUE;
241     ss->ssl3.hs.signatureScheme = scheme;
242     return SECSuccess;
243 }
244 
245 /* Serializes the DC up to the signature. */
246 static SECStatus
tls13_AppendCredentialParams(sslBuffer * buf,sslDelegatedCredential * dc)247 tls13_AppendCredentialParams(sslBuffer *buf, sslDelegatedCredential *dc)
248 {
249     SECStatus rv;
250     rv = sslBuffer_AppendNumber(buf, dc->validTime, 4);
251     if (rv != SECSuccess) {
252         return SECFailure; /* Error set by caller. */
253     }
254 
255     rv = sslBuffer_AppendNumber(buf, dc->expectedCertVerifyAlg, 2);
256     if (rv != SECSuccess) {
257         return SECFailure;
258     }
259 
260     rv = sslBuffer_AppendVariable(buf, dc->derSpki.data, dc->derSpki.len, 3);
261     if (rv != SECSuccess) {
262         return SECFailure;
263     }
264 
265     rv = sslBuffer_AppendNumber(buf, dc->alg, 2);
266     if (rv != SECSuccess) {
267         return SECFailure;
268     }
269 
270     return SECSuccess;
271 }
272 
273 /* Serializes the DC signature. */
274 static SECStatus
tls13_AppendCredentialSignature(sslBuffer * buf,sslDelegatedCredential * dc)275 tls13_AppendCredentialSignature(sslBuffer *buf, sslDelegatedCredential *dc)
276 {
277     SECStatus rv;
278     rv = sslBuffer_AppendVariable(buf, dc->signature.data,
279                                   dc->signature.len, 2);
280     if (rv != SECSuccess) {
281         return SECFailure;
282     }
283 
284     return SECSuccess;
285 }
286 
287 /* Hashes the message used to sign/verify the DC. */
288 static SECStatus
tls13_HashCredentialSignatureMessage(SSL3Hashes * hash,SSLSignatureScheme scheme,const CERTCertificate * cert,const sslBuffer * dcBuf)289 tls13_HashCredentialSignatureMessage(SSL3Hashes *hash,
290                                      SSLSignatureScheme scheme,
291                                      const CERTCertificate *cert,
292                                      const sslBuffer *dcBuf)
293 {
294     SECStatus rv;
295     PK11Context *ctx = NULL;
296     unsigned int hashLen;
297 
298     /* Set up hash context. */
299     hash->hashAlg = ssl_SignatureSchemeToHashType(scheme);
300     ctx = PK11_CreateDigestContext(ssl3_HashTypeToOID(hash->hashAlg));
301     if (!ctx) {
302         PORT_SetError(SEC_ERROR_NO_MEMORY);
303         goto loser;
304     }
305 
306     static const PRUint8 kCtxStrPadding[64] = {
307         0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
308         0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
309         0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
310         0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
311         0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
312         0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
313         0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
314         0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
315     };
316 
317     static const PRUint8 kCtxStr[] = "TLS, server delegated credentials";
318 
319     /* Hash the message signed by the peer. */
320     rv = SECSuccess;
321     rv |= PK11_DigestBegin(ctx);
322     rv |= PK11_DigestOp(ctx, kCtxStrPadding, sizeof kCtxStrPadding);
323     rv |= PK11_DigestOp(ctx, kCtxStr, 1 /* 0-byte */ + strlen((const char *)kCtxStr));
324     rv |= PK11_DigestOp(ctx, cert->derCert.data, cert->derCert.len);
325     rv |= PK11_DigestOp(ctx, dcBuf->buf, dcBuf->len);
326     rv |= PK11_DigestFinal(ctx, hash->u.raw, &hashLen, sizeof hash->u.raw);
327     if (rv != SECSuccess) {
328         PORT_SetError(SSL_ERROR_SHA_DIGEST_FAILURE);
329         goto loser;
330     }
331 
332     hash->len = hashLen;
333     if (ctx) {
334         PK11_DestroyContext(ctx, PR_TRUE);
335     }
336     return SECSuccess;
337 
338 loser:
339     if (ctx) {
340         PK11_DestroyContext(ctx, PR_TRUE);
341     }
342     return SECFailure;
343 }
344 
345 /* Verifies the DC signature. */
346 static SECStatus
tls13_VerifyCredentialSignature(sslSocket * ss,sslDelegatedCredential * dc)347 tls13_VerifyCredentialSignature(sslSocket *ss, sslDelegatedCredential *dc)
348 {
349     SECStatus rv = SECSuccess;
350     SSL3Hashes hash;
351     sslBuffer dcBuf = SSL_BUFFER_EMPTY;
352     CERTCertificate *cert = ss->sec.peerCert;
353     SECKEYPublicKey *pubKey = NULL;
354 
355     /* Serialize the DC parameters. */
356     rv = tls13_AppendCredentialParams(&dcBuf, dc);
357     if (rv != SECSuccess) {
358         goto loser; /* Error set by caller. */
359     }
360 
361     /* Hash the message that was signed by the delegator. */
362     rv = tls13_HashCredentialSignatureMessage(&hash, dc->alg, cert, &dcBuf);
363     if (rv != SECSuccess) {
364         FATAL_ERROR(ss, PORT_GetError(), internal_error);
365         goto loser;
366     }
367 
368     pubKey = SECKEY_ExtractPublicKey(&cert->subjectPublicKeyInfo);
369     if (pubKey == NULL) {
370         FATAL_ERROR(ss, SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE, internal_error);
371         goto loser;
372     }
373 
374     /* Verify the signature of the message. */
375     rv = ssl_VerifySignedHashesWithPubKey(ss, pubKey, dc->alg,
376                                           &hash, &dc->signature);
377     if (rv != SECSuccess) {
378         FATAL_ERROR(ss, SSL_ERROR_DC_BAD_SIGNATURE, illegal_parameter);
379         goto loser;
380     }
381 
382     SECOidTag spkiAlg = SECOID_GetAlgorithmTag(&(dc->spki->algorithm));
383     if (spkiAlg == SEC_OID_PKCS1_RSA_ENCRYPTION) {
384         FATAL_ERROR(ss, SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM, illegal_parameter);
385         goto loser;
386     }
387 
388     SECKEY_DestroyPublicKey(pubKey);
389     sslBuffer_Clear(&dcBuf);
390     return SECSuccess;
391 
392 loser:
393     SECKEY_DestroyPublicKey(pubKey);
394     sslBuffer_Clear(&dcBuf);
395     return SECFailure;
396 }
397 
398 /* Checks that the peer's end-entity certificate has the correct key usage. */
399 static SECStatus
tls13_CheckCertDelegationUsage(sslSocket * ss)400 tls13_CheckCertDelegationUsage(sslSocket *ss)
401 {
402     int i;
403     PRBool found;
404     CERTCertExtension *ext;
405     SECItem delegUsageOid = { siBuffer, NULL, 0 };
406     const CERTCertificate *cert = ss->sec.peerCert;
407 
408     /* 1.3.6.1.4.1.44363.44, as defined in draft-ietf-tls-subcerts. */
409     static unsigned char kDelegationUsageOid[] = {
410         0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0xda, 0x4b, 0x2c,
411     };
412 
413     delegUsageOid.data = kDelegationUsageOid;
414     delegUsageOid.len = sizeof kDelegationUsageOid;
415 
416     /* The certificate must have the delegationUsage extension that authorizes
417      * it to negotiate delegated credentials.
418      */
419     found = PR_FALSE;
420     for (i = 0; cert->extensions[i] != NULL; i++) {
421         ext = cert->extensions[i];
422         if (SECITEM_CompareItem(&ext->id, &delegUsageOid) == SECEqual) {
423             found = PR_TRUE;
424             break;
425         }
426     }
427 
428     /* The certificate must also have the digitalSignature keyUsage set. */
429     if (!found ||
430         !cert->keyUsagePresent ||
431         !(cert->keyUsage & KU_DIGITAL_SIGNATURE)) {
432         FATAL_ERROR(ss, SSL_ERROR_DC_INVALID_KEY_USAGE, illegal_parameter);
433         return SECFailure;
434     }
435 
436     return SECSuccess;
437 }
438 
439 static SECStatus
tls13_CheckCredentialExpiration(sslSocket * ss,sslDelegatedCredential * dc)440 tls13_CheckCredentialExpiration(sslSocket *ss, sslDelegatedCredential *dc)
441 {
442     SECStatus rv;
443     CERTCertificate *cert = ss->sec.peerCert;
444     /* 7 days in microseconds */
445     static const PRTime kMaxDcValidity = ((PRTime)7 * 24 * 60 * 60 * PR_USEC_PER_SEC);
446     PRTime start, now, end; /* microseconds */
447 
448     rv = DER_DecodeTimeChoice(&start, &cert->validity.notBefore);
449     if (rv != SECSuccess) {
450         FATAL_ERROR(ss, PORT_GetError(), internal_error);
451         return SECFailure;
452     }
453 
454     end = start + ((PRTime)dc->validTime * PR_USEC_PER_SEC);
455     now = ssl_Time(ss);
456     if (now > end || end < 0) {
457         FATAL_ERROR(ss, SSL_ERROR_DC_EXPIRED, illegal_parameter);
458         return SECFailure;
459     }
460 
461     /* Not more than 7 days remaining in the validity period. */
462     if (end - now > kMaxDcValidity) {
463         FATAL_ERROR(ss, SSL_ERROR_DC_INAPPROPRIATE_VALIDITY_PERIOD, illegal_parameter);
464         return SECFailure;
465     }
466 
467     return SECSuccess;
468 }
469 
470 /* Returns SECSucces if |dc| is a DC for the current handshake; otherwise it
471  * returns SECFailure. A valid DC meets three requirements: (1) the signature
472  * was produced by the peer's end-entity certificate, (2) the end-entity
473  * certificate must have the correct key usage, and (3) the DC must not be
474  * expired and its remaining TTL must be <= the maximum validity period (fixed
475  * as 7 days).
476  *
477  * This function calls FATAL_ERROR() when an error occurs.
478  */
479 SECStatus
tls13_VerifyDelegatedCredential(sslSocket * ss,sslDelegatedCredential * dc)480 tls13_VerifyDelegatedCredential(sslSocket *ss,
481                                 sslDelegatedCredential *dc)
482 {
483     SECStatus rv;
484     PRTime start;
485     PRExplodedTime end;
486     CERTCertificate *cert = ss->sec.peerCert;
487     char endStr[256];
488 
489     rv = DER_DecodeTimeChoice(&start, &cert->validity.notBefore);
490     if (rv != SECSuccess) {
491         FATAL_ERROR(ss, PORT_GetError(), internal_error);
492         return SECFailure;
493     }
494 
495     PR_ExplodeTime(start + (dc->validTime * PR_USEC_PER_SEC),
496                    PR_GMTParameters, &end);
497     if (PR_FormatTime(endStr, sizeof(endStr), "%a %b %d %H:%M:%S %Y", &end)) {
498         SSL_TRC(20, ("%d: TLS13[%d]: Received delegated credential (expires %s)",
499                      SSL_GETPID(), ss->fd, endStr));
500     } else {
501         SSL_TRC(20, ("%d: TLS13[%d]: Received delegated credential",
502                      SSL_GETPID(), ss->fd));
503     }
504 
505     rv = SECSuccess;
506     rv |= tls13_VerifyCredentialSignature(ss, dc);
507     rv |= tls13_CheckCertDelegationUsage(ss);
508     rv |= tls13_CheckCredentialExpiration(ss, dc);
509     return rv;
510 }
511 
512 static CERTSubjectPublicKeyInfo *
tls13_MakePssSpki(const SECKEYPublicKey * pub,SECOidTag hashOid)513 tls13_MakePssSpki(const SECKEYPublicKey *pub, SECOidTag hashOid)
514 {
515     SECStatus rv;
516     PLArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
517     if (!arena) {
518         goto loser; /* Code already set. */
519     }
520     CERTSubjectPublicKeyInfo *spki = PORT_ArenaZNew(arena, CERTSubjectPublicKeyInfo);
521     if (!spki) {
522         goto loser; /* Code already set. */
523     }
524     spki->arena = arena;
525 
526     SECKEYRSAPSSParams params = { 0 };
527     params.hashAlg = PORT_ArenaZNew(arena, SECAlgorithmID);
528     rv = SECOID_SetAlgorithmID(arena, params.hashAlg, hashOid, NULL);
529     if (rv != SECSuccess) {
530         goto loser; /* Code already set. */
531     }
532 
533     /* Set the mask hash algorithm too, which is an argument to
534      * a SEC_OID_PKCS1_MGF1 value. */
535     SECAlgorithmID maskHashAlg;
536     memset(&maskHashAlg, 0, sizeof(maskHashAlg));
537     rv = SECOID_SetAlgorithmID(arena, &maskHashAlg, hashOid, NULL);
538     if (rv != SECSuccess) {
539         goto loser; /* Code already set. */
540     }
541     SECItem *maskHashAlgItem =
542         SEC_ASN1EncodeItem(arena, NULL, &maskHashAlg,
543                            SEC_ASN1_GET(SECOID_AlgorithmIDTemplate));
544     if (!maskHashAlgItem) {
545         /* Probably OOM, but not certain. */
546         PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
547         goto loser;
548     }
549 
550     params.maskAlg = PORT_ArenaZNew(arena, SECAlgorithmID);
551     rv = SECOID_SetAlgorithmID(arena, params.maskAlg, SEC_OID_PKCS1_MGF1,
552                                maskHashAlgItem);
553     if (rv != SECSuccess) {
554         goto loser; /* Code already set. */
555     }
556 
557     /* Always include saltLength: all hashes are larger than 20. */
558     unsigned int saltLength = HASH_ResultLenByOidTag(hashOid);
559     PORT_Assert(saltLength > 20);
560     if (!SEC_ASN1EncodeInteger(arena, &params.saltLength, saltLength)) {
561         PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
562         goto loser;
563     }
564     /* Omit the trailerField always. */
565 
566     SECItem *algorithmItem =
567         SEC_ASN1EncodeItem(arena, NULL, &params,
568                            SEC_ASN1_GET(SECKEY_RSAPSSParamsTemplate));
569     if (!algorithmItem) {
570         PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
571         goto loser; /* Code already set. */
572     }
573     rv = SECOID_SetAlgorithmID(arena, &spki->algorithm,
574                                SEC_OID_PKCS1_RSA_PSS_SIGNATURE, algorithmItem);
575     if (rv != SECSuccess) {
576         goto loser; /* Code already set. */
577     }
578 
579     SECItem *pubItem = SEC_ASN1EncodeItem(arena, &spki->subjectPublicKey, pub,
580                                           SEC_ASN1_GET(SECKEY_RSAPublicKeyTemplate));
581     if (!pubItem) {
582         PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
583         goto loser;
584     }
585     spki->subjectPublicKey.len *= 8; /* Key length is in bits. */
586     return spki;
587 
588 loser:
589     PORT_FreeArena(arena, PR_FALSE);
590     return NULL;
591 }
592 
593 static CERTSubjectPublicKeyInfo *
tls13_MakeDcSpki(const SECKEYPublicKey * dcPub,SSLSignatureScheme dcCertVerifyAlg)594 tls13_MakeDcSpki(const SECKEYPublicKey *dcPub, SSLSignatureScheme dcCertVerifyAlg)
595 {
596     switch (SECKEY_GetPublicKeyType(dcPub)) {
597         case rsaKey: {
598             SECOidTag hashOid;
599             switch (dcCertVerifyAlg) {
600                 /* Note: RSAE schemes are NOT permitted within DC SPKIs. However,
601                  * support for their issuance remains so as to enable negative
602                  * testing of client behavior. */
603                 case ssl_sig_rsa_pss_rsae_sha256:
604                 case ssl_sig_rsa_pss_rsae_sha384:
605                 case ssl_sig_rsa_pss_rsae_sha512:
606                     return SECKEY_CreateSubjectPublicKeyInfo(dcPub);
607                 case ssl_sig_rsa_pss_pss_sha256:
608                     hashOid = SEC_OID_SHA256;
609                     break;
610                 case ssl_sig_rsa_pss_pss_sha384:
611                     hashOid = SEC_OID_SHA384;
612                     break;
613                 case ssl_sig_rsa_pss_pss_sha512:
614                     hashOid = SEC_OID_SHA512;
615                     break;
616 
617                 default:
618                     PORT_SetError(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM);
619                     return NULL;
620             }
621             return tls13_MakePssSpki(dcPub, hashOid);
622         }
623 
624         case ecKey: {
625             const sslNamedGroupDef *group = ssl_ECPubKey2NamedGroup(dcPub);
626             if (!group) {
627                 PORT_SetError(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM);
628                 return NULL;
629             }
630             SSLSignatureScheme keyScheme;
631             switch (group->name) {
632                 case ssl_grp_ec_secp256r1:
633                     keyScheme = ssl_sig_ecdsa_secp256r1_sha256;
634                     break;
635                 case ssl_grp_ec_secp384r1:
636                     keyScheme = ssl_sig_ecdsa_secp384r1_sha384;
637                     break;
638                 case ssl_grp_ec_secp521r1:
639                     keyScheme = ssl_sig_ecdsa_secp521r1_sha512;
640                     break;
641                 default:
642                     PORT_SetError(SEC_ERROR_INVALID_KEY);
643                     return NULL;
644             }
645             if (keyScheme != dcCertVerifyAlg) {
646                 PORT_SetError(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM);
647                 return NULL;
648             }
649             return SECKEY_CreateSubjectPublicKeyInfo(dcPub);
650         }
651 
652         default:
653             break;
654     }
655 
656     PORT_SetError(SEC_ERROR_INVALID_KEY);
657     return NULL;
658 }
659 
660 /* Returns a serialized DC with the given parameters.
661  *
662  * Note that this function is meant primarily for testing. In particular, it
663  * DOES NOT verify any of the following:
664  *  - |certPriv| is the private key corresponding to |cert|;
665  *  - that |checkCertKeyUsage(cert) == SECSuccess|;
666  *  - |dcValidFor| is less than 7 days (the maximum permitted by the spec); or
667  *  - validTime doesn't overflow a PRUint32.
668  *
669  * These conditions are things we want to test for, which is why we allow them
670  * here. A real API for creating DCs would want to explicitly check ALL of these
671  * conditions are met.
672  */
673 SECStatus
SSLExp_DelegateCredential(const CERTCertificate * cert,const SECKEYPrivateKey * certPriv,const SECKEYPublicKey * dcPub,SSLSignatureScheme dcCertVerifyAlg,PRUint32 dcValidFor,PRTime now,SECItem * out)674 SSLExp_DelegateCredential(const CERTCertificate *cert,
675                           const SECKEYPrivateKey *certPriv,
676                           const SECKEYPublicKey *dcPub,
677                           SSLSignatureScheme dcCertVerifyAlg,
678                           PRUint32 dcValidFor,
679                           PRTime now,
680                           SECItem *out)
681 {
682     SECStatus rv;
683     SSL3Hashes hash;
684     CERTSubjectPublicKeyInfo *spki = NULL;
685     SECKEYPrivateKey *tmpPriv = NULL;
686     sslDelegatedCredential *dc = NULL;
687     sslBuffer dcBuf = SSL_BUFFER_EMPTY;
688 
689     if (!cert || !certPriv || !dcPub || !out) {
690         PORT_SetError(SEC_ERROR_INVALID_ARGS);
691         return SECFailure;
692     }
693 
694     dc = PORT_ZNew(sslDelegatedCredential);
695     if (!dc) {
696         PORT_SetError(SEC_ERROR_NO_MEMORY);
697         goto loser;
698     }
699 
700     /* Serialize the DC parameters. */
701     PRTime start;
702     rv = DER_DecodeTimeChoice(&start, &cert->validity.notBefore);
703     if (rv != SECSuccess) {
704         goto loser;
705     }
706     dc->validTime = ((now - start) / PR_USEC_PER_SEC) + dcValidFor;
707 
708     /* Building the SPKI also validates |dcCertVerifyAlg|. */
709     spki = tls13_MakeDcSpki(dcPub, dcCertVerifyAlg);
710     if (!spki) {
711         goto loser;
712     }
713     dc->expectedCertVerifyAlg = dcCertVerifyAlg;
714 
715     SECItem *spkiDer =
716         SEC_ASN1EncodeItem(NULL /*arena*/, &dc->derSpki, spki,
717                            SEC_ASN1_GET(CERT_SubjectPublicKeyInfoTemplate));
718     if (!spkiDer) {
719         goto loser;
720     }
721 
722     rv = ssl_SignatureSchemeFromSpki(&cert->subjectPublicKeyInfo,
723                                      PR_TRUE /* isTls13 */, &dc->alg);
724     if (rv != SECSuccess) {
725         goto loser;
726     }
727 
728     if (dc->alg == ssl_sig_none) {
729         SECOidTag spkiOid = SECOID_GetAlgorithmTag(&cert->subjectPublicKeyInfo.algorithm);
730         /* If the Cert SPKI contained an AlgorithmIdentifier of "rsaEncryption", set a
731          * default rsa_pss_rsae_sha256 scheme. NOTE: RSAE SPKIs are not permitted within
732          * "real" Delegated Credentials. However, since this function is primarily used for
733          * testing, we retain this support in order to verify that these DCs are rejected
734          * by tls13_VerifyDelegatedCredential. */
735         if (spkiOid == SEC_OID_PKCS1_RSA_ENCRYPTION) {
736             SSLSignatureScheme scheme = ssl_sig_rsa_pss_rsae_sha256;
737             if (ssl_SignatureSchemeValid(scheme, spkiOid, PR_TRUE /* isTls13 */)) {
738                 dc->alg = scheme;
739             }
740         }
741     }
742     PORT_Assert(dc->alg != ssl_sig_none);
743 
744     rv = tls13_AppendCredentialParams(&dcBuf, dc);
745     if (rv != SECSuccess) {
746         goto loser;
747     }
748 
749     /* Hash signature message. */
750     rv = tls13_HashCredentialSignatureMessage(&hash, dc->alg, cert, &dcBuf);
751     if (rv != SECSuccess) {
752         goto loser;
753     }
754 
755     /* Sign the hash with the delegation key.
756      *
757      * The PK11 API discards const qualifiers, so we have to make a copy of
758      * |certPriv| and pass the copy to |ssl3_SignHashesWithPrivKey|.
759      */
760     tmpPriv = SECKEY_CopyPrivateKey(certPriv);
761     rv = ssl3_SignHashesWithPrivKey(&hash, tmpPriv, dc->alg,
762                                     PR_TRUE /* isTls */, &dc->signature);
763     if (rv != SECSuccess) {
764         goto loser;
765     }
766 
767     /* Serialize the DC signature. */
768     rv = tls13_AppendCredentialSignature(&dcBuf, dc);
769     if (rv != SECSuccess) {
770         goto loser;
771     }
772 
773     /* Copy the serialized DC to |out|. */
774     rv = SECITEM_MakeItem(NULL, out, dcBuf.buf, dcBuf.len);
775     if (rv != SECSuccess) {
776         goto loser;
777     }
778 
779     PRINT_BUF(20, (NULL, "delegated credential", dcBuf.buf, dcBuf.len));
780 
781     SECKEY_DestroySubjectPublicKeyInfo(spki);
782     SECKEY_DestroyPrivateKey(tmpPriv);
783     tls13_DestroyDelegatedCredential(dc);
784     sslBuffer_Clear(&dcBuf);
785     return SECSuccess;
786 
787 loser:
788     SECKEY_DestroySubjectPublicKeyInfo(spki);
789     SECKEY_DestroyPrivateKey(tmpPriv);
790     tls13_DestroyDelegatedCredential(dc);
791     sslBuffer_Clear(&dcBuf);
792     return SECFailure;
793 }
794