@@ -344,7 +344,7 @@ function normalizeDate(value) {
344344 }
345345
346346 if ( typeof value === 'string' ) {
347- if ( / ^ \d { 14 } Z $ / . test ( value ) ) {
347+ if ( / ^ \d { 12 } Z $ / . test ( value ) || / ^ \d { 14 } Z $ / . test ( value ) ) {
348348 return parseAsn1Date ( value )
349349 }
350350 const date = new Date ( value )
@@ -358,30 +358,51 @@ function normalizeDate(value) {
358358}
359359
360360function formatAsn1Date ( date ) {
361- const pad = ( num , size ) => {
361+ const pad = ( num ) => {
362362 let s = String ( num )
363- while ( s . length < size ) {
363+ while ( s . length < 2 ) {
364364 s = '0' + s
365365 }
366366 return s
367367 }
368368
369- return date . getUTCFullYear ( ) . toString ( ) +
370- pad ( date . getUTCMonth ( ) + 1 , 2 ) +
371- pad ( date . getUTCDate ( ) , 2 ) +
372- pad ( date . getUTCHours ( ) , 2 ) +
373- pad ( date . getUTCMinutes ( ) , 2 ) +
374- pad ( date . getUTCSeconds ( ) , 2 ) +
375- 'Z'
369+ const timePortion = pad ( date . getUTCMonth ( ) + 1 ) +
370+ pad ( date . getUTCDate ( ) ) +
371+ pad ( date . getUTCHours ( ) ) +
372+ pad ( date . getUTCMinutes ( ) ) +
373+ pad ( date . getUTCSeconds ( ) )
374+
375+ const year = date . getUTCFullYear ( )
376+ if ( year >= 1950 && year <= 2049 ) {
377+ return pad ( year % 100 ) + timePortion + 'Z'
378+ }
379+
380+ return year . toString ( ) + timePortion + 'Z'
376381}
377382
378383function parseAsn1Date ( value ) {
379- const year = Number ( value . slice ( 0 , 4 ) )
380- const month = Number ( value . slice ( 4 , 6 ) ) - 1
381- const day = Number ( value . slice ( 6 , 8 ) )
382- const hour = Number ( value . slice ( 8 , 10 ) )
383- const minute = Number ( value . slice ( 10 , 12 ) )
384- const second = Number ( value . slice ( 12 , 14 ) )
384+ const normalized = value . replace ( / \s + / g, '' )
385+ if ( ! / ^ \d { 12 } Z $ / . test ( normalized ) && ! / ^ \d { 14 } Z $ / . test ( normalized ) ) {
386+ throw new Error ( 'Invalid ASN.1 date value' )
387+ }
388+
389+ let offset
390+ let year
391+
392+ if ( normalized . length === 13 ) { // YYMMDDHHMMSSZ
393+ const twoDigit = Number ( normalized . slice ( 0 , 2 ) )
394+ year = twoDigit >= 50 ? 1900 + twoDigit : 2000 + twoDigit
395+ offset = 2
396+ } else { // YYYYMMDDHHMMSSZ
397+ year = Number ( normalized . slice ( 0 , 4 ) )
398+ offset = 4
399+ }
400+
401+ const month = Number ( normalized . slice ( offset , offset + 2 ) ) - 1
402+ const day = Number ( normalized . slice ( offset + 2 , offset + 4 ) )
403+ const hour = Number ( normalized . slice ( offset + 4 , offset + 6 ) )
404+ const minute = Number ( normalized . slice ( offset + 6 , offset + 8 ) )
405+ const second = Number ( normalized . slice ( offset + 8 , offset + 10 ) )
385406 const date = new Date ( Date . UTC ( year , month , day , hour , minute , second ) )
386407 if ( Number . isNaN ( date . getTime ( ) ) ) {
387408 throw new Error ( 'Invalid ASN.1 date value' )
0 commit comments