private static byte [ ] readOneBlock ( InputStream is ) throws IOException { // The first character of a BLOCK. int c = is . read ( ) ; if ( c == - 1 ) { return null ; } if ( c == DerValue . tag_Sequence ) { ByteArrayOutputStream bout = new ByteArrayOutputStream ( 2048 ) ; bout . write ( c ) ; readBERInternal ( is , bout , c ) ; return bout . toByteArray ( ) ; } else { // Read BASE64 encoded data, might skip info at the beginning char [ ] data = new char [ 2048 ] ; int pos = 0 ; // Step 1: Read until header is found int hyphen = ( c == ' ' ) ? 1 : 0 ; // count of consequent hyphens int last = ( c == ' ' ) ? - 1 : c ; // the char before hyphen while ( true ) { int next = is . read ( ) ; if ( next == - 1 ) { // We accept useless data after the last block, // say, empty lines. return null ; } if ( next == ' ' ) { hyphen ++ ; } else { hyphen = 0 ; last = next ; } if ( hyphen == 5 && ( last == - 1 || last == ' ' || last == ' ' ) ) { break ; } } // Step 2: Read the rest of header, determine the line end int end ; StringBuffer header = new StringBuffer ( "-----" ) ; while ( true ) { int next = is . read ( ) ; if ( next == - 1 ) { throw new IOException ( "Incomplete data" ) ; } if ( next == ' ' ) { end = ' ' ; break ; } if ( next == ' ' ) { next = is . read ( ) ; if ( next == - 1 ) { throw new IOException ( "Incomplete data" ) ; } if ( next == ' ' ) { end = ' ' ; } else { end = ' ' ; data [ pos ++ ] = ( char ) next ; } break ; } header . append ( ( char ) next ) ; } // Step 3: Read the data while ( true ) { int next = is . read ( ) ; if ( next == - 1 ) { throw new IOException ( "Incomplete data" ) ; } if ( next != ' ' ) { data [ pos ++ ] = ( char ) next ; if ( pos >= data . length ) { data = Arrays . copyOf ( data , data . length + 1024 ) ; } } else { break ; } } // Step 4: Consume the footer StringBuffer footer = new StringBuffer ( "-" ) ; while ( true ) { int next = is . read ( ) ; // Add next == '\n' for maximum safety, in case endline // is not consistent. if ( next == - 1 || next == end || next == ' ' ) { break ; } if ( next != ' ' ) footer . append ( ( char ) next ) ; } checkHeaderFooter ( header . toString ( ) , footer . toString ( ) ) ; BASE64Decoder decoder = new BASE64Decoder ( ) ; return decoder . decodeBuffer ( new String ( data , 0 , pos ) ) ; } }
Returns an ASN . 1 SEQUENCE from a stream which might be a BER - encoded binary block or a PEM - style BASE64 - encoded ASCII data . In the latter case it s de - BASE64 ed before return .