@@ -20,6 +20,27 @@ FPS.ecdsa = sshpk.parseFingerprint(
2020FPS . ecdsa2 = sshpk . parseFingerprint (
2121 'SHA256:Kyu0EMqH8fzfp9RXKJ6kmsk9qKGBqVRtlOuk6bXfCEU' ) ;
2222
23+ var ASN1PARSE_LINE =
24+ / ^ \s * ( [ 0 - 9 ] * ) : d = ( [ 0 - 9 ] + ) \s + h l = ( [ 0 - 9 ] + ) \s + l = \s * ( [ 0 - 9 ] + ) \s * ( [ a - z ] + ) : \s * ( [ ^ : \[ ] + ) \s * ( \[ [ ^ \] ] + \] ) ? \s * ( : .+ ) ? $ / ;
25+ function asn1parse_line2obj ( line ) {
26+ var m = line . match ( ASN1PARSE_LINE ) ;
27+ if ( ! m )
28+ throw ( new Error ( 'Not a valid asn1parse output line' ) ) ;
29+ var obj = {
30+ offset : parseInt ( m [ 1 ] , 10 ) ,
31+ depth : parseInt ( m [ 2 ] , 10 ) ,
32+ headerLength : parseInt ( m [ 3 ] , 10 ) ,
33+ length : parseInt ( m [ 4 ] , 10 ) ,
34+ type : m [ 5 ] ,
35+ tag : m [ 6 ] . trim ( )
36+ } ;
37+ if ( m [ 7 ] )
38+ obj . valueType = m [ 7 ] . slice ( 1 , m [ 7 ] . length - 1 ) ;
39+ if ( m [ 8 ] )
40+ obj . value = m [ 8 ] . slice ( 1 ) ;
41+ return ( obj ) ;
42+ }
43+
2344temp . track ( ) ;
2445
2546test ( 'openssl version' , function ( t ) {
@@ -306,19 +327,21 @@ function genTests() {
306327 var output = Buffer . concat ( bufs ) . toString ( 'utf8' ) ;
307328 var lines = output . split ( '\n' ) ;
308329 var foundString = false ;
309- lines . forEach ( function ( line ) {
310- if ( line . indexOf ( 'おはよう' ) !== - 1 ) {
311- t . strictEqual (
312- line . indexOf ( 'PRINTABLESTRING' ) ,
313- - 1 ) ;
314- t . strictEqual (
315- line . indexOf ( 'IA5STRING' ) ,
316- - 1 ) ;
317- t . notStrictEqual (
318- line . indexOf ( 'UTF8STRING' ) , - 1 ) ;
330+ for ( var i = 0 ; i < lines . length ; ++ i ) {
331+ if ( ! lines [ i ] )
332+ continue ;
333+ var line = asn1parse_line2obj ( lines [ i ] ) ;
334+ if ( line . tag === 'OBJECT' &&
335+ line . value === 'commonName' ) {
336+ var nline = asn1parse_line2obj (
337+ lines [ i + 1 ] ) ;
338+ t . strictEqual ( nline . value ,
339+ 'おはよう' , 'CN should be set' ) ;
340+ t . strictEqual ( nline . tag , 'UTF8STRING' ,
341+ 'CN should be a utf8string' ) ;
319342 foundString = true ;
320343 }
321- } ) ;
344+ }
322345 t . ok ( foundString ) ;
323346 t . end ( ) ;
324347 } ) ;
@@ -342,18 +365,21 @@ function genTests() {
342365 var output = Buffer . concat ( bufs ) . toString ( 'utf8' ) ;
343366 var lines = output . split ( '\n' ) ;
344367 var foundString = false ;
345- lines . forEach ( function ( line ) {
346- if ( line . indexOf ( 'foo_bar@' ) !== - 1 ) {
347- t . strictEqual (
348- line . indexOf ( 'PRINTABLESTRING' ) ,
349- - 1 ) ;
350- t . strictEqual (
351- line . indexOf ( 'UTF8STRING' ) , - 1 ) ;
352- t . notStrictEqual (
353- line . indexOf ( 'IA5STRING' ) , - 1 ) ;
368+ for ( var i = 0 ; i < lines . length ; ++ i ) {
369+ if ( ! lines [ i ] )
370+ continue ;
371+ var line = asn1parse_line2obj ( lines [ i ] ) ;
372+ if ( line . tag === 'OBJECT' &&
373+ line . value === 'commonName' ) {
374+ var nline = asn1parse_line2obj (
375+ lines [ i + 1 ] ) ;
376+ t . strictEqual ( nline . value ,
377+ 'foo_bar@' , 'CN should be set' ) ;
378+ t . strictEqual ( nline . tag , 'IA5STRING' ,
379+ 'CN should be a ia5string' ) ;
354380 foundString = true ;
355381 }
356- } ) ;
382+ }
357383 t . ok ( foundString ) ;
358384 t . end ( ) ;
359385 } ) ;
@@ -391,6 +417,45 @@ function genTests() {
391417 } ) ;
392418} ) ;
393419
420+ test ( 'nulls in x509 rsa certs (#39)' , function ( t ) {
421+ var pem = fs . readFileSync ( path . join ( testDir , 'id_rsa' ) ) ;
422+ var key = sshpk . parsePrivateKey ( pem , 'pkcs1' ) ;
423+
424+ var id = sshpk . identityFromDN ( 'cn=foobar' ) ;
425+ var cert = sshpk . createSelfSignedCertificate ( id , key ) ;
426+ var certPem = cert . toBuffer ( 'pem' ) ;
427+
428+ var kid = spawn ( 'openssl' , [ 'asn1parse' ] ) ;
429+ var bufs = [ ] ;
430+ kid . stdout . on ( 'data' , bufs . push . bind ( bufs ) ) ;
431+ kid . on ( 'close' , function ( rc ) {
432+ t . equal ( rc , 0 , 'openssl command exit status 0' ) ;
433+ var output = Buffer . concat ( bufs ) . toString ( 'utf8' ) ;
434+ var lines = output . split ( '\n' ) ;
435+ var found = false ;
436+ for ( var i = 0 ; i < lines . length ; ++ i ) {
437+ if ( lines [ i ] . length < 1 )
438+ continue ;
439+ var line = asn1parse_line2obj ( lines [ i ] ) ;
440+ if ( line . type === 'prim' && line . tag === 'OBJECT' &&
441+ line . value === 'sha256WithRSAEncryption' ) {
442+ var nline = asn1parse_line2obj ( lines [ i + 1 ] ) ;
443+ t . strictEqual ( nline . tag , 'NULL' ,
444+ 'null value must follow RSA OID' ) ;
445+ t . strictEqual ( nline . type , 'prim' ,
446+ 'null should be primitive' ) ;
447+ t . strictEqual ( nline . depth , line . depth ,
448+ 'null should be at same depth as RSA OID' ) ;
449+ found = true ;
450+ }
451+ }
452+ t . ok ( found , 'should have an RSA OID' ) ;
453+ t . end ( ) ;
454+ } ) ;
455+ kid . stdin . write ( certPem ) ;
456+ kid . stdin . end ( ) ;
457+ } ) ;
458+
394459test ( 'utf8string in issuer DN (#40)' , function ( t ) {
395460 var pem = fs . readFileSync ( path . join ( testDir , 'id_rsa' ) ) ;
396461 var ikey = sshpk . parsePrivateKey ( pem , 'pkcs1' ) ;
0 commit comments