~ubuntu-branches/ubuntu/saucy/gnutls28/saucy

« back to all changes in this revision

Viewing changes to lib/auth/cert.c

  • Committer: Package Import Robot
  • Author(s): Jeremy Bicha
  • Date: 2013-07-30 21:40:07 UTC
  • mfrom: (14.1.9 saucy-proposed)
  • Revision ID: package-import@ubuntu.com-20130730214007-9mrd08xo61kla008
Tags: 3.2.3-1ubuntu1
* Sync with Debian (LP: #1068029). Remaining change:
  - Drop gnutls-bin and -doc since we want to use the versions
    in gnutls26 as the defaults instead

Show diffs side-by-side

added added

removed removed

Lines of Context:
7
7
 *
8
8
 * The GnuTLS is free software; you can redistribute it and/or
9
9
 * modify it under the terms of the GNU Lesser General Public License
10
 
 * as published by the Free Software Foundation; either version 3 of
 
10
 * as published by the Free Software Foundation; either version 2.1 of
11
11
 * the License, or (at your option) any later version.
12
12
 *
13
13
 * This library is distributed in the hope that it will be useful, but
73
73
 * exported certificate struct (cert_auth_info_t)
74
74
 */
75
75
static int
76
 
_gnutls_copy_certificate_auth_info (cert_auth_info_t info, gnutls_pcert_st * certs, size_t ncerts, int subkey_used,     /* openpgp only */
 
76
_gnutls_copy_certificate_auth_info (cert_auth_info_t info, gnutls_pcert_st * certs, size_t ncerts, /* openpgp only */
77
77
                                    void *keyid)
78
78
{
79
79
  /* Copy peer's information to auth_info_t
123
123
#ifdef ENABLE_OPENPGP
124
124
  if (certs[0].type == GNUTLS_CRT_OPENPGP)
125
125
    {
126
 
      info->use_subkey = subkey_used;
127
126
      if (keyid)
128
127
        memcpy (info->subkey_id, keyid, GNUTLS_OPENPGP_KEYID_SIZE);
129
128
    }
475
474
  unsigned int pcert_length = 0;
476
475
 
477
476
  cred = (gnutls_certificate_credentials_t)
478
 
    _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
 
477
    _gnutls_get_cred (session, GNUTLS_CRD_CERTIFICATE, NULL);
479
478
  if (cred == NULL)
480
479
    {
481
480
      gnutls_assert ();
698
697
  gnutls_datum_t *issuers_dn = NULL;
699
698
 
700
699
  cred = (gnutls_certificate_credentials_t)
701
 
    _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
 
700
    _gnutls_get_cred (session, GNUTLS_CRD_CERTIFICATE, NULL);
702
701
  if (cred == NULL)
703
702
    {
704
703
      gnutls_assert ();
846
845
}
847
846
 
848
847
enum PGPKeyDescriptorType
849
 
{ PGP_KEY_FINGERPRINT, PGP_KEY, PGP_KEY_SUBKEY, PGP_KEY_FINGERPRINT_SUBKEY };
 
848
{ PGP_EMPTY_KEY=1, PGP_KEY_SUBKEY, PGP_KEY_FINGERPRINT_SUBKEY };
850
849
 
851
850
#ifdef ENABLE_OPENPGP
852
851
static int
857
856
  gnutls_pcert_st *apr_cert_list;
858
857
  gnutls_privkey_t apr_pkey;
859
858
  int apr_cert_list_length;
 
859
  unsigned int subkey;
860
860
  uint8_t type;
861
 
  uint8_t fpr[20];
 
861
  uint8_t fpr[GNUTLS_OPENPGP_V4_FINGERPRINT_SIZE];
 
862
  char buf[2*GNUTLS_OPENPGP_KEYID_SIZE+1];
862
863
  size_t fpr_size;
863
 
  unsigned int use_subkey = 0;
864
864
 
865
865
  /* find the appropriate certificate */
866
866
  if ((ret =
873
873
 
874
874
  ret = 3 + 1 + 3;
875
875
 
876
 
 
877
 
 
878
876
  if (apr_cert_list_length > 0)
879
877
    {
880
878
      fpr_size = sizeof (fpr);
881
879
      ret =
882
880
        gnutls_pubkey_get_openpgp_key_id (apr_cert_list[0].pubkey, 0, fpr,
883
 
                                          &fpr_size, &use_subkey);
 
881
                                          &fpr_size, &subkey);
884
882
      if (ret < 0)
885
883
        return gnutls_assert_val (ret);
886
884
 
887
 
      if (use_subkey != 0)
888
 
        ret += 1 + fpr_size;    /* for the keyid */
 
885
      ret += 1 + fpr_size;    /* for the keyid */
 
886
      _gnutls_handshake_log("Sending PGP key ID %s (%s)\n", _gnutls_bin2hex(fpr, GNUTLS_OPENPGP_KEYID_SIZE, buf, sizeof(buf), NULL), 
 
887
                        subkey?"subkey":"master");
889
888
 
890
889
      ret += apr_cert_list[0].cert.size;
891
890
    }
897
896
 
898
897
  if (apr_cert_list_length > 0)
899
898
    {
900
 
      if (use_subkey != 0)
901
 
        {
902
 
          type = PGP_KEY_SUBKEY;
903
 
 
904
 
          ret = _gnutls_buffer_append_data (data, &type, 1);
905
 
          if (ret < 0)
906
 
            return gnutls_assert_val (ret);
907
 
 
908
 
          ret = _gnutls_buffer_append_data_prefix (data, 8, fpr, fpr_size);
909
 
          if (ret < 0)
910
 
            return gnutls_assert_val (ret);
911
 
        }
912
 
      else
913
 
        {
914
 
          type = PGP_KEY;
915
 
          ret = _gnutls_buffer_append_data (data, &type, 1);
916
 
          if (ret < 0)
917
 
            return gnutls_assert_val (ret);
918
 
        }
 
899
      type = PGP_KEY_SUBKEY;
 
900
 
 
901
      ret = _gnutls_buffer_append_data (data, &type, 1);
 
902
      if (ret < 0)
 
903
        return gnutls_assert_val (ret);
 
904
 
 
905
      ret = _gnutls_buffer_append_data_prefix (data, 8, fpr, fpr_size);
 
906
      if (ret < 0)
 
907
        return gnutls_assert_val (ret);
919
908
 
920
909
      ret =
921
910
        _gnutls_buffer_append_data_prefix (data, 24,
926
915
    }
927
916
  else                          /* empty - no certificate */
928
917
    {
929
 
      type = PGP_KEY;
 
918
      type = PGP_EMPTY_KEY;
930
919
 
931
920
      ret = _gnutls_buffer_append_data (data, &type, 1);
932
921
      if (ret < 0)
945
934
                                     gnutls_buffer_st * data)
946
935
{
947
936
  int ret, packet_size;
948
 
  uint8_t type, fpr[20];
949
 
  size_t fpr_size;
 
937
  uint8_t type, fpr[GNUTLS_OPENPGP_V4_FINGERPRINT_SIZE];
 
938
  uint8_t id[GNUTLS_OPENPGP_KEYID_SIZE];
 
939
  unsigned int subkey;
 
940
  size_t fpr_size, id_size;
950
941
  gnutls_pcert_st *apr_cert_list;
951
942
  gnutls_privkey_t apr_pkey;
952
943
  int apr_cert_list_length;
953
 
  unsigned int use_subkey = 0;
954
944
 
955
945
  /* find the appropriate certificate */
956
946
  if ((ret =
961
951
      return ret;
962
952
    }
963
953
 
 
954
  if (apr_cert_list_length <= 0)
 
955
    return _gnutls_gen_openpgp_certificate (session, data);
 
956
 
 
957
  id_size = sizeof (id);
 
958
  ret =
 
959
    gnutls_pubkey_get_openpgp_key_id (apr_cert_list[0].pubkey, 0, id,
 
960
                                      &id_size, &subkey);
 
961
  if (ret < 0)
 
962
    return gnutls_assert_val (ret);
 
963
 
964
964
  fpr_size = sizeof (fpr);
965
965
  ret =
966
 
    gnutls_pubkey_get_openpgp_key_id (apr_cert_list[0].pubkey, 0, fpr,
967
 
                                      &fpr_size, &use_subkey);
 
966
    gnutls_pubkey_get_openpgp_key_id (apr_cert_list[0].pubkey, 
 
967
                                        GNUTLS_PUBKEY_GET_OPENPGP_FINGERPRINT, 
 
968
                                        fpr, &fpr_size, NULL);
968
969
  if (ret < 0)
969
970
    return gnutls_assert_val (ret);
970
971
 
971
972
  packet_size = 3 + 1;
972
 
 
973
 
  if (use_subkey)
974
 
    packet_size += 1 + fpr_size;        /* for the keyid */
 
973
  packet_size += 1 + fpr_size;        /* for the keyid */
975
974
 
976
975
  /* Only v4 fingerprints are sent 
977
976
   */
978
 
  if (apr_cert_list_length > 0)
979
 
    packet_size += 20 + 1;
980
 
  else                          /* empty certificate case */
981
 
    return _gnutls_gen_openpgp_certificate (session, data);
 
977
  packet_size += 20 + 1;
982
978
 
983
979
  ret = _gnutls_buffer_append_prefix (data, 24, packet_size - 3);
984
980
  if (ret < 0)
985
981
    return gnutls_assert_val (ret);
986
982
 
987
 
  if (use_subkey)
988
 
    {
989
 
      type = PGP_KEY_FINGERPRINT_SUBKEY;
990
 
      ret = _gnutls_buffer_append_data (data, &type, 1);
991
 
      if (ret < 0)
992
 
        return gnutls_assert_val (ret);
993
 
 
994
 
      ret = _gnutls_buffer_append_data_prefix (data, 8, fpr, fpr_size);
995
 
      if (ret < 0)
996
 
        return gnutls_assert_val (ret);
997
 
    }
998
 
  else
999
 
    {
1000
 
      type = PGP_KEY_FINGERPRINT;       /* key fingerprint */
1001
 
      ret = _gnutls_buffer_append_data (data, &type, 1);
1002
 
      if (ret < 0)
1003
 
        return gnutls_assert_val (ret);
1004
 
    }
1005
 
 
1006
 
  fpr_size = sizeof (fpr);
1007
 
  if ((ret =
1008
 
       _gnutls_openpgp_fingerprint (&apr_cert_list[0].cert, fpr,
1009
 
                                    &fpr_size)) < 0)
1010
 
    {
1011
 
      gnutls_assert ();
1012
 
      return ret;
1013
 
    }
 
983
  type = PGP_KEY_FINGERPRINT_SUBKEY;
 
984
  ret = _gnutls_buffer_append_data (data, &type, 1);
 
985
  if (ret < 0)
 
986
    return gnutls_assert_val (ret);
 
987
 
 
988
  ret = _gnutls_buffer_append_data_prefix (data, 8, id, id_size);
 
989
  if (ret < 0)
 
990
    return gnutls_assert_val (ret);
1014
991
 
1015
992
  ret = _gnutls_buffer_append_data_prefix (data, 8, fpr, fpr_size);
1016
993
  if (ret < 0)
1080
1057
  gnutls_datum_t tmp;
1081
1058
 
1082
1059
  cred = (gnutls_certificate_credentials_t)
1083
 
    _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
 
1060
    _gnutls_get_cred (session, GNUTLS_CRD_CERTIFICATE, NULL);
1084
1061
  if (cred == NULL)
1085
1062
    {
1086
1063
      gnutls_assert ();
1182
1159
  if ((ret =
1183
1160
       _gnutls_copy_certificate_auth_info (info,
1184
1161
                                           peer_certificate_list,
1185
 
                                           peer_certificate_list_size, 0,
 
1162
                                           peer_certificate_list_size,
1186
1163
                                           NULL)) < 0)
1187
1164
    {
1188
1165
      gnutls_assert ();
1209
1186
#ifdef ENABLE_OPENPGP
1210
1187
static int
1211
1188
_gnutls_proc_openpgp_server_crt (gnutls_session_t session,
1212
 
                                         uint8_t * data, size_t data_size)
 
1189
                                 uint8_t * data, size_t data_size)
1213
1190
{
1214
1191
  int size, ret, len;
1215
1192
  uint8_t *p = data;
1216
1193
  cert_auth_info_t info;
1217
1194
  gnutls_certificate_credentials_t cred;
1218
1195
  ssize_t dsize = data_size;
1219
 
  int x, key_type;
 
1196
  int key_type;
1220
1197
  gnutls_pcert_st *peer_certificate_list = NULL;
1221
 
  int peer_certificate_list_size = 0;
1222
1198
  gnutls_datum_t tmp, akey = { NULL, 0 };
 
1199
  unsigned int compat = 0;
1223
1200
  uint8_t subkey_id[GNUTLS_OPENPGP_KEYID_SIZE];
1224
 
  unsigned int subkey_id_set = 0;
1225
1201
 
1226
1202
  cred = (gnutls_certificate_credentials_t)
1227
 
    _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
 
1203
    _gnutls_get_cred (session, GNUTLS_CRD_CERTIFICATE, NULL);
1228
1204
  if (cred == NULL)
1229
1205
    {
1230
1206
      gnutls_assert ();
1279
1255
      DECR_LEN (dsize, GNUTLS_OPENPGP_KEYID_SIZE);
1280
1256
      memcpy (subkey_id, p, GNUTLS_OPENPGP_KEYID_SIZE);
1281
1257
      p += GNUTLS_OPENPGP_KEYID_SIZE;
1282
 
 
1283
 
      subkey_id_set = 1;
1284
 
 
1285
1258
    }
1286
1259
 
1287
 
  /* read the actual key or fingerprint */
1288
 
  if (key_type == PGP_KEY_FINGERPRINT
1289
 
      || key_type == PGP_KEY_FINGERPRINT_SUBKEY)
1290
 
    {                           /* the fingerprint */
1291
 
 
 
1260
  if (key_type == PGP_KEY_FINGERPRINT_SUBKEY)
 
1261
    {
1292
1262
      DECR_LEN (dsize, 1);
1293
1263
      len = (uint8_t) * p;
1294
1264
      p++;
1311
1281
          return ret;
1312
1282
        }
1313
1283
      tmp = akey;
1314
 
      peer_certificate_list_size++;
1315
 
 
1316
1284
    }
1317
 
  else if (key_type == PGP_KEY || key_type == PGP_KEY_SUBKEY)
 
1285
  else if (key_type == PGP_KEY_SUBKEY)
1318
1286
    {                           /* the whole key */
1319
1287
 
1320
1288
      /* Read the actual certificate */
1326
1294
        {
1327
1295
          gnutls_assert ();
1328
1296
          /* no certificate was sent */
1329
 
          return GNUTLS_E_NO_CERTIFICATE_FOUND;
 
1297
          return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
1330
1298
        }
1331
1299
 
1332
1300
      DECR_LEN (dsize, len);
1333
 
      peer_certificate_list_size++;
1334
 
 
1335
 
      tmp.size = len;
1336
 
      tmp.data = p;
1337
 
 
 
1301
 
 
1302
      tmp.size = len;
 
1303
      tmp.data = p;
 
1304
 
 
1305
    }
 
1306
  else if (key_type == PGP_EMPTY_KEY)
 
1307
    {                           /* the whole key */
 
1308
 
 
1309
      /* Read the actual certificate */
 
1310
      DECR_LEN (dsize, 3);
 
1311
      len = _gnutls_read_uint24 (p);
 
1312
      p += 3;
 
1313
 
 
1314
      if (len == 0) /* PGP_EMPTY_KEY */
 
1315
        return GNUTLS_E_NO_CERTIFICATE_FOUND;
 
1316
      /* Uncomment to remove compatibility with RFC5081.
 
1317
      else
 
1318
        return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);*/
 
1319
 
 
1320
      DECR_LEN (dsize, len);
 
1321
 
 
1322
      tmp.size = len;
 
1323
      tmp.data = p;
 
1324
      
 
1325
      compat = 1;
1338
1326
    }
1339
1327
  else
1340
1328
    {
1344
1332
 
1345
1333
  /* ok we now have the peer's key in tmp datum
1346
1334
   */
1347
 
 
1348
 
  if (peer_certificate_list_size == 0)
1349
 
    {
1350
 
      gnutls_assert ();
1351
 
      return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1352
 
    }
1353
 
 
1354
1335
  peer_certificate_list =
1355
 
    gnutls_calloc (1,
1356
 
                   sizeof (gnutls_pcert_st) * (peer_certificate_list_size));
 
1336
    gnutls_calloc (1, sizeof (gnutls_pcert_st));
1357
1337
  if (peer_certificate_list == NULL)
1358
1338
    {
1359
1339
      gnutls_assert ();
1365
1345
    gnutls_pcert_import_openpgp_raw (&peer_certificate_list[0],
1366
1346
                                     &tmp,
1367
1347
                                     GNUTLS_OPENPGP_FMT_RAW,
1368
 
                                     (subkey_id_set != 0) ? subkey_id : NULL,
 
1348
                                     (compat==0)?subkey_id:NULL,
1369
1349
                                     0);
1370
1350
  if (ret < 0)
1371
1351
    {
1372
1352
      gnutls_assert ();
1373
1353
      goto cleanup;
1374
1354
    }
 
1355
  
 
1356
  if (compat != 0)
 
1357
    {
 
1358
      size_t t = sizeof(subkey_id);
 
1359
      gnutls_pubkey_get_openpgp_key_id(peer_certificate_list[0].pubkey, 0, subkey_id, &t, NULL);
 
1360
    }
1375
1361
 
1376
1362
  ret =
1377
1363
    _gnutls_copy_certificate_auth_info (info,
1378
1364
                                        peer_certificate_list,
1379
 
                                        peer_certificate_list_size,
1380
 
                                        subkey_id_set,
1381
 
                                        (subkey_id_set !=
1382
 
                                         0) ? subkey_id : NULL);
 
1365
                                        1, subkey_id);
1383
1366
  if (ret < 0)
1384
1367
    {
1385
1368
      gnutls_assert ();
1399
1382
cleanup:
1400
1383
 
1401
1384
  _gnutls_free_datum (&akey);
1402
 
  CLEAR_CERTS;
 
1385
  gnutls_pcert_deinit(&peer_certificate_list[0]);
1403
1386
  gnutls_free (peer_certificate_list);
1404
1387
  return ret;
1405
1388
 
1407
1390
#endif
1408
1391
 
1409
1392
int
1410
 
_gnutls_proc_crt (gnutls_session_t session,
1411
 
                                      uint8_t * data, size_t data_size)
 
1393
_gnutls_proc_crt (gnutls_session_t session, uint8_t * data, size_t data_size)
1412
1394
{
1413
1395
  int ret;
1414
1396
  gnutls_certificate_credentials_t cred;
1415
1397
 
1416
1398
  cred =
1417
 
    (gnutls_certificate_credentials_t) _gnutls_get_cred (session->key,
 
1399
    (gnutls_certificate_credentials_t) _gnutls_get_cred (session,
1418
1400
                                                         GNUTLS_CRD_CERTIFICATE,
1419
1401
                                                         NULL);
1420
1402
  if (cred == NULL)
1439
1421
      return GNUTLS_E_INTERNAL_ERROR;
1440
1422
    }
1441
1423
 
1442
 
  if (ret == 0 && cred->verify_callback != NULL)
1443
 
    {
1444
 
      ret = cred->verify_callback (session);
1445
 
      if (ret != 0)
1446
 
        ret = GNUTLS_E_CERTIFICATE_ERROR;
1447
 
    }
1448
 
 
1449
1424
  return ret;
1450
1425
}
1451
1426
 
1481
1456
  int i;
1482
1457
  gnutls_pk_algorithm_t pk_algos[MAX_CLIENT_SIGN_ALGOS];
1483
1458
  int pk_algos_length;
1484
 
  gnutls_protocol_t ver = gnutls_protocol_get_version (session);
 
1459
  const version_entry_st* ver = get_version (session);
 
1460
 
 
1461
  if (unlikely(ver == NULL))
 
1462
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
1485
1463
 
1486
1464
  cred = (gnutls_certificate_credentials_t)
1487
 
    _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
 
1465
    _gnutls_get_cred (session, GNUTLS_CRD_CERTIFICATE, NULL);
1488
1466
  if (cred == NULL)
1489
1467
    {
1490
1468
      gnutls_assert ();
1572
1550
  /* We should reply with a certificate message, 
1573
1551
   * even if we have no certificate to send.
1574
1552
   */
1575
 
  session->key->crt_requested = 1;
 
1553
  session->key.crt_requested = 1;
1576
1554
 
1577
1555
  return 0;
1578
1556
}
1586
1564
  gnutls_privkey_t apr_pkey;
1587
1565
  int apr_cert_list_length;
1588
1566
  gnutls_datum_t signature = { NULL, 0 };
1589
 
  int total_data;
1590
1567
  gnutls_sign_algorithm_t sign_algo;
1591
 
  gnutls_protocol_t ver = gnutls_protocol_get_version (session);
 
1568
  const version_entry_st* ver = get_version (session);
 
1569
 
 
1570
  if (unlikely(ver == NULL))
 
1571
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
1592
1572
 
1593
1573
  /* find the appropriate certificate */
1594
1574
  if ((ret =
1616
1596
      return 0;
1617
1597
    }
1618
1598
 
1619
 
  total_data = signature.size + 2;
1620
 
 
1621
 
  /* add hash and signature algorithms */
1622
 
  if (_gnutls_version_has_selectable_sighash (ver))
1623
 
    {
1624
 
      total_data += 2;
1625
 
    }
1626
 
 
1627
1599
  if (_gnutls_version_has_selectable_sighash (ver))
1628
1600
    {
1629
1601
      const sign_algorithm_st *aid;
1670
1642
  cert_auth_info_t info = _gnutls_get_auth_info (session);
1671
1643
  gnutls_pcert_st peer_cert;
1672
1644
  gnutls_sign_algorithm_t sign_algo = GNUTLS_SIGN_UNKNOWN;
1673
 
  gnutls_protocol_t ver = gnutls_protocol_get_version (session);
 
1645
  const version_entry_st* ver = get_version (session);
1674
1646
 
1675
 
  if (info == NULL || info->ncerts == 0)
 
1647
  if (unlikely(info == NULL || info->ncerts == 0 || ver == NULL))
1676
1648
    {
1677
1649
      gnutls_assert ();
1678
1650
      /* we need this in order to get peer's certificate */
1740
1712
                                  gnutls_buffer_st * data)
1741
1713
{
1742
1714
  gnutls_certificate_credentials_t cred;
1743
 
  int size, ret;
 
1715
  int ret;
1744
1716
  uint8_t tmp_data[CERTTYPE_SIZE];
1745
 
  gnutls_protocol_t ver = gnutls_protocol_get_version (session);
 
1717
  const version_entry_st* ver = get_version (session);
 
1718
 
 
1719
  if (unlikely(ver == NULL))
 
1720
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
1746
1721
 
1747
1722
  /* Now we need to generate the RDN sequence. This is
1748
1723
   * already in the CERTIFICATE_CRED structure, to improve
1750
1725
   */
1751
1726
 
1752
1727
  cred = (gnutls_certificate_credentials_t)
1753
 
    _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
 
1728
    _gnutls_get_cred (session, GNUTLS_CRD_CERTIFICATE, NULL);
1754
1729
  if (cred == NULL)
1755
1730
    {
1756
1731
      gnutls_assert ();
1757
1732
      return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1758
1733
    }
1759
1734
 
1760
 
  size = CERTTYPE_SIZE + 2;     /* 2 for gnutls_certificate_type_t + 2 for size of rdn_seq 
1761
 
                                 */
1762
 
 
1763
 
  if (session->security_parameters.cert_type == GNUTLS_CRT_X509 &&
1764
 
      session->internals.ignore_rdn_sequence == 0)
1765
 
    size += cred->x509_rdn_sequence.size;
1766
 
 
1767
 
  if (_gnutls_version_has_selectable_sighash (ver))
1768
 
    /* Need two bytes to announce the number of supported hash
1769
 
       functions (see below).  */
1770
 
    size += MAX_SIGN_ALGO_SIZE;
1771
 
 
1772
1735
  tmp_data[0] = CERTTYPE_SIZE - 1;
1773
1736
  tmp_data[1] = RSA_SIGN;
1774
1737
  tmp_data[2] = DSA_SIGN;
1790
1753
          return ret;
1791
1754
        }
1792
1755
 
1793
 
      /* recalculate size */
1794
 
      size -= MAX_SIGN_ALGO_SIZE + ret;
1795
 
 
1796
1756
      ret = _gnutls_buffer_append_data (data, p, ret);
1797
1757
      if (ret < 0)
1798
1758
        return gnutls_assert_val (ret);
2125
2085
  char server_name[MAX_CN];
2126
2086
 
2127
2087
  cred = (gnutls_certificate_credentials_t)
2128
 
    _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
 
2088
    _gnutls_get_cred (session, GNUTLS_CRD_CERTIFICATE, NULL);
2129
2089
  if (cred == NULL)
2130
2090
    {
2131
2091
      gnutls_assert ();
2247
2207
  _gnutls_free_datum (&rsa->modulus);
2248
2208
  _gnutls_free_datum (&rsa->exponent);
2249
2209
}
 
2210
 
 
2211
int _gnutls_gen_dhe_signature(gnutls_session_t session, gnutls_buffer_st* data,
 
2212
        uint8_t* plain, unsigned plain_size)
 
2213
{
 
2214
gnutls_pcert_st *apr_cert_list;
 
2215
gnutls_privkey_t apr_pkey;
 
2216
int apr_cert_list_length;
 
2217
gnutls_datum_t signature = { NULL, 0 }, ddata;
 
2218
gnutls_sign_algorithm_t sign_algo;
 
2219
const version_entry_st* ver = get_version (session);
 
2220
int ret;
 
2221
 
 
2222
  if (unlikely(ver == NULL))
 
2223
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
 
2224
 
 
2225
  ddata.data = plain;
 
2226
  ddata.size = plain_size;
 
2227
 
 
2228
  /* find the appropriate certificate */
 
2229
  if ((ret =
 
2230
       _gnutls_get_selected_cert (session, &apr_cert_list,
 
2231
                                  &apr_cert_list_length, &apr_pkey)) < 0)
 
2232
    {
 
2233
      gnutls_assert ();
 
2234
      return ret;
 
2235
    }
 
2236
 
 
2237
  if (apr_cert_list_length > 0)
 
2238
    {
 
2239
      if ((ret =
 
2240
           _gnutls_handshake_sign_data (session, &apr_cert_list[0],
 
2241
                                        apr_pkey, &ddata, &signature,
 
2242
                                        &sign_algo)) < 0)
 
2243
        {
 
2244
          gnutls_assert ();
 
2245
          goto cleanup;
 
2246
        }
 
2247
    }
 
2248
  else
 
2249
    {
 
2250
      gnutls_assert ();
 
2251
      ret = 0; /* ANON-DH, do not put a signature - ILLEGAL! */
 
2252
      goto cleanup;
 
2253
    }
 
2254
 
 
2255
  if (_gnutls_version_has_selectable_sighash (ver))
 
2256
    {
 
2257
      const sign_algorithm_st *aid;
 
2258
      uint8_t p[2];
 
2259
 
 
2260
      if (sign_algo == GNUTLS_SIGN_UNKNOWN)
 
2261
        {
 
2262
          ret = GNUTLS_E_UNKNOWN_ALGORITHM;
 
2263
          goto cleanup;
 
2264
        }
 
2265
 
 
2266
      aid = _gnutls_sign_to_tls_aid (sign_algo);
 
2267
      if (aid == NULL)
 
2268
        {
 
2269
          gnutls_assert();
 
2270
          ret = GNUTLS_E_UNKNOWN_ALGORITHM;
 
2271
          goto cleanup;
 
2272
        }
 
2273
      
 
2274
      p[0] = aid->hash_algorithm;
 
2275
      p[1] = aid->sign_algorithm;
 
2276
      
 
2277
      ret = _gnutls_buffer_append_data(data, p, 2);
 
2278
      if (ret < 0)
 
2279
        {
 
2280
          gnutls_assert();
 
2281
          goto cleanup;
 
2282
        }
 
2283
    }
 
2284
 
 
2285
  ret = _gnutls_buffer_append_data_prefix(data, 16, signature.data, signature.size);
 
2286
  if (ret < 0)
 
2287
    {
 
2288
      gnutls_assert();
 
2289
    }
 
2290
 
 
2291
  ret = 0;
 
2292
 
 
2293
cleanup:
 
2294
  _gnutls_free_datum (&signature);
 
2295
  return ret;
 
2296
}
 
2297
 
 
2298
int
 
2299
_gnutls_proc_dhe_signature (gnutls_session_t session, uint8_t * data,
 
2300
                    size_t _data_size, gnutls_datum_t* vparams)
 
2301
{
 
2302
  int sigsize;
 
2303
  gnutls_datum_t signature;
 
2304
  int ret;
 
2305
  cert_auth_info_t info = _gnutls_get_auth_info (session);
 
2306
  ssize_t data_size = _data_size;
 
2307
  gnutls_pcert_st peer_cert;
 
2308
  gnutls_sign_algorithm_t sign_algo = GNUTLS_SIGN_UNKNOWN;
 
2309
  const version_entry_st* ver = get_version (session);
 
2310
 
 
2311
  if (unlikely(info == NULL || info->ncerts == 0 || ver == NULL))
 
2312
    {
 
2313
      gnutls_assert ();
 
2314
      /* we need this in order to get peer's certificate */
 
2315
      return GNUTLS_E_INTERNAL_ERROR;
 
2316
    }
 
2317
 
 
2318
  /* VERIFY SIGNATURE */
 
2319
  if (_gnutls_version_has_selectable_sighash (ver))
 
2320
    {
 
2321
      sign_algorithm_st aid;
 
2322
 
 
2323
      DECR_LEN (data_size, 1);
 
2324
      aid.hash_algorithm = *data++;
 
2325
      DECR_LEN (data_size, 1);
 
2326
      aid.sign_algorithm = *data++;
 
2327
      sign_algo = _gnutls_tls_aid_to_sign (&aid);
 
2328
      if (sign_algo == GNUTLS_SIGN_UNKNOWN)
 
2329
        {
 
2330
          _gnutls_debug_log("unknown signature %d.%d\n", aid.sign_algorithm, aid.hash_algorithm);
 
2331
          gnutls_assert ();
 
2332
          return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
 
2333
        }
 
2334
    }
 
2335
  DECR_LEN (data_size, 2);
 
2336
  sigsize = _gnutls_read_uint16 (data);
 
2337
  data += 2;
 
2338
 
 
2339
  DECR_LEN (data_size, sigsize);
 
2340
  signature.data = data;
 
2341
  signature.size = sigsize;
 
2342
 
 
2343
  if ((ret =
 
2344
       _gnutls_get_auth_info_pcert (&peer_cert,
 
2345
                                    session->security_parameters.cert_type,
 
2346
                                    info)) < 0)
 
2347
    {
 
2348
      gnutls_assert ();
 
2349
      return ret;
 
2350
    }
 
2351
 
 
2352
  ret =
 
2353
    _gnutls_handshake_verify_data (session, &peer_cert, vparams, &signature,
 
2354
                                   sign_algo);
 
2355
 
 
2356
  gnutls_pcert_deinit (&peer_cert);
 
2357
  if (ret < 0)
 
2358
    {
 
2359
      gnutls_assert ();
 
2360
      return ret;
 
2361
    }
 
2362
 
 
2363
  return 0;
 
2364
}