@@ -30,6 +30,23 @@ func addBytesWithLength(b *cryptobyte.Builder, v []byte, n int) {
30
30
}))
31
31
}
32
32
33
+ // addUint64 appends a big-endian, 64-bit value to the cryptobyte.Builder.
34
+ func addUint64 (b * cryptobyte.Builder , v uint64 ) {
35
+ b .AddUint32 (uint32 (v >> 32 ))
36
+ b .AddUint32 (uint32 (v ))
37
+ }
38
+
39
+ // readUint64 decodes a big-endian, 64-bit value into out and advances over it.
40
+ // It reports whether the read was successful.
41
+ func readUint64 (s * cryptobyte.String , out * uint64 ) bool {
42
+ var hi , lo uint32
43
+ if ! s .ReadUint32 (& hi ) || ! s .ReadUint32 (& lo ) {
44
+ return false
45
+ }
46
+ * out = uint64 (hi )<< 32 | uint64 (lo )
47
+ return true
48
+ }
49
+
33
50
// readUint8LengthPrefixed acts like s.ReadUint8LengthPrefixed, but targets a
34
51
// []byte instead of a cryptobyte.String.
35
52
func readUint8LengthPrefixed (s * cryptobyte.String , out * []byte ) bool {
@@ -1266,89 +1283,110 @@ func (m *certificateMsgTLS13) marshal() []byte {
1266
1283
b .AddUint8 (typeCertificate )
1267
1284
b .AddUint24LengthPrefixed (func (b * cryptobyte.Builder ) {
1268
1285
b .AddUint8 (0 ) // certificate_request_context
1269
- b .AddUint24LengthPrefixed (func (b * cryptobyte.Builder ) {
1270
- for i , cert := range m .certificate .Certificate {
1271
- b .AddUint24LengthPrefixed (func (b * cryptobyte.Builder ) {
1272
- b .AddBytes (cert )
1273
- })
1274
- b .AddUint16LengthPrefixed (func (b * cryptobyte.Builder ) {
1275
- if i > 0 {
1276
- // This library only supports OCSP and SCT for leaf certificates.
1277
- return
1278
- }
1279
- if m .ocspStapling {
1280
- b .AddUint16 (extensionStatusRequest )
1281
- b .AddUint16LengthPrefixed (func (b * cryptobyte.Builder ) {
1282
- b .AddUint8 (statusTypeOCSP )
1283
- b .AddUint24LengthPrefixed (func (b * cryptobyte.Builder ) {
1284
- b .AddBytes (m .certificate .OCSPStaple )
1285
- })
1286
- })
1287
- }
1288
- if m .scts {
1289
- b .AddUint16 (extensionSCT )
1290
- b .AddUint16LengthPrefixed (func (b * cryptobyte.Builder ) {
1291
- b .AddUint16LengthPrefixed (func (b * cryptobyte.Builder ) {
1292
- for _ , sct := range m .certificate .SignedCertificateTimestamps {
1293
- b .AddUint16LengthPrefixed (func (b * cryptobyte.Builder ) {
1294
- b .AddBytes (sct )
1295
- })
1296
- }
1297
- })
1298
- })
1299
- }
1300
- })
1301
- }
1302
- })
1286
+
1287
+ certificate := m .certificate
1288
+ if ! m .ocspStapling {
1289
+ certificate .OCSPStaple = nil
1290
+ }
1291
+ if ! m .scts {
1292
+ certificate .SignedCertificateTimestamps = nil
1293
+ }
1294
+ marshalCertificate (b , certificate )
1303
1295
})
1304
1296
1305
1297
m .raw = b .BytesOrPanic ()
1306
1298
return m .raw
1307
1299
}
1308
1300
1301
+ func marshalCertificate (b * cryptobyte.Builder , certificate Certificate ) {
1302
+ b .AddUint24LengthPrefixed (func (b * cryptobyte.Builder ) {
1303
+ for i , cert := range certificate .Certificate {
1304
+ b .AddUint24LengthPrefixed (func (b * cryptobyte.Builder ) {
1305
+ b .AddBytes (cert )
1306
+ })
1307
+ b .AddUint16LengthPrefixed (func (b * cryptobyte.Builder ) {
1308
+ if i > 0 {
1309
+ // This library only supports OCSP and SCT for leaf certificates.
1310
+ return
1311
+ }
1312
+ if certificate .OCSPStaple != nil {
1313
+ b .AddUint16 (extensionStatusRequest )
1314
+ b .AddUint16LengthPrefixed (func (b * cryptobyte.Builder ) {
1315
+ b .AddUint8 (statusTypeOCSP )
1316
+ b .AddUint24LengthPrefixed (func (b * cryptobyte.Builder ) {
1317
+ b .AddBytes (certificate .OCSPStaple )
1318
+ })
1319
+ })
1320
+ }
1321
+ if certificate .SignedCertificateTimestamps != nil {
1322
+ b .AddUint16 (extensionSCT )
1323
+ b .AddUint16LengthPrefixed (func (b * cryptobyte.Builder ) {
1324
+ b .AddUint16LengthPrefixed (func (b * cryptobyte.Builder ) {
1325
+ for _ , sct := range certificate .SignedCertificateTimestamps {
1326
+ b .AddUint16LengthPrefixed (func (b * cryptobyte.Builder ) {
1327
+ b .AddBytes (sct )
1328
+ })
1329
+ }
1330
+ })
1331
+ })
1332
+ }
1333
+ })
1334
+ }
1335
+ })
1336
+ }
1337
+
1309
1338
func (m * certificateMsgTLS13 ) unmarshal (data []byte ) bool {
1310
1339
* m = certificateMsgTLS13 {raw : data }
1311
1340
s := cryptobyte .String (data )
1312
1341
1313
- var context , certList cryptobyte.String
1342
+ var context cryptobyte.String
1314
1343
if ! s .Skip (4 ) || // message type and uint24 length field
1315
1344
! s .ReadUint8LengthPrefixed (& context ) || ! context .Empty () ||
1316
- ! s . ReadUint24LengthPrefixed ( & certList ) ||
1345
+ ! unmarshalCertificate ( & s , & m . certificate ) ||
1317
1346
! s .Empty () {
1318
1347
return false
1319
1348
}
1320
1349
1350
+ m .scts = m .certificate .SignedCertificateTimestamps != nil
1351
+ m .ocspStapling = m .certificate .OCSPStaple != nil
1352
+
1353
+ return true
1354
+ }
1355
+
1356
+ func unmarshalCertificate (s * cryptobyte.String , certificate * Certificate ) bool {
1357
+ var certList cryptobyte.String
1358
+ if ! s .ReadUint24LengthPrefixed (& certList ) {
1359
+ return false
1360
+ }
1321
1361
for ! certList .Empty () {
1322
1362
var cert []byte
1323
1363
var extensions cryptobyte.String
1324
1364
if ! readUint24LengthPrefixed (& certList , & cert ) ||
1325
1365
! certList .ReadUint16LengthPrefixed (& extensions ) {
1326
1366
return false
1327
1367
}
1328
- m . certificate .Certificate = append (m . certificate .Certificate , cert )
1368
+ certificate .Certificate = append (certificate .Certificate , cert )
1329
1369
for ! extensions .Empty () {
1330
1370
var extension uint16
1331
1371
var extData cryptobyte.String
1332
1372
if ! extensions .ReadUint16 (& extension ) ||
1333
1373
! extensions .ReadUint16LengthPrefixed (& extData ) {
1334
1374
return false
1335
1375
}
1336
- if len (m . certificate .Certificate ) > 1 {
1376
+ if len (certificate .Certificate ) > 1 {
1337
1377
// This library only supports OCSP and SCT for leaf certificates.
1338
1378
continue
1339
1379
}
1340
1380
1341
1381
switch extension {
1342
1382
case extensionStatusRequest :
1343
- m .ocspStapling = true
1344
1383
var statusType uint8
1345
1384
if ! extData .ReadUint8 (& statusType ) || statusType != statusTypeOCSP ||
1346
- ! readUint24LengthPrefixed (& extData , & m . certificate .OCSPStaple ) ||
1347
- len (m . certificate .OCSPStaple ) == 0 {
1385
+ ! readUint24LengthPrefixed (& extData , & certificate .OCSPStaple ) ||
1386
+ len (certificate .OCSPStaple ) == 0 {
1348
1387
return false
1349
1388
}
1350
1389
case extensionSCT :
1351
- m .scts = true
1352
1390
var sctList cryptobyte.String
1353
1391
if ! extData .ReadUint16LengthPrefixed (& sctList ) || sctList .Empty () {
1354
1392
return false
@@ -1359,8 +1397,8 @@ func (m *certificateMsgTLS13) unmarshal(data []byte) bool {
1359
1397
len (sct ) == 0 {
1360
1398
return false
1361
1399
}
1362
- m . certificate .SignedCertificateTimestamps = append (
1363
- m . certificate .SignedCertificateTimestamps , sct )
1400
+ certificate .SignedCertificateTimestamps = append (
1401
+ certificate .SignedCertificateTimestamps , sct )
1364
1402
}
1365
1403
default :
1366
1404
// Ignore unknown extensions.
0 commit comments