diff options
Diffstat (limited to 'src/daemon/https/x509/privkey_pkcs8.c')
-rw-r--r-- | src/daemon/https/x509/privkey_pkcs8.c | 838 |
1 files changed, 7 insertions, 831 deletions
diff --git a/src/daemon/https/x509/privkey_pkcs8.c b/src/daemon/https/x509/privkey_pkcs8.c index 1ef59d2f..741552e1 100644 --- a/src/daemon/https/x509/privkey_pkcs8.c +++ b/src/daemon/https/x509/privkey_pkcs8.c | |||
@@ -34,8 +34,8 @@ | |||
34 | #include <gnutls_x509.h> | 34 | #include <gnutls_x509.h> |
35 | #include <x509_b64.h> | 35 | #include <x509_b64.h> |
36 | #include <x509.h> | 36 | #include <x509.h> |
37 | #include <dn.h> | ||
38 | #include <pkcs12.h> | 37 | #include <pkcs12.h> |
38 | #include <dn.h> | ||
39 | #include <privkey.h> | 39 | #include <privkey.h> |
40 | #include <extensions.h> | 40 | #include <extensions.h> |
41 | #include <mpi.h> | 41 | #include <mpi.h> |
@@ -68,10 +68,6 @@ struct pbe_enc_params | |||
68 | int iv_size; | 68 | int iv_size; |
69 | }; | 69 | }; |
70 | 70 | ||
71 | static int generate_key (schema_id schema, const char *password, | ||
72 | struct pbkdf2_params *kdf_params, | ||
73 | struct pbe_enc_params *enc_params, | ||
74 | MHD_gnutls_datum_t * key); | ||
75 | static int read_pbkdf2_params (ASN1_TYPE pbes2_asn, | 71 | static int read_pbkdf2_params (ASN1_TYPE pbes2_asn, |
76 | const MHD_gnutls_datum_t * der, | 72 | const MHD_gnutls_datum_t * der, |
77 | struct pbkdf2_params *params); | 73 | struct pbkdf2_params *params); |
@@ -85,18 +81,8 @@ static int decrypt_data (schema_id, ASN1_TYPE pkcs8_asn, const char *root, | |||
85 | MHD_gnutls_datum_t * decrypted_data); | 81 | MHD_gnutls_datum_t * decrypted_data); |
86 | static int decode_private_key_info (const MHD_gnutls_datum_t * der, | 82 | static int decode_private_key_info (const MHD_gnutls_datum_t * der, |
87 | MHD_gnutls_x509_privkey_t pkey); | 83 | MHD_gnutls_x509_privkey_t pkey); |
88 | static int write_schema_params (schema_id schema, ASN1_TYPE pkcs8_asn, | ||
89 | const char *where, | ||
90 | const struct pbkdf2_params *kdf_params, | ||
91 | const struct pbe_enc_params *enc_params); | ||
92 | static int encrypt_data (const MHD_gnutls_datum_t * plain, | ||
93 | const struct pbe_enc_params *enc_params, | ||
94 | MHD_gnutls_datum_t * key, MHD_gnutls_datum_t * encrypted); | ||
95 | |||
96 | static int readMHD_pkcs12_kdf_params (ASN1_TYPE pbes2_asn, | 84 | static int readMHD_pkcs12_kdf_params (ASN1_TYPE pbes2_asn, |
97 | struct pbkdf2_params *params); | 85 | struct pbkdf2_params *params); |
98 | static int writeMHD_pkcs12_kdf_params (ASN1_TYPE pbes2_asn, | ||
99 | const struct pbkdf2_params *params); | ||
100 | 86 | ||
101 | #define PEM_PKCS8 "ENCRYPTED PRIVATE KEY" | 87 | #define PEM_PKCS8 "ENCRYPTED PRIVATE KEY" |
102 | #define PEM_UNENCRYPTED_PKCS8 "PRIVATE KEY" | 88 | #define PEM_UNENCRYPTED_PKCS8 "PRIVATE KEY" |
@@ -104,7 +90,7 @@ static int writeMHD_pkcs12_kdf_params (ASN1_TYPE pbes2_asn, | |||
104 | /* Returns a negative error code if the encryption schema in | 90 | /* Returns a negative error code if the encryption schema in |
105 | * the OID is not supported. The schema ID is returned. | 91 | * the OID is not supported. The schema ID is returned. |
106 | */ | 92 | */ |
107 | inline static int | 93 | static int |
108 | check_schema (const char *oid) | 94 | check_schema (const char *oid) |
109 | { | 95 | { |
110 | 96 | ||
@@ -420,78 +406,6 @@ error: | |||
420 | return ret; | 406 | return ret; |
421 | } | 407 | } |
422 | 408 | ||
423 | /* TODO rm if unsed - we will probable support only RSA certificates */ | ||
424 | /* Decodes an DSA privateKey and params from a PKCS8 structure. | ||
425 | static int | ||
426 | _decode_pkcs8_dsa_key (ASN1_TYPE pkcs8_asn, MHD_gnutls_x509_privkey pkey) | ||
427 | { | ||
428 | int ret; | ||
429 | MHD_gnutls_datum tmp; | ||
430 | |||
431 | ret = MHD__gnutls_x509_read_value (pkcs8_asn, "privateKey", &tmp, 0); | ||
432 | if (ret < 0) | ||
433 | { | ||
434 | MHD_gnutls_assert (); | ||
435 | goto error; | ||
436 | } | ||
437 | |||
438 | ret = MHD__gnutls_x509_read_der_int (tmp.data, tmp.size, &pkey->params[4]); | ||
439 | MHD__gnutls_free_datum (&tmp); | ||
440 | |||
441 | if (ret < 0) | ||
442 | { | ||
443 | MHD_gnutls_assert (); | ||
444 | goto error; | ||
445 | } | ||
446 | |||
447 | ret = | ||
448 | MHD__gnutls_x509_read_value (pkcs8_asn, "privateKeyAlgorithm.parameters", | ||
449 | &tmp, 0); | ||
450 | if (ret < 0) | ||
451 | { | ||
452 | MHD_gnutls_assert (); | ||
453 | goto error; | ||
454 | } | ||
455 | |||
456 | ret = MHD__gnutls_x509_read_dsa_params (tmp.data, tmp.size, pkey->params); | ||
457 | MHD__gnutls_free_datum (&tmp); | ||
458 | if (ret < 0) | ||
459 | { | ||
460 | MHD_gnutls_assert (); | ||
461 | goto error; | ||
462 | } | ||
463 | |||
464 | the public key can be generated as g^x mod p | ||
465 | pkey->params[3] = MHD__gnutls_mpi_alloc_like (pkey->params[0]); | ||
466 | if (pkey->params[3] == NULL) | ||
467 | { | ||
468 | MHD_gnutls_assert (); | ||
469 | goto error; | ||
470 | } | ||
471 | |||
472 | MHD__gnutls_mpi_powm (pkey->params[3], pkey->params[2], pkey->params[4], | ||
473 | pkey->params[0]); | ||
474 | |||
475 | if (!pkey->crippled) | ||
476 | { | ||
477 | ret = MHD__gnutls_asn1_encode_dsa (&pkey->key, pkey->params); | ||
478 | if (ret < 0) | ||
479 | { | ||
480 | MHD_gnutls_assert (); | ||
481 | goto error; | ||
482 | } | ||
483 | } | ||
484 | |||
485 | pkey->params_size = DSA_PRIVATE_PARAMS; | ||
486 | |||
487 | return 0; | ||
488 | |||
489 | error: | ||
490 | MHD_gnutls_x509_privkey_deinit (pkey); | ||
491 | return ret; | ||
492 | } | ||
493 | */ | ||
494 | |||
495 | static int | 409 | static int |
496 | decode_private_key_info (const MHD_gnutls_datum_t * der, | 410 | decode_private_key_info (const MHD_gnutls_datum_t * der, |
497 | MHD_gnutls_x509_privkey_t pkey) | 411 | MHD_gnutls_x509_privkey_t pkey) |
@@ -532,7 +446,7 @@ decode_private_key_info (const MHD_gnutls_datum_t * der, | |||
532 | 446 | ||
533 | /* we only support RSA and DSA private keys. | 447 | /* we only support RSA and DSA private keys. |
534 | */ | 448 | */ |
535 | if (strcmp (oid, PK_PKIX1_RSA_OID) == 0) | 449 | if (strcmp ((const char*) oid, PK_PKIX1_RSA_OID) == 0) |
536 | pkey->pk_algorithm = MHD_GNUTLS_PK_RSA; | 450 | pkey->pk_algorithm = MHD_GNUTLS_PK_RSA; |
537 | else | 451 | else |
538 | { | 452 | { |
@@ -824,49 +738,9 @@ error: | |||
824 | 738 | ||
825 | } | 739 | } |
826 | 740 | ||
827 | /* Writes the PBE parameters for PKCS-12 schemas. | ||
828 | */ | ||
829 | static int | ||
830 | writeMHD_pkcs12_kdf_params (ASN1_TYPE pbes2_asn, | ||
831 | const struct pbkdf2_params *kdf_params) | ||
832 | { | ||
833 | int result; | ||
834 | |||
835 | /* write the salt | ||
836 | */ | ||
837 | result = | ||
838 | MHD__asn1_write_value (pbes2_asn, "salt", | ||
839 | kdf_params->salt, kdf_params->salt_size); | ||
840 | if (result != ASN1_SUCCESS) | ||
841 | { | ||
842 | MHD_gnutls_assert (); | ||
843 | result = MHD_gtls_asn2err (result); | ||
844 | goto error; | ||
845 | } | ||
846 | MHD__gnutls_hard_log ("salt.size: %d\n", kdf_params->salt_size); | ||
847 | |||
848 | /* write the iteration count | ||
849 | */ | ||
850 | result = | ||
851 | MHD__gnutls_x509_write_uint32 (pbes2_asn, "iterations", | ||
852 | kdf_params->iter_count); | ||
853 | if (result < 0) | ||
854 | { | ||
855 | MHD_gnutls_assert (); | ||
856 | goto error; | ||
857 | } | ||
858 | MHD__gnutls_hard_log ("iterationCount: %d\n", kdf_params->iter_count); | ||
859 | |||
860 | return 0; | ||
861 | |||
862 | error: | ||
863 | return result; | ||
864 | |||
865 | } | ||
866 | |||
867 | /* Converts an OID to a gnutls cipher type. | 741 | /* Converts an OID to a gnutls cipher type. |
868 | */ | 742 | */ |
869 | inline static int | 743 | static int |
870 | oid2cipher (const char *oid, enum MHD_GNUTLS_CipherAlgorithm *algo) | 744 | oid2cipher (const char *oid, enum MHD_GNUTLS_CipherAlgorithm *algo) |
871 | { | 745 | { |
872 | 746 | ||
@@ -1025,8 +899,9 @@ decrypt_data (schema_id schema, ASN1_TYPE pkcs8_asn, | |||
1025 | if (schema == PBES2) | 899 | if (schema == PBES2) |
1026 | { | 900 | { |
1027 | result = MHD_gc_pbkdf2_sha1 (password, strlen (password), | 901 | result = MHD_gc_pbkdf2_sha1 (password, strlen (password), |
1028 | kdf_params->salt, kdf_params->salt_size, | 902 | (const char*) kdf_params->salt, kdf_params->salt_size, |
1029 | kdf_params->iter_count, key, key_size); | 903 | kdf_params->iter_count, |
904 | (char*) key, key_size); | ||
1030 | 905 | ||
1031 | if (result != GC_OK) | 906 | if (result != GC_OK) |
1032 | { | 907 | { |
@@ -1095,704 +970,5 @@ error: | |||
1095 | return result; | 970 | return result; |
1096 | } | 971 | } |
1097 | 972 | ||
1098 | /* Writes the PBKDF2 parameters. | ||
1099 | */ | ||
1100 | static int | ||
1101 | write_pbkdf2_params (ASN1_TYPE pbes2_asn, | ||
1102 | const struct pbkdf2_params *kdf_params) | ||
1103 | { | ||
1104 | int result; | ||
1105 | ASN1_TYPE pbkdf2_asn = ASN1_TYPE_EMPTY; | ||
1106 | opaque tmp[64]; | ||
1107 | |||
1108 | /* Write the key derivation algorithm | ||
1109 | */ | ||
1110 | result = | ||
1111 | MHD__asn1_write_value (pbes2_asn, "keyDerivationFunc.algorithm", | ||
1112 | PBKDF2_OID, 1); | ||
1113 | if (result != ASN1_SUCCESS) | ||
1114 | { | ||
1115 | MHD_gnutls_assert (); | ||
1116 | return MHD_gtls_asn2err (result); | ||
1117 | } | ||
1118 | |||
1119 | /* Now write the key derivation and the encryption | ||
1120 | * functions. | ||
1121 | */ | ||
1122 | if ((result = | ||
1123 | MHD__asn1_create_element (MHD__gnutls_get_pkix (), | ||
1124 | "PKIX1.pkcs-5-PBKDF2-params", | ||
1125 | &pbkdf2_asn)) != ASN1_SUCCESS) | ||
1126 | { | ||
1127 | MHD_gnutls_assert (); | ||
1128 | return MHD_gtls_asn2err (result); | ||
1129 | } | ||
1130 | |||
1131 | result = MHD__asn1_write_value (pbkdf2_asn, "salt", "specified", 1); | ||
1132 | if (result != ASN1_SUCCESS) | ||
1133 | { | ||
1134 | MHD_gnutls_assert (); | ||
1135 | result = MHD_gtls_asn2err (result); | ||
1136 | goto error; | ||
1137 | } | ||
1138 | |||
1139 | /* write the salt | ||
1140 | */ | ||
1141 | result = | ||
1142 | MHD__asn1_write_value (pbkdf2_asn, "salt.specified", | ||
1143 | kdf_params->salt, kdf_params->salt_size); | ||
1144 | if (result != ASN1_SUCCESS) | ||
1145 | { | ||
1146 | MHD_gnutls_assert (); | ||
1147 | result = MHD_gtls_asn2err (result); | ||
1148 | goto error; | ||
1149 | } | ||
1150 | MHD__gnutls_hard_log ("salt.specified.size: %d\n", kdf_params->salt_size); | ||
1151 | |||
1152 | /* write the iteration count | ||
1153 | */ | ||
1154 | MHD_gtls_write_uint32 (kdf_params->iter_count, tmp); | ||
1155 | |||
1156 | result = MHD__asn1_write_value (pbkdf2_asn, "iterationCount", tmp, 4); | ||
1157 | if (result != ASN1_SUCCESS) | ||
1158 | { | ||
1159 | MHD_gnutls_assert (); | ||
1160 | result = MHD_gtls_asn2err (result); | ||
1161 | goto error; | ||
1162 | } | ||
1163 | MHD__gnutls_hard_log ("iterationCount: %d\n", kdf_params->iter_count); | ||
1164 | |||
1165 | /* write the keylength, if it is set. | ||
1166 | */ | ||
1167 | result = MHD__asn1_write_value (pbkdf2_asn, "keyLength", NULL, 0); | ||
1168 | if (result != ASN1_SUCCESS) | ||
1169 | { | ||
1170 | MHD_gnutls_assert (); | ||
1171 | result = MHD_gtls_asn2err (result); | ||
1172 | goto error; | ||
1173 | } | ||
1174 | |||
1175 | /* We write an emptry prf. | ||
1176 | */ | ||
1177 | result = MHD__asn1_write_value (pbkdf2_asn, "prf", NULL, 0); | ||
1178 | if (result != ASN1_SUCCESS) | ||
1179 | { | ||
1180 | MHD_gnutls_assert (); | ||
1181 | result = MHD_gtls_asn2err (result); | ||
1182 | goto error; | ||
1183 | } | ||
1184 | |||
1185 | /* now encode them an put the DER output | ||
1186 | * in the keyDerivationFunc.parameters | ||
1187 | */ | ||
1188 | result = MHD__gnutls_x509_der_encode_and_copy (pbkdf2_asn, "", | ||
1189 | pbes2_asn, | ||
1190 | "keyDerivationFunc.parameters", | ||
1191 | 0); | ||
1192 | if (result < 0) | ||
1193 | { | ||
1194 | MHD_gnutls_assert (); | ||
1195 | goto error; | ||
1196 | } | ||
1197 | |||
1198 | return 0; | ||
1199 | |||
1200 | error: | ||
1201 | MHD__asn1_delete_structure (&pbkdf2_asn); | ||
1202 | return result; | ||
1203 | |||
1204 | } | ||
1205 | |||
1206 | static int | ||
1207 | write_pbe_enc_params (ASN1_TYPE pbes2_asn, | ||
1208 | const struct pbe_enc_params *params) | ||
1209 | { | ||
1210 | int result; | ||
1211 | ASN1_TYPE pbe_asn = ASN1_TYPE_EMPTY; | ||
1212 | |||
1213 | /* Write the encryption algorithm | ||
1214 | */ | ||
1215 | result = | ||
1216 | MHD__asn1_write_value (pbes2_asn, "encryptionScheme.algorithm", | ||
1217 | DES_EDE3_CBC_OID, 1); | ||
1218 | if (result != ASN1_SUCCESS) | ||
1219 | { | ||
1220 | MHD_gnutls_assert (); | ||
1221 | goto error; | ||
1222 | } | ||
1223 | MHD__gnutls_hard_log ("encryptionScheme.algorithm: %s\n", DES_EDE3_CBC_OID); | ||
1224 | |||
1225 | /* Now check the encryption parameters. | ||
1226 | */ | ||
1227 | if ((result = | ||
1228 | MHD__asn1_create_element (MHD__gnutls_get_pkix (), | ||
1229 | "PKIX1.pkcs-5-des-EDE3-CBC-params", | ||
1230 | &pbe_asn)) != ASN1_SUCCESS) | ||
1231 | { | ||
1232 | MHD_gnutls_assert (); | ||
1233 | return MHD_gtls_asn2err (result); | ||
1234 | } | ||
1235 | |||
1236 | /* read the salt */ | ||
1237 | result = MHD__asn1_write_value (pbe_asn, "", params->iv, params->iv_size); | ||
1238 | if (result != ASN1_SUCCESS) | ||
1239 | { | ||
1240 | MHD_gnutls_assert (); | ||
1241 | result = MHD_gtls_asn2err (result); | ||
1242 | goto error; | ||
1243 | } | ||
1244 | MHD__gnutls_hard_log ("IV.size: %d\n", params->iv_size); | ||
1245 | |||
1246 | /* now encode them an put the DER output | ||
1247 | * in the encryptionScheme.parameters | ||
1248 | */ | ||
1249 | result = MHD__gnutls_x509_der_encode_and_copy (pbe_asn, "", | ||
1250 | pbes2_asn, | ||
1251 | "encryptionScheme.parameters", | ||
1252 | 0); | ||
1253 | if (result < 0) | ||
1254 | { | ||
1255 | MHD_gnutls_assert (); | ||
1256 | goto error; | ||
1257 | } | ||
1258 | |||
1259 | return 0; | ||
1260 | |||
1261 | error: | ||
1262 | MHD__asn1_delete_structure (&pbe_asn); | ||
1263 | return result; | ||
1264 | |||
1265 | } | ||
1266 | |||
1267 | /* Generates a key and also stores the key parameters. | ||
1268 | */ | ||
1269 | static int | ||
1270 | generate_key (schema_id schema, | ||
1271 | const char *password, | ||
1272 | struct pbkdf2_params *kdf_params, | ||
1273 | struct pbe_enc_params *enc_params, MHD_gnutls_datum_t * key) | ||
1274 | { | ||
1275 | opaque rnd[2]; | ||
1276 | int ret; | ||
1277 | |||
1278 | /* We should use the flags here to use different | ||
1279 | * encryption algorithms etc. | ||
1280 | */ | ||
1281 | |||
1282 | if (schema == PKCS12_ARCFOUR_SHA1) | ||
1283 | enc_params->cipher = MHD_GNUTLS_CIPHER_ARCFOUR_128; | ||
1284 | else if (schema == PKCS12_3DES_SHA1) | ||
1285 | enc_params->cipher = MHD_GNUTLS_CIPHER_3DES_CBC; | ||
1286 | else if (schema == PKCS12_RC2_40_SHA1) | ||
1287 | enc_params->cipher = MHD_GNUTLS_CIPHER_RC2_40_CBC; | ||
1288 | |||
1289 | if (MHD_gc_pseudo_random (rnd, 2) != GC_OK) | ||
1290 | { | ||
1291 | MHD_gnutls_assert (); | ||
1292 | return GNUTLS_E_RANDOM_FAILED; | ||
1293 | } | ||
1294 | |||
1295 | /* generate salt */ | ||
1296 | |||
1297 | if (schema == PBES2) | ||
1298 | { | ||
1299 | kdf_params->salt_size = | ||
1300 | MIN (sizeof (kdf_params->salt), (unsigned) (10 + (rnd[1] % 10))); | ||
1301 | } | ||
1302 | else | ||
1303 | kdf_params->salt_size = 8; | ||
1304 | |||
1305 | if (MHD_gc_pseudo_random (kdf_params->salt, kdf_params->salt_size) != GC_OK) | ||
1306 | { | ||
1307 | MHD_gnutls_assert (); | ||
1308 | return GNUTLS_E_RANDOM_FAILED; | ||
1309 | } | ||
1310 | |||
1311 | kdf_params->iter_count = 256 + rnd[0]; | ||
1312 | key->size = kdf_params->key_size = | ||
1313 | MHD__gnutls_cipher_get_key_size (enc_params->cipher); | ||
1314 | |||
1315 | enc_params->iv_size = MHD_gtls_cipher_get_iv_size (enc_params->cipher); | ||
1316 | |||
1317 | key->data = MHD_gnutls_secure_malloc (key->size); | ||
1318 | if (key->data == NULL) | ||
1319 | { | ||
1320 | MHD_gnutls_assert (); | ||
1321 | return GNUTLS_E_MEMORY_ERROR; | ||
1322 | } | ||
1323 | |||
1324 | /* now generate the key. | ||
1325 | */ | ||
1326 | |||
1327 | if (schema == PBES2) | ||
1328 | { | ||
1329 | |||
1330 | ret = MHD_gc_pbkdf2_sha1 (password, strlen (password), | ||
1331 | kdf_params->salt, kdf_params->salt_size, | ||
1332 | kdf_params->iter_count, | ||
1333 | key->data, kdf_params->key_size); | ||
1334 | if (ret != GC_OK) | ||
1335 | { | ||
1336 | MHD_gnutls_assert (); | ||
1337 | return GNUTLS_E_ENCRYPTION_FAILED; | ||
1338 | } | ||
1339 | |||
1340 | if (enc_params->iv_size && | ||
1341 | MHD_gc_nonce (enc_params->iv, enc_params->iv_size) != GC_OK) | ||
1342 | { | ||
1343 | MHD_gnutls_assert (); | ||
1344 | return GNUTLS_E_RANDOM_FAILED; | ||
1345 | } | ||
1346 | } | ||
1347 | else | ||
1348 | { /* PKCS12 schemas */ | ||
1349 | ret = | ||
1350 | MHD_pkcs12_string_to_key (1 /*KEY*/, kdf_params->salt, | ||
1351 | kdf_params->salt_size, | ||
1352 | kdf_params->iter_count, password, | ||
1353 | kdf_params->key_size, key->data); | ||
1354 | if (ret < 0) | ||
1355 | { | ||
1356 | MHD_gnutls_assert (); | ||
1357 | return ret; | ||
1358 | } | ||
1359 | |||
1360 | /* Now generate the IV | ||
1361 | */ | ||
1362 | if (enc_params->iv_size) | ||
1363 | { | ||
1364 | ret = | ||
1365 | MHD_pkcs12_string_to_key (2 /*IV*/, kdf_params->salt, | ||
1366 | kdf_params->salt_size, | ||
1367 | kdf_params->iter_count, password, | ||
1368 | enc_params->iv_size, enc_params->iv); | ||
1369 | if (ret < 0) | ||
1370 | { | ||
1371 | MHD_gnutls_assert (); | ||
1372 | return ret; | ||
1373 | } | ||
1374 | } | ||
1375 | } | ||
1376 | |||
1377 | return 0; | ||
1378 | } | ||
1379 | |||
1380 | /* Encodes the parameters to be written in the encryptionAlgorithm.parameters | ||
1381 | * part. | ||
1382 | */ | ||
1383 | static int | ||
1384 | write_schema_params (schema_id schema, ASN1_TYPE pkcs8_asn, | ||
1385 | const char *where, | ||
1386 | const struct pbkdf2_params *kdf_params, | ||
1387 | const struct pbe_enc_params *enc_params) | ||
1388 | { | ||
1389 | int result; | ||
1390 | ASN1_TYPE pbes2_asn = ASN1_TYPE_EMPTY; | ||
1391 | |||
1392 | if (schema == PBES2) | ||
1393 | { | ||
1394 | if ((result = | ||
1395 | MHD__asn1_create_element (MHD__gnutls_get_pkix (), | ||
1396 | "PKIX1.pkcs-5-PBES2-params", | ||
1397 | &pbes2_asn)) != ASN1_SUCCESS) | ||
1398 | { | ||
1399 | MHD_gnutls_assert (); | ||
1400 | return MHD_gtls_asn2err (result); | ||
1401 | } | ||
1402 | |||
1403 | result = write_pbkdf2_params (pbes2_asn, kdf_params); | ||
1404 | if (result < 0) | ||
1405 | { | ||
1406 | MHD_gnutls_assert (); | ||
1407 | goto error; | ||
1408 | } | ||
1409 | |||
1410 | result = write_pbe_enc_params (pbes2_asn, enc_params); | ||
1411 | if (result < 0) | ||
1412 | { | ||
1413 | MHD_gnutls_assert (); | ||
1414 | goto error; | ||
1415 | } | ||
1416 | |||
1417 | result = MHD__gnutls_x509_der_encode_and_copy (pbes2_asn, "", | ||
1418 | pkcs8_asn, where, 0); | ||
1419 | if (result < 0) | ||
1420 | { | ||
1421 | MHD_gnutls_assert (); | ||
1422 | goto error; | ||
1423 | } | ||
1424 | |||
1425 | MHD__asn1_delete_structure (&pbes2_asn); | ||
1426 | } | ||
1427 | else | ||
1428 | { /* PKCS12 schemas */ | ||
1429 | |||
1430 | if ((result = | ||
1431 | MHD__asn1_create_element (MHD__gnutls_get_pkix (), | ||
1432 | "PKIX1.pkcs-12-PbeParams", | ||
1433 | &pbes2_asn)) != ASN1_SUCCESS) | ||
1434 | { | ||
1435 | MHD_gnutls_assert (); | ||
1436 | result = MHD_gtls_asn2err (result); | ||
1437 | goto error; | ||
1438 | } | ||
1439 | |||
1440 | result = writeMHD_pkcs12_kdf_params (pbes2_asn, kdf_params); | ||
1441 | if (result < 0) | ||
1442 | { | ||
1443 | MHD_gnutls_assert (); | ||
1444 | goto error; | ||
1445 | } | ||
1446 | |||
1447 | result = MHD__gnutls_x509_der_encode_and_copy (pbes2_asn, "", | ||
1448 | pkcs8_asn, where, 0); | ||
1449 | if (result < 0) | ||
1450 | { | ||
1451 | MHD_gnutls_assert (); | ||
1452 | goto error; | ||
1453 | } | ||
1454 | |||
1455 | MHD__asn1_delete_structure (&pbes2_asn); | ||
1456 | |||
1457 | } | ||
1458 | |||
1459 | return 0; | ||
1460 | |||
1461 | error: | ||
1462 | MHD__asn1_delete_structure (&pbes2_asn); | ||
1463 | return result; | ||
1464 | |||
1465 | } | ||
1466 | |||
1467 | static int | ||
1468 | encrypt_data (const MHD_gnutls_datum_t * plain, | ||
1469 | const struct pbe_enc_params *enc_params, | ||
1470 | MHD_gnutls_datum_t * key, MHD_gnutls_datum_t * encrypted) | ||
1471 | { | ||
1472 | int result; | ||
1473 | int data_size; | ||
1474 | opaque *data = NULL; | ||
1475 | MHD_gnutls_datum_t d_iv; | ||
1476 | cipher_hd_t ch = NULL; | ||
1477 | opaque pad, pad_size; | ||
1478 | |||
1479 | pad_size = MHD_gtls_cipher_get_block_size (enc_params->cipher); | ||
1480 | |||
1481 | if (pad_size == 1) /* stream */ | ||
1482 | pad_size = 0; | ||
1483 | |||
1484 | data = MHD_gnutls_malloc (plain->size + pad_size); | ||
1485 | if (data == NULL) | ||
1486 | { | ||
1487 | MHD_gnutls_assert (); | ||
1488 | return GNUTLS_E_MEMORY_ERROR; | ||
1489 | } | ||
1490 | |||
1491 | memcpy (data, plain->data, plain->size); | ||
1492 | |||
1493 | if (pad_size > 0) | ||
1494 | { | ||
1495 | pad = pad_size - (plain->size % pad_size); | ||
1496 | if (pad == 0) | ||
1497 | pad = pad_size; | ||
1498 | memset (&data[plain->size], pad, pad); | ||
1499 | } | ||
1500 | else | ||
1501 | pad = 0; | ||
1502 | |||
1503 | data_size = plain->size + pad; | ||
1504 | |||
1505 | d_iv.data = (opaque *) enc_params->iv; | ||
1506 | d_iv.size = enc_params->iv_size; | ||
1507 | ch = MHD_gtls_cipher_init (enc_params->cipher, key, &d_iv); | ||
1508 | |||
1509 | if (ch == GNUTLS_CIPHER_FAILED) | ||
1510 | { | ||
1511 | MHD_gnutls_assert (); | ||
1512 | result = GNUTLS_E_ENCRYPTION_FAILED; | ||
1513 | goto error; | ||
1514 | } | ||
1515 | |||
1516 | result = MHD_gtls_cipher_encrypt (ch, data, data_size); | ||
1517 | if (result < 0) | ||
1518 | { | ||
1519 | MHD_gnutls_assert (); | ||
1520 | goto error; | ||
1521 | } | ||
1522 | |||
1523 | encrypted->data = data; | ||
1524 | encrypted->size = data_size; | ||
1525 | |||
1526 | MHD_gnutls_cipher_deinit (ch); | ||
1527 | |||
1528 | return 0; | ||
1529 | |||
1530 | error: | ||
1531 | MHD_gnutls_free (data); | ||
1532 | if (ch != NULL) | ||
1533 | MHD_gnutls_cipher_deinit (ch); | ||
1534 | return result; | ||
1535 | } | ||
1536 | |||
1537 | /* Decrypts a PKCS #7 encryptedData. The output is allocated | ||
1538 | * and stored in dec. | ||
1539 | */ | ||
1540 | int | ||
1541 | MHD__gnutls_pkcs7_decrypt_data (const MHD_gnutls_datum_t * data, | ||
1542 | const char *password, MHD_gnutls_datum_t * dec) | ||
1543 | { | ||
1544 | int result, len; | ||
1545 | char enc_oid[64]; | ||
1546 | MHD_gnutls_datum_t tmp; | ||
1547 | ASN1_TYPE pbes2_asn = ASN1_TYPE_EMPTY, pkcs7_asn = ASN1_TYPE_EMPTY; | ||
1548 | int params_start, params_end, params_len; | ||
1549 | struct pbkdf2_params kdf_params; | ||
1550 | struct pbe_enc_params enc_params; | ||
1551 | schema_id schema; | ||
1552 | |||
1553 | if ((result = | ||
1554 | MHD__asn1_create_element (MHD__gnutls_get_pkix (), | ||
1555 | "PKIX1.pkcs-7-EncryptedData", | ||
1556 | &pkcs7_asn)) != ASN1_SUCCESS) | ||
1557 | { | ||
1558 | MHD_gnutls_assert (); | ||
1559 | result = MHD_gtls_asn2err (result); | ||
1560 | goto error; | ||
1561 | } | ||
1562 | |||
1563 | result = MHD__asn1_der_decoding (&pkcs7_asn, data->data, data->size, NULL); | ||
1564 | if (result != ASN1_SUCCESS) | ||
1565 | { | ||
1566 | MHD_gnutls_assert (); | ||
1567 | result = MHD_gtls_asn2err (result); | ||
1568 | goto error; | ||
1569 | } | ||
1570 | |||
1571 | /* Check the encryption schema OID | ||
1572 | */ | ||
1573 | len = sizeof (enc_oid); | ||
1574 | result = | ||
1575 | MHD__asn1_read_value (pkcs7_asn, | ||
1576 | "encryptedContentInfo.contentEncryptionAlgorithm.algorithm", | ||
1577 | enc_oid, &len); | ||
1578 | if (result != ASN1_SUCCESS) | ||
1579 | { | ||
1580 | MHD_gnutls_assert (); | ||
1581 | result = MHD_gtls_asn2err (result); | ||
1582 | goto error; | ||
1583 | } | ||
1584 | |||
1585 | if ((result = check_schema (enc_oid)) < 0) | ||
1586 | { | ||
1587 | MHD_gnutls_assert (); | ||
1588 | goto error; | ||
1589 | } | ||
1590 | schema = result; | ||
1591 | |||
1592 | /* Get the DER encoding of the parameters. | ||
1593 | */ | ||
1594 | result = | ||
1595 | MHD__asn1_der_decoding_startEnd (pkcs7_asn, data->data, data->size, | ||
1596 | "encryptedContentInfo.contentEncryptionAlgorithm.parameters", | ||
1597 | ¶ms_start, ¶ms_end); | ||
1598 | if (result != ASN1_SUCCESS) | ||
1599 | { | ||
1600 | MHD_gnutls_assert (); | ||
1601 | result = MHD_gtls_asn2err (result); | ||
1602 | goto error; | ||
1603 | } | ||
1604 | params_len = params_end - params_start + 1; | ||
1605 | |||
1606 | result = | ||
1607 | read_pkcs_schema_params (schema, password, | ||
1608 | &data->data[params_start], | ||
1609 | params_len, &kdf_params, &enc_params); | ||
1610 | if (result < ASN1_SUCCESS) | ||
1611 | { | ||
1612 | MHD_gnutls_assert (); | ||
1613 | result = MHD_gtls_asn2err (result); | ||
1614 | goto error; | ||
1615 | } | ||
1616 | |||
1617 | /* Parameters have been decoded. Now | ||
1618 | * decrypt the EncryptedData. | ||
1619 | */ | ||
1620 | |||
1621 | result = | ||
1622 | decrypt_data (schema, pkcs7_asn, | ||
1623 | "encryptedContentInfo.encryptedContent", password, | ||
1624 | &kdf_params, &enc_params, &tmp); | ||
1625 | if (result < 0) | ||
1626 | { | ||
1627 | MHD_gnutls_assert (); | ||
1628 | goto error; | ||
1629 | } | ||
1630 | |||
1631 | MHD__asn1_delete_structure (&pkcs7_asn); | ||
1632 | |||
1633 | *dec = tmp; | ||
1634 | |||
1635 | return 0; | ||
1636 | |||
1637 | error: | ||
1638 | MHD__asn1_delete_structure (&pbes2_asn); | ||
1639 | MHD__asn1_delete_structure (&pkcs7_asn); | ||
1640 | return result; | ||
1641 | } | ||
1642 | |||
1643 | /* Encrypts to a PKCS #7 encryptedData. The output is allocated | ||
1644 | * and stored in enc. | ||
1645 | */ | ||
1646 | int | ||
1647 | MHD__gnutls_pkcs7_encrypt_data (schema_id schema, | ||
1648 | const MHD_gnutls_datum_t * data, | ||
1649 | const char *password, MHD_gnutls_datum_t * enc) | ||
1650 | { | ||
1651 | int result; | ||
1652 | MHD_gnutls_datum_t key = { NULL, 0 }; | ||
1653 | MHD_gnutls_datum_t tmp = { NULL, 0 }; | ||
1654 | ASN1_TYPE pkcs7_asn = ASN1_TYPE_EMPTY; | ||
1655 | struct pbkdf2_params kdf_params; | ||
1656 | struct pbe_enc_params enc_params; | ||
1657 | |||
1658 | if ((result = | ||
1659 | MHD__asn1_create_element (MHD__gnutls_get_pkix (), | ||
1660 | "PKIX1.pkcs-7-EncryptedData", | ||
1661 | &pkcs7_asn)) != ASN1_SUCCESS) | ||
1662 | { | ||
1663 | MHD_gnutls_assert (); | ||
1664 | result = MHD_gtls_asn2err (result); | ||
1665 | goto error; | ||
1666 | } | ||
1667 | |||
1668 | /* Write the encryption schema OID | ||
1669 | */ | ||
1670 | switch (schema) | ||
1671 | { | ||
1672 | case PBES2: | ||
1673 | result = | ||
1674 | MHD__asn1_write_value (pkcs7_asn, | ||
1675 | "encryptedContentInfo.contentEncryptionAlgorithm.algorithm", | ||
1676 | PBES2_OID, 1); | ||
1677 | break; | ||
1678 | case PKCS12_3DES_SHA1: | ||
1679 | result = | ||
1680 | MHD__asn1_write_value (pkcs7_asn, | ||
1681 | "encryptedContentInfo.contentEncryptionAlgorithm.algorithm", | ||
1682 | PKCS12_PBE_3DES_SHA1_OID, 1); | ||
1683 | break; | ||
1684 | case PKCS12_ARCFOUR_SHA1: | ||
1685 | result = | ||
1686 | MHD__asn1_write_value (pkcs7_asn, | ||
1687 | "encryptedContentInfo.contentEncryptionAlgorithm.algorithm", | ||
1688 | PKCS12_PBE_ARCFOUR_SHA1_OID, 1); | ||
1689 | break; | ||
1690 | case PKCS12_RC2_40_SHA1: | ||
1691 | result = | ||
1692 | MHD__asn1_write_value (pkcs7_asn, | ||
1693 | "encryptedContentInfo.contentEncryptionAlgorithm.algorithm", | ||
1694 | PKCS12_PBE_RC2_40_SHA1_OID, 1); | ||
1695 | break; | ||
1696 | |||
1697 | } | ||
1698 | |||
1699 | if (result != ASN1_SUCCESS) | ||
1700 | { | ||
1701 | MHD_gnutls_assert (); | ||
1702 | result = MHD_gtls_asn2err (result); | ||
1703 | goto error; | ||
1704 | } | ||
1705 | |||
1706 | /* Generate a symmetric key. | ||
1707 | */ | ||
1708 | |||
1709 | result = generate_key (schema, password, &kdf_params, &enc_params, &key); | ||
1710 | if (result < 0) | ||
1711 | { | ||
1712 | MHD_gnutls_assert (); | ||
1713 | goto error; | ||
1714 | } | ||
1715 | |||
1716 | result = write_schema_params (schema, pkcs7_asn, | ||
1717 | "encryptedContentInfo.contentEncryptionAlgorithm.parameters", | ||
1718 | &kdf_params, &enc_params); | ||
1719 | if (result < 0) | ||
1720 | { | ||
1721 | MHD_gnutls_assert (); | ||
1722 | goto error; | ||
1723 | } | ||
1724 | |||
1725 | /* Parameters have been encoded. Now | ||
1726 | * encrypt the Data. | ||
1727 | */ | ||
1728 | result = encrypt_data (data, &enc_params, &key, &tmp); | ||
1729 | if (result < 0) | ||
1730 | { | ||
1731 | MHD_gnutls_assert (); | ||
1732 | goto error; | ||
1733 | } | ||
1734 | |||
1735 | /* write the encrypted data. | ||
1736 | */ | ||
1737 | result = | ||
1738 | MHD__asn1_write_value (pkcs7_asn, | ||
1739 | "encryptedContentInfo.encryptedContent", tmp.data, | ||
1740 | tmp.size); | ||
1741 | if (result != ASN1_SUCCESS) | ||
1742 | { | ||
1743 | MHD_gnutls_assert (); | ||
1744 | result = MHD_gtls_asn2err (result); | ||
1745 | goto error; | ||
1746 | } | ||
1747 | |||
1748 | MHD__gnutls_free_datum (&tmp); | ||
1749 | MHD__gnutls_free_datum (&key); | ||
1750 | |||
1751 | /* Now write the rest of the pkcs-7 stuff. | ||
1752 | */ | ||
1753 | |||
1754 | result = MHD__gnutls_x509_write_uint32 (pkcs7_asn, "version", 0); | ||
1755 | if (result < 0) | ||
1756 | { | ||
1757 | MHD_gnutls_assert (); | ||
1758 | goto error; | ||
1759 | } | ||
1760 | |||
1761 | result = | ||
1762 | MHD__asn1_write_value (pkcs7_asn, "encryptedContentInfo.contentType", | ||
1763 | DATA_OID, 1); | ||
1764 | if (result != ASN1_SUCCESS) | ||
1765 | { | ||
1766 | MHD_gnutls_assert (); | ||
1767 | result = MHD_gtls_asn2err (result); | ||
1768 | goto error; | ||
1769 | } | ||
1770 | |||
1771 | result = MHD__asn1_write_value (pkcs7_asn, "unprotectedAttrs", NULL, 0); | ||
1772 | if (result != ASN1_SUCCESS) | ||
1773 | { | ||
1774 | MHD_gnutls_assert (); | ||
1775 | result = MHD_gtls_asn2err (result); | ||
1776 | goto error; | ||
1777 | } | ||
1778 | |||
1779 | /* Now encode and copy the DER stuff. | ||
1780 | */ | ||
1781 | result = MHD__gnutls_x509_der_encode (pkcs7_asn, "", enc, 0); | ||
1782 | |||
1783 | MHD__asn1_delete_structure (&pkcs7_asn); | ||
1784 | |||
1785 | if (result < 0) | ||
1786 | { | ||
1787 | MHD_gnutls_assert (); | ||
1788 | goto error; | ||
1789 | } | ||
1790 | |||
1791 | error: | ||
1792 | MHD__gnutls_free_datum (&key); | ||
1793 | MHD__gnutls_free_datum (&tmp); | ||
1794 | MHD__asn1_delete_structure (&pkcs7_asn); | ||
1795 | return result; | ||
1796 | } | ||
1797 | 973 | ||
1798 | #endif | 974 | #endif |