35
35
// - RPKI support:
36
36
// - Support for SubjectInfoAccess extension
37
37
// - Support for RFC3779 extensions (in rpki.go)
38
+ // - RSAES-OAEP support:
39
+ // - Support for parsing RSASES-OAEP public keys from certificates
38
40
// - General improvements:
39
41
// - Export and use OID values throughout.
40
42
// - Export OIDFromNamedCurve().
@@ -190,6 +192,9 @@ type tbsCertificate struct {
190
192
Extensions []pkix.Extension `asn1:"optional,explicit,tag:3"`
191
193
}
192
194
195
+ // RFC 4055, 4.1
196
+ // The current ASN.1 parser does not support non-integer defaults so
197
+ // the 'default:' tags here do nothing.
193
198
type rsaesoaepAlgorithmParameters struct {
194
199
HashFunc pkix.AlgorithmIdentifier `asn1:"optional,explicit,tag:0,default:sha1Identifier"`
195
200
MaskgenFunc pkix.AlgorithmIdentifier `asn1:"optional,explicit,tag:1,default:mgf1SHA1Identifier"`
@@ -244,34 +249,36 @@ const (
244
249
SHA512WithRSAPSS
245
250
)
246
251
247
- // RFC 4055
248
- // Various identifiers
249
- var (
250
- // 2.1. One-way Hash Functions
251
- OIDSHA1 = asn1.ObjectIdentifier {1 , 3 , 14 , 3 , 2 , 26 }
252
- // 2.2. Mask Generation Functions
253
- OIDMFGSHA1 = asn1.ObjectIdentifier {1 , 2 , 840 , 113549 , 1 , 1 , 8 }
254
- // 6. Basic object identifiers
255
- OIDpSpecified = asn1.ObjectIdentifier {1 , 2 , 840 , 113549 , 1 , 1 , 9 }
256
- )
252
+ // RFC 4055, 6. Basic object identifiers
253
+ var oidpSpecified = asn1.ObjectIdentifier {1 , 2 , 840 , 113549 , 1 , 1 , 9 }
257
254
258
255
// These are the default parameters for an RSAES-OAEP pubkey.
259
256
// The current ASN.1 parser does not support non-integer defaults so
260
257
// these currently do nothing.
261
- // It has been suggested that we switch to cryptobytes but that
262
- // only supports parsing primitives (tag < 32).
263
258
var (
264
259
sha1Identifier = pkix.AlgorithmIdentifier {
265
- Algorithm : OIDSHA1 ,
260
+ Algorithm : oidSHA1 ,
266
261
Parameters : asn1 .NullRawValue ,
267
262
}
268
263
mgf1SHA1Identifier = pkix.AlgorithmIdentifier {
269
- Algorithm : OIDMFGSHA1 ,
270
- Parameters : asn1.RawValue {0 , 6 , false , []byte {43 , 14 , 3 , 2 , 26 }, []byte {6 , 5 , 43 , 14 , 3 , 2 , 26 }},
264
+ Algorithm : oidMGF1 ,
265
+ // RFC 4055, 2.1 sha1Identifier
266
+ Parameters : asn1.RawValue {
267
+ Class : asn1 .ClassUniversal ,
268
+ Tag : asn1 .TagSequence ,
269
+ IsCompound : false ,
270
+ Bytes : []byte {6 , 5 , 43 , 14 , 3 , 2 , 26 , 5 , 0 },
271
+ FullBytes : []byte {16 , 9 , 6 , 5 , 43 , 14 , 3 , 2 , 26 , 5 , 0 }},
271
272
}
272
273
pSpecifiedEmptyIdentifier = pkix.AlgorithmIdentifier {
273
- Algorithm : OIDpSpecified ,
274
- Parameters : asn1.RawValue {0 , 4 , false , []byte {}, []byte {4 , 0 }},
274
+ Algorithm : oidpSpecified ,
275
+ // RFC 4055, 4.1 nullOctetString
276
+ Parameters : asn1.RawValue {
277
+ Class : asn1 .ClassUniversal ,
278
+ Tag : asn1 .TagOctetString ,
279
+ IsCompound : false ,
280
+ Bytes : []byte {},
281
+ FullBytes : []byte {4 , 0 }},
275
282
}
276
283
)
277
284
@@ -384,6 +391,7 @@ var (
384
391
oidSignatureECDSAWithSHA384 = asn1.ObjectIdentifier {1 , 2 , 840 , 10045 , 4 , 3 , 3 }
385
392
oidSignatureECDSAWithSHA512 = asn1.ObjectIdentifier {1 , 2 , 840 , 10045 , 4 , 3 , 4 }
386
393
394
+ oidSHA1 = asn1.ObjectIdentifier {1 , 3 , 14 , 3 , 2 , 26 }
387
395
oidSHA256 = asn1.ObjectIdentifier {2 , 16 , 840 , 1 , 101 , 3 , 4 , 2 , 1 }
388
396
oidSHA384 = asn1.ObjectIdentifier {2 , 16 , 840 , 1 , 101 , 3 , 4 , 2 , 2 }
389
397
oidSHA512 = asn1.ObjectIdentifier {2 , 16 , 840 , 1 , 101 , 3 , 4 , 2 , 3 }
@@ -1286,40 +1294,28 @@ type distributionPointName struct {
1286
1294
func parsePublicKey (algo PublicKeyAlgorithm , keyData * publicKeyInfo , nfe * NonFatalErrors ) (interface {}, error ) {
1287
1295
asn1Data := keyData .PublicKey .RightAlign ()
1288
1296
switch algo {
1289
- case RSA :
1297
+ case RSA , RSAESOAEP :
1290
1298
// RSA public keys must have a NULL in the parameters.
1291
1299
// See RFC 3279, Section 2.3.1.
1292
- if ! bytes .Equal (keyData .Algorithm .Parameters .FullBytes , asn1 .NullBytes ) {
1300
+ if algo == RSA && ! bytes .Equal (keyData .Algorithm .Parameters .FullBytes , asn1 .NullBytes ) {
1293
1301
nfe .AddError (errors .New ("x509: RSA key missing NULL parameters" ))
1294
1302
}
1295
-
1296
- p := new (pkcs1PublicKey )
1297
- rest , err := asn1 .Unmarshal (asn1Data , p )
1298
- if err != nil {
1299
- var laxErr error
1300
- rest , laxErr = asn1 .UnmarshalWithParams (asn1Data , p , "lax" )
1301
- if laxErr != nil {
1302
- return nil , laxErr
1303
+ if algo == RSAESOAEP {
1304
+ // We only parse the parameters to ensure it is a valid encoding, we throw out the actually values
1305
+ paramsData := keyData .Algorithm .Parameters .FullBytes
1306
+ params := new (rsaesoaepAlgorithmParameters )
1307
+ params .HashFunc = sha1Identifier
1308
+ params .MaskgenFunc = mgf1SHA1Identifier
1309
+ params .PSourceFunc = pSpecifiedEmptyIdentifier
1310
+ rest , err := asn1 .Unmarshal (paramsData , params )
1311
+ if err != nil {
1312
+ return nil , err
1313
+ }
1314
+ if len (rest ) != 0 {
1315
+ return nil , errors .New ("x509: trailing data after RSAES-OAEP parameters" )
1303
1316
}
1304
- nfe .AddError (err )
1305
- }
1306
- if len (rest ) != 0 {
1307
- return nil , errors .New ("x509: trailing data after RSA public key" )
1308
- }
1309
-
1310
- if p .N .Sign () <= 0 {
1311
- nfe .AddError (errors .New ("x509: RSA modulus is not a positive number" ))
1312
- }
1313
- if p .E <= 0 {
1314
- return nil , errors .New ("x509: RSA public exponent is not a positive number" )
1315
1317
}
1316
1318
1317
- pub := & rsa.PublicKey {
1318
- E : p .E ,
1319
- N : p .N ,
1320
- }
1321
- return pub , nil
1322
- case RSAESOAEP :
1323
1319
p := new (pkcs1PublicKey )
1324
1320
rest , err := asn1 .Unmarshal (asn1Data , p )
1325
1321
if err != nil {
@@ -1339,16 +1335,8 @@ func parsePublicKey(algo PublicKeyAlgorithm, keyData *publicKeyInfo, nfe *NonFat
1339
1335
if p .E <= 0 {
1340
1336
return nil , errors .New ("x509: RSA public exponent is not a positive number" )
1341
1337
}
1342
- paramsData := keyData .Algorithm .Parameters .FullBytes
1343
- params := new (rsaesoaepAlgorithmParameters )
1344
- rest , err = asn1 .Unmarshal (paramsData , params )
1345
- if err != nil {
1346
- return nil , err
1347
- }
1348
- if len (rest ) != 0 {
1349
- return nil , errors .New ("x509: trailing data after RSAES-OAEP parameters" )
1350
- }
1351
1338
1339
+ // TODO(dkarch): Update to return the parameters once crypto/x509 has come up with permanent solution
1352
1340
pub := & rsa.PublicKey {
1353
1341
E : p .E ,
1354
1342
N : p .N ,
0 commit comments