00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <gnutls_int.h>
00026 #include <gnutls_errors.h>
00027 #include <x509_b64.h>
00028 #include <auth_cert.h>
00029 #include <gnutls_cert.h>
00030 #include <gnutls_datum.h>
00031 #include <gnutls_mpi.h>
00032 #include <gnutls_global.h>
00033 #include <gnutls_pk.h>
00034 #include <debug.h>
00035 #include <gnutls_buffers.h>
00036 #include <gnutls_sig.h>
00037 #include <gnutls_kx.h>
00038
00039 static int MHD__gnutls_tls_sign (MHD_gtls_session_t session,
00040 MHD_gnutls_cert * cert,
00041 MHD_gnutls_privkey * pkey,
00042 const MHD_gnutls_datum_t * hash_concat,
00043 MHD_gnutls_datum_t * signature);
00044
00045
00046
00047
00048 int
00049 MHD_gtls_tls_sign_hdata (MHD_gtls_session_t session,
00050 MHD_gnutls_cert * cert,
00051 MHD_gnutls_privkey * pkey,
00052 MHD_gnutls_datum_t * signature)
00053 {
00054 MHD_gnutls_datum_t dconcat;
00055 int ret;
00056 opaque concat[36];
00057 mac_hd_t td_md5;
00058 mac_hd_t td_sha;
00059 enum MHD_GNUTLS_Protocol ver = MHD__gnutls_protocol_get_version (session);
00060
00061 td_sha = MHD_gnutls_hash_copy (session->internals.handshake_mac_handle_sha);
00062 if (td_sha == NULL)
00063 {
00064 MHD_gnutls_assert ();
00065 return GNUTLS_E_HASH_FAILED;
00066 }
00067
00068 if (ver == MHD_GNUTLS_PROTOCOL_SSL3)
00069 {
00070 ret = MHD_gtls_generate_master (session, 1);
00071 if (ret < 0)
00072 {
00073 MHD_gnutls_assert ();
00074 return ret;
00075 }
00076
00077 MHD_gnutls_mac_deinit_ssl3_handshake (td_sha, &concat[16],
00078 session->security_parameters.
00079 master_secret, TLS_MASTER_SIZE);
00080 }
00081 else
00082 MHD_gnutls_hash_deinit (td_sha, &concat[16]);
00083
00084 switch (cert->subject_pk_algorithm)
00085 {
00086 case MHD_GNUTLS_PK_RSA:
00087 td_md5 =
00088 MHD_gnutls_hash_copy (session->internals.handshake_mac_handle_md5);
00089 if (td_md5 == NULL)
00090 {
00091 MHD_gnutls_assert ();
00092 return GNUTLS_E_HASH_FAILED;
00093 }
00094
00095 if (ver == MHD_GNUTLS_PROTOCOL_SSL3)
00096 MHD_gnutls_mac_deinit_ssl3_handshake (td_md5, concat,
00097 session->security_parameters.
00098 master_secret, TLS_MASTER_SIZE);
00099 else
00100 MHD_gnutls_hash_deinit (td_md5, concat);
00101
00102 dconcat.data = concat;
00103 dconcat.size = 36;
00104 break;
00105 default:
00106 MHD_gnutls_assert ();
00107 return GNUTLS_E_INTERNAL_ERROR;
00108 }
00109 ret = MHD__gnutls_tls_sign (session, cert, pkey, &dconcat, signature);
00110 if (ret < 0)
00111 {
00112 MHD_gnutls_assert ();
00113 }
00114
00115 return ret;
00116 }
00117
00118
00119
00120
00121 int
00122 MHD_gtls_tls_sign_params (MHD_gtls_session_t session,
00123 MHD_gnutls_cert * cert,
00124 MHD_gnutls_privkey * pkey,
00125 MHD_gnutls_datum_t * params,
00126 MHD_gnutls_datum_t * signature)
00127 {
00128 MHD_gnutls_datum_t dconcat;
00129 int ret;
00130 mac_hd_t td_sha;
00131 opaque concat[36];
00132 enum MHD_GNUTLS_Protocol ver = MHD__gnutls_protocol_get_version (session);
00133
00134 td_sha = MHD_gtls_hash_init (MHD_GNUTLS_MAC_SHA1);
00135 if (td_sha == NULL)
00136 {
00137 MHD_gnutls_assert ();
00138 return GNUTLS_E_HASH_FAILED;
00139 }
00140
00141 MHD_gnutls_hash (td_sha, session->security_parameters.client_random,
00142 TLS_RANDOM_SIZE);
00143 MHD_gnutls_hash (td_sha, session->security_parameters.server_random,
00144 TLS_RANDOM_SIZE);
00145 MHD_gnutls_hash (td_sha, params->data, params->size);
00146
00147 switch (cert->subject_pk_algorithm)
00148 {
00149 case MHD_GNUTLS_PK_RSA:
00150 if (ver < MHD_GNUTLS_PROTOCOL_TLS1_2)
00151 {
00152 mac_hd_t td_md5 = MHD_gtls_hash_init (MHD_GNUTLS_MAC_MD5);
00153 if (td_md5 == NULL)
00154 {
00155 MHD_gnutls_assert ();
00156 return GNUTLS_E_HASH_FAILED;
00157 }
00158
00159 MHD_gnutls_hash (td_md5, session->security_parameters.client_random,
00160 TLS_RANDOM_SIZE);
00161 MHD_gnutls_hash (td_md5, session->security_parameters.server_random,
00162 TLS_RANDOM_SIZE);
00163 MHD_gnutls_hash (td_md5, params->data, params->size);
00164
00165 MHD_gnutls_hash_deinit (td_md5, concat);
00166 MHD_gnutls_hash_deinit (td_sha, &concat[16]);
00167
00168 dconcat.size = 36;
00169 }
00170 else
00171 {
00172 #if 1
00173
00174 memcpy (concat,
00175 "\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14",
00176 15);
00177 MHD_gnutls_hash_deinit (td_sha, &concat[15]);
00178 dconcat.size = 35;
00179 #else
00180
00181 memcpy (concat,
00182 "\x30\x1f\x30\x07\x06\x05\x2b\x0e\x03\x02\x1a\x04\x14", 13);
00183 MHD_gnutls_hash_deinit (td_sha, &concat[13]);
00184 dconcat.size = 33;
00185 #endif
00186 }
00187 dconcat.data = concat;
00188 break;
00189 default:
00190 MHD_gnutls_assert ();
00191 MHD_gnutls_hash_deinit (td_sha, NULL);
00192 return GNUTLS_E_INTERNAL_ERROR;
00193 }
00194 ret = MHD__gnutls_tls_sign (session, cert, pkey, &dconcat, signature);
00195 if (ret < 0)
00196 {
00197 MHD_gnutls_assert ();
00198 }
00199
00200 return ret;
00201
00202 }
00203
00204
00205
00206
00207 static int
00208 MHD_gtls_sign (enum MHD_GNUTLS_PublicKeyAlgorithm algo,
00209 mpi_t * params,
00210 int params_size,
00211 const MHD_gnutls_datum_t * data,
00212 MHD_gnutls_datum_t * signature)
00213 {
00214 int ret;
00215
00216 switch (algo)
00217 {
00218 case MHD_GNUTLS_PK_RSA:
00219
00220 if ((ret =
00221 MHD_gtls_pkcs1_rsa_encrypt (signature, data, params, params_size,
00222 1)) < 0)
00223 {
00224 MHD_gnutls_assert ();
00225 return ret;
00226 }
00227
00228 break;
00229 default:
00230 MHD_gnutls_assert ();
00231 return GNUTLS_E_INTERNAL_ERROR;
00232 break;
00233 }
00234
00235 return 0;
00236 }
00237
00238
00239
00240
00241
00242 static int
00243 MHD__gnutls_tls_sign (MHD_gtls_session_t session,
00244 MHD_gnutls_cert * cert,
00245 MHD_gnutls_privkey * pkey,
00246 const MHD_gnutls_datum_t * hash_concat,
00247 MHD_gnutls_datum_t * signature)
00248 {
00249
00250
00251
00252
00253 if (cert != NULL)
00254 if (cert->key_usage != 0)
00255 if (!(cert->key_usage & KEY_DIGITAL_SIGNATURE))
00256 {
00257 MHD_gnutls_assert ();
00258 return GNUTLS_E_KEY_USAGE_VIOLATION;
00259 }
00260
00261
00262 if (!pkey || pkey->params_size == 0)
00263 {
00264 if (!session->internals.sign_func)
00265 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
00266
00267 return (*session->internals.sign_func) (session,
00268 session->internals.
00269 sign_func_userdata,
00270 cert->cert_type, &cert->raw,
00271 hash_concat, signature);
00272 }
00273
00274 return MHD_gtls_sign (pkey->pk_algorithm, pkey->params, pkey->params_size,
00275 hash_concat, signature);
00276 }
00277
00278 static int
00279 MHD__gnutls_verify_sig (MHD_gnutls_cert * cert,
00280 const MHD_gnutls_datum_t * hash_concat,
00281 MHD_gnutls_datum_t * signature, size_t sha1pos)
00282 {
00283 int ret;
00284 MHD_gnutls_datum_t vdata;
00285
00286 if ((cert == NULL) || (cert->version == 0))
00287 {
00288
00289
00290 MHD_gnutls_assert ();
00291 return GNUTLS_E_CERTIFICATE_ERROR;
00292 }
00293
00294
00295
00296 if (cert != NULL)
00297 if (cert->key_usage != 0)
00298 if (!(cert->key_usage & KEY_DIGITAL_SIGNATURE))
00299 {
00300 MHD_gnutls_assert ();
00301 return GNUTLS_E_KEY_USAGE_VIOLATION;
00302 }
00303
00304 switch (cert->subject_pk_algorithm)
00305 {
00306 case MHD_GNUTLS_PK_RSA:
00307
00308 vdata.data = hash_concat->data;
00309 vdata.size = hash_concat->size;
00310
00311
00312 if ((ret = MHD_gtls_rsa_verify (&vdata, signature, cert->params,
00313 cert->params_size, 1)) < 0)
00314 {
00315 MHD_gnutls_assert ();
00316 return ret;
00317 }
00318
00319 break;
00320 default:
00321 MHD_gnutls_assert ();
00322 return GNUTLS_E_INTERNAL_ERROR;
00323 }
00324
00325 return 0;
00326 }
00327
00328
00329
00330
00331 int
00332 MHD_gtls_verify_sig_hdata (MHD_gtls_session_t session,
00333 MHD_gnutls_cert * cert,
00334 MHD_gnutls_datum_t * signature)
00335 {
00336 int ret;
00337 opaque concat[36];
00338 mac_hd_t td_md5;
00339 mac_hd_t td_sha;
00340 MHD_gnutls_datum_t dconcat;
00341 enum MHD_GNUTLS_Protocol ver = MHD__gnutls_protocol_get_version (session);
00342
00343 td_md5 = MHD_gnutls_hash_copy (session->internals.handshake_mac_handle_md5);
00344 if (td_md5 == NULL)
00345 {
00346 MHD_gnutls_assert ();
00347 return GNUTLS_E_HASH_FAILED;
00348 }
00349
00350 td_sha = MHD_gnutls_hash_copy (session->internals.handshake_mac_handle_sha);
00351 if (td_sha == NULL)
00352 {
00353 MHD_gnutls_assert ();
00354 MHD_gnutls_hash_deinit (td_md5, NULL);
00355 return GNUTLS_E_HASH_FAILED;
00356 }
00357
00358 if (ver == MHD_GNUTLS_PROTOCOL_SSL3)
00359 {
00360 ret = MHD_gtls_generate_master (session, 1);
00361 if (ret < 0)
00362 {
00363 MHD_gnutls_assert ();
00364 return ret;
00365 }
00366
00367 MHD_gnutls_mac_deinit_ssl3_handshake (td_md5, concat,
00368 session->security_parameters.
00369 master_secret, TLS_MASTER_SIZE);
00370 MHD_gnutls_mac_deinit_ssl3_handshake (td_sha, &concat[16],
00371 session->security_parameters.
00372 master_secret, TLS_MASTER_SIZE);
00373 }
00374 else
00375 {
00376 MHD_gnutls_hash_deinit (td_md5, concat);
00377 MHD_gnutls_hash_deinit (td_sha, &concat[16]);
00378 }
00379
00380 dconcat.data = concat;
00381 dconcat.size = 20 + 16;
00382
00383 ret = MHD__gnutls_verify_sig (cert, &dconcat, signature, 16);
00384 if (ret < 0)
00385 {
00386 MHD_gnutls_assert ();
00387 return ret;
00388 }
00389
00390 return ret;
00391
00392 }
00393
00394
00395
00396
00397 int
00398 MHD_gtls_verify_sig_params (MHD_gtls_session_t session,
00399 MHD_gnutls_cert * cert,
00400 const MHD_gnutls_datum_t * params,
00401 MHD_gnutls_datum_t * signature)
00402 {
00403 MHD_gnutls_datum_t dconcat;
00404 int ret;
00405 mac_hd_t td_md5 = NULL;
00406 mac_hd_t td_sha;
00407 opaque concat[36];
00408 enum MHD_GNUTLS_Protocol ver = MHD__gnutls_protocol_get_version (session);
00409
00410 if (ver < MHD_GNUTLS_PROTOCOL_TLS1_2)
00411 {
00412 td_md5 = MHD_gtls_hash_init (MHD_GNUTLS_MAC_MD5);
00413 if (td_md5 == NULL)
00414 {
00415 MHD_gnutls_assert ();
00416 return GNUTLS_E_HASH_FAILED;
00417 }
00418
00419 MHD_gnutls_hash (td_md5, session->security_parameters.client_random,
00420 TLS_RANDOM_SIZE);
00421 MHD_gnutls_hash (td_md5, session->security_parameters.server_random,
00422 TLS_RANDOM_SIZE);
00423 MHD_gnutls_hash (td_md5, params->data, params->size);
00424 }
00425
00426 td_sha = MHD_gtls_hash_init (MHD_GNUTLS_MAC_SHA1);
00427 if (td_sha == NULL)
00428 {
00429 MHD_gnutls_assert ();
00430 if (td_md5)
00431 MHD_gnutls_hash_deinit (td_md5, NULL);
00432 return GNUTLS_E_HASH_FAILED;
00433 }
00434
00435 MHD_gnutls_hash (td_sha, session->security_parameters.client_random,
00436 TLS_RANDOM_SIZE);
00437 MHD_gnutls_hash (td_sha, session->security_parameters.server_random,
00438 TLS_RANDOM_SIZE);
00439 MHD_gnutls_hash (td_sha, params->data, params->size);
00440
00441 if (ver < MHD_GNUTLS_PROTOCOL_TLS1_2)
00442 {
00443 MHD_gnutls_hash_deinit (td_md5, concat);
00444 MHD_gnutls_hash_deinit (td_sha, &concat[16]);
00445 dconcat.size = 36;
00446 }
00447 else
00448 {
00449 #if 1
00450
00451 memcpy (concat,
00452 "\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14",
00453 15);
00454 MHD_gnutls_hash_deinit (td_sha, &concat[15]);
00455 dconcat.size = 35;
00456 #else
00457
00458 memcpy (concat,
00459 "\x30\x1f\x30\x07\x06\x05\x2b\x0e\x03\x02\x1a\x04\x14", 13);
00460 MHD_gnutls_hash_deinit (td_sha, &concat[13]);
00461 dconcat.size = 33;
00462 #endif
00463 }
00464
00465 dconcat.data = concat;
00466
00467 ret = MHD__gnutls_verify_sig (cert, &dconcat, signature, dconcat.size - 20);
00468 if (ret < 0)
00469 {
00470 MHD_gnutls_assert ();
00471 return ret;
00472 }
00473
00474 return ret;
00475
00476 }