@@ -956,7 +956,7 @@ private static RubyString name(final ThreadContext context, IRubyObject value,
956956 } // ObjectId
957957
958958 static IRubyObject decodeObject (final ThreadContext context ,
959- final RubyModule ASN1 , final org . bouncycastle . asn1 . ASN1Encodable obj )
959+ final RubyModule ASN1 , final ASN1Encodable obj )
960960 throws IOException , IllegalArgumentException {
961961 final Ruby runtime = context .runtime ;
962962
@@ -1072,22 +1072,47 @@ else if ( obj instanceof DERBMPString ) {
10721072 return ASN1 .getClass ("ObjectId" ).newInstance (context , runtime .newString (objId ), Block .NULL_BLOCK );
10731073 }
10741074
1075- if (obj instanceof ASN1TaggedObject ) {
1075+
1076+ if ( obj instanceof ASN1TaggedObject ) {
10761077 final ASN1TaggedObject taggedObj = (ASN1TaggedObject ) obj ;
1077- if (taggedObj .getTagClass () == BERTags .APPLICATION ) {
1078- IRubyObject tag = runtime .newFixnum ( taggedObj .getTagNo () );
1079- IRubyObject tag_class = runtime .newSymbol ("APPLICATION" );
1080- final ASN1Sequence sequence = (ASN1Sequence ) taggedObj .getBaseUniversal (false , SEQUENCE );
1081- @ SuppressWarnings ("unchecked" )
1078+ // IRubyObject val = decodeObject(context, ASN1, taggedObj.getBaseObject());
1079+ IRubyObject tag = runtime .newFixnum ( taggedObj .getTagNo () );
1080+ IRubyObject tag_class ;
1081+ switch (taggedObj .getTagClass ()) {
1082+ case BERTags .PRIVATE :
1083+ tag_class = runtime .newSymbol ("PRIVATE" );
1084+ break ;
1085+ case BERTags .APPLICATION :
1086+ tag_class = runtime .newSymbol ("APPLICATION" );
1087+ break ;
1088+ case BERTags .CONTEXT_SPECIFIC :
1089+ tag_class = runtime .newSymbol ("CONTEXT_SPECIFIC" );
1090+ break ;
1091+ default :
1092+ tag_class = runtime .newSymbol ("UNIVERSAL" );
1093+ break ;
1094+ }
1095+
1096+ try {
1097+ final ASN1Sequence sequence = (ASN1Sequence ) taggedObj .getExplicitBaseObject ();
10821098 final RubyArray valArr = decodeObjects (context , ASN1 , sequence .getObjects ());
10831099 return ASN1 .getClass ("ASN1Data" ).newInstance (context , new IRubyObject [] { valArr , tag , tag_class }, Block .NULL_BLOCK );
1084- } else {
1085- IRubyObject val = decodeObject (context , ASN1 , taggedObj .getBaseObject ());
1086- IRubyObject tag = runtime .newFixnum ( taggedObj .getTagNo () );
1087- IRubyObject tag_class = runtime .newSymbol ("CONTEXT_SPECIFIC" );
1088- final RubyArray valArr = runtime .newArray (val );
1089- return ASN1 .getClass ("ASN1Data" ).newInstance (context , new IRubyObject [] { valArr , tag , tag_class }, Block .NULL_BLOCK );
1100+ } catch (ClassCastException e ) {
1101+ final ASN1Encodable taggedBaseObj = taggedObj .getBaseObject ();
1102+ return ASN1 .getClass ("ASN1Data" ).newInstance (context , new IRubyObject [] { decodeObject (context , ASN1 , taggedBaseObj ).callMethod (context , "value" ), tag , tag_class }, Block .NULL_BLOCK );
10901103 }
1104+
1105+ // if ( obj instanceof DLTaggedObject ) { // isConstructed
1106+ // System.out.println("ASN1Data constructive!");
1107+ // final ASN1Sequence sequence = (ASN1Sequence) taggedObj.getBaseUniversal(false, SEQUENCE);
1108+ // @SuppressWarnings("unchecked")
1109+ // final RubyArray valArr = decodeObjects(context, ASN1, sequence.getObjects());
1110+ // return ASN1.getClass("ASN1Data").newInstance(context, new IRubyObject[] { valArr, tag, tag_class }, Block.NULL_BLOCK);
1111+ // } else {
1112+ // final ASN1Encodable taggedBaseObj = taggedObj.getBaseObject();
1113+ // System.out.println("ASN1Data primitive!");
1114+ // return ASN1.getClass("ASN1Data").newInstance(context, new IRubyObject[] { decodeObject(context, ASN1, taggedBaseObj).callMethod(context, "value"), tag, tag_class }, Block.NULL_BLOCK);
1115+ // }
10911116 }
10921117
10931118 if ( obj instanceof ASN1Sequence ) {
@@ -1384,29 +1409,59 @@ ASN1Encodable toASN1(final ThreadContext context) {
13841409
13851410 final ASN1TaggedObject toASN1TaggedObject (final ThreadContext context ) {
13861411 final int tag = getTag (context );
1412+ final RubyModule ASN1 = _ASN1 (context .runtime );
1413+
1414+ IRubyObject val = callMethod (context , "value" );
1415+ final IRubyObject tagClass = callMethod (context , "tag_class" );
1416+ ASN1Encodable obj ;
1417+ int berTag ;
13871418
1388- final IRubyObject val = callMethod (context , "value" );
13891419 if ( val instanceof RubyArray ) {
13901420 final RubyArray arr = (RubyArray ) val ;
1391- if ( arr .size () > 1 ) {
1392- ASN1EncodableVector vec = new ASN1EncodableVector ();
1393- for ( final IRubyObject obj : arr .toJavaArray () ) {
1394- ASN1Encodable data = ((ASN1Data ) obj ).toASN1 (context );
1395- if ( data == null ) break ; vec .add ( data );
1421+
1422+ if ( arr .size () >= 1 ) {
1423+ ByteArrayOutputStream bytes = new ByteArrayOutputStream ( );
1424+
1425+ for ( final IRubyObject o : arr .toJavaArray () ) {
1426+ try {
1427+ bytes .write (((RubyString ) o ).getBytes ());
1428+ } catch (IOException e ) {
1429+ throw new IllegalStateException (e .getMessage ());
1430+ } catch (ClassCastException e ) {
1431+ throw context .runtime .newTypeError (e .getMessage ());
1432+ }
13961433 }
1397- return new DERTaggedObject (isExplicitTagging (), tag , new DERSequence (vec ));
1398- }
1399- else if ( arr .size () == 1 ) {
1400- ASN1Encodable data = ((ASN1Data ) arr .entry (0 )).toASN1 (context );
1401- return new DERTaggedObject (isExplicitTagging (), tag , data );
1402- }
1403- else {
1434+ obj = new DEROctetString (bytes .toByteArray ());
1435+ } else {
14041436 throw new IllegalStateException ("empty array detected" );
14051437 }
1438+ } else {
1439+ try {
1440+ obj = new DEROctetString (((RubyString ) val ).getBytes ());
1441+ } catch (ClassCastException e ) {
1442+ throw context .runtime .newTypeError ("no implicit conversion of " + val .getMetaClass ().getName () + " into String" );
1443+ }
14061444 }
1407- return new DERTaggedObject (isExplicitTagging (), tag , ((ASN1Data ) val ).toASN1 (context ));
1445+
1446+ switch (tagClass .toString ()) {
1447+ case "PRIVATE" :
1448+ berTag = BERTags .PRIVATE ;
1449+ break ;
1450+ case "APPLICATION" :
1451+ berTag = BERTags .APPLICATION ;
1452+ break ;
1453+ case "CONTEXT_SPECIFIC" :
1454+ berTag = BERTags .CONTEXT_SPECIFIC ;
1455+ break ;
1456+ default :
1457+ berTag = BERTags .UNIVERSAL ;
1458+ break ;
1459+ }
1460+
1461+ return new DERTaggedObject (isExplicitTagging (), berTag , tag , obj );
14081462 }
14091463
1464+
14101465 @ JRubyMethod
14111466 public IRubyObject to_der (final ThreadContext context ) {
14121467 try {
0 commit comments