106106import com .oracle .graal .python .builtins .objects .tuple .PTuple ;
107107import com .oracle .graal .python .nodes .ErrorMessages ;
108108import com .oracle .graal .python .runtime .object .PythonObjectFactory ;
109- import com .oracle .graal .python .util .BiConsumer ;
110109import com .oracle .truffle .api .CompilerDirectives .TruffleBoundary ;
111110import com .oracle .truffle .api .TruffleFile ;
112111import com .oracle .truffle .api .nodes .Node ;
@@ -151,7 +150,7 @@ static boolean isCrl(boolean[] keyUsage) {
151150 * _ssl.c#_decode_certificate
152151 */
153152 @ TruffleBoundary
154- public static PDict decodeCertificate (Node node , X509Certificate cert ) throws IOException , CertificateParsingException {
153+ public static PDict decodeCertificate (Node node , X509Certificate cert ) throws CertificateParsingException {
155154 PythonObjectFactory factory = PythonObjectFactory .getUncached ();
156155 PDict dict = factory .createDict ();
157156 HashingStorage storage = dict .getDictStorage ();
@@ -289,77 +288,92 @@ private static final class DerValue {
289288 private static final byte OBJECT_IDENTIFIER = 0x06 ;
290289 private static final byte SEQUENCE = 0x10 ;
291290
291+ private static final String ERROR_MESSAGE = "Invalid DER encoded data" ;
292+
292293 final byte [] data ;
293- final int end ;
294294 final boolean isContextTag ;
295295 final int contentLen ;
296296 final int contentStart ;
297297 int contentTag ;
298298
299- DerValue (byte [] data ) {
299+ DerValue (byte [] data ) throws CertificateParsingException {
300300 this (data , 0 , data .length );
301301 }
302302
303- DerValue (byte [] data , int offset , int end ) {
304- this .data = data ;
305- this .end = end ;
306-
307- this .contentTag = data [offset ] & 0b11111;
308- this .isContextTag = (data [offset ] & 0b11000000) == 0b10000000;
309- int [] lenAndOffset = readLength (data , offset );
310- this .contentStart = lenAndOffset [0 ];
311- this .contentLen = lenAndOffset [1 ];
312-
313- assert this .contentTag != 0b11111 : "extended tag range not supported" ;
314- assert contentStart + contentLen <= end ;
303+ DerValue (byte [] data , int offset , int end ) throws CertificateParsingException {
304+ if (offset == data .length ) {
305+ // this is a 0-length value at the end of the data
306+ this .data = data ;
307+ this .contentTag = 0 ;
308+ this .isContextTag = false ;
309+ this .contentStart = offset ;
310+ this .contentLen = 0 ;
311+ } else if (offset < data .length ) {
312+ this .data = data ;
313+
314+ this .contentTag = data [offset ] & 0b11111;
315+ this .isContextTag = (data [offset ] & 0b11000000) == 0b10000000;
316+ int [] lenAndOffset = readLength (data , offset );
317+ this .contentStart = lenAndOffset [0 ];
318+ this .contentLen = lenAndOffset [1 ];
319+
320+ assert this .contentTag != 0b11111 : "extended tag range not supported" ;
321+ assert contentStart + contentLen <= end ;
322+ } else {
323+ throw new CertificateParsingException (ERROR_MESSAGE );
324+ }
315325 }
316326
317- private static int [] readLength (byte [] data , int offset ) {
318- int lenBase = data [offset + 1 ] & 0xff ;
319- if (lenBase < 128 ) {
320- return new int []{offset + 2 , lenBase };
321- } else {
322- int lengthOfLength = lenBase - 128 ;
323- if (lengthOfLength > 4 ) {
324- throw new IllegalArgumentException ("longer than int-range DER values not supported" );
325- }
326- int fullLength = 0 ;
327- for (int i = 0 ; i < lengthOfLength ; i ++) {
328- fullLength = (fullLength << 8 ) | data [offset + 2 + i ];
327+ private static int [] readLength (byte [] data , int offset ) throws CertificateParsingException {
328+ try {
329+ int lenBase = data [offset + 1 ] & 0xff ;
330+ if (lenBase < 128 ) {
331+ return new int []{offset + 2 , lenBase };
332+ } else {
333+ int lengthOfLength = lenBase - 128 ;
334+ if (lengthOfLength > 4 ) {
335+ throw new IllegalArgumentException ("longer than int-range DER values not supported" );
336+ }
337+ int fullLength = 0 ;
338+ for (int i = 0 ; i < lengthOfLength ; i ++) {
339+ fullLength = (fullLength << 8 ) | data [offset + 2 + i ];
340+ }
341+ return new int []{offset + 2 + lengthOfLength , fullLength };
329342 }
330- return new int []{offset + 2 + lengthOfLength , fullLength };
343+ } catch (ArrayIndexOutOfBoundsException e ) {
344+ throw new CertificateParsingException (ERROR_MESSAGE );
331345 }
332346 }
333347
334348 byte [] getRawData () {
335349 return Arrays .copyOfRange (data , contentStart , contentStart + contentLen );
336350 }
337351
338- DerValue getObjectIdentifier () {
352+ DerValue getObjectIdentifier () throws CertificateParsingException {
339353 if (contentTag != OBJECT_IDENTIFIER ) {
340354 return null ;
341355 } else {
342356 return new DerValue (data , contentStart , contentStart + contentLen );
343357 }
344358 }
345359
346- DerValue getContextTag (int tag ) {
360+ DerValue getContextTag (int tag ) throws CertificateParsingException {
347361 if (contentTag != tag || !isContextTag ) {
348362 return null ;
349363 } else {
350364 return new DerValue (data , contentStart , contentStart + contentLen );
351365 }
352366 }
353367
354- DerValue getOctetString () {
368+ DerValue getOctetString () throws CertificateParsingException {
355369 if (contentTag != OCTET_STRING ) {
356370 return null ;
357371 } else {
358372 return new DerValue (data , contentStart , contentStart + contentLen );
359373 }
360374 }
361375
362- DerValue getSequence () {
376+ DerValue getSequence () throws CertificateParsingException {
363377 if (contentTag != SEQUENCE ) {
364378 return null ;
365379 } else {
@@ -386,15 +400,20 @@ String getGeneralNameURI() {
386400 }
387401 }
388402
389- List <DerValue > getSequenceElements () {
403+ List <DerValue > getSequenceElements () throws CertificateParsingException {
390404 List <DerValue > result = new ArrayList <>();
391405 iterateSequence ((e , r ) -> {
392406 result .add (e );
393407 }, result );
394408 return result ;
395409 }
396410
397- <T > void iterateSequence (BiConsumer <DerValue , T > consumer , T value ) {
411+ @ FunctionalInterface
412+ private interface DerSequenceConsumer <A , B > {
413+ abstract void accept (A a , B b ) throws CertificateParsingException ;
414+ }
415+
416+ <T > void iterateSequence (DerSequenceConsumer <DerValue , T > consumer , T value ) throws CertificateParsingException {
398417 int sequenceStart = contentStart ;
399418 int sequenceEnd = contentStart + contentLen ;
400419 DerValue sequenceData = getSequence ();
@@ -411,7 +430,7 @@ <T> void iterateSequence(BiConsumer<DerValue, T> consumer, T value) {
411430 }
412431
413432 @ TruffleBoundary
414- private static PTuple parseCRLPoints (X509Certificate cert , PythonObjectFactory factory ) throws IOException {
433+ private static PTuple parseCRLPoints (X509Certificate cert , PythonObjectFactory factory ) throws CertificateParsingException {
415434 List <String > result = new ArrayList <>();
416435 byte [] bytes = cert .getExtensionValue (OID_CRL_DISTRIBUTION_POINTS );
417436 if (bytes == null ) {
@@ -452,7 +471,7 @@ private static PTuple parseCRLPoints(X509Certificate cert, PythonObjectFactory f
452471 }
453472
454473 @ TruffleBoundary
455- private static PTuple parseCAIssuers (X509Certificate cert , PythonObjectFactory factory ) throws IOException {
474+ private static PTuple parseCAIssuers (X509Certificate cert , PythonObjectFactory factory ) throws CertificateParsingException {
456475 List <String > result = new ArrayList <>();
457476 byte [] bytes = cert .getExtensionValue (OID_AUTHORITY_INFO_ACCESS );
458477 if (bytes == null ) {
@@ -484,7 +503,7 @@ private static PTuple parseCAIssuers(X509Certificate cert, PythonObjectFactory f
484503 }
485504
486505 @ TruffleBoundary
487- private static PTuple parseOCSP (X509Certificate cert , PythonObjectFactory factory ) {
506+ private static PTuple parseOCSP (X509Certificate cert , PythonObjectFactory factory ) throws CertificateParsingException {
488507 List <String > result = new ArrayList <>();
489508 byte [] bytes = cert .getExtensionValue (OID_AUTHORITY_INFO_ACCESS );
490509 if (bytes == null ) {
0 commit comments