@@ -934,7 +934,7 @@ private static RubyString name(final ThreadContext context, IRubyObject value,
934934 } // ObjectId
935935
936936 static IRubyObject decodeObject (final ThreadContext context ,
937- final RubyModule ASN1 , final org . bouncycastle . asn1 . ASN1Encodable obj )
937+ final RubyModule ASN1 , final ASN1Encodable obj )
938938 throws IOException , IllegalArgumentException {
939939 final Ruby runtime = context .runtime ;
940940
@@ -1046,20 +1046,34 @@ else if ( obj instanceof ASN1GraphicString ) {
10461046
10471047 if (obj instanceof ASN1TaggedObject ) {
10481048 final ASN1TaggedObject taggedObj = (ASN1TaggedObject ) obj ;
1049- if (taggedObj .getTagClass () == BERTags .APPLICATION ) {
1050- IRubyObject tag = runtime .newFixnum ( taggedObj .getTagNo () );
1051- IRubyObject tag_class = runtime .newSymbol ("APPLICATION" );
1052- final ASN1Sequence sequence = (ASN1Sequence ) taggedObj .getBaseUniversal (false , SEQUENCE );
1053- @ SuppressWarnings ("unchecked" )
1049+ // IRubyObject val = decodeObject(context, ASN1, taggedObj.getBaseObject());
1050+ IRubyObject tag = runtime .newFixnum ( taggedObj .getTagNo () );
1051+ IRubyObject tag_class ;
1052+ switch (taggedObj .getTagClass ()) {
1053+ case BERTags .PRIVATE :
1054+ tag_class = runtime .newSymbol ("PRIVATE" );
1055+ break ;
1056+ case BERTags .APPLICATION :
1057+ tag_class = runtime .newSymbol ("APPLICATION" );
1058+ break ;
1059+ case BERTags .CONTEXT_SPECIFIC :
1060+ tag_class = runtime .newSymbol ("CONTEXT_SPECIFIC" );
1061+ break ;
1062+ default :
1063+ tag_class = runtime .newSymbol ("UNIVERSAL" );
1064+ break ;
1065+ }
1066+
1067+ final ASN1Encodable taggedBaseObj = taggedObj .getBaseObject ();
1068+
1069+ // TODO: how to infer that this tagged object is constructed
1070+ if (taggedBaseObj instanceof ASN1Sequence ) {
1071+ final ASN1Sequence sequence = (ASN1Sequence ) taggedBaseObj ;
10541072 final RubyArray valArr = decodeObjects (context , ASN1 , sequence .getObjects ());
10551073 return ASN1 .getClass ("ASN1Data" ).newInstance (context , new IRubyObject [] { valArr , tag , tag_class }, Block .NULL_BLOCK );
1056- } else {
1057- IRubyObject val = decodeObject (context , ASN1 , taggedObj .getBaseObject ());
1058- IRubyObject tag = runtime .newFixnum ( taggedObj .getTagNo () );
1059- IRubyObject tag_class = runtime .newSymbol ("CONTEXT_SPECIFIC" );
1060- final RubyArray valArr = runtime .newArray (val );
1061- return ASN1 .getClass ("ASN1Data" ).newInstance (context , new IRubyObject [] { valArr , tag , tag_class }, Block .NULL_BLOCK );
10621074 }
1075+
1076+ return ASN1 .getClass ("ASN1Data" ).newInstance (context , new IRubyObject [] { decodeObject (context , ASN1 , taggedBaseObj ).callMethod (context , "value" ), tag , tag_class }, Block .NULL_BLOCK );
10631077 }
10641078
10651079 if ( obj instanceof ASN1Sequence ) {
@@ -1367,27 +1381,47 @@ ASN1Encodable toASN1(final ThreadContext context) {
13671381
13681382 final ASN1TaggedObject toASN1TaggedObject (final ThreadContext context ) {
13691383 final int tag = getTag (context );
1384+ final RubyModule ASN1 = _ASN1 (context .runtime );
1385+
1386+ IRubyObject value = callMethod (context , "value" );
1387+ final IRubyObject tagClass = callMethod (context , "tag_class" );
1388+ int berTag ;
1389+ String tagClassName = tagClass .toString ();
1390+
1391+ if (tagClassName .equals ("PRIVATE" )) {
1392+ berTag = BERTags .PRIVATE ;
1393+ } else if (tagClassName .equals ("APPLICATION" )) {
1394+ berTag = BERTags .APPLICATION ;
1395+ } else if (tagClassName .equals ("CONTEXT_SPECIFIC" )) {
1396+ berTag = BERTags .CONTEXT_SPECIFIC ;
1397+ } else {
1398+ berTag = BERTags .UNIVERSAL ;
1399+ }
13701400
1371- final IRubyObject value = callMethod (context , "value" );
1372- if (value instanceof RubyArray ) {
1401+ if ( value instanceof RubyArray ) {
13731402 final RubyArray arr = (RubyArray ) value ;
13741403 assert ! arr .isEmpty ();
13751404
13761405 ASN1EncodableVector vec = new ASN1EncodableVector ();
1377- for (final IRubyObject obj : arr .toJavaArray ()) {
1406+ for ( final IRubyObject obj : arr .toJavaArray () ) {
13781407 ASN1Encodable data = ((ASN1Data ) obj ).toASN1 (context );
13791408 if ( data == null ) break ;
13801409 vec .add ( data );
13811410 }
1382- return new DERTaggedObject (isExplicitTagging (), tag , new DERSequence (vec ));
1411+
1412+ // TODO: it's not possible to generate a constructed tagged object, bc raises exception
1413+ // berTag = berTag | BERTags.CONSTRUCTED;
1414+ return new DERTaggedObject (isExplicitTagging (), berTag , tag , new DERSequence (vec ));
13831415 }
13841416
13851417 if (!(value instanceof ASN1Data )) {
13861418 throw new UnsupportedOperationException ("toASN1 " + inspect () + " value: " + value .inspect () + " (" + value .getMetaClass () + ")" );
13871419 }
1388- return new DERTaggedObject (isExplicitTagging (), tag , ((ASN1Data ) value ).toASN1 (context ));
1420+
1421+ return new DERTaggedObject (isExplicitTagging (), berTag , tag , ((ASN1Data ) value ).toASN1 (context ));
13891422 }
13901423
1424+
13911425 @ JRubyMethod
13921426 public IRubyObject to_der (final ThreadContext context ) {
13931427 try {
0 commit comments