diff options
| -rw-r--r-- | crypto/asymmetric_keys/pkcs7_verify.c | 64 | ||||
| -rw-r--r-- | include/crypto/pkcs7.h | 5 |
2 files changed, 69 insertions, 0 deletions
diff --git a/crypto/asymmetric_keys/pkcs7_verify.c b/crypto/asymmetric_keys/pkcs7_verify.c index 0bb408a5b64f..745e5c86a35e 100644 --- a/crypto/asymmetric_keys/pkcs7_verify.c +++ b/crypto/asymmetric_keys/pkcs7_verify.c | |||
| @@ -120,6 +120,55 @@ error_no_desc: | |||
| 120 | } | 120 | } |
| 121 | 121 | ||
| 122 | /* | 122 | /* |
| 123 | * Find the key (X.509 certificate) to use to verify a PKCS#7 message. PKCS#7 | ||
| 124 | * uses the issuer's name and the issuing certificate serial number for | ||
| 125 | * matching purposes. These must match the certificate issuer's name (not | ||
| 126 | * subject's name) and the certificate serial number [RFC 2315 6.7]. | ||
| 127 | */ | ||
| 128 | static int pkcs7_find_key(struct pkcs7_message *pkcs7, | ||
| 129 | struct pkcs7_signed_info *sinfo) | ||
| 130 | { | ||
| 131 | struct x509_certificate *x509; | ||
| 132 | unsigned certix = 1; | ||
| 133 | |||
| 134 | kenter("%u,%u,%u", | ||
| 135 | sinfo->index, sinfo->raw_serial_size, sinfo->raw_issuer_size); | ||
| 136 | |||
| 137 | for (x509 = pkcs7->certs; x509; x509 = x509->next, certix++) { | ||
| 138 | /* I'm _assuming_ that the generator of the PKCS#7 message will | ||
| 139 | * encode the fields from the X.509 cert in the same way in the | ||
| 140 | * PKCS#7 message - but I can't be 100% sure of that. It's | ||
| 141 | * possible this will need element-by-element comparison. | ||
| 142 | */ | ||
| 143 | if (x509->raw_serial_size != sinfo->raw_serial_size || | ||
| 144 | memcmp(x509->raw_serial, sinfo->raw_serial, | ||
| 145 | sinfo->raw_serial_size) != 0) | ||
| 146 | continue; | ||
| 147 | pr_devel("Sig %u: Found cert serial match X.509[%u]\n", | ||
| 148 | sinfo->index, certix); | ||
| 149 | |||
| 150 | if (x509->raw_issuer_size != sinfo->raw_issuer_size || | ||
| 151 | memcmp(x509->raw_issuer, sinfo->raw_issuer, | ||
| 152 | sinfo->raw_issuer_size) != 0) { | ||
| 153 | pr_warn("Sig %u: X.509 subject and PKCS#7 issuer don't match\n", | ||
| 154 | sinfo->index); | ||
| 155 | continue; | ||
| 156 | } | ||
| 157 | |||
| 158 | if (x509->pub->pkey_algo != sinfo->sig.pkey_algo) { | ||
| 159 | pr_warn("Sig %u: X.509 algo and PKCS#7 sig algo don't match\n", | ||
| 160 | sinfo->index); | ||
| 161 | continue; | ||
| 162 | } | ||
| 163 | |||
| 164 | sinfo->signer = x509; | ||
| 165 | return 0; | ||
| 166 | } | ||
| 167 | pr_warn("Sig %u: Issuing X.509 cert not found (#%*ph)\n", | ||
| 168 | sinfo->index, sinfo->raw_serial_size, sinfo->raw_serial); | ||
| 169 | return -ENOKEY; | ||
| 170 | } | ||
| 171 | |||
| 123 | /* | 172 | /* |
| 124 | * Verify one signed information block from a PKCS#7 message. | 173 | * Verify one signed information block from a PKCS#7 message. |
| 125 | */ | 174 | */ |
| @@ -137,6 +186,21 @@ static int pkcs7_verify_one(struct pkcs7_message *pkcs7, | |||
| 137 | if (ret < 0) | 186 | if (ret < 0) |
| 138 | return ret; | 187 | return ret; |
| 139 | 188 | ||
| 189 | /* Find the key for the signature */ | ||
| 190 | ret = pkcs7_find_key(pkcs7, sinfo); | ||
| 191 | if (ret < 0) | ||
| 192 | return ret; | ||
| 193 | |||
| 194 | pr_devel("Using X.509[%u] for sig %u\n", | ||
| 195 | sinfo->signer->index, sinfo->index); | ||
| 196 | |||
| 197 | /* Verify the PKCS#7 binary against the key */ | ||
| 198 | ret = public_key_verify_signature(sinfo->signer->pub, &sinfo->sig); | ||
| 199 | if (ret < 0) | ||
| 200 | return ret; | ||
| 201 | |||
| 202 | pr_devel("Verified signature %u\n", sinfo->index); | ||
| 203 | |||
| 140 | return 0; | 204 | return 0; |
| 141 | } | 205 | } |
| 142 | 206 | ||
diff --git a/include/crypto/pkcs7.h b/include/crypto/pkcs7.h index 8f2628fbdfce..8ba0f3810d67 100644 --- a/include/crypto/pkcs7.h +++ b/include/crypto/pkcs7.h | |||
| @@ -21,3 +21,8 @@ extern void pkcs7_free_message(struct pkcs7_message *pkcs7); | |||
| 21 | extern int pkcs7_get_content_data(const struct pkcs7_message *pkcs7, | 21 | extern int pkcs7_get_content_data(const struct pkcs7_message *pkcs7, |
| 22 | const void **_data, size_t *_datalen, | 22 | const void **_data, size_t *_datalen, |
| 23 | bool want_wrapper); | 23 | bool want_wrapper); |
| 24 | |||
| 25 | /* | ||
| 26 | * pkcs7_verify.c | ||
| 27 | */ | ||
| 28 | extern int pkcs7_verify(struct pkcs7_message *pkcs7); | ||
