%% Generated by the Erlang ASN.1 BER_V2-compiler version, utilizing bit-syntax:1.7
%% Purpose: encoder and decoder to the types in mod PKCS-FRAME

-module('PKCS-FRAME').

-export([dec_AttributeUsage/2, dec_Attributes/2,
	 dec_Context/2, dec_EncryptedData/2,
	 dec_EncryptedPrivateKeyInfo/2, dec_PBEParameter/2,
	 'dec_PBES2-params'/2, 'dec_PBKDF2-params'/2,
	 'dec_PBMAC1-params'/2, dec_PrivateKey/2,
	 dec_PrivateKeyInfo/2, 'dec_RC2-CBC-Parameter'/2,
	 'dec_RC5-CBC-Parameters'/2, dec_Version/2, decode/2,
	 decode_disp/2, 'des-EDE3-CBC'/0, desCBC/0,
	 digestAlgorithm/0, enc_AttributeUsage/2,
	 enc_Attributes/2, enc_Context/2, enc_EncryptedData/2,
	 enc_EncryptedPrivateKeyInfo/2, enc_PBEParameter/2,
	 'enc_PBES2-params'/2, 'enc_PBKDF2-params'/2,
	 'enc_PBMAC1-params'/2, enc_PrivateKey/2,
	 enc_PrivateKeyInfo/2, 'enc_RC2-CBC-Parameter'/2,
	 'enc_RC5-CBC-Parameters'/2, enc_Version/2, encode/2,
	 encode_disp/2, encoding_rule/0, encryptionAlgorithm/0,
	 getdec_KeyEncryptionAlgorithms/2,
	 getdec_PBES1Algorithms/2, 'getdec_PBES2-Encs'/2,
	 'getdec_PBES2-KDFs'/2, getdec_PBES2Algorithms/2,
	 'getdec_PBKDF2-PRFs'/2, 'getdec_PBKDF2-SaltSources'/2,
	 'getdec_PBMAC1-KDFs'/2, 'getdec_PBMAC1-MACs'/2,
	 getdec_PBMAC1Algorithms/2,
	 getdec_PrivateKeyAlgorithms/2,
	 getdec_SupportedContexts/2,
	 getdec_SupportingAlgorithms/2,
	 getdec_internal_object_set_argument_1/2,
	 getdec_internal_object_set_argument_2/2,
	 getdec_internal_object_set_argument_3/2,
	 getdec_internal_object_set_argument_4/2,
	 getdec_internal_object_set_argument_5/2,
	 getdec_internal_object_set_argument_6/2,
	 getdec_internal_object_set_argument_7/2,
	 getdec_internal_object_set_argument_8/2,
	 getdec_internal_object_set_argument_9/2,
	 getenc_KeyEncryptionAlgorithms/2,
	 getenc_PBES1Algorithms/2, 'getenc_PBES2-Encs'/2,
	 'getenc_PBES2-KDFs'/2, getenc_PBES2Algorithms/2,
	 'getenc_PBKDF2-PRFs'/2, 'getenc_PBKDF2-SaltSources'/2,
	 'getenc_PBMAC1-KDFs'/2, 'getenc_PBMAC1-MACs'/2,
	 getenc_PBMAC1Algorithms/2,
	 getenc_PrivateKeyAlgorithms/2,
	 getenc_SupportedContexts/2,
	 getenc_SupportingAlgorithms/2,
	 getenc_internal_object_set_argument_1/2,
	 getenc_internal_object_set_argument_2/2,
	 getenc_internal_object_set_argument_3/2,
	 getenc_internal_object_set_argument_4/2,
	 getenc_internal_object_set_argument_5/2,
	 getenc_internal_object_set_argument_6/2,
	 getenc_internal_object_set_argument_7/2,
	 getenc_internal_object_set_argument_8/2,
	 getenc_internal_object_set_argument_9/2, 'id-PBES2'/0,
	 'id-PBKDF2'/0, 'id-PBMAC1'/0, 'id-hmacWithSHA1'/0,
	 info/0, 'pbeWithMD2AndDES-CBC'/0,
	 'pbeWithMD2AndRC2-CBC'/0, 'pbeWithMD5AndDES-CBC'/0,
	 'pbeWithMD5AndRC2-CBC'/0, 'pbeWithSHA1AndDES-CBC'/0,
	 'pbeWithSHA1AndRC2-CBC'/0, pkcs/0, 'pkcs-5'/0, rc2CBC/0,
	 'rc5-CBC-PAD'/0, rsadsi/0]).

-asn1_info([{vsn, '1.7'}, {module, 'PKCS-FRAME'},
	    {options,
	     [ber_bin_v2, warnings, errors,
	      {cwd,
	       "/net/isildur/ldisk/daily_build/r15b01_prebuil"
	       "d_opu_o.2012-04-01_20/otp_src_R15B01/lib/publ"
	       "ic_key/asn1"},
	      {outdir,
	       "/net/isildur/ldisk/daily_build/r15b01_prebuil"
	       "d_opu_o.2012-04-01_20/otp_src_R15B01/lib/publ"
	       "ic_key/asn1"},
	      nif, inline, asn1config, noobj, optimize,
	      compact_bit_string, der, {i, "."},
	      {i,
	       "/net/isildur/ldisk/daily_build/r15b01_prebuil"
	       "d_opu_o.2012-04-01_20/otp_src_R15B01/lib/publ"
	       "ic_key/asn1"}]}]).

%%<<< -asn1_info([{vsn, '1.7'}, {module, 'PKCS-FRAME'},
%%<<<             {options,
%%<<<              [ber_bin_v2, warnings, errors,
%%<<<               {cwd,
%%<<<                "/net/isildur/ldisk/daily_build/r15b01_prebuil"
%%<<<                "d_opu_o.2012-04-01_20/otp_src_R15B01/lib/publ"
%%<<<                "ic_key/asn1"},
%%<<<               {outdir,
%%<<<                "/net/isildur/ldisk/daily_build/r15b01_prebuil"
%%<<<                "d_opu_o.2012-04-01_20/otp_src_R15B01/lib/publ"
%%<<<                "ic_key/asn1"},
%%<<<               nif, inline, asn1config, noobj, optimize,
%%<<<               compact_bit_string, der, {i, "."},
%%<<<               {i,
%%<<<                "/net/isildur/ldisk/daily_build/r15b01_prebuil"
%%<<<                "d_opu_o.2012-04-01_20/otp_src_R15B01/lib/publ"
%%<<<                "ic_key/asn1"}]}]).

encoding_rule() -> ber_bin_v2.

encode(Type, Data) ->
    case catch encode_disp(Type, Data) of
      {'EXIT', {error, Reason}} -> {error, Reason};
      {'EXIT', Reason} -> {error, {asn1, Reason}};
      {Bytes, _Len} -> {ok, Bytes};
      Bytes -> {ok, Bytes}
    end.

decode(Type, Data) ->
    case catch decode_disp(Type,
			   element(1, asn1rt_ber_bin_v2__decode(Data, nif)))
	of
      {'EXIT', {error, Reason}} -> {error, Reason};
      {'EXIT', Reason} -> {error, {asn1, Reason}};
      Result -> {ok, Result}
    end.

encode_disp('RC5-CBC-Parameters', Data) ->
    'enc_RC5-CBC-Parameters'(Data);
encode_disp('RC2-CBC-Parameter', Data) ->
    'enc_RC2-CBC-Parameter'(Data);
encode_disp('PBMAC1-params', Data) ->
    'enc_PBMAC1-params'(Data);
encode_disp('PBES2-params', Data) ->
    'enc_PBES2-params'(Data);
encode_disp('PBEParameter', Data) ->
    enc_PBEParameter(Data);
encode_disp('PBKDF2-params', Data) ->
    'enc_PBKDF2-params'(Data);
encode_disp('AttributeUsage', Data) ->
    enc_AttributeUsage(Data);
encode_disp('Context', Data) -> enc_Context(Data);
encode_disp('EncryptedData', Data) ->
    enc_EncryptedData(Data);
encode_disp('EncryptedPrivateKeyInfo', Data) ->
    enc_EncryptedPrivateKeyInfo(Data);
encode_disp('Attributes', Data) -> enc_Attributes(Data);
encode_disp('PrivateKey', Data) -> enc_PrivateKey(Data);
encode_disp('Version', Data) -> enc_Version(Data);
encode_disp('PrivateKeyInfo', Data) ->
    enc_PrivateKeyInfo(Data);
encode_disp(Type, _Data) ->
    exit({error, {asn1, {undefined_type, Type}}}).

decode_disp('RC5-CBC-Parameters', Data) ->
    'dec_RC5-CBC-Parameters'(Data);
decode_disp('RC2-CBC-Parameter', Data) ->
    'dec_RC2-CBC-Parameter'(Data);
decode_disp('PBMAC1-params', Data) ->
    'dec_PBMAC1-params'(Data);
decode_disp('PBES2-params', Data) ->
    'dec_PBES2-params'(Data);
decode_disp('PBEParameter', Data) ->
    dec_PBEParameter(Data);
decode_disp('PBKDF2-params', Data) ->
    'dec_PBKDF2-params'(Data);
decode_disp('AttributeUsage', Data) ->
    dec_AttributeUsage(Data);
decode_disp('Context', Data) -> dec_Context(Data);
decode_disp('EncryptedData', Data) ->
    dec_EncryptedData(Data);
decode_disp('EncryptedPrivateKeyInfo', Data) ->
    dec_EncryptedPrivateKeyInfo(Data);
decode_disp('Attributes', Data) -> dec_Attributes(Data);
decode_disp('PrivateKey', Data) -> dec_PrivateKey(Data);
decode_disp('Version', Data) -> dec_Version(Data);
decode_disp('PrivateKeyInfo', Data) ->
    dec_PrivateKeyInfo(Data);
decode_disp(Type, _Data) ->
    exit({error, {asn1, {undefined_type, Type}}}).

info() ->
    case 'PKCS-FRAME':module_info() of
      MI when is_list(MI) ->
	  case lists:keysearch(attributes, 1, MI) of
	    {value, {_, Attributes}} when is_list(Attributes) ->
		case lists:keysearch(asn1_info, 1, Attributes) of
		  {value, {_, Info}} when is_list(Info) -> Info;
		  _ -> []
		end;
	    _ -> []
	  end
    end.

%%================================
%%  RC5-CBC-Parameters
%%================================
'enc_RC5-CBC-Parameters'(Val) ->
    'enc_RC5-CBC-Parameters'(Val, [<<48>>]).

'enc_RC5-CBC-Parameters'(Val, TagIn) ->
    {_, Cindex1, Cindex2, Cindex3, Cindex4} = Val,
    %%-------------------------------------------------
    %% attribute version(1) with type INTEGER
    %%-------------------------------------------------
    {EncBytes1, EncLen1} = encode_integer([], Cindex1,
					  [{'v1-0', 16}], [<<2>>]),
    %%-------------------------------------------------
    %% attribute rounds(2) with type INTEGER
    %%-------------------------------------------------
    {EncBytes2, EncLen2} = encode_integer([], Cindex2,
					  [<<2>>]),
    %%-------------------------------------------------
    %% attribute blockSizeInBits(3) with type INTEGER
    %%-------------------------------------------------
    {EncBytes3, EncLen3} = encode_integer([], Cindex3,
					  [<<2>>]),
    %%-------------------------------------------------
    %% attribute iv(4) with type OCTET STRING OPTIONAL
    %%-------------------------------------------------
    {EncBytes4, EncLen4} = case Cindex4 of
			     asn1_NOVALUE -> {<<>>, 0};
			     _ -> encode_octet_string([], Cindex4, [<<4>>])
			   end,
    BytesSoFar = [EncBytes1, EncBytes2, EncBytes3,
		  EncBytes4],
    LenSoFar = EncLen1 + EncLen2 + EncLen3 + EncLen4,
    encode_tags(TagIn, BytesSoFar, LenSoFar).

'dec_RC5-CBC-Parameters'(Tlv) ->
    'dec_RC5-CBC-Parameters'(Tlv, [16]).

'dec_RC5-CBC-Parameters'(Tlv, TagIn) ->
    %%-------------------------------------------------
    %% decode tag and length
    %%-------------------------------------------------
    Tlv1 = match_tags(Tlv, TagIn),
    %%-------------------------------------------------
    %% attribute version(1) with type INTEGER
    %%-------------------------------------------------
    [V1 | Tlv2] = Tlv1,
    Term1 = decode_integer(V1, [], [{'v1-0', 16}], [2]),
    %%-------------------------------------------------
    %% attribute rounds(2) with type INTEGER
    %%-------------------------------------------------
    [V2 | Tlv3] = Tlv2,
    Term2 = decode_integer(V2, {8, 127}, [2]),
    %%-------------------------------------------------
    %% attribute blockSizeInBits(3) with type INTEGER
    %%-------------------------------------------------
    [V3 | Tlv4] = Tlv3,
    Term3 = decode_integer(V3, [64, 128], [2]),
    %%-------------------------------------------------
    %% attribute iv(4) with type OCTET STRING OPTIONAL
    %%-------------------------------------------------
    {Term4, Tlv5} = case Tlv4 of
		      [{4, V4} | TempTlv5] ->
			  {decode_octet_string(V4, [], []), TempTlv5};
		      _ -> {asn1_NOVALUE, Tlv4}
		    end,
    case Tlv5 of
      [] -> true;
      _ ->
	  exit({error,
		{asn1, {unexpected, Tlv5}}}) % extra fields not allowed
    end,
    {'RC5-CBC-Parameters', Term1, Term2, Term3, Term4}.

%%================================
%%  RC2-CBC-Parameter
%%================================
'enc_RC2-CBC-Parameter'(Val) ->
    'enc_RC2-CBC-Parameter'(Val, [<<48>>]).

'enc_RC2-CBC-Parameter'(Val, TagIn) ->
    {_, Cindex1, Cindex2} = Val,
    %%-------------------------------------------------
    %% attribute rc2ParameterVersion(1) with type INTEGER OPTIONAL
    %%-------------------------------------------------
    {EncBytes1, EncLen1} = case Cindex1 of
			     asn1_NOVALUE -> {<<>>, 0};
			     _ -> encode_integer([], Cindex1, [<<2>>])
			   end,
    %%-------------------------------------------------
    %% attribute iv(2) with type OCTET STRING
    %%-------------------------------------------------
    {EncBytes2, EncLen2} = encode_octet_string([], Cindex2,
					       [<<4>>]),
    BytesSoFar = [EncBytes1, EncBytes2],
    LenSoFar = EncLen1 + EncLen2,
    encode_tags(TagIn, BytesSoFar, LenSoFar).

'dec_RC2-CBC-Parameter'(Tlv) ->
    'dec_RC2-CBC-Parameter'(Tlv, [16]).

'dec_RC2-CBC-Parameter'(Tlv, TagIn) ->
    %%-------------------------------------------------
    %% decode tag and length
    %%-------------------------------------------------
    Tlv1 = match_tags(Tlv, TagIn),
    %%-------------------------------------------------
    %% attribute rc2ParameterVersion(1) with type INTEGER OPTIONAL
    %%-------------------------------------------------
    {Term1, Tlv2} = case Tlv1 of
		      [{2, V1} | TempTlv2] ->
			  {decode_integer(V1, [], []), TempTlv2};
		      _ -> {asn1_NOVALUE, Tlv1}
		    end,
    %%-------------------------------------------------
    %% attribute iv(2) with type OCTET STRING
    %%-------------------------------------------------
    [V2 | Tlv3] = Tlv2,
    Term2 = decode_octet_string(V2, 8, [4]),
    case Tlv3 of
      [] -> true;
      _ ->
	  exit({error,
		{asn1, {unexpected, Tlv3}}}) % extra fields not allowed
    end,
    {'RC2-CBC-Parameter', Term1, Term2}.

%%================================
%%  PBMAC1-params
%%================================
'enc_PBMAC1-params'(Val) ->
    'enc_PBMAC1-params'(Val, [<<48>>]).

'enc_PBMAC1-params'(Val, TagIn) ->
    {_, Cindex1, Cindex2} = Val,
    %%-------------------------------------------------
    %% attribute keyDerivationFunc(1) with type SEQUENCE
    %%-------------------------------------------------
    {EncBytes1, EncLen1} =
	'enc_PBMAC1-params_keyDerivationFunc'(Cindex1,
					      [<<48>>]),
    %%-------------------------------------------------
    %% attribute messageAuthScheme(2) with type SEQUENCE
    %%-------------------------------------------------
    {EncBytes2, EncLen2} =
	'enc_PBMAC1-params_messageAuthScheme'(Cindex2,
					      [<<48>>]),
    BytesSoFar = [EncBytes1, EncBytes2],
    LenSoFar = EncLen1 + EncLen2,
    encode_tags(TagIn, BytesSoFar, LenSoFar).

%%================================
%%  PBMAC1-params_keyDerivationFunc
%%================================
'enc_PBMAC1-params_keyDerivationFunc'(Val, TagIn) ->
    {_, Cindex1, Cindex2} = Val,
    Objalgorithm =
	'PKCS-FRAME':getenc_internal_object_set_argument_1(id,
							   Cindex1),
    %%-------------------------------------------------
    %% attribute algorithm(1) with type fixedtypevaluefieldidtypetagUNIVERSAL6IMPLICIT0OBJECT IDENTIFIERno
    %%-------------------------------------------------
    {EncBytes1, EncLen1} = encode_object_identifier(Cindex1,
						    [<<6>>]),
    %%-------------------------------------------------
    %% attribute parameters(2) with type typefieldType OPTIONAL
    %%-------------------------------------------------
    {EncBytes2, EncLen2} = case Cindex2 of
			     asn1_NOVALUE -> {<<>>, 0};
			     _ ->
				 {TmpBytes, _} = Objalgorithm('Type', Cindex2,
							      []),
				 {TmpBytes1, TmpLen} =
				     encode_open_type(TmpBytes, []),
				 {TmpBytes1, TmpLen}
			   end,
    BytesSoFar = [EncBytes1, EncBytes2],
    LenSoFar = EncLen1 + EncLen2,
    encode_tags(TagIn, BytesSoFar, LenSoFar).

'dec_PBMAC1-params_keyDerivationFunc'(Tlv, TagIn) ->
    %%-------------------------------------------------
    %% decode tag and length
    %%-------------------------------------------------
    Tlv1 = match_tags(Tlv, TagIn),
    %%-------------------------------------------------
    %% attribute algorithm(1) with type fixedtypevaluefieldidtypetagUNIVERSAL6IMPLICIT0OBJECT IDENTIFIERno
    %%-------------------------------------------------
    [V1 | Tlv2] = Tlv1,
    Term1 = decode_object_identifier(V1, [6]),
    %%-------------------------------------------------
    %% attribute parameters(2) with type typefieldType OPTIONAL
    %%-------------------------------------------------
    {Tmpterm1, Tlv3} = case Tlv2 of
			 [V2 | TempTlv3] ->
			     {decode_open_type(V2, [], nif), TempTlv3};
			 _ -> {asn1_NOVALUE, Tlv2}
		       end,
    DecObjalgorithmTerm1 =
	'PKCS-FRAME':getdec_internal_object_set_argument_1(id,
							   Term1),
    Term2 = case Tmpterm1 of
	      asn1_NOVALUE -> asn1_NOVALUE;
	      _ ->
		  case catch DecObjalgorithmTerm1('Type', Tmpterm1, []) of
		    {'EXIT', Reason1} ->
			exit({'Type not compatible with table constraint',
			      Reason1});
		    Tmpterm2 -> Tmpterm2
		  end
	    end,
    case Tlv3 of
      [] -> true;
      _ ->
	  exit({error,
		{asn1, {unexpected, Tlv3}}}) % extra fields not allowed
    end,
    {'PBMAC1-params_keyDerivationFunc', Term1, Term2}.

%%================================
%%  PBMAC1-params_messageAuthScheme
%%================================
'enc_PBMAC1-params_messageAuthScheme'(Val, TagIn) ->
    {_, Cindex1, Cindex2} = Val,
    Objalgorithm =
	'PKCS-FRAME':getenc_internal_object_set_argument_2(id,
							   Cindex1),
    %%-------------------------------------------------
    %% attribute algorithm(1) with type fixedtypevaluefieldidtypetagUNIVERSAL6IMPLICIT0OBJECT IDENTIFIERno
    %%-------------------------------------------------
    {EncBytes1, EncLen1} = encode_object_identifier(Cindex1,
						    [<<6>>]),
    %%-------------------------------------------------
    %% attribute parameters(2) with type typefieldType OPTIONAL
    %%-------------------------------------------------
    {EncBytes2, EncLen2} = case Cindex2 of
			     asn1_NOVALUE -> {<<>>, 0};
			     _ ->
				 {TmpBytes, _} = Objalgorithm('Type', Cindex2,
							      []),
				 {TmpBytes1, TmpLen} =
				     encode_open_type(TmpBytes, []),
				 {TmpBytes1, TmpLen}
			   end,
    BytesSoFar = [EncBytes1, EncBytes2],
    LenSoFar = EncLen1 + EncLen2,
    encode_tags(TagIn, BytesSoFar, LenSoFar).

'dec_PBMAC1-params_messageAuthScheme'(Tlv, TagIn) ->
    %%-------------------------------------------------
    %% decode tag and length
    %%-------------------------------------------------
    Tlv1 = match_tags(Tlv, TagIn),
    %%-------------------------------------------------
    %% attribute algorithm(1) with type fixedtypevaluefieldidtypetagUNIVERSAL6IMPLICIT0OBJECT IDENTIFIERno
    %%-------------------------------------------------
    [V1 | Tlv2] = Tlv1,
    Term1 = decode_object_identifier(V1, [6]),
    %%-------------------------------------------------
    %% attribute parameters(2) with type typefieldType OPTIONAL
    %%-------------------------------------------------
    {Tmpterm1, Tlv3} = case Tlv2 of
			 [V2 | TempTlv3] ->
			     {decode_open_type(V2, [], nif), TempTlv3};
			 _ -> {asn1_NOVALUE, Tlv2}
		       end,
    DecObjalgorithmTerm1 =
	'PKCS-FRAME':getdec_internal_object_set_argument_2(id,
							   Term1),
    Term2 = case Tmpterm1 of
	      asn1_NOVALUE -> asn1_NOVALUE;
	      _ ->
		  case catch DecObjalgorithmTerm1('Type', Tmpterm1, []) of
		    {'EXIT', Reason1} ->
			exit({'Type not compatible with table constraint',
			      Reason1});
		    Tmpterm2 -> Tmpterm2
		  end
	    end,
    case Tlv3 of
      [] -> true;
      _ ->
	  exit({error,
		{asn1, {unexpected, Tlv3}}}) % extra fields not allowed
    end,
    {'PBMAC1-params_messageAuthScheme', Term1, Term2}.

'dec_PBMAC1-params'(Tlv) ->
    'dec_PBMAC1-params'(Tlv, [16]).

'dec_PBMAC1-params'(Tlv, TagIn) ->
    %%-------------------------------------------------
    %% decode tag and length
    %%-------------------------------------------------
    Tlv1 = match_tags(Tlv, TagIn),
    %%-------------------------------------------------
    %% attribute keyDerivationFunc(1) with type SEQUENCE
    %%-------------------------------------------------
    [V1 | Tlv2] = Tlv1,
    Term1 = 'dec_PBMAC1-params_keyDerivationFunc'(V1, [16]),
    %%-------------------------------------------------
    %% attribute messageAuthScheme(2) with type SEQUENCE
    %%-------------------------------------------------
    [V2 | Tlv3] = Tlv2,
    Term2 = 'dec_PBMAC1-params_messageAuthScheme'(V2, [16]),
    case Tlv3 of
      [] -> true;
      _ ->
	  exit({error,
		{asn1, {unexpected, Tlv3}}}) % extra fields not allowed
    end,
    {'PBMAC1-params', Term1, Term2}.

%%================================
%%  PBES2-params
%%================================
'enc_PBES2-params'(Val) ->
    'enc_PBES2-params'(Val, [<<48>>]).

'enc_PBES2-params'(Val, TagIn) ->
    {_, Cindex1, Cindex2} = Val,
    %%-------------------------------------------------
    %% attribute keyDerivationFunc(1) with type SEQUENCE
    %%-------------------------------------------------
    {EncBytes1, EncLen1} =
	'enc_PBES2-params_keyDerivationFunc'(Cindex1, [<<48>>]),
    %%-------------------------------------------------
    %% attribute encryptionScheme(2) with type SEQUENCE
    %%-------------------------------------------------
    {EncBytes2, EncLen2} =
	'enc_PBES2-params_encryptionScheme'(Cindex2, [<<48>>]),
    BytesSoFar = [EncBytes1, EncBytes2],
    LenSoFar = EncLen1 + EncLen2,
    encode_tags(TagIn, BytesSoFar, LenSoFar).

%%================================
%%  PBES2-params_keyDerivationFunc
%%================================
'enc_PBES2-params_keyDerivationFunc'(Val, TagIn) ->
    {_, Cindex1, Cindex2} = Val,
    Objalgorithm =
	'PKCS-FRAME':getenc_internal_object_set_argument_3(id,
							   Cindex1),
    %%-------------------------------------------------
    %% attribute algorithm(1) with type fixedtypevaluefieldidtypetagUNIVERSAL6IMPLICIT0OBJECT IDENTIFIERno
    %%-------------------------------------------------
    {EncBytes1, EncLen1} = encode_object_identifier(Cindex1,
						    [<<6>>]),
    %%-------------------------------------------------
    %% attribute parameters(2) with type typefieldType OPTIONAL
    %%-------------------------------------------------
    {EncBytes2, EncLen2} = case Cindex2 of
			     asn1_NOVALUE -> {<<>>, 0};
			     _ ->
				 {TmpBytes, _} = Objalgorithm('Type', Cindex2,
							      []),
				 {TmpBytes1, TmpLen} =
				     encode_open_type(TmpBytes, []),
				 {TmpBytes1, TmpLen}
			   end,
    BytesSoFar = [EncBytes1, EncBytes2],
    LenSoFar = EncLen1 + EncLen2,
    encode_tags(TagIn, BytesSoFar, LenSoFar).

'dec_PBES2-params_keyDerivationFunc'(Tlv, TagIn) ->
    %%-------------------------------------------------
    %% decode tag and length
    %%-------------------------------------------------
    Tlv1 = match_tags(Tlv, TagIn),
    %%-------------------------------------------------
    %% attribute algorithm(1) with type fixedtypevaluefieldidtypetagUNIVERSAL6IMPLICIT0OBJECT IDENTIFIERno
    %%-------------------------------------------------
    [V1 | Tlv2] = Tlv1,
    Term1 = decode_object_identifier(V1, [6]),
    %%-------------------------------------------------
    %% attribute parameters(2) with type typefieldType OPTIONAL
    %%-------------------------------------------------
    {Tmpterm1, Tlv3} = case Tlv2 of
			 [V2 | TempTlv3] ->
			     {decode_open_type(V2, [], nif), TempTlv3};
			 _ -> {asn1_NOVALUE, Tlv2}
		       end,
    DecObjalgorithmTerm1 =
	'PKCS-FRAME':getdec_internal_object_set_argument_3(id,
							   Term1),
    Term2 = case Tmpterm1 of
	      asn1_NOVALUE -> asn1_NOVALUE;
	      _ ->
		  case catch DecObjalgorithmTerm1('Type', Tmpterm1, []) of
		    {'EXIT', Reason1} ->
			exit({'Type not compatible with table constraint',
			      Reason1});
		    Tmpterm2 -> Tmpterm2
		  end
	    end,
    case Tlv3 of
      [] -> true;
      _ ->
	  exit({error,
		{asn1, {unexpected, Tlv3}}}) % extra fields not allowed
    end,
    {'PBES2-params_keyDerivationFunc', Term1, Term2}.

%%================================
%%  PBES2-params_encryptionScheme
%%================================
'enc_PBES2-params_encryptionScheme'(Val, TagIn) ->
    {_, Cindex1, Cindex2} = Val,
    Objalgorithm =
	'PKCS-FRAME':getenc_internal_object_set_argument_4(id,
							   Cindex1),
    %%-------------------------------------------------
    %% attribute algorithm(1) with type fixedtypevaluefieldidtypetagUNIVERSAL6IMPLICIT0OBJECT IDENTIFIERno
    %%-------------------------------------------------
    {EncBytes1, EncLen1} = encode_object_identifier(Cindex1,
						    [<<6>>]),
    %%-------------------------------------------------
    %% attribute parameters(2) with type typefieldType OPTIONAL
    %%-------------------------------------------------
    {EncBytes2, EncLen2} = case Cindex2 of
			     asn1_NOVALUE -> {<<>>, 0};
			     _ ->
				 {TmpBytes, _} = Objalgorithm('Type', Cindex2,
							      []),
				 {TmpBytes1, TmpLen} =
				     encode_open_type(TmpBytes, []),
				 {TmpBytes1, TmpLen}
			   end,
    BytesSoFar = [EncBytes1, EncBytes2],
    LenSoFar = EncLen1 + EncLen2,
    encode_tags(TagIn, BytesSoFar, LenSoFar).

'dec_PBES2-params_encryptionScheme'(Tlv, TagIn) ->
    %%-------------------------------------------------
    %% decode tag and length
    %%-------------------------------------------------
    Tlv1 = match_tags(Tlv, TagIn),
    %%-------------------------------------------------
    %% attribute algorithm(1) with type fixedtypevaluefieldidtypetagUNIVERSAL6IMPLICIT0OBJECT IDENTIFIERno
    %%-------------------------------------------------
    [V1 | Tlv2] = Tlv1,
    Term1 = decode_object_identifier(V1, [6]),
    %%-------------------------------------------------
    %% attribute parameters(2) with type typefieldType OPTIONAL
    %%-------------------------------------------------
    {Tmpterm1, Tlv3} = case Tlv2 of
			 [V2 | TempTlv3] ->
			     {decode_open_type(V2, [], nif), TempTlv3};
			 _ -> {asn1_NOVALUE, Tlv2}
		       end,
    DecObjalgorithmTerm1 =
	'PKCS-FRAME':getdec_internal_object_set_argument_4(id,
							   Term1),
    Term2 = case Tmpterm1 of
	      asn1_NOVALUE -> asn1_NOVALUE;
	      _ ->
		  case catch DecObjalgorithmTerm1('Type', Tmpterm1, []) of
		    {'EXIT', Reason1} ->
			exit({'Type not compatible with table constraint',
			      Reason1});
		    Tmpterm2 -> Tmpterm2
		  end
	    end,
    case Tlv3 of
      [] -> true;
      _ ->
	  exit({error,
		{asn1, {unexpected, Tlv3}}}) % extra fields not allowed
    end,
    {'PBES2-params_encryptionScheme', Term1, Term2}.

'dec_PBES2-params'(Tlv) ->
    'dec_PBES2-params'(Tlv, [16]).

'dec_PBES2-params'(Tlv, TagIn) ->
    %%-------------------------------------------------
    %% decode tag and length
    %%-------------------------------------------------
    Tlv1 = match_tags(Tlv, TagIn),
    %%-------------------------------------------------
    %% attribute keyDerivationFunc(1) with type SEQUENCE
    %%-------------------------------------------------
    [V1 | Tlv2] = Tlv1,
    Term1 = 'dec_PBES2-params_keyDerivationFunc'(V1, [16]),
    %%-------------------------------------------------
    %% attribute encryptionScheme(2) with type SEQUENCE
    %%-------------------------------------------------
    [V2 | Tlv3] = Tlv2,
    Term2 = 'dec_PBES2-params_encryptionScheme'(V2, [16]),
    case Tlv3 of
      [] -> true;
      _ ->
	  exit({error,
		{asn1, {unexpected, Tlv3}}}) % extra fields not allowed
    end,
    {'PBES2-params', Term1, Term2}.

%%================================
%%  PBEParameter
%%================================
enc_PBEParameter(Val) ->
    enc_PBEParameter(Val, [<<48>>]).

enc_PBEParameter(Val, TagIn) ->
    {_, Cindex1, Cindex2} = Val,
    %%-------------------------------------------------
    %% attribute salt(1) with type OCTET STRING
    %%-------------------------------------------------
    {EncBytes1, EncLen1} = encode_octet_string([], Cindex1,
					       [<<4>>]),
    %%-------------------------------------------------
    %% attribute iterationCount(2) with type INTEGER
    %%-------------------------------------------------
    {EncBytes2, EncLen2} = encode_integer([], Cindex2,
					  [<<2>>]),
    BytesSoFar = [EncBytes1, EncBytes2],
    LenSoFar = EncLen1 + EncLen2,
    encode_tags(TagIn, BytesSoFar, LenSoFar).

dec_PBEParameter(Tlv) -> dec_PBEParameter(Tlv, [16]).

dec_PBEParameter(Tlv, TagIn) ->
    %%-------------------------------------------------
    %% decode tag and length
    %%-------------------------------------------------
    Tlv1 = match_tags(Tlv, TagIn),
    %%-------------------------------------------------
    %% attribute salt(1) with type OCTET STRING
    %%-------------------------------------------------
    [V1 | Tlv2] = Tlv1,
    Term1 = decode_octet_string(V1, 8, [4]),
    %%-------------------------------------------------
    %% attribute iterationCount(2) with type INTEGER
    %%-------------------------------------------------
    [V2 | Tlv3] = Tlv2,
    Term2 = decode_integer(V2, [], [2]),
    case Tlv3 of
      [] -> true;
      _ ->
	  exit({error,
		{asn1, {unexpected, Tlv3}}}) % extra fields not allowed
    end,
    {'PBEParameter', Term1, Term2}.

%%================================
%%  PBKDF2-params
%%================================
'enc_PBKDF2-params'(Val) ->
    'enc_PBKDF2-params'(Val, [<<48>>]).

'enc_PBKDF2-params'(Val, TagIn) ->
    {_, Cindex1, Cindex2, Cindex3, Cindex4} = Val,
    %%-------------------------------------------------
    %% attribute salt(1) with type CHOICE
    %%-------------------------------------------------
    {EncBytes1, EncLen1} = 'enc_PBKDF2-params_salt'(Cindex1,
						    []),
    %%-------------------------------------------------
    %% attribute iterationCount(2) with type INTEGER
    %%-------------------------------------------------
    {EncBytes2, EncLen2} = encode_integer([], Cindex2,
					  [<<2>>]),
    %%-------------------------------------------------
    %% attribute keyLength(3) with type INTEGER OPTIONAL
    %%-------------------------------------------------
    {EncBytes3, EncLen3} = case Cindex3 of
			     asn1_NOVALUE -> {<<>>, 0};
			     _ -> encode_integer([], Cindex3, [<<2>>])
			   end,
    %%-------------------------------------------------
    %% attribute prf(4) with type SEQUENCE DEFAULT = {'PBKDF2-params_prf',{'Externalvaluereference',47,'PKCS5v2-0','id-hmacWithSHA1'},'NULL'}
    %%-------------------------------------------------
    {EncBytes4, EncLen4} = case catch
				  'check_PBKDF2-params_prf'({'PBKDF2-params_prf',
							     {'Externalvaluereference',
							      47, 'PKCS5v2-0',
							      'id-hmacWithSHA1'},
							     'NULL'},
							    Cindex4)
			       of
			     true -> {[], 0};
			     _ -> 'enc_PBKDF2-params_prf'(Cindex4, [<<48>>])
			   end,
    BytesSoFar = [EncBytes1, EncBytes2, EncBytes3,
		  EncBytes4],
    LenSoFar = EncLen1 + EncLen2 + EncLen3 + EncLen4,
    encode_tags(TagIn, BytesSoFar, LenSoFar).

%%================================
%%  PBKDF2-params_salt
%%================================

'enc_PBKDF2-params_salt'({'PBKDF2-params_salt', Val},
			 TagIn) ->
    'enc_PBKDF2-params_salt'(Val, TagIn);
'enc_PBKDF2-params_salt'(Val, TagIn) ->
    {EncBytes, EncLen} = case element(1, Val) of
			   specified ->
			       encode_octet_string([], element(2, Val),
						   [<<4>>]);
			   otherSource ->
			       'enc_PBKDF2-params_salt_otherSource'(element(2,
									    Val),
								    [<<48>>]);
			   Else ->
			       exit({error,
				     {asn1, {invalid_choice_type, Else}}})
			 end,
    encode_tags(TagIn, EncBytes, EncLen).

%%================================
%%  PBKDF2-params_salt_otherSource
%%================================
'enc_PBKDF2-params_salt_otherSource'(Val, TagIn) ->
    {_, Cindex1, Cindex2} = Val,
    Objalgorithm =
	'PKCS-FRAME':getenc_internal_object_set_argument_5(id,
							   Cindex1),
    %%-------------------------------------------------
    %% attribute algorithm(1) with type fixedtypevaluefieldidtypetagUNIVERSAL6IMPLICIT0OBJECT IDENTIFIERno
    %%-------------------------------------------------
    {EncBytes1, EncLen1} = encode_object_identifier(Cindex1,
						    [<<6>>]),
    %%-------------------------------------------------
    %% attribute parameters(2) with type typefieldType OPTIONAL
    %%-------------------------------------------------
    {EncBytes2, EncLen2} = case Cindex2 of
			     asn1_NOVALUE -> {<<>>, 0};
			     _ ->
				 {TmpBytes, _} = Objalgorithm('Type', Cindex2,
							      []),
				 {TmpBytes1, TmpLen} =
				     encode_open_type(TmpBytes, []),
				 {TmpBytes1, TmpLen}
			   end,
    BytesSoFar = [EncBytes1, EncBytes2],
    LenSoFar = EncLen1 + EncLen2,
    encode_tags(TagIn, BytesSoFar, LenSoFar).

'dec_PBKDF2-params_salt_otherSource'(Tlv, TagIn) ->
    %%-------------------------------------------------
    %% decode tag and length
    %%-------------------------------------------------
    Tlv1 = match_tags(Tlv, TagIn),
    %%-------------------------------------------------
    %% attribute algorithm(1) with type fixedtypevaluefieldidtypetagUNIVERSAL6IMPLICIT0OBJECT IDENTIFIERno
    %%-------------------------------------------------
    [V1 | Tlv2] = Tlv1,
    Term1 = decode_object_identifier(V1, [6]),
    %%-------------------------------------------------
    %% attribute parameters(2) with type typefieldType OPTIONAL
    %%-------------------------------------------------
    {Tmpterm1, Tlv3} = case Tlv2 of
			 [V2 | TempTlv3] ->
			     {decode_open_type(V2, [], nif), TempTlv3};
			 _ -> {asn1_NOVALUE, Tlv2}
		       end,
    DecObjalgorithmTerm1 =
	'PKCS-FRAME':getdec_internal_object_set_argument_5(id,
							   Term1),
    Term2 = case Tmpterm1 of
	      asn1_NOVALUE -> asn1_NOVALUE;
	      _ ->
		  case catch DecObjalgorithmTerm1('Type', Tmpterm1, []) of
		    {'EXIT', Reason1} ->
			exit({'Type not compatible with table constraint',
			      Reason1});
		    Tmpterm2 -> Tmpterm2
		  end
	    end,
    case Tlv3 of
      [] -> true;
      _ ->
	  exit({error,
		{asn1, {unexpected, Tlv3}}}) % extra fields not allowed
    end,
    {'PBKDF2-params_salt_otherSource', Term1, Term2}.

'dec_PBKDF2-params_salt'(Tlv, TagIn) ->
    Tlv1 = match_tags(Tlv, TagIn),
    case case Tlv1 of
	   [CtempTlv1] -> CtempTlv1;
	   _ -> Tlv1
	 end
	of
      %% 'specified'
      {4, V1} -> {specified, decode_octet_string(V1, [], [])};
      %% 'otherSource'
      {16, V1} ->
	  {otherSource,
	   'dec_PBKDF2-params_salt_otherSource'(V1, [])};
      Else ->
	  exit({error, {asn1, {invalid_choice_tag, Else}}})
    end.

%%================================
%%  PBKDF2-params_prf
%%================================
'enc_PBKDF2-params_prf'(Val, TagIn) ->
    {_, Cindex1, Cindex2} = Val,
    Objalgorithm =
	'PKCS-FRAME':getenc_internal_object_set_argument_6(id,
							   Cindex1),
    %%-------------------------------------------------
    %% attribute algorithm(1) with type fixedtypevaluefieldidtypetagUNIVERSAL6IMPLICIT0OBJECT IDENTIFIERno
    %%-------------------------------------------------
    {EncBytes1, EncLen1} = encode_object_identifier(Cindex1,
						    [<<6>>]),
    %%-------------------------------------------------
    %% attribute parameters(2) with type typefieldType OPTIONAL
    %%-------------------------------------------------
    {EncBytes2, EncLen2} = case Cindex2 of
			     asn1_NOVALUE -> {<<>>, 0};
			     _ ->
				 {TmpBytes, _} = Objalgorithm('Type', Cindex2,
							      []),
				 {TmpBytes1, TmpLen} =
				     encode_open_type(TmpBytes, []),
				 {TmpBytes1, TmpLen}
			   end,
    BytesSoFar = [EncBytes1, EncBytes2],
    LenSoFar = EncLen1 + EncLen2,
    encode_tags(TagIn, BytesSoFar, LenSoFar).

'dec_PBKDF2-params_prf'(Tlv, TagIn) ->
    %%-------------------------------------------------
    %% decode tag and length
    %%-------------------------------------------------
    Tlv1 = match_tags(Tlv, TagIn),
    %%-------------------------------------------------
    %% attribute algorithm(1) with type fixedtypevaluefieldidtypetagUNIVERSAL6IMPLICIT0OBJECT IDENTIFIERno
    %%-------------------------------------------------
    [V1 | Tlv2] = Tlv1,
    Term1 = decode_object_identifier(V1, [6]),
    %%-------------------------------------------------
    %% attribute parameters(2) with type typefieldType OPTIONAL
    %%-------------------------------------------------
    {Tmpterm1, Tlv3} = case Tlv2 of
			 [V2 | TempTlv3] ->
			     {decode_open_type(V2, [], nif), TempTlv3};
			 _ -> {asn1_NOVALUE, Tlv2}
		       end,
    DecObjalgorithmTerm1 =
	'PKCS-FRAME':getdec_internal_object_set_argument_6(id,
							   Term1),
    Term2 = case Tmpterm1 of
	      asn1_NOVALUE -> asn1_NOVALUE;
	      _ ->
		  case catch DecObjalgorithmTerm1('Type', Tmpterm1, []) of
		    {'EXIT', Reason1} ->
			exit({'Type not compatible with table constraint',
			      Reason1});
		    Tmpterm2 -> Tmpterm2
		  end
	    end,
    case Tlv3 of
      [] -> true;
      _ ->
	  exit({error,
		{asn1, {unexpected, Tlv3}}}) % extra fields not allowed
    end,
    {'PBKDF2-params_prf', Term1, Term2}.

'dec_PBKDF2-params'(Tlv) ->
    'dec_PBKDF2-params'(Tlv, [16]).

'dec_PBKDF2-params'(Tlv, TagIn) ->
    %%-------------------------------------------------
    %% decode tag and length
    %%-------------------------------------------------
    Tlv1 = match_tags(Tlv, TagIn),
    %%-------------------------------------------------
    %% attribute salt(1) with type CHOICE
    %%-------------------------------------------------
    [V1 | Tlv2] = Tlv1,
    Term1 = 'dec_PBKDF2-params_salt'(V1, []),
    %%-------------------------------------------------
    %% attribute iterationCount(2) with type INTEGER
    %%-------------------------------------------------
    [V2 | Tlv3] = Tlv2,
    Term2 = decode_integer(V2, {1, 'MAX'}, [2]),
    %%-------------------------------------------------
    %% attribute keyLength(3) with type INTEGER OPTIONAL
    %%-------------------------------------------------
    {Term3, Tlv4} = case Tlv3 of
		      [{2, V3} | TempTlv4] ->
			  {decode_integer(V3, {1, 'MAX'}, []), TempTlv4};
		      _ -> {asn1_NOVALUE, Tlv3}
		    end,
    %%-------------------------------------------------
    %% attribute prf(4) with type SEQUENCE DEFAULT = {'PBKDF2-params_prf',{'Externalvaluereference',47,'PKCS5v2-0','id-hmacWithSHA1'},'NULL'}
    %%-------------------------------------------------
    {Term4, Tlv5} = case Tlv4 of
		      [{16, V4} | TempTlv5] ->
			  {'dec_PBKDF2-params_prf'(V4, []), TempTlv5};
		      _ ->
			  {{'PBKDF2-params_prf',
			    {'Externalvaluereference', 47, 'PKCS5v2-0',
			     'id-hmacWithSHA1'},
			    'NULL'},
			   Tlv4}
		    end,
    case Tlv5 of
      [] -> true;
      _ ->
	  exit({error,
		{asn1, {unexpected, Tlv5}}}) % extra fields not allowed
    end,
    {'PBKDF2-params', Term1, Term2, Term3, Term4}.

%%================================
%%  AttributeUsage
%%================================
enc_AttributeUsage(Val) ->
    enc_AttributeUsage(Val, [<<10>>]).

enc_AttributeUsage({'AttributeUsage', Val}, TagIn) ->
    enc_AttributeUsage(Val, TagIn);
enc_AttributeUsage(Val, TagIn) ->
    case Val of
      userApplications -> encode_enumerated(0, TagIn);
      directoryOperation -> encode_enumerated(1, TagIn);
      distributedOperation -> encode_enumerated(2, TagIn);
      dSAOperation -> encode_enumerated(3, TagIn);
      Enumval1 ->
	  exit({error,
		{asn1, {enumerated_not_in_range, Enumval1}}})
    end.

dec_AttributeUsage(Tlv) ->
    dec_AttributeUsage(Tlv, [10]).

dec_AttributeUsage(Tlv, TagIn) ->
    decode_enumerated(Tlv, [],
		      [{userApplications, 0}, {directoryOperation, 1},
		       {distributedOperation, 2}, {dSAOperation, 3}],
		      TagIn).

%%================================
%%  Context
%%================================
enc_Context(Val) -> enc_Context(Val, [<<48>>]).

enc_Context(Val, TagIn) ->
    {_, Cindex1, Cindex2, Cindex3} = Val,
    ObjcontextType =
	'PKCS-FRAME':getenc_SupportedContexts(id, Cindex1),
    %%-------------------------------------------------
    %% attribute contextType(1) with type fixedtypevaluefieldidtypetagUNIVERSAL6IMPLICIT0OBJECT IDENTIFIERno
    %%-------------------------------------------------
    {EncBytes1, EncLen1} = encode_object_identifier(Cindex1,
						    [<<6>>]),
    %%-------------------------------------------------
    %% attribute contextValues(2) with type SET OF
    %%-------------------------------------------------
    {EncBytes2, EncLen2} =
	enc_Context_contextValues(Cindex2, [<<49>>],
				  ObjcontextType),
    %%-------------------------------------------------
    %% attribute fallback(3) with type BOOLEAN DEFAULT = false
    %%-------------------------------------------------
    {EncBytes3, EncLen3} = case catch check_bool(false,
						 Cindex3)
			       of
			     true -> {[], 0};
			     _ -> encode_boolean(Cindex3, [<<1>>])
			   end,
    BytesSoFar = [EncBytes1, EncBytes2, EncBytes3],
    LenSoFar = EncLen1 + EncLen2 + EncLen3,
    encode_tags(TagIn, BytesSoFar, LenSoFar).

%%================================
%%  Context_contextValues
%%================================

enc_Context_contextValues({'Context_contextValues',
			   Val},
			  TagIn, ObjFun) ->
    enc_Context_contextValues(Val, TagIn, ObjFun);
enc_Context_contextValues(Val, TagIn, ObjFun) ->
    {EncBytes, EncLen} =
	enc_Context_contextValues_components(Val, ObjFun, [],
					     0),
    encode_tags(TagIn, EncBytes, EncLen).

enc_Context_contextValues_components([], _, AccBytes,
				     AccLen) ->
    {dynamicsort_SETOF(AccBytes), AccLen};
enc_Context_contextValues_components([H | T], ObjFun,
				     AccBytes, AccLen) ->
    {TmpBytes1, _} = ObjFun('Type', H, []),
    {EncBytes, EncLen} = encode_open_type(TmpBytes1, []),
    enc_Context_contextValues_components(T, ObjFun,
					 [EncBytes | AccBytes],
					 AccLen + EncLen).

dec_Context_contextValues(Tlv, TagIn, ObjFun) ->
    %%-------------------------------------------------
    %% decode tag and length
    %%-------------------------------------------------
    Tlv1 = match_tags(Tlv, TagIn),
    [decode_open_type(V1, [], nif) || V1 <- Tlv1].

dec_Context(Tlv) -> dec_Context(Tlv, [16]).

dec_Context(Tlv, TagIn) ->
    %%-------------------------------------------------
    %% decode tag and length
    %%-------------------------------------------------
    Tlv1 = match_tags(Tlv, TagIn),
    %%-------------------------------------------------
    %% attribute contextType(1) with type fixedtypevaluefieldidtypetagUNIVERSAL6IMPLICIT0OBJECT IDENTIFIERno
    %%-------------------------------------------------
    [V1 | Tlv2] = Tlv1,
    Term1 = decode_object_identifier(V1, [6]),
    ObjFun = 'PKCS-FRAME':getdec_SupportedContexts(id,
						   Term1),
    %%-------------------------------------------------
    %% attribute contextValues(2) with type SET OF
    %%-------------------------------------------------
    [V2 | Tlv3] = Tlv2,
    Term2 = dec_Context_contextValues(V2, [17], ObjFun),
    %%-------------------------------------------------
    %% attribute fallback(3) with type BOOLEAN DEFAULT = false
    %%-------------------------------------------------
    {Term3, Tlv4} = case Tlv3 of
		      [{1, V3} | TempTlv4] ->
			  {decode_boolean(V3, []), TempTlv4};
		      _ -> {false, Tlv3}
		    end,
    case Tlv4 of
      [] -> true;
      _ ->
	  exit({error,
		{asn1, {unexpected, Tlv4}}}) % extra fields not allowed
    end,
    {'Context', Term1, Term2, Term3}.

%%================================
%%  EncryptedData
%%================================
enc_EncryptedData(Val) ->
    enc_EncryptedData(Val, [<<4>>]).

enc_EncryptedData({'EncryptedData', Val}, TagIn) ->
    enc_EncryptedData(Val, TagIn);
enc_EncryptedData(Val, TagIn) ->
    encode_octet_string([], Val, TagIn).

dec_EncryptedData(Tlv) -> dec_EncryptedData(Tlv, [4]).

dec_EncryptedData(Tlv, TagIn) ->
    decode_octet_string(Tlv, [], TagIn).

%%================================
%%  EncryptedPrivateKeyInfo
%%================================
enc_EncryptedPrivateKeyInfo(Val) ->
    enc_EncryptedPrivateKeyInfo(Val, [<<48>>]).

enc_EncryptedPrivateKeyInfo(Val, TagIn) ->
    {_, Cindex1, Cindex2} = Val,
    %%-------------------------------------------------
    %% attribute encryptionAlgorithm(1) with type SEQUENCE
    %%-------------------------------------------------
    {EncBytes1, EncLen1} =
	enc_EncryptedPrivateKeyInfo_encryptionAlgorithm(Cindex1,
							[<<48>>]),
    %%-------------------------------------------------
    %% attribute encryptedData(2) with type OCTET STRING
    %%-------------------------------------------------
    {EncBytes2, EncLen2} = encode_octet_string([], Cindex2,
					       [<<4>>]),
    BytesSoFar = [EncBytes1, EncBytes2],
    LenSoFar = EncLen1 + EncLen2,
    encode_tags(TagIn, BytesSoFar, LenSoFar).

%%================================
%%  EncryptedPrivateKeyInfo_encryptionAlgorithm
%%================================
enc_EncryptedPrivateKeyInfo_encryptionAlgorithm(Val,
						TagIn) ->
    {_, Cindex1, Cindex2} = Val,
    Objalgorithm =
	'PKCS-FRAME':getenc_internal_object_set_argument_7(id,
							   Cindex1),
    %%-------------------------------------------------
    %% attribute algorithm(1) with type fixedtypevaluefieldidtypetagUNIVERSAL6IMPLICIT0OBJECT IDENTIFIERno
    %%-------------------------------------------------
    {EncBytes1, EncLen1} = encode_object_identifier(Cindex1,
						    [<<6>>]),
    %%-------------------------------------------------
    %% attribute parameters(2) with type typefieldType OPTIONAL
    %%-------------------------------------------------
    {EncBytes2, EncLen2} = case Cindex2 of
			     asn1_NOVALUE -> {<<>>, 0};
			     _ ->
				 {TmpBytes, _} = Objalgorithm('Type', Cindex2,
							      []),
				 {TmpBytes1, TmpLen} =
				     encode_open_type(TmpBytes, []),
				 {TmpBytes1, TmpLen}
			   end,
    BytesSoFar = [EncBytes1, EncBytes2],
    LenSoFar = EncLen1 + EncLen2,
    encode_tags(TagIn, BytesSoFar, LenSoFar).

dec_EncryptedPrivateKeyInfo_encryptionAlgorithm(Tlv,
						TagIn) ->
    %%-------------------------------------------------
    %% decode tag and length
    %%-------------------------------------------------
    Tlv1 = match_tags(Tlv, TagIn),
    %%-------------------------------------------------
    %% attribute algorithm(1) with type fixedtypevaluefieldidtypetagUNIVERSAL6IMPLICIT0OBJECT IDENTIFIERno
    %%-------------------------------------------------
    [V1 | Tlv2] = Tlv1,
    Term1 = decode_object_identifier(V1, [6]),
    %%-------------------------------------------------
    %% attribute parameters(2) with type typefieldType OPTIONAL
    %%-------------------------------------------------
    {Tmpterm1, Tlv3} = case Tlv2 of
			 [V2 | TempTlv3] ->
			     {decode_open_type(V2, [], nif), TempTlv3};
			 _ -> {asn1_NOVALUE, Tlv2}
		       end,
    DecObjalgorithmTerm1 =
	'PKCS-FRAME':getdec_internal_object_set_argument_7(id,
							   Term1),
    Term2 = case Tmpterm1 of
	      asn1_NOVALUE -> asn1_NOVALUE;
	      _ ->
		  case catch DecObjalgorithmTerm1('Type', Tmpterm1, []) of
		    {'EXIT', Reason1} ->
			exit({'Type not compatible with table constraint',
			      Reason1});
		    Tmpterm2 -> Tmpterm2
		  end
	    end,
    case Tlv3 of
      [] -> true;
      _ ->
	  exit({error,
		{asn1, {unexpected, Tlv3}}}) % extra fields not allowed
    end,
    {'EncryptedPrivateKeyInfo_encryptionAlgorithm', Term1,
     Term2}.

dec_EncryptedPrivateKeyInfo(Tlv) ->
    dec_EncryptedPrivateKeyInfo(Tlv, [16]).

dec_EncryptedPrivateKeyInfo(Tlv, TagIn) ->
    %%-------------------------------------------------
    %% decode tag and length
    %%-------------------------------------------------
    Tlv1 = match_tags(Tlv, TagIn),
    %%-------------------------------------------------
    %% attribute encryptionAlgorithm(1) with type SEQUENCE
    %%-------------------------------------------------
    [V1 | Tlv2] = Tlv1,
    Term1 =
	dec_EncryptedPrivateKeyInfo_encryptionAlgorithm(V1,
							[16]),
    %%-------------------------------------------------
    %% attribute encryptedData(2) with type OCTET STRING
    %%-------------------------------------------------
    [V2 | Tlv3] = Tlv2,
    Term2 = decode_octet_string(V2, [], [4]),
    case Tlv3 of
      [] -> true;
      _ ->
	  exit({error,
		{asn1, {unexpected, Tlv3}}}) % extra fields not allowed
    end,
    {'EncryptedPrivateKeyInfo', Term1, Term2}.

%%================================
%%  Attributes
%%================================
enc_Attributes(Val) -> enc_Attributes(Val, [<<49>>]).

enc_Attributes({'Attributes', Val}, TagIn) ->
    enc_Attributes(Val, TagIn);
enc_Attributes(Val, TagIn) ->
    {EncBytes, EncLen} = enc_Attributes_components(Val, [],
						   0),
    encode_tags(TagIn, EncBytes, EncLen).

enc_Attributes_components([], AccBytes, AccLen) ->
    {dynamicsort_SETOF(AccBytes), AccLen};
enc_Attributes_components([H | T], AccBytes, AccLen) ->
    {EncBytes, EncLen} = enc_Attributes_PKAttribute(H,
						    [<<48>>]),
    enc_Attributes_components(T, [EncBytes | AccBytes],
			      AccLen + EncLen).

%%================================
%%  Attributes_PKAttribute
%%================================
enc_Attributes_PKAttribute(Val, TagIn) ->
    {_, Cindex1, Cindex2, Cindex3} = Val,
    Objtype =
	'PKCS-FRAME':getenc_internal_object_set_argument_8(id,
							   Cindex1),
    %%-------------------------------------------------
    %% attribute type(1) with type fixedtypevaluefieldidtypetagUNIVERSAL6IMPLICIT0OBJECT IDENTIFIERno
    %%-------------------------------------------------
    {EncBytes1, EncLen1} = encode_object_identifier(Cindex1,
						    [<<6>>]),
    %%-------------------------------------------------
    %% attribute values(2) with type SET OF
    %%-------------------------------------------------
    {EncBytes2, EncLen2} =
	enc_Attributes_PKAttribute_values(Cindex2, [<<49>>],
					  Objtype),
    %%-------------------------------------------------
    %% attribute valuesWithContext(3) with type SET OF OPTIONAL
    %%-------------------------------------------------
    {EncBytes3, EncLen3} = case Cindex3 of
			     asn1_NOVALUE -> {<<>>, 0};
			     _ ->
				 enc_Attributes_PKAttribute_valuesWithContext(Cindex3,
									      [<<49>>],
									      Objtype)
			   end,
    BytesSoFar = [EncBytes1, EncBytes2, EncBytes3],
    LenSoFar = EncLen1 + EncLen2 + EncLen3,
    encode_tags(TagIn, BytesSoFar, LenSoFar).

%%================================
%%  Attributes_PKAttribute_values
%%================================

enc_Attributes_PKAttribute_values({'Attributes_PKAttribute_values',
				   Val},
				  TagIn, ObjFun) ->
    enc_Attributes_PKAttribute_values(Val, TagIn, ObjFun);
enc_Attributes_PKAttribute_values(Val, TagIn, ObjFun) ->
    {EncBytes, EncLen} =
	enc_Attributes_PKAttribute_values_components(Val,
						     ObjFun, [], 0),
    encode_tags(TagIn, EncBytes, EncLen).

enc_Attributes_PKAttribute_values_components([], _,
					     AccBytes, AccLen) ->
    {dynamicsort_SETOF(AccBytes), AccLen};
enc_Attributes_PKAttribute_values_components([H | T],
					     ObjFun, AccBytes, AccLen) ->
    {TmpBytes1, _} = ObjFun('Type', H, []),
    {EncBytes, EncLen} = encode_open_type(TmpBytes1, []),
    enc_Attributes_PKAttribute_values_components(T, ObjFun,
						 [EncBytes | AccBytes],
						 AccLen + EncLen).

dec_Attributes_PKAttribute_values(Tlv, TagIn, ObjFun) ->
    %%-------------------------------------------------
    %% decode tag and length
    %%-------------------------------------------------
    Tlv1 = match_tags(Tlv, TagIn),
    [decode_open_type(V1, [], nif) || V1 <- Tlv1].

%%================================
%%  Attributes_PKAttribute_valuesWithContext
%%================================

enc_Attributes_PKAttribute_valuesWithContext({'Attributes_PKAttribute_valuesWithContext',
					      Val},
					     TagIn, ObjFun) ->
    enc_Attributes_PKAttribute_valuesWithContext(Val, TagIn,
						 ObjFun);
enc_Attributes_PKAttribute_valuesWithContext(Val, TagIn,
					     ObjFun) ->
    {EncBytes, EncLen} =
	enc_Attributes_PKAttribute_valuesWithContext_components(Val,
								ObjFun, [], 0),
    encode_tags(TagIn, EncBytes, EncLen).

enc_Attributes_PKAttribute_valuesWithContext_components([],
							_, AccBytes, AccLen) ->
    {dynamicsort_SETOF(AccBytes), AccLen};
enc_Attributes_PKAttribute_valuesWithContext_components([H
							 | T],
							ObjFun, AccBytes,
							AccLen) ->
    {EncBytes, EncLen} =
	enc_Attributes_PKAttribute_valuesWithContext_SETOF(H,
							   [<<48>>], ObjFun),
    enc_Attributes_PKAttribute_valuesWithContext_components(T,
							    ObjFun,
							    [EncBytes
							     | AccBytes],
							    AccLen + EncLen).

%%================================
%%  Attributes_PKAttribute_valuesWithContext_SETOF
%%================================
enc_Attributes_PKAttribute_valuesWithContext_SETOF(Val,
						   TagIn, ObjFun) ->
    {_, Cindex1, Cindex2} = Val,
    %%-------------------------------------------------
    %% attribute value(1) with type typefieldType
    %%-------------------------------------------------
    {TmpBytes1, _} = ObjFun('Type', Cindex1, []),
    {EncBytes1, EncLen1} = encode_open_type(TmpBytes1, []),
    %%-------------------------------------------------
    %% attribute contextList(2) with type SET OF
    %%-------------------------------------------------
    {EncBytes2, EncLen2} =
	enc_Attributes_PKAttribute_valuesWithContext_SETOF_contextList(Cindex2,
								       [<<49>>]),
    BytesSoFar = [EncBytes1, EncBytes2],
    LenSoFar = EncLen1 + EncLen2,
    encode_tags(TagIn, BytesSoFar, LenSoFar).

%%================================
%%  Attributes_PKAttribute_valuesWithContext_SETOF_contextList
%%================================

enc_Attributes_PKAttribute_valuesWithContext_SETOF_contextList({'Attributes_PKAttribute_valuesWithContext_SETOF_contextList',
								Val},
							       TagIn) ->
    enc_Attributes_PKAttribute_valuesWithContext_SETOF_contextList(Val,
								   TagIn);
enc_Attributes_PKAttribute_valuesWithContext_SETOF_contextList(Val,
							       TagIn) ->
    {EncBytes, EncLen} =
	enc_Attributes_PKAttribute_valuesWithContext_SETOF_contextList_components(Val,
										  [],
										  0),
    encode_tags(TagIn, EncBytes, EncLen).

enc_Attributes_PKAttribute_valuesWithContext_SETOF_contextList_components([],
									  AccBytes,
									  AccLen) ->
    {dynamicsort_SETOF(AccBytes), AccLen};
enc_Attributes_PKAttribute_valuesWithContext_SETOF_contextList_components([H
									   | T],
									  AccBytes,
									  AccLen) ->
    {EncBytes, EncLen} = enc_Context(H, [<<48>>]),
    enc_Attributes_PKAttribute_valuesWithContext_SETOF_contextList_components(T,
									      [EncBytes
									       | AccBytes],
									      AccLen
										+
										EncLen).

dec_Attributes_PKAttribute_valuesWithContext_SETOF_contextList(Tlv,
							       TagIn) ->
    %%-------------------------------------------------
    %% decode tag and length
    %%-------------------------------------------------
    Tlv1 = match_tags(Tlv, TagIn),
    [dec_Context(V1, [16]) || V1 <- Tlv1].

dec_Attributes_PKAttribute_valuesWithContext_SETOF(Tlv,
						   TagIn, ObjFun) ->
    %%-------------------------------------------------
    %% decode tag and length
    %%-------------------------------------------------
    Tlv1 = match_tags(Tlv, TagIn),
    %%-------------------------------------------------
    %% attribute value(1) with type typefieldType
    %%-------------------------------------------------
    [V1 | Tlv2] = Tlv1,
    Term1 = begin
	      Tmptlv1 = decode_open_type(V1, [], nif),
	      case catch ObjFun('Type', Tmptlv1, []) of
		{'EXIT', Reason1} ->
		    exit({'Type not compatible with table constraint',
			  Reason1});
		Tmpterm1 -> Tmpterm1
	      end
	    end,
    %%-------------------------------------------------
    %% attribute contextList(2) with type SET OF
    %%-------------------------------------------------
    [V2 | Tlv3] = Tlv2,
    Term2 =
	dec_Attributes_PKAttribute_valuesWithContext_SETOF_contextList(V2,
								       [17]),
    case Tlv3 of
      [] -> true;
      _ ->
	  exit({error,
		{asn1, {unexpected, Tlv3}}}) % extra fields not allowed
    end,
    {'Attributes_PKAttribute_valuesWithContext_SETOF',
     Term1, Term2}.

dec_Attributes_PKAttribute_valuesWithContext(Tlv, TagIn,
					     ObjFun) ->
    %%-------------------------------------------------
    %% decode tag and length
    %%-------------------------------------------------
    Tlv1 = match_tags(Tlv, TagIn),
    [dec_Attributes_PKAttribute_valuesWithContext_SETOF(V1,
							[16], ObjFun)
     || V1 <- Tlv1].

dec_Attributes_PKAttribute(Tlv, TagIn) ->
    %%-------------------------------------------------
    %% decode tag and length
    %%-------------------------------------------------
    Tlv1 = match_tags(Tlv, TagIn),
    %%-------------------------------------------------
    %% attribute type(1) with type fixedtypevaluefieldidtypetagUNIVERSAL6IMPLICIT0OBJECT IDENTIFIERno
    %%-------------------------------------------------
    [V1 | Tlv2] = Tlv1,
    Term1 = decode_object_identifier(V1, [6]),
    ObjFun =
	'PKCS-FRAME':getdec_internal_object_set_argument_8(id,
							   Term1),
    %%-------------------------------------------------
    %% attribute values(2) with type SET OF
    %%-------------------------------------------------
    [V2 | Tlv3] = Tlv2,
    Term2 = dec_Attributes_PKAttribute_values(V2, [17],
					      ObjFun),
    %%-------------------------------------------------
    %% attribute valuesWithContext(3) with type SET OF OPTIONAL
    %%-------------------------------------------------
    {Term3, Tlv4} = case Tlv3 of
		      [{17, V3} | TempTlv4] ->
			  {dec_Attributes_PKAttribute_valuesWithContext(V3, [],
									ObjFun),
			   TempTlv4};
		      _ -> {asn1_NOVALUE, Tlv3}
		    end,
    case Tlv4 of
      [] -> true;
      _ ->
	  exit({error,
		{asn1, {unexpected, Tlv4}}}) % extra fields not allowed
    end,
    {'PKAttribute', Term1, Term2, Term3}.

dec_Attributes(Tlv) -> dec_Attributes(Tlv, [17]).

dec_Attributes(Tlv, TagIn) ->
    %%-------------------------------------------------
    %% decode tag and length
    %%-------------------------------------------------
    Tlv1 = match_tags(Tlv, TagIn),
    [dec_Attributes_PKAttribute(V1, [16]) || V1 <- Tlv1].

%%================================
%%  PrivateKey
%%================================
enc_PrivateKey(Val) -> enc_PrivateKey(Val, [<<4>>]).

enc_PrivateKey({'PrivateKey', Val}, TagIn) ->
    enc_PrivateKey(Val, TagIn);
enc_PrivateKey(Val, TagIn) ->
    encode_octet_string([], Val, TagIn).

dec_PrivateKey(Tlv) -> dec_PrivateKey(Tlv, [4]).

dec_PrivateKey(Tlv, TagIn) ->
    decode_octet_string(Tlv, [], TagIn).

%%================================
%%  Version
%%================================
enc_Version(Val) -> enc_Version(Val, [<<2>>]).

enc_Version({'Version', Val}, TagIn) ->
    enc_Version(Val, TagIn);
enc_Version(Val, TagIn) ->
    encode_integer([], Val, [{v1, 0}], TagIn).

dec_Version(Tlv) -> dec_Version(Tlv, [2]).

dec_Version(Tlv, TagIn) ->
    decode_integer(Tlv, [], [{v1, 0}], TagIn).

%%================================
%%  PrivateKeyInfo
%%================================
enc_PrivateKeyInfo(Val) ->
    enc_PrivateKeyInfo(Val, [<<48>>]).

enc_PrivateKeyInfo(Val, TagIn) ->
    {_, Cindex1, Cindex2, Cindex3, Cindex4} = Val,
    %%-------------------------------------------------
    %% attribute version(1) with type INTEGER
    %%-------------------------------------------------
    {EncBytes1, EncLen1} = encode_integer([], Cindex1,
					  [{v1, 0}], [<<2>>]),
    %%-------------------------------------------------
    %% attribute privateKeyAlgorithm(2) with type SEQUENCE
    %%-------------------------------------------------
    {EncBytes2, EncLen2} =
	enc_PrivateKeyInfo_privateKeyAlgorithm(Cindex2,
					       [<<48>>]),
    %%-------------------------------------------------
    %% attribute privateKey(3) with type OCTET STRING
    %%-------------------------------------------------
    {EncBytes3, EncLen3} = encode_octet_string([], Cindex3,
					       [<<4>>]),
    %%-------------------------------------------------
    %% attribute attributes(4)   External PKCS-FRAME:Attributes OPTIONAL
    %%-------------------------------------------------
    {EncBytes4, EncLen4} = case Cindex4 of
			     asn1_NOVALUE -> {<<>>, 0};
			     _ -> enc_Attributes(Cindex4, [<<160>>])
			   end,
    BytesSoFar = [EncBytes1, EncBytes2, EncBytes3,
		  EncBytes4],
    LenSoFar = EncLen1 + EncLen2 + EncLen3 + EncLen4,
    encode_tags(TagIn, BytesSoFar, LenSoFar).

%%================================
%%  PrivateKeyInfo_privateKeyAlgorithm
%%================================
enc_PrivateKeyInfo_privateKeyAlgorithm(Val, TagIn) ->
    {_, Cindex1, Cindex2} = Val,
    Objalgorithm =
	'PKCS-FRAME':getenc_internal_object_set_argument_9(id,
							   Cindex1),
    %%-------------------------------------------------
    %% attribute algorithm(1) with type fixedtypevaluefieldidtypetagUNIVERSAL6IMPLICIT0OBJECT IDENTIFIERno
    %%-------------------------------------------------
    {EncBytes1, EncLen1} = encode_object_identifier(Cindex1,
						    [<<6>>]),
    %%-------------------------------------------------
    %% attribute parameters(2) with type typefieldType OPTIONAL
    %%-------------------------------------------------
    {EncBytes2, EncLen2} = case Cindex2 of
			     asn1_NOVALUE -> {<<>>, 0};
			     _ ->
				 {TmpBytes, _} = Objalgorithm('Type', Cindex2,
							      []),
				 {TmpBytes1, TmpLen} =
				     encode_open_type(TmpBytes, []),
				 {TmpBytes1, TmpLen}
			   end,
    BytesSoFar = [EncBytes1, EncBytes2],
    LenSoFar = EncLen1 + EncLen2,
    encode_tags(TagIn, BytesSoFar, LenSoFar).

dec_PrivateKeyInfo_privateKeyAlgorithm(Tlv, TagIn) ->
    %%-------------------------------------------------
    %% decode tag and length
    %%-------------------------------------------------
    Tlv1 = match_tags(Tlv, TagIn),
    %%-------------------------------------------------
    %% attribute algorithm(1) with type fixedtypevaluefieldidtypetagUNIVERSAL6IMPLICIT0OBJECT IDENTIFIERno
    %%-------------------------------------------------
    [V1 | Tlv2] = Tlv1,
    Term1 = decode_object_identifier(V1, [6]),
    %%-------------------------------------------------
    %% attribute parameters(2) with type typefieldType OPTIONAL
    %%-------------------------------------------------
    {Tmpterm1, Tlv3} = case Tlv2 of
			 [V2 | TempTlv3] ->
			     {decode_open_type(V2, [], nif), TempTlv3};
			 _ -> {asn1_NOVALUE, Tlv2}
		       end,
    DecObjalgorithmTerm1 =
	'PKCS-FRAME':getdec_internal_object_set_argument_9(id,
							   Term1),
    Term2 = case Tmpterm1 of
	      asn1_NOVALUE -> asn1_NOVALUE;
	      _ ->
		  case catch DecObjalgorithmTerm1('Type', Tmpterm1, []) of
		    {'EXIT', Reason1} ->
			exit({'Type not compatible with table constraint',
			      Reason1});
		    Tmpterm2 -> Tmpterm2
		  end
	    end,
    case Tlv3 of
      [] -> true;
      _ ->
	  exit({error,
		{asn1, {unexpected, Tlv3}}}) % extra fields not allowed
    end,
    {'PrivateKeyInfo_privateKeyAlgorithm', Term1, Term2}.

dec_PrivateKeyInfo(Tlv) ->
    dec_PrivateKeyInfo(Tlv, [16]).

dec_PrivateKeyInfo(Tlv, TagIn) ->
    %%-------------------------------------------------
    %% decode tag and length
    %%-------------------------------------------------
    Tlv1 = match_tags(Tlv, TagIn),
    %%-------------------------------------------------
    %% attribute version(1) with type INTEGER
    %%-------------------------------------------------
    [V1 | Tlv2] = Tlv1,
    Term1 = decode_integer(V1, [], [{v1, 0}], [2]),
    %%-------------------------------------------------
    %% attribute privateKeyAlgorithm(2) with type SEQUENCE
    %%-------------------------------------------------
    [V2 | Tlv3] = Tlv2,
    Term2 = dec_PrivateKeyInfo_privateKeyAlgorithm(V2,
						   [16]),
    %%-------------------------------------------------
    %% attribute privateKey(3) with type OCTET STRING
    %%-------------------------------------------------
    [V3 | Tlv4] = Tlv3,
    Term3 = decode_octet_string(V3, [], [4]),
    %%-------------------------------------------------
    %% attribute attributes(4)   External PKCS-FRAME:Attributes OPTIONAL
    %%-------------------------------------------------
    {Term4, Tlv5} = case Tlv4 of
		      [{131072, V4} | TempTlv5] ->
			  {dec_Attributes(V4, []), TempTlv5};
		      _ -> {asn1_NOVALUE, Tlv4}
		    end,
    case Tlv5 of
      [] -> true;
      _ ->
	  exit({error,
		{asn1, {unexpected, Tlv5}}}) % extra fields not allowed
    end,
    {'PrivateKeyInfo', Term1, Term2, Term3, Term4}.

'rc5-CBC-PAD'() -> {1, 2, 840, 113549, 3, 9}.

rc2CBC() -> {1, 2, 840, 113549, 3, 2}.

'des-EDE3-CBC'() -> {1, 2, 840, 113549, 3, 7}.

desCBC() -> {1, 3, 14, 3, 2, 7}.

'id-hmacWithSHA1'() -> {1, 2, 840, 113549, 2, 7}.

encryptionAlgorithm() -> {1, 2, 840, 113549, 3}.

digestAlgorithm() -> {1, 2, 840, 113549, 2}.

'id-PBMAC1'() -> {1, 2, 840, 113549, 1, 5, 14}.

'id-PBES2'() -> {1, 2, 840, 113549, 1, 5, 13}.

'pbeWithSHA1AndRC2-CBC'() ->
    {1, 2, 840, 113549, 1, 5, 11}.

'pbeWithSHA1AndDES-CBC'() ->
    {1, 2, 840, 113549, 1, 5, 10}.

'pbeWithMD5AndRC2-CBC'() ->
    {1, 2, 840, 113549, 1, 5, 6}.

'pbeWithMD5AndDES-CBC'() ->
    {1, 2, 840, 113549, 1, 5, 3}.

'pbeWithMD2AndRC2-CBC'() ->
    {1, 2, 840, 113549, 1, 5, 4}.

'pbeWithMD2AndDES-CBC'() ->
    {1, 2, 840, 113549, 1, 5, 1}.

'id-PBKDF2'() -> {1, 2, 840, 113549, 1, 5, 12}.

'pkcs-5'() -> {1, 2, 840, 113549, 1, 5}.

pkcs() -> {1, 2, 840, 113549, 1}.

rsadsi() -> {1, 2, 840, 113549}.

%%================================
%%  SupportingAlgorithms
%%================================
getenc_SupportingAlgorithms(id,
			    {1, 2, 840, 113549, 2, 7}) ->
    fun (Type, Val, _RestPrimFieldName) ->
	    case Type of 'Type' -> encode_null(Val, [<<5>>]) end
    end;
getenc_SupportingAlgorithms(id,
			    {1, 2, 840, 113549, 3, 2}) ->
    fun (Type, Val, _RestPrimFieldName) ->
	    case Type of 'Type' -> 'enc_RC2-CBC-Parameter'(Val) end
    end;
getenc_SupportingAlgorithms(id,
			    {1, 2, 840, 113549, 3, 7}) ->
    fun (Type, Val, _RestPrimFieldName) ->
	    case Type of
	      'Type' -> encode_octet_string([], Val, [<<4>>])
	    end
    end;
getenc_SupportingAlgorithms(id,
			    {1, 2, 840, 113549, 3, 9}) ->
    fun (Type, Val, _RestPrimFieldName) ->
	    case Type of 'Type' -> 'enc_RC5-CBC-Parameters'(Val) end
    end;
getenc_SupportingAlgorithms(id, {1, 3, 14, 3, 2, 7}) ->
    fun (Type, Val, _RestPrimFieldName) ->
	    case Type of
	      'Type' -> encode_octet_string([], Val, [<<4>>])
	    end
    end;
getenc_SupportingAlgorithms(_, _) ->
    fun (_, Val, _RestPrimFieldName) ->
	    Len = case Val of
		    Bin when is_binary(Bin) -> size(Bin);
		    _ -> length(Val)
		  end,
	    {Val, Len}
    end.

getdec_SupportingAlgorithms(id,
			    {1, 2, 840, 113549, 2, 7}) ->
    fun (Type, Bytes, _RestPrimFieldName) ->
	    case Type of 'Type' -> decode_null(Bytes, [5]) end
    end;
getdec_SupportingAlgorithms(id,
			    {1, 2, 840, 113549, 3, 2}) ->
    fun (Type, Bytes, _RestPrimFieldName) ->
	    case Type of
	      'Type' -> 'dec_RC2-CBC-Parameter'(Bytes)
	    end
    end;
getdec_SupportingAlgorithms(id,
			    {1, 2, 840, 113549, 3, 7}) ->
    fun (Type, Bytes, _RestPrimFieldName) ->
	    case Type of
	      'Type' -> decode_octet_string(Bytes, 8, [4])
	    end
    end;
getdec_SupportingAlgorithms(id,
			    {1, 2, 840, 113549, 3, 9}) ->
    fun (Type, Bytes, _RestPrimFieldName) ->
	    case Type of
	      'Type' -> 'dec_RC5-CBC-Parameters'(Bytes)
	    end
    end;
getdec_SupportingAlgorithms(id, {1, 3, 14, 3, 2, 7}) ->
    fun (Type, Bytes, _RestPrimFieldName) ->
	    case Type of
	      'Type' -> decode_octet_string(Bytes, 8, [4])
	    end
    end;
getdec_SupportingAlgorithms(_, _) ->
    fun (_, Bytes, _RestPrimFieldName) ->
	    case Bytes of
	      Bin when is_binary(Bin) -> Bin;
	      _ -> asn1rt_ber_bin_v2__encode(Bytes, nif)
	    end
    end.

%%================================
%%  PBMAC1-MACs
%%================================
'getenc_PBMAC1-MACs'(_, _) ->
    fun (_, Val, _RestPrimFieldName) ->
	    Len = case Val of
		    Bin when is_binary(Bin) -> size(Bin);
		    _ -> length(Val)
		  end,
	    {Val, Len}
    end.

'getdec_PBMAC1-MACs'(_, _) ->
    fun (_, Bytes, _RestPrimFieldName) ->
	    case Bytes of
	      Bin when is_binary(Bin) -> Bin;
	      _ -> asn1rt_ber_bin_v2__encode(Bytes, nif)
	    end
    end.

%%================================
%%  PBMAC1-KDFs
%%================================
'getenc_PBMAC1-KDFs'(id,
		     {1, 2, 840, 113549, 1, 5, 12}) ->
    fun (Type, Val, _RestPrimFieldName) ->
	    case Type of 'Type' -> 'enc_PBKDF2-params'(Val) end
    end;
'getenc_PBMAC1-KDFs'(_, _) ->
    fun (_, Val, _RestPrimFieldName) ->
	    Len = case Val of
		    Bin when is_binary(Bin) -> size(Bin);
		    _ -> length(Val)
		  end,
	    {Val, Len}
    end.

'getdec_PBMAC1-KDFs'(id,
		     {1, 2, 840, 113549, 1, 5, 12}) ->
    fun (Type, Bytes, _RestPrimFieldName) ->
	    case Type of 'Type' -> 'dec_PBKDF2-params'(Bytes) end
    end;
'getdec_PBMAC1-KDFs'(_, _) ->
    fun (_, Bytes, _RestPrimFieldName) ->
	    case Bytes of
	      Bin when is_binary(Bin) -> Bin;
	      _ -> asn1rt_ber_bin_v2__encode(Bytes, nif)
	    end
    end.

%%================================
%%  PBMAC1Algorithms
%%================================
getenc_PBMAC1Algorithms(id,
			{1, 2, 840, 113549, 1, 5, 14}) ->
    fun (Type, Val, _RestPrimFieldName) ->
	    case Type of 'Type' -> 'enc_PBMAC1-params'(Val) end
    end;
getenc_PBMAC1Algorithms(_, _) ->
    fun (_, Val, _RestPrimFieldName) ->
	    Len = case Val of
		    Bin when is_binary(Bin) -> size(Bin);
		    _ -> length(Val)
		  end,
	    {Val, Len}
    end.

getdec_PBMAC1Algorithms(id,
			{1, 2, 840, 113549, 1, 5, 14}) ->
    fun (Type, Bytes, _RestPrimFieldName) ->
	    case Type of 'Type' -> 'dec_PBMAC1-params'(Bytes) end
    end;
getdec_PBMAC1Algorithms(_, _) ->
    fun (_, Bytes, _RestPrimFieldName) ->
	    case Bytes of
	      Bin when is_binary(Bin) -> Bin;
	      _ -> asn1rt_ber_bin_v2__encode(Bytes, nif)
	    end
    end.

%%================================
%%  PBES2-Encs
%%================================
'getenc_PBES2-Encs'(_, _) ->
    fun (_, Val, _RestPrimFieldName) ->
	    Len = case Val of
		    Bin when is_binary(Bin) -> size(Bin);
		    _ -> length(Val)
		  end,
	    {Val, Len}
    end.

'getdec_PBES2-Encs'(_, _) ->
    fun (_, Bytes, _RestPrimFieldName) ->
	    case Bytes of
	      Bin when is_binary(Bin) -> Bin;
	      _ -> asn1rt_ber_bin_v2__encode(Bytes, nif)
	    end
    end.

%%================================
%%  PBES2-KDFs
%%================================
'getenc_PBES2-KDFs'(id,
		    {1, 2, 840, 113549, 1, 5, 12}) ->
    fun (Type, Val, _RestPrimFieldName) ->
	    case Type of 'Type' -> 'enc_PBKDF2-params'(Val) end
    end;
'getenc_PBES2-KDFs'(_, _) ->
    fun (_, Val, _RestPrimFieldName) ->
	    Len = case Val of
		    Bin when is_binary(Bin) -> size(Bin);
		    _ -> length(Val)
		  end,
	    {Val, Len}
    end.

'getdec_PBES2-KDFs'(id,
		    {1, 2, 840, 113549, 1, 5, 12}) ->
    fun (Type, Bytes, _RestPrimFieldName) ->
	    case Type of 'Type' -> 'dec_PBKDF2-params'(Bytes) end
    end;
'getdec_PBES2-KDFs'(_, _) ->
    fun (_, Bytes, _RestPrimFieldName) ->
	    case Bytes of
	      Bin when is_binary(Bin) -> Bin;
	      _ -> asn1rt_ber_bin_v2__encode(Bytes, nif)
	    end
    end.

%%================================
%%  PBES2Algorithms
%%================================
getenc_PBES2Algorithms(id,
		       {1, 2, 840, 113549, 1, 5, 13}) ->
    fun (Type, Val, _RestPrimFieldName) ->
	    case Type of 'Type' -> 'enc_PBES2-params'(Val) end
    end;
getenc_PBES2Algorithms(_, _) ->
    fun (_, Val, _RestPrimFieldName) ->
	    Len = case Val of
		    Bin when is_binary(Bin) -> size(Bin);
		    _ -> length(Val)
		  end,
	    {Val, Len}
    end.

getdec_PBES2Algorithms(id,
		       {1, 2, 840, 113549, 1, 5, 13}) ->
    fun (Type, Bytes, _RestPrimFieldName) ->
	    case Type of 'Type' -> 'dec_PBES2-params'(Bytes) end
    end;
getdec_PBES2Algorithms(_, _) ->
    fun (_, Bytes, _RestPrimFieldName) ->
	    case Bytes of
	      Bin when is_binary(Bin) -> Bin;
	      _ -> asn1rt_ber_bin_v2__encode(Bytes, nif)
	    end
    end.

%%================================
%%  PBES1Algorithms
%%================================
getenc_PBES1Algorithms(id,
		       {1, 2, 840, 113549, 1, 5, 1}) ->
    fun (Type, Val, _RestPrimFieldName) ->
	    case Type of 'Type' -> enc_PBEParameter(Val) end
    end;
getenc_PBES1Algorithms(id,
		       {1, 2, 840, 113549, 1, 5, 3}) ->
    fun (Type, Val, _RestPrimFieldName) ->
	    case Type of 'Type' -> enc_PBEParameter(Val) end
    end;
getenc_PBES1Algorithms(id,
		       {1, 2, 840, 113549, 1, 5, 4}) ->
    fun (Type, Val, _RestPrimFieldName) ->
	    case Type of 'Type' -> enc_PBEParameter(Val) end
    end;
getenc_PBES1Algorithms(id,
		       {1, 2, 840, 113549, 1, 5, 6}) ->
    fun (Type, Val, _RestPrimFieldName) ->
	    case Type of 'Type' -> enc_PBEParameter(Val) end
    end;
getenc_PBES1Algorithms(id,
		       {1, 2, 840, 113549, 1, 5, 10}) ->
    fun (Type, Val, _RestPrimFieldName) ->
	    case Type of 'Type' -> enc_PBEParameter(Val) end
    end;
getenc_PBES1Algorithms(id,
		       {1, 2, 840, 113549, 1, 5, 11}) ->
    fun (Type, Val, _RestPrimFieldName) ->
	    case Type of 'Type' -> enc_PBEParameter(Val) end
    end;
getenc_PBES1Algorithms(_, _) ->
    fun (_, Val, _RestPrimFieldName) ->
	    Len = case Val of
		    Bin when is_binary(Bin) -> size(Bin);
		    _ -> length(Val)
		  end,
	    {Val, Len}
    end.

getdec_PBES1Algorithms(id,
		       {1, 2, 840, 113549, 1, 5, 1}) ->
    fun (Type, Bytes, _RestPrimFieldName) ->
	    case Type of 'Type' -> dec_PBEParameter(Bytes) end
    end;
getdec_PBES1Algorithms(id,
		       {1, 2, 840, 113549, 1, 5, 3}) ->
    fun (Type, Bytes, _RestPrimFieldName) ->
	    case Type of 'Type' -> dec_PBEParameter(Bytes) end
    end;
getdec_PBES1Algorithms(id,
		       {1, 2, 840, 113549, 1, 5, 4}) ->
    fun (Type, Bytes, _RestPrimFieldName) ->
	    case Type of 'Type' -> dec_PBEParameter(Bytes) end
    end;
getdec_PBES1Algorithms(id,
		       {1, 2, 840, 113549, 1, 5, 6}) ->
    fun (Type, Bytes, _RestPrimFieldName) ->
	    case Type of 'Type' -> dec_PBEParameter(Bytes) end
    end;
getdec_PBES1Algorithms(id,
		       {1, 2, 840, 113549, 1, 5, 10}) ->
    fun (Type, Bytes, _RestPrimFieldName) ->
	    case Type of 'Type' -> dec_PBEParameter(Bytes) end
    end;
getdec_PBES1Algorithms(id,
		       {1, 2, 840, 113549, 1, 5, 11}) ->
    fun (Type, Bytes, _RestPrimFieldName) ->
	    case Type of 'Type' -> dec_PBEParameter(Bytes) end
    end;
getdec_PBES1Algorithms(_, _) ->
    fun (_, Bytes, _RestPrimFieldName) ->
	    case Bytes of
	      Bin when is_binary(Bin) -> Bin;
	      _ -> asn1rt_ber_bin_v2__encode(Bytes, nif)
	    end
    end.

%%================================
%%  PBKDF2-PRFs
%%================================
'getenc_PBKDF2-PRFs'(id, {1, 2, 840, 113549, 2, 7}) ->
    fun (Type, Val, _RestPrimFieldName) ->
	    case Type of 'Type' -> encode_null(Val, [<<5>>]) end
    end;
'getenc_PBKDF2-PRFs'(_, _) ->
    fun (_, Val, _RestPrimFieldName) ->
	    Len = case Val of
		    Bin when is_binary(Bin) -> size(Bin);
		    _ -> length(Val)
		  end,
	    {Val, Len}
    end.

'getdec_PBKDF2-PRFs'(id, {1, 2, 840, 113549, 2, 7}) ->
    fun (Type, Bytes, _RestPrimFieldName) ->
	    case Type of 'Type' -> decode_null(Bytes, [5]) end
    end;
'getdec_PBKDF2-PRFs'(_, _) ->
    fun (_, Bytes, _RestPrimFieldName) ->
	    case Bytes of
	      Bin when is_binary(Bin) -> Bin;
	      _ -> asn1rt_ber_bin_v2__encode(Bytes, nif)
	    end
    end.

%%================================
%%  PBKDF2-SaltSources
%%================================
'getenc_PBKDF2-SaltSources'(_, _) ->
    fun (_, Val, _RestPrimFieldName) ->
	    Len = case Val of
		    Bin when is_binary(Bin) -> size(Bin);
		    _ -> length(Val)
		  end,
	    {Val, Len}
    end.

'getdec_PBKDF2-SaltSources'(_, _) ->
    fun (_, Bytes, _RestPrimFieldName) ->
	    case Bytes of
	      Bin when is_binary(Bin) -> Bin;
	      _ -> asn1rt_ber_bin_v2__encode(Bytes, nif)
	    end
    end.

%%================================
%%  SupportedContexts
%%================================
getenc_SupportedContexts(_, _) ->
    fun (_, Val, _RestPrimFieldName) ->
	    Len = case Val of
		    Bin when is_binary(Bin) -> size(Bin);
		    _ -> length(Val)
		  end,
	    {Val, Len}
    end.

getdec_SupportedContexts(_, _) ->
    fun (_, Bytes, _RestPrimFieldName) ->
	    case Bytes of
	      Bin when is_binary(Bin) -> Bin;
	      _ -> asn1rt_ber_bin_v2__encode(Bytes, nif)
	    end
    end.

%%================================
%%  KeyEncryptionAlgorithms
%%================================
getenc_KeyEncryptionAlgorithms(_, _) ->
    fun (_, Val, _RestPrimFieldName) ->
	    Len = case Val of
		    Bin when is_binary(Bin) -> size(Bin);
		    _ -> length(Val)
		  end,
	    {Val, Len}
    end.

getdec_KeyEncryptionAlgorithms(_, _) ->
    fun (_, Bytes, _RestPrimFieldName) ->
	    case Bytes of
	      Bin when is_binary(Bin) -> Bin;
	      _ -> asn1rt_ber_bin_v2__encode(Bytes, nif)
	    end
    end.

%%================================
%%  PrivateKeyAlgorithms
%%================================
getenc_PrivateKeyAlgorithms(_, _) ->
    fun (_, Val, _RestPrimFieldName) ->
	    Len = case Val of
		    Bin when is_binary(Bin) -> size(Bin);
		    _ -> length(Val)
		  end,
	    {Val, Len}
    end.

getdec_PrivateKeyAlgorithms(_, _) ->
    fun (_, Bytes, _RestPrimFieldName) ->
	    case Bytes of
	      Bin when is_binary(Bin) -> Bin;
	      _ -> asn1rt_ber_bin_v2__encode(Bytes, nif)
	    end
    end.

%%================================
%%  internal_object_set_argument_9
%%================================
getenc_internal_object_set_argument_9(_, _) ->
    fun (_, Val, _RestPrimFieldName) ->
	    Len = case Val of
		    Bin when is_binary(Bin) -> size(Bin);
		    _ -> length(Val)
		  end,
	    {Val, Len}
    end.

getdec_internal_object_set_argument_9(_, _) ->
    fun (_, Bytes, _RestPrimFieldName) ->
	    case Bytes of
	      Bin when is_binary(Bin) -> Bin;
	      _ -> asn1rt_ber_bin_v2__encode(Bytes, nif)
	    end
    end.

%%================================
%%  internal_object_set_argument_8
%%================================
getenc_internal_object_set_argument_8(_, _) ->
    fun (_, Val, _RestPrimFieldName) ->
	    Len = case Val of
		    Bin when is_binary(Bin) -> size(Bin);
		    _ -> length(Val)
		  end,
	    {Val, Len}
    end.

getdec_internal_object_set_argument_8(_, _) ->
    fun (_, Bytes, _RestPrimFieldName) ->
	    case Bytes of
	      Bin when is_binary(Bin) -> Bin;
	      _ -> asn1rt_ber_bin_v2__encode(Bytes, nif)
	    end
    end.

%%================================
%%  internal_object_set_argument_7
%%================================
getenc_internal_object_set_argument_7(_, _) ->
    fun (_, Val, _RestPrimFieldName) ->
	    Len = case Val of
		    Bin when is_binary(Bin) -> size(Bin);
		    _ -> length(Val)
		  end,
	    {Val, Len}
    end.

getdec_internal_object_set_argument_7(_, _) ->
    fun (_, Bytes, _RestPrimFieldName) ->
	    case Bytes of
	      Bin when is_binary(Bin) -> Bin;
	      _ -> asn1rt_ber_bin_v2__encode(Bytes, nif)
	    end
    end.

%%================================
%%  internal_object_set_argument_6
%%================================
getenc_internal_object_set_argument_6(id,
				      {1, 2, 840, 113549, 2, 7}) ->
    fun (Type, Val, _RestPrimFieldName) ->
	    case Type of 'Type' -> encode_null(Val, [<<5>>]) end
    end;
getenc_internal_object_set_argument_6(id, ErrV) ->
    fun (C, V, _) ->
	    exit({'Type not compatible with table constraint',
		  {component, C}, {value, V},
		  {unique_name_and_value, id, ErrV}})
    end.

getdec_internal_object_set_argument_6(id,
				      {1, 2, 840, 113549, 2, 7}) ->
    fun (Type, Bytes, _RestPrimFieldName) ->
	    case Type of 'Type' -> decode_null(Bytes, [5]) end
    end;
getdec_internal_object_set_argument_6(id, ErrV) ->
    fun (C, V, _) ->
	    exit({{component, C}, {value, V},
		  {unique_name_and_value, id, ErrV}})
    end.

%%================================
%%  internal_object_set_argument_5
%%================================
getenc_internal_object_set_argument_5(_, _) ->
    fun (_, Val, _RestPrimFieldName) ->
	    Len = case Val of
		    Bin when is_binary(Bin) -> size(Bin);
		    _ -> length(Val)
		  end,
	    {Val, Len}
    end.

getdec_internal_object_set_argument_5(_, _) ->
    fun (_, Bytes, _RestPrimFieldName) ->
	    case Bytes of
	      Bin when is_binary(Bin) -> Bin;
	      _ -> asn1rt_ber_bin_v2__encode(Bytes, nif)
	    end
    end.

%%================================
%%  internal_object_set_argument_4
%%================================
getenc_internal_object_set_argument_4(_, _) ->
    fun (_, Val, _RestPrimFieldName) ->
	    Len = case Val of
		    Bin when is_binary(Bin) -> size(Bin);
		    _ -> length(Val)
		  end,
	    {Val, Len}
    end.

getdec_internal_object_set_argument_4(_, _) ->
    fun (_, Bytes, _RestPrimFieldName) ->
	    case Bytes of
	      Bin when is_binary(Bin) -> Bin;
	      _ -> asn1rt_ber_bin_v2__encode(Bytes, nif)
	    end
    end.

%%================================
%%  internal_object_set_argument_3
%%================================
getenc_internal_object_set_argument_3(id,
				      {1, 2, 840, 113549, 1, 5, 12}) ->
    fun (Type, Val, _RestPrimFieldName) ->
	    case Type of 'Type' -> 'enc_PBKDF2-params'(Val) end
    end;
getenc_internal_object_set_argument_3(id, ErrV) ->
    fun (C, V, _) ->
	    exit({'Type not compatible with table constraint',
		  {component, C}, {value, V},
		  {unique_name_and_value, id, ErrV}})
    end.

getdec_internal_object_set_argument_3(id,
				      {1, 2, 840, 113549, 1, 5, 12}) ->
    fun (Type, Bytes, _RestPrimFieldName) ->
	    case Type of 'Type' -> 'dec_PBKDF2-params'(Bytes) end
    end;
getdec_internal_object_set_argument_3(id, ErrV) ->
    fun (C, V, _) ->
	    exit({{component, C}, {value, V},
		  {unique_name_and_value, id, ErrV}})
    end.

%%================================
%%  internal_object_set_argument_2
%%================================
getenc_internal_object_set_argument_2(_, _) ->
    fun (_, Val, _RestPrimFieldName) ->
	    Len = case Val of
		    Bin when is_binary(Bin) -> size(Bin);
		    _ -> length(Val)
		  end,
	    {Val, Len}
    end.

getdec_internal_object_set_argument_2(_, _) ->
    fun (_, Bytes, _RestPrimFieldName) ->
	    case Bytes of
	      Bin when is_binary(Bin) -> Bin;
	      _ -> asn1rt_ber_bin_v2__encode(Bytes, nif)
	    end
    end.

%%================================
%%  internal_object_set_argument_1
%%================================
getenc_internal_object_set_argument_1(id,
				      {1, 2, 840, 113549, 1, 5, 12}) ->
    fun (Type, Val, _RestPrimFieldName) ->
	    case Type of 'Type' -> 'enc_PBKDF2-params'(Val) end
    end;
getenc_internal_object_set_argument_1(id, ErrV) ->
    fun (C, V, _) ->
	    exit({'Type not compatible with table constraint',
		  {component, C}, {value, V},
		  {unique_name_and_value, id, ErrV}})
    end.

getdec_internal_object_set_argument_1(id,
				      {1, 2, 840, 113549, 1, 5, 12}) ->
    fun (Type, Bytes, _RestPrimFieldName) ->
	    case Type of 'Type' -> 'dec_PBKDF2-params'(Bytes) end
    end;
getdec_internal_object_set_argument_1(id, ErrV) ->
    fun (C, V, _) ->
	    exit({{component, C}, {value, V},
		  {unique_name_and_value, id, ErrV}})
    end.

'check_PBKDF2-params_prf'(_V, asn1_DEFAULT) -> true;
'check_PBKDF2-params_prf'(V, V) -> true;
'check_PBKDF2-params_prf'(V, {_, V}) -> true;
'check_PBKDF2-params_prf'(DefaultValue, Value) ->
    check_objectidentifier(element(2, DefaultValue),
			   element(2, Value)),
    if element(3, DefaultValue) == element(3, Value) ->
	   true;
       true -> throw({error, {asn1_open_type}})
    end.

%% =====================================================================
%% 
%% The following code stems from module `asn1rt_ber_bin_v2'.
%% 

%%
%% %CopyrightBegin%
%%
%% Copyright Ericsson AB 2002-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
%%
%% %CopyrightEnd%
%%
%%

%% encoding / decoding of BER

% the encoding of class of tag bits 8 and 7

%%% primitive or constructed encoding % bit 6

%%% The tag-number for universal types

% the complete tag-word of built-in types

                                                              % can be CONSTRUCTED
 % can be CONSTRUCTED

                                                               %can be constructed
 %can be constructed

                                                               %can be constructed
 %can be constructed

                                                               %can be constructed

                                                               %can be constructed
 %can be constructed

                                                               %can be constructed
 %can be constructed

                                                               %can be constructed

% encode(Tlv={_Tag={?PRIMITIVE,_},_VList}) ->
%     encode_primitive(Tlv);
% encode(Tlv) ->
%     encode_constructed(Tlv).

%%! Note from Igor: renamed function to `asn1rt_ber_bin_v2__encode'
%%! Original code:
%%!   encode(...) when ... -> Tlv;
%%!   ....
asn1rt_ber_bin_v2__encode(Tlv, _) when is_binary(Tlv) ->
    Tlv;
asn1rt_ber_bin_v2__encode([Tlv], Method) ->
    asn1rt_ber_bin_v2__encode(Tlv, Method);
asn1rt_ber_bin_v2__encode(Tlv, nif) ->
    case is_nif_loadable() of
      true -> asn1rt_nif:encode_ber_tlv(Tlv);
      false -> encode_erl(Tlv)
    end;
asn1rt_ber_bin_v2__encode(Tlv, _) -> encode_erl(Tlv).

encode_erl({TlvTag, TlvVal}) when is_list(TlvVal) ->
    %% constructed form of value
    encode_tlv(TlvTag, TlvVal, 32);
encode_erl({TlvTag, TlvVal}) ->
    encode_tlv(TlvTag, TlvVal, 0).

encode_tlv(TlvTag, TlvVal, Form) ->
    Tag = encode_tlv_tag(TlvTag, Form),
    {Val, VLen} = encode_tlv_val(TlvVal),
    {Len, _LLen} = encode_length(VLen),
    BinLen = list_to_binary(Len),
    <<Tag/binary, BinLen/binary, Val/binary>>.

encode_tlv_tag(ClassTagNo, Form) ->
    Class = ClassTagNo bsr 16,
    encode_tag_val({Class bsl 6, Form,
		    ClassTagNo - (Class bsl 16)}).

encode_tlv_val(TlvL) when is_list(TlvL) ->
    encode_tlv_list(TlvL, []);
encode_tlv_val(Bin) -> {Bin, size(Bin)}.

encode_tlv_list([Tlv | Tlvs], Acc) ->
    EncTlv = encode_erl(Tlv),
    encode_tlv_list(Tlvs, [EncTlv | Acc]);
encode_tlv_list([], Acc) ->
    Bin = list_to_binary(lists:reverse(Acc)),
    {Bin, size(Bin)}.

decode(B) -> asn1rt_ber_bin_v2__decode(B, erlang).

%% asn1-1.7
%%! Note from Igor: renamed function to `asn1rt_ber_bin_v2__decode'
%%! Original code:
%%!   decode(...) -> ...;
%%!   ....
asn1rt_ber_bin_v2__decode(B, nif) ->
    case is_nif_loadable() of
      true ->
	  case asn1rt_nif:decode_ber_tlv(B) of
	    {error, Reason} -> handle_error(Reason, B);
	    Else -> Else
	  end;
      false -> decode(B)
    end;
asn1rt_ber_bin_v2__decode(B, erlang)
    when is_binary(B) ->
    decode_primitive(B);
asn1rt_ber_bin_v2__decode(Tlv, erlang) -> {Tlv, <<>>}.

%% Have to check this since asn1 is not guaranteed to be available
is_nif_loadable() ->
    case application:get_env(asn1, nif_loadable) of
      {ok, R} -> R;
      undefined ->
	  case catch code:load_file(asn1rt_nif) of
	    {module, asn1rt_nif} ->
		application:set_env(asn1, nif_loadable, true), true;
	    _Else ->
		application:set_env(asn1, nif_loadable, false), false
	  end
    end.

handle_error([], _) ->
    exit({error, {asn1, {"memory allocation problem"}}});
handle_error({$1, _},
	     L) -> % error in nif
    exit({error, {asn1, L}});
handle_error({$2, T},
	     L) -> % error in nif due to wrong tag
    exit({error,
	  {asn1, {"bad tag after byte:", error_pos(T), L}}});
handle_error({$3, T},
	     L) -> % error in driver due to length error
    exit({error,
	  {asn1,
	   {"bad length field after byte:", error_pos(T), L}}});
handle_error({$4, T},
	     L) -> % error in driver due to indefinite length error
    exit({error,
	  {asn1,
	   {"indefinite length without end bytes "
	    "after byte:",
	    error_pos(T), L}}});
handle_error({$5, T},
	     L) -> % error in driver due to indefinite length error
    exit({error,
	  {asn1,
	   {"bad encoded value after byte:", error_pos(T), L}}});
handle_error(ErrL, L) -> exit({error, {asn1, ErrL, L}}).

error_pos([]) -> "unknown position";
error_pos([B]) -> B;
error_pos([B | Bs]) ->
    BS = 8 * length(Bs), B bsl BS + error_pos(Bs).

decode_primitive(Bin) ->
    {Form, TagNo, V, Rest} = decode_tag_and_length(Bin),
    case Form of
      1 -> % constructed
	  {{TagNo, decode_constructed(V)}, Rest};
      0 -> % primitive
	  {{TagNo, V}, Rest};
      2 -> % constructed indefinite
	  {Vlist, Rest2} = decode_constructed_indefinite(V, []),
	  {{TagNo, Vlist}, Rest2}
    end.

decode_constructed(Bin) when byte_size(Bin) =:= 0 -> [];
decode_constructed(Bin) ->
    {Tlv, Rest} = decode_primitive(Bin),
    [Tlv | decode_constructed(Rest)].

decode_constructed_indefinite(<<0, 0, Rest/binary>>,
			      Acc) ->
    {lists:reverse(Acc), Rest};
decode_constructed_indefinite(Bin, Acc) ->
    {Tlv, Rest} = decode_primitive(Bin),
    decode_constructed_indefinite(Rest, [Tlv | Acc]).

%% skip_tag and skip_length_and_value are rutines used both by
%% decode_partial_incomplete and decode_selective (decode/2).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% match_tags takes a Tlv (Tag, Length, Value) structure and matches
%% it with the tags in TagList. If the tags does not match the function
%% crashes otherwise it returns the remaining Tlv after that the tags have
%% been removed.
%%
%% match_tags(Tlv, TagList)
%%

match_tags({T, V}, [T]) -> V;
match_tags({T, V}, [T | Tt]) -> match_tags(V, Tt);
match_tags([{T, V}], [T | Tt]) -> match_tags(V, Tt);
match_tags(Vlist = [{T, _V} | _], [T]) -> Vlist;
match_tags(Tlv, []) -> Tlv;
match_tags({Tag, _V}, [T | _Tt]) ->
    {error, {asn1, {wrong_tag, {Tag, T}}}}.

%%===============================================================================
%%===============================================================================
%%===============================================================================
%% Optionals, preset not filled optionals with asn1_NOVALUE
%%===============================================================================
%%===============================================================================
%%===============================================================================

%%encode_tag(TagClass(?UNI, APP etc), Form (?PRIM etx), TagInteger) ->
%%     8bit Int | binary
encode_tag_val({Class, Form, TagNo}) when TagNo =< 30 ->
    <<(Class bsr 6):2, (Form bsr 5):1, TagNo:5>>;
encode_tag_val({Class, Form, TagNo}) ->
    {Octets, _Len} = mk_object_val(TagNo),
    BinOct = list_to_binary(Octets),
    <<(Class bsr 6):2, (Form bsr 5):1, 31:5,
      BinOct/binary>>.

%%===============================================================================
%% Decode a tag
%%
%% decode_tag(OctetListBuffer) -> {{Form, (Class bsl 16)+ TagNo}, RestOfBuffer, RemovedBytes}
%%===============================================================================

decode_tag_and_length(<<Class:2, Form:1, TagNo:5, 0:1,
			Length:7, V:Length/binary, RestBuffer/binary>>)
    when TagNo < 31 ->
    {Form, Class bsl 16 + TagNo, V, RestBuffer};
decode_tag_and_length(<<Class:2, 1:1, TagNo:5, 1:1, 0:7,
			T/binary>>)
    when TagNo < 31 ->
    {2, Class bsl 16 + TagNo, T, <<>>};
decode_tag_and_length(<<Class:2, Form:1, TagNo:5, 1:1,
			LL:7, Length:LL/unit:8, V:Length/binary, T/binary>>)
    when TagNo < 31 ->
    {Form, Class bsl 16 + TagNo, V, T};
decode_tag_and_length(<<Class:2, Form:1, 31:5, 0:1,
			TagNo:7, 0:1, Length:7, V:Length/binary,
			RestBuffer/binary>>) ->
    {Form, Class bsl 16 + TagNo, V, RestBuffer};
decode_tag_and_length(<<Class:2, 1:1, 31:5, 0:1,
			TagNo:7, 1:1, 0:7, T/binary>>) ->
    {2, Class bsl 16 + TagNo, T, <<>>};
decode_tag_and_length(<<Class:2, Form:1, 31:5, 0:1,
			TagNo:7, 1:1, LL:7, Length:LL/unit:8, V:Length/binary,
			T/binary>>) ->
    {Form, Class bsl 16 + TagNo, V, T};
decode_tag_and_length(<<Class:2, Form:1, 31:5, 1:1,
			TagPart1:7, 0:1, TagPartLast, Buffer/binary>>) ->
    TagNo = TagPart1 bsl 7 bor TagPartLast,
    {Length, RestBuffer} = decode_length(Buffer),
    <<V:Length/binary, RestBuffer2/binary>> = RestBuffer,
    {Form, Class bsl 16 + TagNo, V, RestBuffer2};
decode_tag_and_length(<<Class:2, Form:1, 31:5,
			Buffer/binary>>) ->
    {TagNo, Buffer1} = decode_tag(Buffer, 0),
    {Length, RestBuffer} = decode_length(Buffer1),
    <<V:Length/binary, RestBuffer2/binary>> = RestBuffer,
    {Form, Class bsl 16 + TagNo, V, RestBuffer2}.

%% last partial tag
decode_tag(<<0:1, PartialTag:7, Buffer/binary>>,
	   TagAck) ->
    TagNo = TagAck bsl 7 bor PartialTag,
    %%<<TagNo>> = <<TagAck:1, PartialTag:7>>,
    {TagNo, Buffer};
% more tags
decode_tag(<<_:1, PartialTag:7, Buffer/binary>>,
	   TagAck) ->
    TagAck1 = TagAck bsl 7 bor PartialTag,
    %%<<TagAck1:16>> = <<TagAck:1, PartialTag:7,0:8>>,
    decode_tag(Buffer, TagAck1).

%%=======================================================================
%%
%% Encode all tags in the list Tags and return a possibly deep list of
%% bytes with tag and length encoded
%% The taglist must be in reverse order (fixed by the asn1 compiler)
%% e.g [T1,T2] will result in
%% {[EncodedT2,EncodedT1|BytesSoFar],LenSoFar+LenT2+LenT1}
%%

encode_tags([Tag | Trest], BytesSoFar, LenSoFar) ->
    % remove    {Bytes1,L1} = encode_one_tag(Tag),
    {Bytes2, L2} = encode_length(LenSoFar),
    encode_tags(Trest, [Tag, Bytes2 | BytesSoFar],
		LenSoFar + size(Tag) + L2);
encode_tags([], BytesSoFar, LenSoFar) ->
    {BytesSoFar, LenSoFar}.

encode_tags(TagIn, {BytesSoFar, LenSoFar}) ->
    encode_tags(TagIn, BytesSoFar, LenSoFar).

% encode_one_tag(#tag{class=Class,number=No,type=Type, form = Form}) ->			
%     NewForm = case Type of
% 	       'EXPLICIT' ->
% 		   ?CONSTRUCTED;
% 	       _ ->
% 		   Form
% 	   end,
%     Bytes = encode_tag_val({Class,NewForm,No}),
%     {Bytes,size(Bytes)}.

%%===============================================================================
%%
%% This comment is valid for all the encode/decode functions
%%
%% C = Constraint -> typically {'ValueRange',LowerBound,UpperBound}
%%     used for PER-coding but not for BER-coding.
%%
%% Val = Value.  If Val is an atom then it is a symbolic integer value
%%       (i.e the atom must be one of the names in the NamedNumberList).
%%       The NamedNumberList is used to translate the atom to an integer value
%%       before encoding.
%%
%%===============================================================================

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% encode_open_type(Value) -> io_list (i.e nested list with integers, binaries)
%% Value = list of bytes of an already encoded value (the list must be flat)
%%         | binary

%%
encode_open_type(Val, T) when is_list(Val) ->
    encode_open_type(list_to_binary(Val), T);
encode_open_type(Val, []) -> {Val, size(Val)};
encode_open_type(Val, Tag) ->
    encode_tags(Tag, Val, size(Val)).

decode_open_type(Tlv, TagIn, Method) ->
    case match_tags(Tlv, TagIn) of
      Bin when is_binary(Bin) ->
	  {InnerTlv, _} = asn1rt_ber_bin_v2__decode(Bin, Method),
	  InnerTlv;
      TlvBytes -> TlvBytes
    end.

%%===============================================================================
%%===============================================================================
%%===============================================================================
%% Boolean, ITU_T X.690 Chapter 8.2
%%===============================================================================
%%===============================================================================
%%===============================================================================

%%===============================================================================
%% encode_boolean(Integer, ReversedTagList) -> {[Octet],Len}
%%===============================================================================

encode_boolean({Name, Val}, TagIn) when is_atom(Name) ->
    encode_boolean(Val, TagIn);
encode_boolean(true, TagIn) ->
    encode_tags(TagIn, [255], 1);
encode_boolean(false, TagIn) ->
    encode_tags(TagIn, [0], 1);
encode_boolean(X, _) ->
    exit({error, {asn1, {encode_boolean, X}}}).

%%===============================================================================
%% decode_boolean(BuffList, HasTag, TotalLen) -> {true, Remain, RemovedBytes} |
%%                                               {false, Remain, RemovedBytes}
%%===============================================================================
decode_boolean(Tlv, TagIn) ->
    Val = match_tags(Tlv, TagIn),
    case Val of
      <<0:8>> -> false;
      <<_:8>> -> true;
      _ -> exit({error, {asn1, {decode_boolean, Val}}})
    end.

%%===========================================================================
%% Integer, ITU_T X.690 Chapter 8.3

%% encode_integer(Constraint, Value, Tag) -> [octet list]
%% encode_integer(Constraint, Name, NamedNumberList, Tag) -> [octet list]
%%    Value = INTEGER | {Name,INTEGER}
%%    Tag = tag | notag
%%===========================================================================

encode_integer(C, Val, Tag) when is_integer(Val) ->
    encode_tags(Tag, encode_integer(C, Val));
encode_integer(C, {Name, Val}, Tag)
    when is_atom(Name) ->
    encode_integer(C, Val, Tag);
encode_integer(_C, Val, _Tag) ->
    exit({error, {asn1, {encode_integer, Val}}}).

encode_integer(C, Val, NamedNumberList, Tag)
    when is_atom(Val) ->
    case lists:keysearch(Val, 1, NamedNumberList) of
      {value, {_, NewVal}} ->
	  encode_tags(Tag, encode_integer(C, NewVal));
      _ ->
	  exit({error, {asn1, {encode_integer_namednumber, Val}}})
    end;
encode_integer(C, {_Name, Val}, NamedNumberList, Tag) ->
    encode_integer(C, Val, NamedNumberList, Tag);
encode_integer(C, Val, _NamedNumberList, Tag) ->
    encode_tags(Tag, encode_integer(C, Val)).

encode_integer(_, Val) ->
    Bytes = if Val >= 0 -> encode_integer_pos(Val, []);
	       true -> encode_integer_neg(Val, [])
	    end,
    {Bytes, length(Bytes)}.

encode_integer_pos(0, L = [B | _Acc]) when B < 128 -> L;
encode_integer_pos(N, Acc) ->
    encode_integer_pos(N bsr 8, [N band 255 | Acc]).

encode_integer_neg(-1, L = [B1 | _T]) when B1 > 127 ->
    L;
encode_integer_neg(N, Acc) ->
    encode_integer_neg(N bsr 8, [N band 255 | Acc]).

%%===============================================================================
%% decode integer
%%    (Buffer, Range, HasTag, TotalLen) -> {Integer, Remain, RemovedBytes}
%%    (Buffer, Range, NamedNumberList, HasTag, TotalLen) -> {Integer, Remain, RemovedBytes}
%%===============================================================================

decode_integer(Tlv, Range, NamedNumberList, TagIn) ->
    V = match_tags(Tlv, TagIn),
    Int = decode_integer(V),
    range_check_integer(Int, Range),
    number2name(Int, NamedNumberList).

decode_integer(Tlv, Range, TagIn) ->
    V = match_tags(Tlv, TagIn),
    Int = decode_integer(V),
    range_check_integer(Int, Range),
    Int.

%% decoding postitive integer values.
decode_integer(Bin = <<0:1, _:7, _/binary>>) ->
    Len = size(Bin),
    %    <<Int:Len/unit:8,Buffer2/binary>> = Bin,
    <<Int:Len/unit:8>> = Bin,
    Int;
%% decoding negative integer values.
decode_integer(Bin = <<1:1, B2:7, Bs/binary>>) ->
    Len = size(Bin),
    %    <<N:Len/unit:8,Buffer2/binary>> = <<B2,Bs/binary>>,
    <<N:Len/unit:8>> = <<B2, Bs/binary>>,
    Int = N - (1 bsl (8 * Len - 1)),
    Int.

range_check_integer(Int, Range) ->
    case Range of
      [] -> % No length constraint
	  Int;
      {Lb, Ub}
	  when Int >= Lb,
	       Ub >= Int -> % variable length constraint
	  Int;
      Int -> % fixed value constraint
	  Int;
      {_, _} ->
	  exit({error, {asn1, {integer_range, Range, Int}}});
      SingleValue when is_integer(SingleValue) ->
	  exit({error, {asn1, {integer_range, Range, Int}}});
      _ -> % some strange constraint that we don't support yet
	  Int
    end.

number2name(Int, []) -> Int;
number2name(Int, NamedNumberList) ->
    case lists:keysearch(Int, 2, NamedNumberList) of
      {value, {NamedVal, _}} -> NamedVal;
      _ -> Int
    end.

%%============================================================================
%% Enumerated value, ITU_T X.690 Chapter 8.4

%% encode enumerated value
%%============================================================================
encode_enumerated(Val, TagIn) when is_integer(Val) ->
    encode_tags(TagIn, encode_integer(false, Val));
encode_enumerated({Name, Val}, TagIn)
    when is_atom(Name) ->
    encode_enumerated(Val, TagIn).

%% The encode_enumerated functions below this line can be removed when the
%% new code generation is stable. (the functions might have to be kept here
%% a while longer for compatibility reasons)

%%============================================================================
%% decode enumerated value
%%   (Buffer, Range, NamedNumberList, HasTag, TotalLen) ->  Value
%%===========================================================================
decode_enumerated(Tlv, Range, NamedNumberList, Tags) ->
    Buffer = match_tags(Tlv, Tags),
    decode_enumerated_notag(Buffer, Range, NamedNumberList,
			    Tags).

decode_enumerated_notag(Buffer, _Range,
			{NamedNumberList, ExtList}, _Tags) ->
    IVal = decode_integer2(size(Buffer), Buffer),
    case decode_enumerated1(IVal, NamedNumberList) of
      {asn1_enum, IVal} -> decode_enumerated1(IVal, ExtList);
      EVal -> EVal
    end;
decode_enumerated_notag(Buffer, _Range, NNList,
			_Tags) ->
    IVal = decode_integer2(size(Buffer), Buffer),
    case decode_enumerated1(IVal, NNList) of
      {asn1_enum, _} ->
	  exit({error, {asn1, {illegal_enumerated, IVal}}});
      EVal -> EVal
    end.

decode_enumerated1(Val, NamedNumberList) ->
    %% it must be a named integer
    case lists:keysearch(Val, 2, NamedNumberList) of
      {value, {NamedVal, _}} -> NamedVal;
      _ -> {asn1_enum, Val}
    end.

%%============================================================================
%%
%% Real value, ITU_T X.690 Chapter 8.5
%%============================================================================
%%
%% encode real value
%%============================================================================

%%============================================================================
%% decode real value
%%
%% decode_real([OctetBufferList], tuple|value, tag|notag) ->
%%  {{Mantissa, Base, Exp} | realval | PLUS-INFINITY | MINUS-INFINITY | 0,
%%     RestBuff}
%%
%% only for base 2 and 10 decoding sofar!!
%%============================================================================

% decode_real2(Buffer, Form, Len) ->
%     <<First, Buffer2/binary>> = Buffer,
%     if
% 	First =:= 2#01000000 -> {'PLUS-INFINITY', Buffer2};
% 	First =:= 2#01000001 -> {'MINUS-INFINITY', Buffer2};
% 	First =:= 2#00000000 -> {0, Buffer2};
% 	true ->
% 	    %% have some check here to verify only supported bases (2)
% 	    <<B7:1,B6:1,B5_4:2,B3_2:2,B1_0:2>> = <<First>>,
% 		Sign = B6,
% 	    Base =
% 		case B5_4 of
% 		    0 -> 2;  % base 2, only one so far
% 		    _ -> exit({error,{asn1, {non_supported_base, First}}})
% 		end,
% 	    ScalingFactor =
% 		case B3_2 of
% 		    0 -> 0;  % no scaling so far
% 		    _ -> exit({error,{asn1, {non_supported_scaling, First}}})
% 		end,

% 	    {FirstLen,Exp,Buffer3} =
% 		case B1_0 of
% 		    0 ->
% 			<<_:1/unit:8,Buffer21/binary>> = Buffer2,
% 			{2, decode_integer2(1, Buffer2),Buffer21};
% 		    1 ->
% 			<<_:2/unit:8,Buffer21/binary>> = Buffer2,
% 			{3, decode_integer2(2, Buffer2)};
% 		    2 ->
% 			<<_:3/unit:8,Buffer21/binary>> = Buffer2,
% 			{4, decode_integer2(3, Buffer2)};
% 		    3 ->
% 			<<ExpLen1,RestBuffer/binary>> = Buffer2,
% 			<<_:ExpLen1/unit:8,RestBuffer2/binary>> = RestBuffer,
% 			{ ExpLen1 + 2,
% 			  decode_integer2(ExpLen1, RestBuffer, RemBytes1),
% 			  RestBuffer2}
% 		end,
% 	    Length = Len - FirstLen,
% 	    <<LongInt:Length/unit:8,RestBuff/binary>> = Buffer3,
% 	    {Mantissa, Buffer4} =
% 		if Sign =:= 0 ->

% 			{LongInt, RestBuff};%  sign plus,
% 		   true ->

% 			{-LongInt, RestBuff}%  sign minus
% 		end,
% 	    case Form of
% 		tuple ->
% 		    {Val,Buf,RemB} = Exp,
% 		    {{Mantissa, Base, {Val,Buf}}, Buffer4, RemBytes2+RemBytes3};
% 		_value ->
% 		    comming
% 	    end
%     end.

%%============================================================================
%% Bitstring value, ITU_T X.690 Chapter 8.6
%%
%% encode bitstring value
%%
%% bitstring NamedBitList
%% Val can be  of:
%% - [identifiers] where only named identifers are set to one,
%%   the Constraint must then have some information of the
%%   bitlength.
%% - [list of ones and zeroes] all bits
%% - integer value representing the bitlist
%% C is constrint Len, only valid when identifiers
%%============================================================================

%%=================================================================
%% Encode named bits
%%=================================================================

%%----------------------------------------
%% get_all_bitposes([list of named bits to set], named_bit_db, []) ->
%%   [sorted_list_of_bitpositions_to_set]
%%----------------------------------------

%%----------------------------------------
%% make_and_set_list(Len of list to return, [list of positions to set to 1])->
%% returns list of Len length, with all in SetPos set.
%% in positioning in list the first element is 0, the second 1 etc.., but
%% Len will make a list of length Len, not Len + 1.
%%    BitList = make_and_set_list(C, ToSetPos, 0),
%%----------------------------------------

%%=================================================================
%% Do the actual encoding
%%     ([bitlist]) -> {ListLen, UnusedBits, OctetList}
%%=================================================================

%%============================================================================
%% decode bitstring value
%%    (Buffer, Range, NamedNumberList, HasTag, TotalLen) -> {Integer, Remain, RemovedBytes}
%%============================================================================

decode_bit_string2(<<0>>, _NamedNumberList, BinOrOld) ->
    case BinOrOld of
      bin -> {0, <<>>};
      _ -> []
    end;
decode_bit_string2(<<Unused, Bits/binary>>,
		   NamedNumberList, BinOrOld) ->
    case NamedNumberList of
      [] ->
	  case BinOrOld of
	    bin -> {Unused, Bits};
	    _ -> decode_bitstring2(size(Bits), Unused, Bits)
	  end;
      _ ->
	  BitString = decode_bitstring2(size(Bits), Unused, Bits),
	  decode_bitstring_NNL(BitString, NamedNumberList)
    end.

%%----------------------------------------
%% Decode the in buffer to bits
%%----------------------------------------
decode_bitstring2(1, Unused,
		  <<B7:1, B6:1, B5:1, B4:1, B3:1, B2:1, B1:1, B0:1,
		    _/binary>>) ->
    lists:sublist([B7, B6, B5, B4, B3, B2, B1, B0],
		  8 - Unused);
decode_bitstring2(Len, Unused,
		  <<B7:1, B6:1, B5:1, B4:1, B3:1, B2:1, B1:1, B0:1,
		    Buffer/binary>>) ->
    [B7, B6, B5, B4, B3, B2, B1, B0 | decode_bitstring2(Len
							  - 1,
							Unused, Buffer)].

%%decode_bitstring2(1, Unused, Buffer) ->
%%    make_bits_of_int(hd(Buffer), 128, 8-Unused);
%%decode_bitstring2(Len, Unused, [BitVal | Buffer]) ->
%%    [B7, B6, B5, B4, B3, B2, B1, B0] = make_bits_of_int(BitVal, 128, 8),
%%    [B7, B6, B5, B4, B3, B2, B1, B0 |
%%     decode_bitstring2(Len - 1, Unused, Buffer)].

%%make_bits_of_int(_, _, 0) ->
%%    [];
%%make_bits_of_int(BitVal, MaskVal, Unused) when Unused > 0 ->
%%    X = case MaskVal band BitVal of
%%	    0 -> 0 ;
%%	    _ -> 1
%%	end,
%%    [X | make_bits_of_int(BitVal, MaskVal bsr 1, Unused - 1)].

%%----------------------------------------
%% Decode the bitlist to names
%%----------------------------------------

decode_bitstring_NNL(BitList, NamedNumberList) ->
    decode_bitstring_NNL(BitList, NamedNumberList, 0, []).

decode_bitstring_NNL([], _, _No, Result) ->
    lists:reverse(Result);
decode_bitstring_NNL([B | BitList],
		     [{Name, No} | NamedNumberList], No, Result) ->
    if B == 0 ->
	   decode_bitstring_NNL(BitList, NamedNumberList, No + 1,
				Result);
       true ->
	   decode_bitstring_NNL(BitList, NamedNumberList, No + 1,
				[Name | Result])
    end;
decode_bitstring_NNL([1 | BitList], NamedNumberList, No,
		     Result) ->
    decode_bitstring_NNL(BitList, NamedNumberList, No + 1,
			 [{bit, No} | Result]);
decode_bitstring_NNL([0 | BitList], NamedNumberList, No,
		     Result) ->
    decode_bitstring_NNL(BitList, NamedNumberList, No + 1,
			 Result).

%%============================================================================
%% Octet string, ITU_T X.690 Chapter 8.7
%%
%% encode octet string
%% The OctetList must be a flat list of integers in the range 0..255
%% the function does not check this because it takes to much time
%%============================================================================
encode_octet_string(_C, OctetList, TagIn)
    when is_binary(OctetList) ->
    encode_tags(TagIn, OctetList, size(OctetList));
encode_octet_string(_C, OctetList, TagIn)
    when is_list(OctetList) ->
    encode_tags(TagIn, OctetList, length(OctetList));
encode_octet_string(C, {Name, OctetList}, TagIn)
    when is_atom(Name) ->
    encode_octet_string(C, OctetList, TagIn).

%%============================================================================
%% decode octet string
%%    (Buffer, Range, HasTag, TotalLen) -> {String, Remain, RemovedBytes}
%%
%% Octet string is decoded as a restricted string
%%============================================================================
decode_octet_string(Buffer, Range, Tags) ->
    %    NewTags = new_tags(HasTag,#tag{class=?UNIVERSAL,number=?N_OCTET_STRING}),
    decode_restricted_string(Buffer, Range, 4, Tags, [],
			     old).

%%============================================================================
%% Null value, ITU_T X.690 Chapter 8.8
%%
%% encode NULL value
%%============================================================================

encode_null({Name, _Val}, TagIn) when is_atom(Name) ->
    encode_tags(TagIn, [], 0);
encode_null(_Val, TagIn) -> encode_tags(TagIn, [], 0).

%%============================================================================
%% decode NULL value
%%    (Buffer, HasTag, TotalLen) -> {NULL, Remain, RemovedBytes}
%%============================================================================

decode_null(Tlv, Tags) ->
    Val = match_tags(Tlv, Tags),
    case Val of
      <<>> -> 'NULL';
      _ -> exit({error, {asn1, {decode_null, Val}}})
    end.

%%============================================================================
%% Object identifier, ITU_T X.690 Chapter 8.19
%%
%% encode Object Identifier value
%%============================================================================

encode_object_identifier({Name, Val}, TagIn)
    when is_atom(Name) ->
    encode_object_identifier(Val, TagIn);
encode_object_identifier(Val, TagIn) ->
    encode_tags(TagIn, e_object_identifier(Val)).

e_object_identifier({'OBJECT IDENTIFIER', V}) ->
    e_object_identifier(V);
e_object_identifier({Cname, V})
    when is_atom(Cname), is_tuple(V) ->
    e_object_identifier(tuple_to_list(V));
e_object_identifier({Cname, V})
    when is_atom(Cname), is_list(V) ->
    e_object_identifier(V);
e_object_identifier(V) when is_tuple(V) ->
    e_object_identifier(tuple_to_list(V));
%%%%%%%%%%%%%%%
%% e_object_identifier([List of Obect Identifiers]) ->
%% {[Encoded Octetlist of ObjIds], IntLength}
%%
e_object_identifier([E1, E2 | Tail]) ->
    Head = 40 * E1 + E2,  % wow!
    {H, Lh} = mk_object_val(Head),
    {R, Lr} = lists:mapfoldl(fun enc_obj_id_tail/2, 0,
			     Tail),
    {[H | R], Lh + Lr}.

enc_obj_id_tail(H, Len) ->
    {B, L} = mk_object_val(H), {B, Len + L}.

%%%%%%%%%%%
%% mk_object_val(Value) -> {OctetList, Len}
%% returns a Val as a list of octets, the 8 bit is allways set to one except
%% for the last octet, where its 0
%%

mk_object_val(Val) when Val =< 127 ->
    {[255 band Val], 1};
mk_object_val(Val) ->
    mk_object_val(Val bsr 7, [Val band 127], 1).

mk_object_val(0, Ack, Len) -> {Ack, Len};
mk_object_val(Val, Ack, Len) ->
    mk_object_val(Val bsr 7, [Val band 127 bor 128 | Ack],
		  Len + 1).

%%============================================================================
%% decode Object Identifier value
%%    (Buffer, HasTag, TotalLen) -> {{ObjId}, Remain, RemovedBytes}
%%============================================================================

decode_object_identifier(Tlv, Tags) ->
    Val = match_tags(Tlv, Tags),
    [AddedObjVal | ObjVals] = dec_subidentifiers(Val, 0,
						 []),
    {Val1, Val2} = if AddedObjVal < 40 -> {0, AddedObjVal};
		      AddedObjVal < 80 -> {1, AddedObjVal - 40};
		      true -> {2, AddedObjVal - 80}
		   end,
    list_to_tuple([Val1, Val2 | ObjVals]).

dec_subidentifiers(<<>>, _Av, Al) -> lists:reverse(Al);
dec_subidentifiers(<<1:1, H:7, T/binary>>, Av, Al) ->
    dec_subidentifiers(T, Av bsl 7 + H, Al);
dec_subidentifiers(<<H, T/binary>>, Av, Al) ->
    dec_subidentifiers(T, 0, [Av bsl 7 + H | Al]).

%%============================================================================
%% decode Numeric Printable Teletex Videotex Visible IA5 Graphic General strings
%%    (Buffer, Range, StringType, HasTag, TotalLen) ->
%%                                  {String, Remain, RemovedBytes}
%%============================================================================

decode_restricted_string(Tlv, Range, StringType, TagsIn,
			 NamedNumberList, BinOrOld) ->
    Val = match_tags(Tlv, TagsIn),
    Val2 = case Val of
	     PartList = [_H | _T] -> % constructed val
		 Bin = collect_parts(PartList),
		 decode_restricted(Bin, StringType, NamedNumberList,
				   BinOrOld);
	     Bin ->
		 decode_restricted(Bin, StringType, NamedNumberList,
				   BinOrOld)
	   end,
    check_and_convert_restricted_string(Val2, StringType,
					Range, NamedNumberList, BinOrOld).

% 	case StringType of
% 	    ?N_BIT_STRING when BinOrOld == bin ->
% 		{concat_bit_binaries(AccVal, Val), AccRb+Rb};
% 	    _ when is_binary(Val),is_binary(AccVal) ->
% 		{<<AccVal/binary,Val/binary>>,AccRb+Rb};
% 	    _ when is_binary(Val), AccVal==[] ->
% 		{Val,AccRb+Rb};				
% 	    _ ->	
% 		{AccVal++Val, AccRb+Rb}
% 	end,

decode_restricted(Bin, StringType, NamedNumberList,
		  BinOrOld) ->
    case StringType of
      3 -> decode_bit_string2(Bin, NamedNumberList, BinOrOld);
      28 -> mk_universal_string(binary_to_list(Bin));
      30 -> mk_BMP_string(binary_to_list(Bin));
      _ -> Bin
    end.

check_and_convert_restricted_string(Val, StringType,
				    Range, NamedNumberList, _BinOrOld) ->
    {StrLen, NewVal} = case StringType of
			 3 when NamedNumberList /= [] -> {no_check, Val};
			 3 when is_list(Val) -> {length(Val), Val};
			 3 when is_tuple(Val) ->
			     {size(element(2, Val)) * 8 - element(1, Val), Val};
			 _ when is_binary(Val) ->
			     {size(Val), binary_to_list(Val)};
			 _ when is_list(Val) -> {length(Val), Val}
		       end,
    case Range of
      _ when StrLen == no_check -> NewVal;
      [] -> % No length constraint
	  NewVal;
      {Lb, Ub}
	  when StrLen >= Lb,
	       Ub >= StrLen -> % variable length constraint
	  NewVal;
      {{Lb, _Ub}, []} when StrLen >= Lb -> NewVal;
      {{Lb, _Ub}, _Ext = [Min | _]}
	  when StrLen >= Lb; StrLen >= Min ->
	  NewVal;
      {{Lb1, Ub1}, {Lb2, Ub2}}
	  when StrLen >= Lb1, StrLen =< Ub1;
	       StrLen =< Ub2, StrLen >= Lb2 ->
	  NewVal;
      StrLen -> % fixed length constraint
	  NewVal;
      {_, _} -> exit({error, {asn1, {length, Range, Val}}});
      _Len when is_integer(_Len) ->
	  exit({error, {asn1, {length, Range, Val}}});
      _ -> % some strange constraint that we don't support yet
	  NewVal
    end.

%%============================================================================
%% encode Universal string
%%============================================================================

%%===========================================================================
%% decode Universal strings
%%    (Buffer, Range, StringType, HasTag, LenIn) ->
%%                           {String, Remain, RemovedBytes}
%%===========================================================================

mk_universal_string(In) -> mk_universal_string(In, []).

mk_universal_string([], Acc) -> lists:reverse(Acc);
mk_universal_string([0, 0, 0, D | T], Acc) ->
    mk_universal_string(T, [D | Acc]);
mk_universal_string([A, B, C, D | T], Acc) ->
    mk_universal_string(T, [{A, B, C, D} | Acc]).

%%============================================================================
%% encode UTF8 string
%%============================================================================

%%============================================================================
%% decode UTF8 string
%%============================================================================

%%============================================================================
%% encode BMP string
%%============================================================================

mk_BMP_string(In) -> mk_BMP_string(In, []).

mk_BMP_string([], US) -> lists:reverse(US);
mk_BMP_string([0, B | T], US) ->
    mk_BMP_string(T, [B | US]);
mk_BMP_string([C, D | T], US) ->
    mk_BMP_string(T, [{0, 0, C, D} | US]).

%%============================================================================
%% Generalized time, ITU_T X.680 Chapter 39
%%
%% encode Generalized time
%%============================================================================

%%============================================================================
%% decode Generalized time
%%    (Buffer, Range, HasTag, TotalLen) -> {String, Remain, RemovedBytes}
%%============================================================================

%%============================================================================
%% Universal time, ITU_T X.680 Chapter 40
%%
%% encode UTC time
%%============================================================================

%%============================================================================
%% decode UTC time
%%    (Buffer, Range, HasTag, TotalLen) -> {String, Remain, RemovedBytes}
%%============================================================================

%%============================================================================
%% Length handling
%%
%% Encode length
%%
%% encode_length(Int | indefinite) ->
%%          [<127]| [128 + Int (<127),OctetList] | [16#80]
%%============================================================================

encode_length(indefinite) ->
    {[128], 1}; % 128
encode_length(L) when L =< 127 -> {[L], 1};
encode_length(L) ->
    Oct = minimum_octets(L),
    Len = length(Oct),
    if Len =< 126 -> {[128 + Len | Oct], Len + 1};
       true -> exit({error, {asn1, to_long_length_oct, Len}})
    end.

%% Val must be >= 0
minimum_octets(Val) -> minimum_octets(Val, []).

minimum_octets(0, Acc) -> Acc;
minimum_octets(Val, Acc) ->
    minimum_octets(Val bsr 8, [Val band 255 | Acc]).

%%===========================================================================
%% Decode length
%%
%% decode_length(OctetList) -> {{indefinite, RestOctetsL}, NoRemovedBytes} |
%%                             {{Length, RestOctetsL}, NoRemovedBytes}
%%===========================================================================

decode_length(<<1:1, 0:7, T/binary>>) ->
    {indefinite, T};
decode_length(<<0:1, Length:7, T/binary>>) ->
    {Length, T};
decode_length(<<1:1, LL:7, T/binary>>) ->
    <<Length:LL/unit:8, Rest/binary>> = T, {Length, Rest}.

%%-------------------------------------------------------------------------
%% INTERNAL HELPER FUNCTIONS (not exported)
%%-------------------------------------------------------------------------

%% decoding postitive integer values.
decode_integer2(Len, Bin = <<0:1, _:7, _Bs/binary>>) ->
    <<Int:Len/unit:8>> = Bin, Int;
%% decoding negative integer values.
decode_integer2(Len, <<1:1, B2:7, Bs/binary>>) ->
    <<N:Len/unit:8>> = <<B2, Bs/binary>>,
    Int = N - (1 bsl (8 * Len - 1)),
    Int.

collect_parts(TlvList) -> collect_parts(TlvList, []).

collect_parts([{_, L} | Rest], Acc) when is_list(L) ->
    collect_parts(Rest, [collect_parts(L) | Acc]);
collect_parts([{3, <<Unused, Bits/binary>>} | Rest],
	      _Acc) ->
    collect_parts_bit(Rest, [Bits], Unused);
collect_parts([{_T, V} | Rest], Acc) ->
    collect_parts(Rest, [V | Acc]);
collect_parts([], Acc) ->
    list_to_binary(lists:reverse(Acc)).

collect_parts_bit([{3, <<Unused, Bits/binary>>} | Rest],
		  Acc, Uacc) ->
    collect_parts_bit(Rest, [Bits | Acc], Unused + Uacc);
collect_parts_bit([], Acc, Uacc) ->
    list_to_binary([Uacc | lists:reverse(Acc)]).

%% =====================================================================
%% 
%% The following code stems from module `asn1rt_check'.
%% 

%%
%% %CopyrightBegin%
%%
%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
%%
%% %CopyrightEnd%
%%
%%

check_bool(_Bool, asn1_DEFAULT) -> true;
check_bool(Bool, Bool)
    when Bool == true; Bool == false ->
    true;
check_bool(_Bool1, Bool2) -> throw({error, Bool2}).

check_objectidentifier(_, asn1_DEFAULT) -> true;
check_objectidentifier(OI, OI) -> true;
check_objectidentifier(DOI, OI)
    when is_tuple(DOI), is_tuple(OI) ->
    check_objectidentifier1(tuple_to_list(DOI),
			    tuple_to_list(OI));
check_objectidentifier(_, OI) -> throw({error, OI}).

check_objectidentifier1([V | Rest1], [V | Rest2]) ->
    check_objectidentifier1(Rest1, Rest2, V);
check_objectidentifier1([V1 | Rest1], [V2 | Rest2]) ->
    case reserved_objectid(V2, []) of
      V1 -> check_objectidentifier1(Rest1, Rest2, [V1]);
      V -> throw({error, V})
    end.

check_objectidentifier1([V | Rest1], [V | Rest2],
			Above) ->
    check_objectidentifier1(Rest1, Rest2, [V | Above]);
check_objectidentifier1([V1 | Rest1], [V2 | Rest2],
			Above) ->
    case reserved_objectid(V2, Above) of
      V1 ->
	  check_objectidentifier1(Rest1, Rest2, [V1 | Above]);
      V -> throw({error, V})
    end;
check_objectidentifier1([], [], _) -> true;
check_objectidentifier1(_, V, _) ->
    throw({error, object, identifier, V}).

%% ITU-T Rec. X.680 Annex B - D
reserved_objectid('itu-t', []) -> 0;
reserved_objectid(ccitt, []) -> 0;
%% arcs below "itu-t"
reserved_objectid(recommendation, [0]) -> 0;
reserved_objectid(question, [0]) -> 1;
reserved_objectid(administration, [0]) -> 2;
reserved_objectid('network-operator', [0]) -> 3;
reserved_objectid('identified-organization', [0]) -> 4;
reserved_objectid(iso, []) -> 1;
%% arcs below "iso", note that number 1 is not used
reserved_objectid(standard, [1]) -> 0;
reserved_objectid('member-body', [1]) -> 2;
reserved_objectid('identified-organization', [1]) -> 3;
reserved_objectid('joint-iso-itu-t', []) -> 2;
reserved_objectid('joint-iso-ccitt', []) -> 2;
reserved_objectid(_, _) -> false.

%% dynamicsort_SETOF(Arg) -> Res
%% Arg -> list()
%% Res -> list()
%% Sorts the elements in Arg in increasing size
dynamicsort_SETOF(ListOfEncVal) ->
    BinL = [dynamicsort_SETOF_1(V1) || V1 <- ListOfEncVal],
    lists:sort(BinL).

dynamicsort_SETOF_1(L) when is_list(L) ->
    list_to_binary(L);
dynamicsort_SETOF_1(B) -> B.

%% =====================================================================
%% 
%% The following code stems from module `asn1rt'.
%% 

%%
%% %CopyrightBegin%
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
%%
%% %CopyrightEnd%
%%
%%

%% Runtime functions for ASN.1 (i.e encode, decode)

%%<<< -deprecated([{load_driver, 0}, {unload_driver, 0}]).

%% macros used for utf8 encoding

