summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2016-11-14 16:30:46 +0100
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2016-11-14 18:25:49 +0100
commitf93240cce1736ba1d9e7b7fef93cacd35956e1ec (patch)
tree2a0933b71cede99c1f54780c6499fb29a37a5e61
parentbb3d16f37d26ab6b1d5949a182b08f3e39868a76 (diff)
downloadgnutls-f93240cce1736ba1d9e7b7fef93cacd35956e1ec.tar.gz
PKCS#5,7 decryption: verify the correctness of padding
That is, for block ciphers (i.e., cbc), verify that all the padding bytes match the expected contents according to RFC2898. Relates #148
-rw-r--r--lib/x509/pkcs7-crypt.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/lib/x509/pkcs7-crypt.c b/lib/x509/pkcs7-crypt.c
index e1edfc4913..6d6b743c58 100644
--- a/lib/x509/pkcs7-crypt.c
+++ b/lib/x509/pkcs7-crypt.c
@@ -1114,16 +1114,28 @@ _gnutls_pkcs_raw_decrypt_data(schema_id schema, ASN1_TYPE pkcs8_asn,
decrypted_data->data = enc.data;
- if (block_size != 1) {
- if (enc.data[enc.size - 1] >= enc.size) {
+ if (ce->type == CIPHER_BLOCK && block_size != 1) {
+ unsigned pslen = (uint8_t)enc.data[enc.size - 1];
+ unsigned i;
+
+ if (pslen > block_size || pslen >= enc.size || pslen == 0) {
gnutls_assert();
result = GNUTLS_E_ILLEGAL_PARAMETER;
goto error;
}
- decrypted_data->size = enc.size - enc.data[enc.size - 1];
- } else
+ /* verify padding according to rfc2898 */
+ decrypted_data->size = enc.size - pslen;
+ for (i=0;i<pslen;i++) {
+ if (enc.data[enc.size-1-i] != pslen) {
+ gnutls_assert();
+ result = GNUTLS_E_ILLEGAL_PARAMETER;
+ goto error;
+ }
+ }
+ } else {
decrypted_data->size = enc.size;
+ }
_gnutls_cipher_deinit(&ch);