diff --git a/libtomcrypt_VS2008.vcproj b/libtomcrypt_VS2008.vcproj
index 5837b6f33..6cc6aeee5 100644
--- a/libtomcrypt_VS2008.vcproj
+++ b/libtomcrypt_VS2008.vcproj
@@ -1591,6 +1591,26 @@
>
+
+
+
+
+
+
+
+
+
+
@@ -1871,6 +1891,10 @@
+
+
@@ -2092,6 +2116,10 @@
RelativePath="src\pk\asn1\der\sequence\der_encode_sequence_multi.c"
>
+
+
@@ -2182,7 +2210,7 @@
Name="oid"
>
+
+
+
+
@@ -2294,6 +2330,14 @@
RelativePath="src\pk\dsa\dsa_import.c"
>
+
+
+
+
diff --git a/makefile.mingw b/makefile.mingw
index 7a691f0b8..3746fb31b 100644
--- a/makefile.mingw
+++ b/makefile.mingw
@@ -111,6 +111,7 @@ src/misc/crypt/crypt_unregister_cipher.o src/misc/crypt/crypt_unregister_hash.o
src/misc/crypt/crypt_unregister_prng.o src/misc/error_to_string.o src/misc/hkdf/hkdf.o \
src/misc/hkdf/hkdf_test.o src/misc/mem_neq.o src/misc/padding/padding_depad.o \
src/misc/padding/padding_pad.o src/misc/pbes/pbes.o src/misc/pbes/pbes1.o src/misc/pbes/pbes2.o \
+src/misc/pem/pem.o src/misc/pem/pem_pkcs.o src/misc/pem/pem_read.o src/misc/pem/pem_ssh.o \
src/misc/pkcs12/pkcs12_kdf.o src/misc/pkcs12/pkcs12_utf8_to_utf16.o src/misc/pkcs5/pkcs_5_1.o \
src/misc/pkcs5/pkcs_5_2.o src/misc/pkcs5/pkcs_5_test.o src/misc/ssh/ssh_decode_sequence_multi.o \
src/misc/ssh/ssh_encode_sequence_multi.o src/misc/zeromem.o src/modes/cbc/cbc_decrypt.o \
@@ -158,7 +159,8 @@ src/pk/asn1/der/sequence/der_decode_sequence_ex.o \
src/pk/asn1/der/sequence/der_decode_sequence_flexi.o \
src/pk/asn1/der/sequence/der_decode_sequence_multi.o \
src/pk/asn1/der/sequence/der_encode_sequence_ex.o \
-src/pk/asn1/der/sequence/der_encode_sequence_multi.o src/pk/asn1/der/sequence/der_length_sequence.o \
+src/pk/asn1/der/sequence/der_encode_sequence_multi.o \
+src/pk/asn1/der/sequence/der_flexi_sequence_cmp.o src/pk/asn1/der/sequence/der_length_sequence.o \
src/pk/asn1/der/sequence/der_sequence_free.o src/pk/asn1/der/sequence/der_sequence_shrink.o \
src/pk/asn1/der/set/der_encode_set.o src/pk/asn1/der/set/der_encode_setof.o \
src/pk/asn1/der/short_integer/der_decode_short_integer.o \
@@ -169,15 +171,17 @@ src/pk/asn1/der/teletex_string/der_length_teletex_string.o \
src/pk/asn1/der/utctime/der_decode_utctime.o src/pk/asn1/der/utctime/der_encode_utctime.o \
src/pk/asn1/der/utctime/der_length_utctime.o src/pk/asn1/der/utf8/der_decode_utf8_string.o \
src/pk/asn1/der/utf8/der_encode_utf8_string.o src/pk/asn1/der/utf8/der_length_utf8_string.o \
-src/pk/asn1/oid/pk_get_oid.o src/pk/asn1/oid/pk_oid_cmp.o src/pk/asn1/oid/pk_oid_str.o \
-src/pk/asn1/pkcs8/pkcs8_decode_flexi.o src/pk/asn1/x509/x509_decode_public_key_from_certificate.o \
+src/pk/asn1/oid/pk_get.o src/pk/asn1/oid/pk_oid_cmp.o src/pk/asn1/oid/pk_oid_str.o \
+src/pk/asn1/pkcs8/pkcs8_decode_flexi.o src/pk/asn1/pkcs8/pkcs8_get.o \
+src/pk/asn1/x509/x509_decode_public_key_from_certificate.o \
src/pk/asn1/x509/x509_decode_subject_public_key_info.o \
src/pk/asn1/x509/x509_encode_subject_public_key_info.o src/pk/dh/dh.o src/pk/dh/dh_check_pubkey.o \
src/pk/dh/dh_export.o src/pk/dh/dh_export_key.o src/pk/dh/dh_free.o src/pk/dh/dh_generate_key.o \
-src/pk/dh/dh_import.o src/pk/dh/dh_set.o src/pk/dh/dh_set_pg_dhparam.o src/pk/dh/dh_shared_secret.o \
-src/pk/dsa/dsa_decrypt_key.o src/pk/dsa/dsa_encrypt_key.o src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o \
-src/pk/dsa/dsa_generate_key.o src/pk/dsa/dsa_generate_pqg.o src/pk/dsa/dsa_import.o \
-src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_set.o src/pk/dsa/dsa_set_pqg_dsaparam.o \
+src/pk/dh/dh_import.o src/pk/dh/dh_import_pkcs8.o src/pk/dh/dh_set.o src/pk/dh/dh_set_pg_dhparam.o \
+src/pk/dh/dh_shared_secret.o src/pk/dsa/dsa_decrypt_key.o src/pk/dsa/dsa_encrypt_key.o \
+src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o src/pk/dsa/dsa_generate_key.o \
+src/pk/dsa/dsa_generate_pqg.o src/pk/dsa/dsa_import.o src/pk/dsa/dsa_import_pkcs8.o \
+src/pk/dsa/dsa_init.o src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_set.o src/pk/dsa/dsa_set_pqg_dsaparam.o \
src/pk/dsa/dsa_shared_secret.o src/pk/dsa/dsa_sign_hash.o src/pk/dsa/dsa_verify_hash.o \
src/pk/dsa/dsa_verify_key.o src/pk/ec25519/ec25519_crypto_ctx.o src/pk/ec25519/ec25519_export.o \
src/pk/ec25519/ec25519_import_pkcs8.o src/pk/ec25519/tweetnacl.o src/pk/ecc/ecc.o \
@@ -196,12 +200,12 @@ src/pk/ecc/ltc_ecc_projective_add_point.o src/pk/ecc/ltc_ecc_projective_dbl_poin
src/pk/ecc/ltc_ecc_verify_key.o src/pk/ed25519/ed25519_export.o src/pk/ed25519/ed25519_import.o \
src/pk/ed25519/ed25519_import_pkcs8.o src/pk/ed25519/ed25519_import_raw.o \
src/pk/ed25519/ed25519_import_x509.o src/pk/ed25519/ed25519_make_key.o src/pk/ed25519/ed25519_sign.o \
-src/pk/ed25519/ed25519_verify.o src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o \
-src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o \
-src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/pkcs1/pkcs_1_v1_5_decode.o \
-src/pk/pkcs1/pkcs_1_v1_5_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o \
-src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_get_size.o src/pk/rsa/rsa_import.o \
-src/pk/rsa/rsa_import_pkcs8.o src/pk/rsa/rsa_import_x509.o src/pk/rsa/rsa_key.o \
+src/pk/ed25519/ed25519_verify.o src/pk/pka_key_free.o src/pk/pkcs1/pkcs_1_i2osp.o \
+src/pk/pkcs1/pkcs_1_mgf1.o src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o \
+src/pk/pkcs1/pkcs_1_os2ip.o src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o \
+src/pk/pkcs1/pkcs_1_v1_5_decode.o src/pk/pkcs1/pkcs_1_v1_5_encode.o src/pk/rsa/rsa_decrypt_key.o \
+src/pk/rsa/rsa_encrypt_key.o src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_get_size.o \
+src/pk/rsa/rsa_import.o src/pk/rsa/rsa_import_pkcs8.o src/pk/rsa/rsa_import_x509.o src/pk/rsa/rsa_key.o \
src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_set.o src/pk/rsa/rsa_sign_hash.o \
src/pk/rsa/rsa_sign_saltlen_get.o src/pk/rsa/rsa_verify_hash.o src/pk/x25519/x25519_export.o \
src/pk/x25519/x25519_import.o src/pk/x25519/x25519_import_pkcs8.o src/pk/x25519/x25519_import_raw.o \
@@ -227,7 +231,7 @@ TOBJECTS=tests/base16_test.o tests/base32_test.o tests/base64_test.o tests/bcryp
tests/cipher_hash_test.o tests/common.o tests/der_test.o tests/dh_test.o tests/dsa_test.o \
tests/ecc_test.o tests/ed25519_test.o tests/file_test.o tests/mac_test.o tests/misc_test.o \
tests/modes_test.o tests/mpi_test.o tests/multi_test.o tests/no_null_termination_check_test.o \
-tests/no_prng.o tests/padding_test.o tests/pkcs_1_eme_test.o tests/pkcs_1_emsa_test.o \
+tests/no_prng.o tests/padding_test.o tests/pem_test.o tests/pkcs_1_eme_test.o tests/pkcs_1_emsa_test.o \
tests/pkcs_1_oaep_test.o tests/pkcs_1_pss_test.o tests/pkcs_1_test.o tests/prng_test.o \
tests/rotate_test.o tests/rsa_test.o tests/ssh_test.o tests/store_test.o tests/test.o tests/x25519_test.o
diff --git a/makefile.msvc b/makefile.msvc
index 1a0472195..217f87510 100644
--- a/makefile.msvc
+++ b/makefile.msvc
@@ -104,6 +104,7 @@ src/misc/crypt/crypt_unregister_cipher.obj src/misc/crypt/crypt_unregister_hash.
src/misc/crypt/crypt_unregister_prng.obj src/misc/error_to_string.obj src/misc/hkdf/hkdf.obj \
src/misc/hkdf/hkdf_test.obj src/misc/mem_neq.obj src/misc/padding/padding_depad.obj \
src/misc/padding/padding_pad.obj src/misc/pbes/pbes.obj src/misc/pbes/pbes1.obj src/misc/pbes/pbes2.obj \
+src/misc/pem/pem.obj src/misc/pem/pem_pkcs.obj src/misc/pem/pem_read.obj src/misc/pem/pem_ssh.obj \
src/misc/pkcs12/pkcs12_kdf.obj src/misc/pkcs12/pkcs12_utf8_to_utf16.obj src/misc/pkcs5/pkcs_5_1.obj \
src/misc/pkcs5/pkcs_5_2.obj src/misc/pkcs5/pkcs_5_test.obj src/misc/ssh/ssh_decode_sequence_multi.obj \
src/misc/ssh/ssh_encode_sequence_multi.obj src/misc/zeromem.obj src/modes/cbc/cbc_decrypt.obj \
@@ -151,7 +152,8 @@ src/pk/asn1/der/sequence/der_decode_sequence_ex.obj \
src/pk/asn1/der/sequence/der_decode_sequence_flexi.obj \
src/pk/asn1/der/sequence/der_decode_sequence_multi.obj \
src/pk/asn1/der/sequence/der_encode_sequence_ex.obj \
-src/pk/asn1/der/sequence/der_encode_sequence_multi.obj src/pk/asn1/der/sequence/der_length_sequence.obj \
+src/pk/asn1/der/sequence/der_encode_sequence_multi.obj \
+src/pk/asn1/der/sequence/der_flexi_sequence_cmp.obj src/pk/asn1/der/sequence/der_length_sequence.obj \
src/pk/asn1/der/sequence/der_sequence_free.obj src/pk/asn1/der/sequence/der_sequence_shrink.obj \
src/pk/asn1/der/set/der_encode_set.obj src/pk/asn1/der/set/der_encode_setof.obj \
src/pk/asn1/der/short_integer/der_decode_short_integer.obj \
@@ -162,15 +164,17 @@ src/pk/asn1/der/teletex_string/der_length_teletex_string.obj \
src/pk/asn1/der/utctime/der_decode_utctime.obj src/pk/asn1/der/utctime/der_encode_utctime.obj \
src/pk/asn1/der/utctime/der_length_utctime.obj src/pk/asn1/der/utf8/der_decode_utf8_string.obj \
src/pk/asn1/der/utf8/der_encode_utf8_string.obj src/pk/asn1/der/utf8/der_length_utf8_string.obj \
-src/pk/asn1/oid/pk_get_oid.obj src/pk/asn1/oid/pk_oid_cmp.obj src/pk/asn1/oid/pk_oid_str.obj \
-src/pk/asn1/pkcs8/pkcs8_decode_flexi.obj src/pk/asn1/x509/x509_decode_public_key_from_certificate.obj \
+src/pk/asn1/oid/pk_get.obj src/pk/asn1/oid/pk_oid_cmp.obj src/pk/asn1/oid/pk_oid_str.obj \
+src/pk/asn1/pkcs8/pkcs8_decode_flexi.obj src/pk/asn1/pkcs8/pkcs8_get.obj \
+src/pk/asn1/x509/x509_decode_public_key_from_certificate.obj \
src/pk/asn1/x509/x509_decode_subject_public_key_info.obj \
src/pk/asn1/x509/x509_encode_subject_public_key_info.obj src/pk/dh/dh.obj src/pk/dh/dh_check_pubkey.obj \
src/pk/dh/dh_export.obj src/pk/dh/dh_export_key.obj src/pk/dh/dh_free.obj src/pk/dh/dh_generate_key.obj \
-src/pk/dh/dh_import.obj src/pk/dh/dh_set.obj src/pk/dh/dh_set_pg_dhparam.obj src/pk/dh/dh_shared_secret.obj \
-src/pk/dsa/dsa_decrypt_key.obj src/pk/dsa/dsa_encrypt_key.obj src/pk/dsa/dsa_export.obj src/pk/dsa/dsa_free.obj \
-src/pk/dsa/dsa_generate_key.obj src/pk/dsa/dsa_generate_pqg.obj src/pk/dsa/dsa_import.obj \
-src/pk/dsa/dsa_make_key.obj src/pk/dsa/dsa_set.obj src/pk/dsa/dsa_set_pqg_dsaparam.obj \
+src/pk/dh/dh_import.obj src/pk/dh/dh_import_pkcs8.obj src/pk/dh/dh_set.obj src/pk/dh/dh_set_pg_dhparam.obj \
+src/pk/dh/dh_shared_secret.obj src/pk/dsa/dsa_decrypt_key.obj src/pk/dsa/dsa_encrypt_key.obj \
+src/pk/dsa/dsa_export.obj src/pk/dsa/dsa_free.obj src/pk/dsa/dsa_generate_key.obj \
+src/pk/dsa/dsa_generate_pqg.obj src/pk/dsa/dsa_import.obj src/pk/dsa/dsa_import_pkcs8.obj \
+src/pk/dsa/dsa_init.obj src/pk/dsa/dsa_make_key.obj src/pk/dsa/dsa_set.obj src/pk/dsa/dsa_set_pqg_dsaparam.obj \
src/pk/dsa/dsa_shared_secret.obj src/pk/dsa/dsa_sign_hash.obj src/pk/dsa/dsa_verify_hash.obj \
src/pk/dsa/dsa_verify_key.obj src/pk/ec25519/ec25519_crypto_ctx.obj src/pk/ec25519/ec25519_export.obj \
src/pk/ec25519/ec25519_import_pkcs8.obj src/pk/ec25519/tweetnacl.obj src/pk/ecc/ecc.obj \
@@ -189,12 +193,12 @@ src/pk/ecc/ltc_ecc_projective_add_point.obj src/pk/ecc/ltc_ecc_projective_dbl_po
src/pk/ecc/ltc_ecc_verify_key.obj src/pk/ed25519/ed25519_export.obj src/pk/ed25519/ed25519_import.obj \
src/pk/ed25519/ed25519_import_pkcs8.obj src/pk/ed25519/ed25519_import_raw.obj \
src/pk/ed25519/ed25519_import_x509.obj src/pk/ed25519/ed25519_make_key.obj src/pk/ed25519/ed25519_sign.obj \
-src/pk/ed25519/ed25519_verify.obj src/pk/pkcs1/pkcs_1_i2osp.obj src/pk/pkcs1/pkcs_1_mgf1.obj \
-src/pk/pkcs1/pkcs_1_oaep_decode.obj src/pk/pkcs1/pkcs_1_oaep_encode.obj src/pk/pkcs1/pkcs_1_os2ip.obj \
-src/pk/pkcs1/pkcs_1_pss_decode.obj src/pk/pkcs1/pkcs_1_pss_encode.obj src/pk/pkcs1/pkcs_1_v1_5_decode.obj \
-src/pk/pkcs1/pkcs_1_v1_5_encode.obj src/pk/rsa/rsa_decrypt_key.obj src/pk/rsa/rsa_encrypt_key.obj \
-src/pk/rsa/rsa_export.obj src/pk/rsa/rsa_exptmod.obj src/pk/rsa/rsa_get_size.obj src/pk/rsa/rsa_import.obj \
-src/pk/rsa/rsa_import_pkcs8.obj src/pk/rsa/rsa_import_x509.obj src/pk/rsa/rsa_key.obj \
+src/pk/ed25519/ed25519_verify.obj src/pk/pka_key_free.obj src/pk/pkcs1/pkcs_1_i2osp.obj \
+src/pk/pkcs1/pkcs_1_mgf1.obj src/pk/pkcs1/pkcs_1_oaep_decode.obj src/pk/pkcs1/pkcs_1_oaep_encode.obj \
+src/pk/pkcs1/pkcs_1_os2ip.obj src/pk/pkcs1/pkcs_1_pss_decode.obj src/pk/pkcs1/pkcs_1_pss_encode.obj \
+src/pk/pkcs1/pkcs_1_v1_5_decode.obj src/pk/pkcs1/pkcs_1_v1_5_encode.obj src/pk/rsa/rsa_decrypt_key.obj \
+src/pk/rsa/rsa_encrypt_key.obj src/pk/rsa/rsa_export.obj src/pk/rsa/rsa_exptmod.obj src/pk/rsa/rsa_get_size.obj \
+src/pk/rsa/rsa_import.obj src/pk/rsa/rsa_import_pkcs8.obj src/pk/rsa/rsa_import_x509.obj src/pk/rsa/rsa_key.obj \
src/pk/rsa/rsa_make_key.obj src/pk/rsa/rsa_set.obj src/pk/rsa/rsa_sign_hash.obj \
src/pk/rsa/rsa_sign_saltlen_get.obj src/pk/rsa/rsa_verify_hash.obj src/pk/x25519/x25519_export.obj \
src/pk/x25519/x25519_import.obj src/pk/x25519/x25519_import_pkcs8.obj src/pk/x25519/x25519_import_raw.obj \
@@ -220,7 +224,7 @@ TOBJECTS=tests/base16_test.obj tests/base32_test.obj tests/base64_test.obj tests
tests/cipher_hash_test.obj tests/common.obj tests/der_test.obj tests/dh_test.obj tests/dsa_test.obj \
tests/ecc_test.obj tests/ed25519_test.obj tests/file_test.obj tests/mac_test.obj tests/misc_test.obj \
tests/modes_test.obj tests/mpi_test.obj tests/multi_test.obj tests/no_null_termination_check_test.obj \
-tests/no_prng.obj tests/padding_test.obj tests/pkcs_1_eme_test.obj tests/pkcs_1_emsa_test.obj \
+tests/no_prng.obj tests/padding_test.obj tests/pem_test.obj tests/pkcs_1_eme_test.obj tests/pkcs_1_emsa_test.obj \
tests/pkcs_1_oaep_test.obj tests/pkcs_1_pss_test.obj tests/pkcs_1_test.obj tests/prng_test.obj \
tests/rotate_test.obj tests/rsa_test.obj tests/ssh_test.obj tests/store_test.obj tests/test.obj tests/x25519_test.obj
diff --git a/makefile.unix b/makefile.unix
index c25b286f2..24f276b17 100644
--- a/makefile.unix
+++ b/makefile.unix
@@ -121,6 +121,7 @@ src/misc/crypt/crypt_unregister_cipher.o src/misc/crypt/crypt_unregister_hash.o
src/misc/crypt/crypt_unregister_prng.o src/misc/error_to_string.o src/misc/hkdf/hkdf.o \
src/misc/hkdf/hkdf_test.o src/misc/mem_neq.o src/misc/padding/padding_depad.o \
src/misc/padding/padding_pad.o src/misc/pbes/pbes.o src/misc/pbes/pbes1.o src/misc/pbes/pbes2.o \
+src/misc/pem/pem.o src/misc/pem/pem_pkcs.o src/misc/pem/pem_read.o src/misc/pem/pem_ssh.o \
src/misc/pkcs12/pkcs12_kdf.o src/misc/pkcs12/pkcs12_utf8_to_utf16.o src/misc/pkcs5/pkcs_5_1.o \
src/misc/pkcs5/pkcs_5_2.o src/misc/pkcs5/pkcs_5_test.o src/misc/ssh/ssh_decode_sequence_multi.o \
src/misc/ssh/ssh_encode_sequence_multi.o src/misc/zeromem.o src/modes/cbc/cbc_decrypt.o \
@@ -168,7 +169,8 @@ src/pk/asn1/der/sequence/der_decode_sequence_ex.o \
src/pk/asn1/der/sequence/der_decode_sequence_flexi.o \
src/pk/asn1/der/sequence/der_decode_sequence_multi.o \
src/pk/asn1/der/sequence/der_encode_sequence_ex.o \
-src/pk/asn1/der/sequence/der_encode_sequence_multi.o src/pk/asn1/der/sequence/der_length_sequence.o \
+src/pk/asn1/der/sequence/der_encode_sequence_multi.o \
+src/pk/asn1/der/sequence/der_flexi_sequence_cmp.o src/pk/asn1/der/sequence/der_length_sequence.o \
src/pk/asn1/der/sequence/der_sequence_free.o src/pk/asn1/der/sequence/der_sequence_shrink.o \
src/pk/asn1/der/set/der_encode_set.o src/pk/asn1/der/set/der_encode_setof.o \
src/pk/asn1/der/short_integer/der_decode_short_integer.o \
@@ -179,15 +181,17 @@ src/pk/asn1/der/teletex_string/der_length_teletex_string.o \
src/pk/asn1/der/utctime/der_decode_utctime.o src/pk/asn1/der/utctime/der_encode_utctime.o \
src/pk/asn1/der/utctime/der_length_utctime.o src/pk/asn1/der/utf8/der_decode_utf8_string.o \
src/pk/asn1/der/utf8/der_encode_utf8_string.o src/pk/asn1/der/utf8/der_length_utf8_string.o \
-src/pk/asn1/oid/pk_get_oid.o src/pk/asn1/oid/pk_oid_cmp.o src/pk/asn1/oid/pk_oid_str.o \
-src/pk/asn1/pkcs8/pkcs8_decode_flexi.o src/pk/asn1/x509/x509_decode_public_key_from_certificate.o \
+src/pk/asn1/oid/pk_get.o src/pk/asn1/oid/pk_oid_cmp.o src/pk/asn1/oid/pk_oid_str.o \
+src/pk/asn1/pkcs8/pkcs8_decode_flexi.o src/pk/asn1/pkcs8/pkcs8_get.o \
+src/pk/asn1/x509/x509_decode_public_key_from_certificate.o \
src/pk/asn1/x509/x509_decode_subject_public_key_info.o \
src/pk/asn1/x509/x509_encode_subject_public_key_info.o src/pk/dh/dh.o src/pk/dh/dh_check_pubkey.o \
src/pk/dh/dh_export.o src/pk/dh/dh_export_key.o src/pk/dh/dh_free.o src/pk/dh/dh_generate_key.o \
-src/pk/dh/dh_import.o src/pk/dh/dh_set.o src/pk/dh/dh_set_pg_dhparam.o src/pk/dh/dh_shared_secret.o \
-src/pk/dsa/dsa_decrypt_key.o src/pk/dsa/dsa_encrypt_key.o src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o \
-src/pk/dsa/dsa_generate_key.o src/pk/dsa/dsa_generate_pqg.o src/pk/dsa/dsa_import.o \
-src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_set.o src/pk/dsa/dsa_set_pqg_dsaparam.o \
+src/pk/dh/dh_import.o src/pk/dh/dh_import_pkcs8.o src/pk/dh/dh_set.o src/pk/dh/dh_set_pg_dhparam.o \
+src/pk/dh/dh_shared_secret.o src/pk/dsa/dsa_decrypt_key.o src/pk/dsa/dsa_encrypt_key.o \
+src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o src/pk/dsa/dsa_generate_key.o \
+src/pk/dsa/dsa_generate_pqg.o src/pk/dsa/dsa_import.o src/pk/dsa/dsa_import_pkcs8.o \
+src/pk/dsa/dsa_init.o src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_set.o src/pk/dsa/dsa_set_pqg_dsaparam.o \
src/pk/dsa/dsa_shared_secret.o src/pk/dsa/dsa_sign_hash.o src/pk/dsa/dsa_verify_hash.o \
src/pk/dsa/dsa_verify_key.o src/pk/ec25519/ec25519_crypto_ctx.o src/pk/ec25519/ec25519_export.o \
src/pk/ec25519/ec25519_import_pkcs8.o src/pk/ec25519/tweetnacl.o src/pk/ecc/ecc.o \
@@ -206,12 +210,12 @@ src/pk/ecc/ltc_ecc_projective_add_point.o src/pk/ecc/ltc_ecc_projective_dbl_poin
src/pk/ecc/ltc_ecc_verify_key.o src/pk/ed25519/ed25519_export.o src/pk/ed25519/ed25519_import.o \
src/pk/ed25519/ed25519_import_pkcs8.o src/pk/ed25519/ed25519_import_raw.o \
src/pk/ed25519/ed25519_import_x509.o src/pk/ed25519/ed25519_make_key.o src/pk/ed25519/ed25519_sign.o \
-src/pk/ed25519/ed25519_verify.o src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o \
-src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o \
-src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/pkcs1/pkcs_1_v1_5_decode.o \
-src/pk/pkcs1/pkcs_1_v1_5_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o \
-src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_get_size.o src/pk/rsa/rsa_import.o \
-src/pk/rsa/rsa_import_pkcs8.o src/pk/rsa/rsa_import_x509.o src/pk/rsa/rsa_key.o \
+src/pk/ed25519/ed25519_verify.o src/pk/pka_key_free.o src/pk/pkcs1/pkcs_1_i2osp.o \
+src/pk/pkcs1/pkcs_1_mgf1.o src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o \
+src/pk/pkcs1/pkcs_1_os2ip.o src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o \
+src/pk/pkcs1/pkcs_1_v1_5_decode.o src/pk/pkcs1/pkcs_1_v1_5_encode.o src/pk/rsa/rsa_decrypt_key.o \
+src/pk/rsa/rsa_encrypt_key.o src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_get_size.o \
+src/pk/rsa/rsa_import.o src/pk/rsa/rsa_import_pkcs8.o src/pk/rsa/rsa_import_x509.o src/pk/rsa/rsa_key.o \
src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_set.o src/pk/rsa/rsa_sign_hash.o \
src/pk/rsa/rsa_sign_saltlen_get.o src/pk/rsa/rsa_verify_hash.o src/pk/x25519/x25519_export.o \
src/pk/x25519/x25519_import.o src/pk/x25519/x25519_import_pkcs8.o src/pk/x25519/x25519_import_raw.o \
@@ -237,7 +241,7 @@ TOBJECTS=tests/base16_test.o tests/base32_test.o tests/base64_test.o tests/bcryp
tests/cipher_hash_test.o tests/common.o tests/der_test.o tests/dh_test.o tests/dsa_test.o \
tests/ecc_test.o tests/ed25519_test.o tests/file_test.o tests/mac_test.o tests/misc_test.o \
tests/modes_test.o tests/mpi_test.o tests/multi_test.o tests/no_null_termination_check_test.o \
-tests/no_prng.o tests/padding_test.o tests/pkcs_1_eme_test.o tests/pkcs_1_emsa_test.o \
+tests/no_prng.o tests/padding_test.o tests/pem_test.o tests/pkcs_1_eme_test.o tests/pkcs_1_emsa_test.o \
tests/pkcs_1_oaep_test.o tests/pkcs_1_pss_test.o tests/pkcs_1_test.o tests/prng_test.o \
tests/rotate_test.o tests/rsa_test.o tests/ssh_test.o tests/store_test.o tests/test.o tests/x25519_test.o
diff --git a/makefile_include.mk b/makefile_include.mk
index 77302f968..a38aa3a3d 100644
--- a/makefile_include.mk
+++ b/makefile_include.mk
@@ -289,6 +289,7 @@ src/misc/crypt/crypt_unregister_cipher.o src/misc/crypt/crypt_unregister_hash.o
src/misc/crypt/crypt_unregister_prng.o src/misc/error_to_string.o src/misc/hkdf/hkdf.o \
src/misc/hkdf/hkdf_test.o src/misc/mem_neq.o src/misc/padding/padding_depad.o \
src/misc/padding/padding_pad.o src/misc/pbes/pbes.o src/misc/pbes/pbes1.o src/misc/pbes/pbes2.o \
+src/misc/pem/pem.o src/misc/pem/pem_pkcs.o src/misc/pem/pem_read.o src/misc/pem/pem_ssh.o \
src/misc/pkcs12/pkcs12_kdf.o src/misc/pkcs12/pkcs12_utf8_to_utf16.o src/misc/pkcs5/pkcs_5_1.o \
src/misc/pkcs5/pkcs_5_2.o src/misc/pkcs5/pkcs_5_test.o src/misc/ssh/ssh_decode_sequence_multi.o \
src/misc/ssh/ssh_encode_sequence_multi.o src/misc/zeromem.o src/modes/cbc/cbc_decrypt.o \
@@ -336,7 +337,8 @@ src/pk/asn1/der/sequence/der_decode_sequence_ex.o \
src/pk/asn1/der/sequence/der_decode_sequence_flexi.o \
src/pk/asn1/der/sequence/der_decode_sequence_multi.o \
src/pk/asn1/der/sequence/der_encode_sequence_ex.o \
-src/pk/asn1/der/sequence/der_encode_sequence_multi.o src/pk/asn1/der/sequence/der_length_sequence.o \
+src/pk/asn1/der/sequence/der_encode_sequence_multi.o \
+src/pk/asn1/der/sequence/der_flexi_sequence_cmp.o src/pk/asn1/der/sequence/der_length_sequence.o \
src/pk/asn1/der/sequence/der_sequence_free.o src/pk/asn1/der/sequence/der_sequence_shrink.o \
src/pk/asn1/der/set/der_encode_set.o src/pk/asn1/der/set/der_encode_setof.o \
src/pk/asn1/der/short_integer/der_decode_short_integer.o \
@@ -347,15 +349,17 @@ src/pk/asn1/der/teletex_string/der_length_teletex_string.o \
src/pk/asn1/der/utctime/der_decode_utctime.o src/pk/asn1/der/utctime/der_encode_utctime.o \
src/pk/asn1/der/utctime/der_length_utctime.o src/pk/asn1/der/utf8/der_decode_utf8_string.o \
src/pk/asn1/der/utf8/der_encode_utf8_string.o src/pk/asn1/der/utf8/der_length_utf8_string.o \
-src/pk/asn1/oid/pk_get_oid.o src/pk/asn1/oid/pk_oid_cmp.o src/pk/asn1/oid/pk_oid_str.o \
-src/pk/asn1/pkcs8/pkcs8_decode_flexi.o src/pk/asn1/x509/x509_decode_public_key_from_certificate.o \
+src/pk/asn1/oid/pk_get.o src/pk/asn1/oid/pk_oid_cmp.o src/pk/asn1/oid/pk_oid_str.o \
+src/pk/asn1/pkcs8/pkcs8_decode_flexi.o src/pk/asn1/pkcs8/pkcs8_get.o \
+src/pk/asn1/x509/x509_decode_public_key_from_certificate.o \
src/pk/asn1/x509/x509_decode_subject_public_key_info.o \
src/pk/asn1/x509/x509_encode_subject_public_key_info.o src/pk/dh/dh.o src/pk/dh/dh_check_pubkey.o \
src/pk/dh/dh_export.o src/pk/dh/dh_export_key.o src/pk/dh/dh_free.o src/pk/dh/dh_generate_key.o \
-src/pk/dh/dh_import.o src/pk/dh/dh_set.o src/pk/dh/dh_set_pg_dhparam.o src/pk/dh/dh_shared_secret.o \
-src/pk/dsa/dsa_decrypt_key.o src/pk/dsa/dsa_encrypt_key.o src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o \
-src/pk/dsa/dsa_generate_key.o src/pk/dsa/dsa_generate_pqg.o src/pk/dsa/dsa_import.o \
-src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_set.o src/pk/dsa/dsa_set_pqg_dsaparam.o \
+src/pk/dh/dh_import.o src/pk/dh/dh_import_pkcs8.o src/pk/dh/dh_set.o src/pk/dh/dh_set_pg_dhparam.o \
+src/pk/dh/dh_shared_secret.o src/pk/dsa/dsa_decrypt_key.o src/pk/dsa/dsa_encrypt_key.o \
+src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o src/pk/dsa/dsa_generate_key.o \
+src/pk/dsa/dsa_generate_pqg.o src/pk/dsa/dsa_import.o src/pk/dsa/dsa_import_pkcs8.o \
+src/pk/dsa/dsa_init.o src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_set.o src/pk/dsa/dsa_set_pqg_dsaparam.o \
src/pk/dsa/dsa_shared_secret.o src/pk/dsa/dsa_sign_hash.o src/pk/dsa/dsa_verify_hash.o \
src/pk/dsa/dsa_verify_key.o src/pk/ec25519/ec25519_crypto_ctx.o src/pk/ec25519/ec25519_export.o \
src/pk/ec25519/ec25519_import_pkcs8.o src/pk/ec25519/tweetnacl.o src/pk/ecc/ecc.o \
@@ -374,12 +378,12 @@ src/pk/ecc/ltc_ecc_projective_add_point.o src/pk/ecc/ltc_ecc_projective_dbl_poin
src/pk/ecc/ltc_ecc_verify_key.o src/pk/ed25519/ed25519_export.o src/pk/ed25519/ed25519_import.o \
src/pk/ed25519/ed25519_import_pkcs8.o src/pk/ed25519/ed25519_import_raw.o \
src/pk/ed25519/ed25519_import_x509.o src/pk/ed25519/ed25519_make_key.o src/pk/ed25519/ed25519_sign.o \
-src/pk/ed25519/ed25519_verify.o src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o \
-src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o \
-src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/pkcs1/pkcs_1_v1_5_decode.o \
-src/pk/pkcs1/pkcs_1_v1_5_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o \
-src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_get_size.o src/pk/rsa/rsa_import.o \
-src/pk/rsa/rsa_import_pkcs8.o src/pk/rsa/rsa_import_x509.o src/pk/rsa/rsa_key.o \
+src/pk/ed25519/ed25519_verify.o src/pk/pka_key_free.o src/pk/pkcs1/pkcs_1_i2osp.o \
+src/pk/pkcs1/pkcs_1_mgf1.o src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o \
+src/pk/pkcs1/pkcs_1_os2ip.o src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o \
+src/pk/pkcs1/pkcs_1_v1_5_decode.o src/pk/pkcs1/pkcs_1_v1_5_encode.o src/pk/rsa/rsa_decrypt_key.o \
+src/pk/rsa/rsa_encrypt_key.o src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_get_size.o \
+src/pk/rsa/rsa_import.o src/pk/rsa/rsa_import_pkcs8.o src/pk/rsa/rsa_import_x509.o src/pk/rsa/rsa_key.o \
src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_set.o src/pk/rsa/rsa_sign_hash.o \
src/pk/rsa/rsa_sign_saltlen_get.o src/pk/rsa/rsa_verify_hash.o src/pk/x25519/x25519_export.o \
src/pk/x25519/x25519_import.o src/pk/x25519/x25519_import_pkcs8.o src/pk/x25519/x25519_import_raw.o \
@@ -405,7 +409,7 @@ TOBJECTS=tests/base16_test.o tests/base32_test.o tests/base64_test.o tests/bcryp
tests/cipher_hash_test.o tests/common.o tests/der_test.o tests/dh_test.o tests/dsa_test.o \
tests/ecc_test.o tests/ed25519_test.o tests/file_test.o tests/mac_test.o tests/misc_test.o \
tests/modes_test.o tests/mpi_test.o tests/multi_test.o tests/no_null_termination_check_test.o \
-tests/no_prng.o tests/padding_test.o tests/pkcs_1_eme_test.o tests/pkcs_1_emsa_test.o \
+tests/no_prng.o tests/padding_test.o tests/pem_test.o tests/pkcs_1_eme_test.o tests/pkcs_1_emsa_test.o \
tests/pkcs_1_oaep_test.o tests/pkcs_1_pss_test.o tests/pkcs_1_test.o tests/prng_test.o \
tests/rotate_test.o tests/rsa_test.o tests/ssh_test.o tests/store_test.o tests/test.o tests/x25519_test.o
diff --git a/sources.cmake b/sources.cmake
index 6f1724292..c5e463e35 100644
--- a/sources.cmake
+++ b/sources.cmake
@@ -237,6 +237,10 @@ src/misc/padding/padding_pad.c
src/misc/pbes/pbes.c
src/misc/pbes/pbes1.c
src/misc/pbes/pbes2.c
+src/misc/pem/pem.c
+src/misc/pem/pem_pkcs.c
+src/misc/pem/pem_read.c
+src/misc/pem/pem_ssh.c
src/misc/pkcs12/pkcs12_kdf.c
src/misc/pkcs12/pkcs12_utf8_to_utf16.c
src/misc/pkcs5/pkcs_5_1.c
@@ -337,6 +341,7 @@ src/pk/asn1/der/sequence/der_decode_sequence_flexi.c
src/pk/asn1/der/sequence/der_decode_sequence_multi.c
src/pk/asn1/der/sequence/der_encode_sequence_ex.c
src/pk/asn1/der/sequence/der_encode_sequence_multi.c
+src/pk/asn1/der/sequence/der_flexi_sequence_cmp.c
src/pk/asn1/der/sequence/der_length_sequence.c
src/pk/asn1/der/sequence/der_sequence_free.c
src/pk/asn1/der/sequence/der_sequence_shrink.c
@@ -353,10 +358,11 @@ src/pk/asn1/der/utctime/der_length_utctime.c
src/pk/asn1/der/utf8/der_decode_utf8_string.c
src/pk/asn1/der/utf8/der_encode_utf8_string.c
src/pk/asn1/der/utf8/der_length_utf8_string.c
-src/pk/asn1/oid/pk_get_oid.c
+src/pk/asn1/oid/pk_get.c
src/pk/asn1/oid/pk_oid_cmp.c
src/pk/asn1/oid/pk_oid_str.c
src/pk/asn1/pkcs8/pkcs8_decode_flexi.c
+src/pk/asn1/pkcs8/pkcs8_get.c
src/pk/asn1/x509/x509_decode_public_key_from_certificate.c
src/pk/asn1/x509/x509_decode_subject_public_key_info.c
src/pk/asn1/x509/x509_encode_subject_public_key_info.c
@@ -367,6 +373,7 @@ src/pk/dh/dh_export_key.c
src/pk/dh/dh_free.c
src/pk/dh/dh_generate_key.c
src/pk/dh/dh_import.c
+src/pk/dh/dh_import_pkcs8.c
src/pk/dh/dh_set.c
src/pk/dh/dh_set_pg_dhparam.c
src/pk/dh/dh_shared_secret.c
@@ -377,6 +384,8 @@ src/pk/dsa/dsa_free.c
src/pk/dsa/dsa_generate_key.c
src/pk/dsa/dsa_generate_pqg.c
src/pk/dsa/dsa_import.c
+src/pk/dsa/dsa_import_pkcs8.c
+src/pk/dsa/dsa_init.c
src/pk/dsa/dsa_make_key.c
src/pk/dsa/dsa_set.c
src/pk/dsa/dsa_set_pqg_dsaparam.c
@@ -434,6 +443,7 @@ src/pk/ed25519/ed25519_import_x509.c
src/pk/ed25519/ed25519_make_key.c
src/pk/ed25519/ed25519_sign.c
src/pk/ed25519/ed25519_verify.c
+src/pk/pka_key_free.c
src/pk/pkcs1/pkcs_1_i2osp.c
src/pk/pkcs1/pkcs_1_mgf1.c
src/pk/pkcs1/pkcs_1_oaep_decode.c
diff --git a/tests/sources.cmake b/tests/sources.cmake
index d63a1cc47..b384305b0 100644
--- a/tests/sources.cmake
+++ b/tests/sources.cmake
@@ -19,6 +19,7 @@ multi_test.c
no_null_termination_check_test.c
no_prng.c
padding_test.c
+pem_test.c
pkcs_1_eme_test.c
pkcs_1_emsa_test.c
pkcs_1_oaep_test.c