pq_crypto 0.6.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 11bb63e90651697a30709e9621678c7a53224facc67264a331291a8c57520880
4
- data.tar.gz: 111c87fa0809924f0c2997fc0d9c2ea41c43e88044c2802d35370c01ed5f88ca
3
+ metadata.gz: 78b11d409c22bfd37c2afcf11cfdeb8bc7e825a1e4ebf8b0a94c655afbd59f78
4
+ data.tar.gz: 0206a99c5b364c812176c3d31629e5eb1490dcf694a2c8902b9537fd1ab16ebc
5
5
  SHA512:
6
- metadata.gz: c95c38ec77fce342cb92febfbdbecdee5c35495323e7f153a2e263e04b89dc6cb13e8bd2874b8abb0b5e19e5b26cde13fb7f6b9d99ef107c5d6e3e41b20d819c
7
- data.tar.gz: 1aa62a91a03203fcd6253e3175d1166b5bf2a3590889509517b8b5eaa57ff6fac49023b253f0859b45c7c2e0f4b28b849a657a5d089890b328da8a234ef7b5c9
6
+ metadata.gz: d79069163427ae03428e5ff8d01af39315cef796d498f59ca8e021c92f6a987b6a1a6d04c8e6826529a85df1af428f80086dc1f56cda74b0866e16aca27b8901
7
+ data.tar.gz: 552eb1abce00c25fc1313690c5df3a4a341b158caa3aa3ec2e37b604499c43c514fd2e0b82b245961acc4e73895dcbc1b7637112958660a91e0a32b8e3e91134
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.6.1] - 2026-05-14
4
+
5
+ ### Security
6
+
7
+ - Moved PKCS#8 PEM handling, PrivateKeyInfo wrapping/unwrapping, and encrypted PKCS#8 encryption/decryption to native C/OpenSSL helpers.
8
+ - Removed Ruby `OpenSSL::ASN1` parsing/building from the PKCS#8 path while preserving the existing Ruby API.
9
+
3
10
  ## [0.6.0] - 2026-05-14
4
11
 
5
12
  ### Added
@@ -201,6 +201,8 @@ def configure_openssl!
201
201
  abort "openssl/evp.h is required" unless have_header("openssl/evp.h")
202
202
  abort "openssl/rand.h is required" unless have_header("openssl/rand.h")
203
203
  abort "openssl/crypto.h is required" unless have_header("openssl/crypto.h")
204
+ abort "openssl/x509.h is required" unless have_header("openssl/x509.h")
205
+ abort "openssl/pkcs12.h is required" unless have_header("openssl/pkcs12.h")
204
206
 
205
207
  version_check = <<~SRC
206
208
  #include <openssl/opensslv.h>
@@ -1741,6 +1741,136 @@ static VALUE pqcrypto__native_mldsa_verify_mu(int argc, VALUE *argv, VALUE self)
1741
1741
  pq_raise_general_error(call.result);
1742
1742
  }
1743
1743
 
1744
+ static VALUE pqcrypto_pkcs8_private_key_info_to_der(VALUE self, VALUE oid_text, VALUE private_key) {
1745
+ (void)self;
1746
+ uint8_t *out = NULL;
1747
+ size_t out_len = 0;
1748
+ VALUE result;
1749
+ int ret;
1750
+
1751
+ StringValue(oid_text);
1752
+ StringValue(private_key);
1753
+ ret = pq_pkcs8_private_key_info_to_der(&out, &out_len, RSTRING_PTR(oid_text),
1754
+ (const uint8_t *)RSTRING_PTR(private_key),
1755
+ (size_t)RSTRING_LEN(private_key));
1756
+ if (ret != PQ_SUCCESS)
1757
+ pq_raise_general_error(ret);
1758
+ result = pq_string_from_buffer(out, out_len);
1759
+ pq_wipe_and_free(out, out_len);
1760
+ return result;
1761
+ }
1762
+
1763
+ static VALUE pqcrypto_pkcs8_private_key_info_from_der(VALUE self, VALUE der) {
1764
+ (void)self;
1765
+ char *oid_text = NULL;
1766
+ uint8_t *private_key = NULL;
1767
+ size_t private_key_len = 0;
1768
+ VALUE result;
1769
+ int ret;
1770
+
1771
+ StringValue(der);
1772
+ ret = pq_pkcs8_private_key_info_from_der(&oid_text, &private_key, &private_key_len,
1773
+ (const uint8_t *)RSTRING_PTR(der),
1774
+ (size_t)RSTRING_LEN(der));
1775
+ if (ret != PQ_SUCCESS)
1776
+ pq_raise_general_error(ret);
1777
+
1778
+ result = rb_ary_new_capa(2);
1779
+ rb_ary_push(result, rb_str_new_cstr(oid_text));
1780
+ rb_ary_push(result, pq_string_from_buffer(private_key, private_key_len));
1781
+ free(oid_text);
1782
+ pq_wipe_and_free(private_key, private_key_len);
1783
+ return result;
1784
+ }
1785
+
1786
+ static VALUE pqcrypto_pkcs8_encrypt_der(VALUE self, VALUE der, VALUE passphrase,
1787
+ VALUE iterations_value) {
1788
+ (void)self;
1789
+ uint8_t *out = NULL;
1790
+ size_t out_len = 0;
1791
+ int iterations;
1792
+ VALUE result;
1793
+ int ret;
1794
+
1795
+ StringValue(der);
1796
+ StringValue(passphrase);
1797
+ iterations = NUM2INT(iterations_value);
1798
+ ret = pq_pkcs8_encrypt_private_key_info_der(&out, &out_len, (const uint8_t *)RSTRING_PTR(der),
1799
+ (size_t)RSTRING_LEN(der), RSTRING_PTR(passphrase),
1800
+ (size_t)RSTRING_LEN(passphrase), iterations);
1801
+ if (ret != PQ_SUCCESS)
1802
+ pq_raise_general_error(ret);
1803
+ result = pq_string_from_buffer(out, out_len);
1804
+ pq_wipe_and_free(out, out_len);
1805
+ return result;
1806
+ }
1807
+
1808
+ static VALUE pqcrypto_pkcs8_decrypt_der(VALUE self, VALUE der, VALUE passphrase) {
1809
+ (void)self;
1810
+ uint8_t *out = NULL;
1811
+ size_t out_len = 0;
1812
+ VALUE result;
1813
+ int ret;
1814
+
1815
+ StringValue(der);
1816
+ StringValue(passphrase);
1817
+ ret = pq_pkcs8_decrypt_private_key_info_der(&out, &out_len, (const uint8_t *)RSTRING_PTR(der),
1818
+ (size_t)RSTRING_LEN(der), RSTRING_PTR(passphrase),
1819
+ (size_t)RSTRING_LEN(passphrase));
1820
+ if (ret != PQ_SUCCESS)
1821
+ pq_raise_general_error(ret);
1822
+ result = pq_string_from_buffer(out, out_len);
1823
+ pq_wipe_and_free(out, out_len);
1824
+ return result;
1825
+ }
1826
+
1827
+ static VALUE pqcrypto_pkcs8_encrypted_der_p(VALUE self, VALUE der) {
1828
+ (void)self;
1829
+ StringValue(der);
1830
+ return pq_pkcs8_der_is_encrypted_private_key_info((const uint8_t *)RSTRING_PTR(der),
1831
+ (size_t)RSTRING_LEN(der))
1832
+ ? Qtrue
1833
+ : Qfalse;
1834
+ }
1835
+
1836
+ static VALUE pqcrypto_pkcs8_der_to_pem(VALUE self, VALUE der, VALUE encrypted_value) {
1837
+ (void)self;
1838
+ char *pem = NULL;
1839
+ size_t pem_len = 0;
1840
+ VALUE result;
1841
+ int ret;
1842
+
1843
+ StringValue(der);
1844
+ ret = pq_pkcs8_der_to_pem(&pem, &pem_len, (const uint8_t *)RSTRING_PTR(der),
1845
+ (size_t)RSTRING_LEN(der), RTEST(encrypted_value) ? 1 : 0);
1846
+ if (ret != PQ_SUCCESS)
1847
+ pq_raise_general_error(ret);
1848
+ result = rb_str_new(pem, (long)pem_len);
1849
+ pq_secure_wipe(pem, pem_len);
1850
+ free(pem);
1851
+ return result;
1852
+ }
1853
+
1854
+ static VALUE pqcrypto_pkcs8_pem_to_der(VALUE self, VALUE pem) {
1855
+ (void)self;
1856
+ uint8_t *der = NULL;
1857
+ size_t der_len = 0;
1858
+ int encrypted = 0;
1859
+ VALUE result;
1860
+ int ret;
1861
+
1862
+ StringValue(pem);
1863
+ ret =
1864
+ pq_pkcs8_pem_to_der(&der, &der_len, &encrypted, RSTRING_PTR(pem), (size_t)RSTRING_LEN(pem));
1865
+ if (ret != PQ_SUCCESS)
1866
+ pq_raise_general_error(ret);
1867
+ result = rb_ary_new_capa(2);
1868
+ rb_ary_push(result, encrypted ? Qtrue : Qfalse);
1869
+ rb_ary_push(result, pq_string_from_buffer(der, der_len));
1870
+ pq_wipe_and_free(der, der_len);
1871
+ return result;
1872
+ }
1873
+
1744
1874
  static void define_constants(void) {
1745
1875
  rb_define_const(mPQCrypto, "ML_KEM_512_PUBLIC_KEY_BYTES", INT2NUM(MLKEM512_PUBLICKEYBYTES));
1746
1876
  rb_define_const(mPQCrypto, "ML_KEM_512_SECRET_KEY_BYTES", INT2NUM(MLKEM512_SECRETKEYBYTES));
@@ -1911,6 +2041,15 @@ void Init_pqcrypto_secure(void) {
1911
2041
  pqcrypto_secret_key_from_pqc_container_der, 1);
1912
2042
  rb_define_module_function(mPQCrypto, "secret_key_from_pqc_container_pem",
1913
2043
  pqcrypto_secret_key_from_pqc_container_pem, 1);
2044
+ rb_define_module_function(mPQCrypto, "pkcs8_private_key_info_to_der",
2045
+ pqcrypto_pkcs8_private_key_info_to_der, 2);
2046
+ rb_define_module_function(mPQCrypto, "pkcs8_private_key_info_from_der",
2047
+ pqcrypto_pkcs8_private_key_info_from_der, 1);
2048
+ rb_define_module_function(mPQCrypto, "pkcs8_encrypt_der", pqcrypto_pkcs8_encrypt_der, 3);
2049
+ rb_define_module_function(mPQCrypto, "pkcs8_decrypt_der", pqcrypto_pkcs8_decrypt_der, 2);
2050
+ rb_define_module_function(mPQCrypto, "pkcs8_encrypted_der?", pqcrypto_pkcs8_encrypted_der_p, 1);
2051
+ rb_define_module_function(mPQCrypto, "pkcs8_der_to_pem", pqcrypto_pkcs8_der_to_pem, 2);
2052
+ rb_define_module_function(mPQCrypto, "pkcs8_pem_to_der", pqcrypto_pkcs8_pem_to_der, 1);
1914
2053
  rb_define_module_function(mPQCrypto, "_native_mldsa_extract_tr",
1915
2054
  pqcrypto__native_mldsa_extract_tr, -1);
1916
2055
  rb_define_module_function(mPQCrypto, "_native_mldsa_compute_tr",