pq_crypto 0.6.6 → 0.6.8
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 +4 -4
- data/CHANGELOG.md +108 -0
- data/README.md +11 -0
- data/SECURITY.md +46 -0
- data/ext/pqcrypto/extconf.rb +4 -0
- data/ext/pqcrypto/pqcrypto_native_api.h +6 -0
- data/ext/pqcrypto/pqcrypto_ruby_secure.c +122 -11
- data/ext/pqcrypto/pqcrypto_secure.c +553 -296
- data/ext/pqcrypto/pqcrypto_secure.h +14 -1
- data/ext/pqcrypto/pqcrypto_version.h +1 -1
- data/lib/pq_crypto/internal.rb +20 -0
- data/lib/pq_crypto/kem.rb +52 -15
- data/lib/pq_crypto/key.rb +14 -8
- data/lib/pq_crypto/pkcs8/der.rb +26 -11
- data/lib/pq_crypto/pkcs8/private_key_choice.rb +21 -25
- data/lib/pq_crypto/pkcs8.rb +13 -5
- data/lib/pq_crypto/signature.rb +61 -48
- data/lib/pq_crypto/spki.rb +39 -24
- data/lib/pq_crypto/version.rb +1 -1
- data/lib/pq_crypto.rb +9 -0
- metadata +1 -1
data/lib/pq_crypto/spki.rb
CHANGED
|
@@ -26,7 +26,7 @@ module PQCrypto
|
|
|
26
26
|
]),
|
|
27
27
|
OpenSSL::ASN1::BitString.new(bytes),
|
|
28
28
|
]).to_der.b
|
|
29
|
-
rescue OpenSSL::
|
|
29
|
+
rescue OpenSSL::OpenSSLError, TypeError => e
|
|
30
30
|
raise SerializationError, e.message
|
|
31
31
|
end
|
|
32
32
|
|
|
@@ -39,43 +39,58 @@ module PQCrypto
|
|
|
39
39
|
def decode_der(der)
|
|
40
40
|
input = String(der).b
|
|
41
41
|
outer = decode_asn1(input)
|
|
42
|
+
algorithm_identifier, subject_public_key = spki_elements(outer, input)
|
|
43
|
+
algorithm = decode_algorithm_identifier(algorithm_identifier)
|
|
44
|
+
[algorithm, decode_subject_public_key(algorithm, subject_public_key)]
|
|
45
|
+
rescue OpenSSL::OpenSSLError, TypeError => e
|
|
46
|
+
raise SerializationError, e.message
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def decode_pem(pem)
|
|
50
|
+
der = der_from_pem(pem)
|
|
51
|
+
decode_der(der)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
private
|
|
55
|
+
|
|
56
|
+
def decode_asn1(der)
|
|
57
|
+
OpenSSL::ASN1.decode(der)
|
|
58
|
+
rescue OpenSSL::OpenSSLError, TypeError => e
|
|
59
|
+
raise SerializationError, e.message
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def spki_elements(outer, input)
|
|
42
63
|
raise SerializationError, "SPKI DER contains trailing data" unless outer.to_der.b == input
|
|
43
64
|
raise SerializationError, "SPKI must be an ASN.1 SEQUENCE" unless outer.is_a?(OpenSSL::ASN1::Sequence)
|
|
44
65
|
raise SerializationError, "SPKI SEQUENCE must contain exactly 2 elements" unless outer.value.size == 2
|
|
45
66
|
|
|
46
|
-
|
|
47
|
-
|
|
67
|
+
outer.value
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def decode_subject_public_key(algorithm, subject_public_key)
|
|
48
71
|
entry = AlgorithmRegistry.fetch(algorithm)
|
|
49
72
|
validate_public_key_algorithm!(algorithm, entry)
|
|
73
|
+
validate_subject_public_key!(subject_public_key)
|
|
50
74
|
|
|
75
|
+
bytes = String(subject_public_key.value).b
|
|
76
|
+
validate_public_key_length!(algorithm, bytes, entry.fetch(:public_key_bytes))
|
|
77
|
+
bytes
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def validate_subject_public_key!(subject_public_key)
|
|
51
81
|
unless subject_public_key.is_a?(OpenSSL::ASN1::BitString)
|
|
52
82
|
raise SerializationError, "SPKI subjectPublicKey must be a BIT STRING"
|
|
53
83
|
end
|
|
54
|
-
|
|
55
|
-
raise SerializationError, "SPKI subjectPublicKey must have zero unused bits"
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
bytes = String(subject_public_key.value).b
|
|
59
|
-
expected = entry.fetch(:public_key_bytes)
|
|
60
|
-
unless bytes.bytesize == expected
|
|
61
|
-
raise SerializationError,
|
|
62
|
-
"Invalid #{algorithm.inspect} SPKI public key length: expected #{expected}, got #{bytes.bytesize}"
|
|
63
|
-
end
|
|
84
|
+
return if subject_public_key.unused_bits.zero?
|
|
64
85
|
|
|
65
|
-
|
|
86
|
+
raise SerializationError, "SPKI subjectPublicKey must have zero unused bits"
|
|
66
87
|
end
|
|
67
88
|
|
|
68
|
-
def
|
|
69
|
-
|
|
70
|
-
decode_der(der)
|
|
71
|
-
end
|
|
89
|
+
def validate_public_key_length!(algorithm, bytes, expected)
|
|
90
|
+
return if bytes.bytesize == expected
|
|
72
91
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
def decode_asn1(der)
|
|
76
|
-
OpenSSL::ASN1.decode(der)
|
|
77
|
-
rescue OpenSSL::ASN1::ASN1Error => e
|
|
78
|
-
raise SerializationError, e.message
|
|
92
|
+
raise SerializationError,
|
|
93
|
+
"Invalid #{algorithm.inspect} SPKI public key length: expected #{expected}, got #{bytes.bytesize}"
|
|
79
94
|
end
|
|
80
95
|
|
|
81
96
|
def decode_algorithm_identifier(value)
|
data/lib/pq_crypto/version.rb
CHANGED
data/lib/pq_crypto.rb
CHANGED
|
@@ -65,6 +65,15 @@ module PQCrypto
|
|
|
65
65
|
ml_kem_1024_keypair_from_seed
|
|
66
66
|
ml_kem_1024_encapsulate
|
|
67
67
|
ml_kem_1024_decapsulate
|
|
68
|
+
ml_kem_check_public_key
|
|
69
|
+
ml_kem_check_secret_key
|
|
70
|
+
ml_kem_512_check_public_key
|
|
71
|
+
ml_kem_512_check_secret_key
|
|
72
|
+
ml_kem_1024_check_public_key
|
|
73
|
+
ml_kem_1024_check_secret_key
|
|
74
|
+
ml_dsa_check_secret_key
|
|
75
|
+
ml_dsa_44_check_secret_key
|
|
76
|
+
ml_dsa_87_check_secret_key
|
|
68
77
|
hybrid_kem_keypair
|
|
69
78
|
hybrid_kem_encapsulate
|
|
70
79
|
hybrid_kem_expand_secret_key
|