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
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include <assert.h>
00040 #include <stdio.h>
00041 #include <stdlib.h>
00042 #include <string.h>
00043 #include <time.h>
00044
00045 #include "ksm/database.h"
00046 #include "ksm/database_statement.h"
00047 #include "ksm/datetime.h"
00048 #include "ksm/db_fields.h"
00049 #include "ksm/debug.h"
00050 #include "ksm/kmedef.h"
00051 #include "ksm/ksm.h"
00052 #include "ksm/ksmdef.h"
00053 #include "ksm/ksm_internal.h"
00054 #include "ksm/message.h"
00055 #include "ksm/string_util.h"
00056 #include "ksm/string_util2.h"
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 int KsmKeyPairCreate(int policy_id, const char* HSMKeyID, int smID, int size, int alg, const char* generate, DB_ID* id)
00087 {
00088 unsigned long rowid;
00089 int status = 0;
00090 char* sql = NULL;
00091
00092
00093 if (id == NULL) {
00094 return MsgLog(KSM_INVARG, "NULL id");
00095 }
00096
00097 sql = DisSpecifyInit("keypairs", "policy_id, HSMkey_id, securitymodule_id, size, algorithm, generate");
00098 DisAppendInt(&sql, policy_id);
00099 DisAppendString(&sql, HSMKeyID);
00100 DisAppendInt(&sql, smID);
00101 DisAppendInt(&sql, size);
00102 DisAppendInt(&sql, alg);
00103 DisAppendString(&sql, generate);
00104 DisEnd(&sql);
00105
00106
00107
00108 status = DbExecuteSqlNoResult(DbHandle(), sql);
00109 DisFree(sql);
00110
00111 if (status == 0) {
00112
00113
00114
00115 status = DbLastRowId(DbHandle(), &rowid);
00116 if (status == 0) {
00117 *id = (DB_ID) rowid;
00118 }
00119 }
00120
00121 return status;
00122 }
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143 int KsmDnssecKeyCreate(int zone_id, int keypair_id, int keytype, int state, const char* time, DB_ID* id)
00144 {
00145 unsigned long rowid;
00146 int status = 0;
00147 char* sql = NULL;
00148 char* columns = NULL;
00149
00150
00151 if (id == NULL) {
00152 return MsgLog(KSM_INVARG, "NULL id");
00153 }
00154
00155 StrAppend(&columns, "zone_id, keypair_id, keytype, state");
00156 if (state != KSM_STATE_GENERATE) {
00157 StrAppend(&columns, ", ");
00158 StrAppend(&columns, KsmKeywordStateValueToName(state));
00159 }
00160
00161 sql = DisSpecifyInit("dnsseckeys", columns);
00162 DisAppendInt(&sql, zone_id);
00163 DisAppendInt(&sql, keypair_id);
00164 DisAppendInt(&sql, keytype);
00165 DisAppendInt(&sql, state);
00166 if (state != KSM_STATE_GENERATE) {
00167 DisAppendString(&sql, time);
00168 }
00169 DisEnd(&sql);
00170
00171
00172
00173 status = DbExecuteSqlNoResult(DbHandle(), sql);
00174 DisFree(sql);
00175 StrFree(columns);
00176
00177 if (status == 0) {
00178
00179
00180
00181 status = DbLastRowId(DbHandle(), &rowid);
00182 if (status == 0) {
00183 *id = (DB_ID) rowid;
00184 }
00185 }
00186
00187 return status;
00188 }
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 int KsmKeyInitSql(DB_RESULT* result, const char* sql)
00214 {
00215 return DbExecuteSql(DbHandle(), sql, result);
00216 }
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245 int KsmKeyInit(DB_RESULT* result, DQS_QUERY_CONDITION* condition)
00246 {
00247 int i;
00248 char* sql = NULL;
00249 int status = 0;
00250
00251
00252
00253 sql = DqsSpecifyInit("KEYDATA_VIEW", DB_KEYDATA_FIELDS);
00254 if (condition) {
00255 for (i = 0; condition[i].compare != DQS_END_OF_LIST; ++i) {
00256 switch (condition[i].code) {
00257 case DB_KEYDATA_ALGORITHM:
00258 DqsConditionInt(&sql, "ALGORITHM", condition[i].compare,
00259 condition[i].data.number, i);
00260 break;
00261
00262 case DB_KEYDATA_ID:
00263 DqsConditionInt(&sql, "ID", condition[i].compare,
00264 condition[i].data.number, i);
00265 break;
00266
00267 case DB_KEYDATA_KEYTYPE:
00268 DqsConditionInt(&sql, "KEYTYPE", condition[i].compare,
00269 condition[i].data.number, i);
00270 break;
00271
00272 case DB_KEYDATA_STATE:
00273 DqsConditionInt(&sql, "STATE", condition[i].compare,
00274 condition[i].data.number, i);
00275 break;
00276
00277 case DB_KEYDATA_ZONE_ID:
00278 DqsConditionInt(&sql, "ZONE_ID", condition[i].compare,
00279 condition[i].data.number, i);
00280 break;
00281
00282 default:
00283
00284
00285
00286 MsgLog(KME_UNRCONCOD, condition[i].code);
00287 }
00288 }
00289 }
00290 DqsEnd(&sql);
00291
00292
00293
00294 status = KsmKeyInitSql(result, sql);
00295 DqsFree(sql);
00296
00297 return status;
00298 }
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322 int KsmKeyInitId(DB_RESULT* result, DB_ID id)
00323 {
00324 DQS_QUERY_CONDITION condition[2];
00325
00326
00327
00328 condition[0].code = DB_KEYDATA_ID;
00329 condition[0].compare = DQS_COMPARE_EQ;
00330 condition[0].data.number = (int) id;
00331
00332 condition[1].compare = DQS_END_OF_LIST;
00333
00334 return KsmKeyInit(result, condition);
00335 }
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362 int KsmKey(DB_RESULT result, KSM_KEYDATA* data)
00363 {
00364 DB_ROW row = NULL;
00365 int status = 0;
00366
00367
00368 if (data == NULL) {
00369 return MsgLog(KSM_INVARG, "NULL data");
00370 }
00371
00372
00373
00374 memset(data, 0, sizeof(KSM_KEYDATA));
00375
00376
00377
00378 status = DbFetchRow(result, &row);
00379
00380 if (status == 0) {
00381 status = DbUnsignedLong(row, DB_KEYDATA_ID, &(data->keypair_id));
00382 }
00383
00384 if (status == 0) {
00385 status = DbInt(row, DB_KEYDATA_STATE, &(data->state));
00386 }
00387
00388 if (status == 0) {
00389 status = DbStringBuffer(row, DB_KEYDATA_GENERATE,
00390 data->generate, sizeof(data->generate));
00391 }
00392
00393 if (status == 0) {
00394 status = DbStringBuffer(row, DB_KEYDATA_PUBLISH,
00395 data->publish, sizeof(data->publish));
00396 }
00397
00398 if (status == 0) {
00399 status = DbStringBuffer(row, DB_KEYDATA_READY,
00400 data->ready, sizeof(data->ready));
00401 }
00402
00403 if (status == 0) {
00404 status = DbStringBuffer(row, DB_KEYDATA_ACTIVE,
00405 data->active, sizeof(data->active));
00406 }
00407
00408 if (status == 0) {
00409 status = DbStringBuffer(row, DB_KEYDATA_RETIRE,
00410 data->retire, sizeof(data->retire));
00411 }
00412
00413 if (status == 0) {
00414 status = DbStringBuffer(row, DB_KEYDATA_DEAD,
00415 data->dead, sizeof(data->dead));
00416 }
00417
00418 if (status == 0) {
00419 status = DbInt(row, DB_KEYDATA_KEYTYPE, &(data->keytype));
00420 }
00421
00422 if (status == 0) {
00423 status = DbInt(row, DB_KEYDATA_ALGORITHM, &(data->algorithm));
00424 }
00425
00426
00427
00428
00429
00430 if (status == 0) {
00431 status = DbStringBuffer(row, DB_KEYDATA_LOCATION,
00432 data->location, sizeof(data->location));
00433 }
00434
00435 if (status == 0) {
00436 status = DbInt(row, DB_KEYDATA_ZONE_ID, &(data->zone_id));
00437 }
00438
00439 if (status == 0) {
00440 status = DbInt(row, DB_KEYDATA_FIXED_DATE, &(data->fixedDate));
00441 }
00442
00443 DbFreeRow(row);
00444
00445 return status;
00446 }
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465 void KsmKeyEnd(DB_RESULT result)
00466 {
00467 DbFreeResult(result);
00468 }
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494 int KsmKeyData(DB_ID id, KSM_KEYDATA* data)
00495 {
00496 DB_RESULT result;
00497 int status;
00498
00499 status = KsmKeyInitId(&result, id);
00500 if (status == 0) {
00501
00502
00503
00504 status = KsmKey(result, data);
00505 (void) KsmKeyEnd(result);
00506 }
00507
00508
00509
00510
00511
00512
00513 return status;
00514 }
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558 int KsmKeyPredict(int policy_id, int keytype, int shared_keys, int interval, int *count, int rollover_scheme, int zone_count)
00559 {
00560 int status = 0;
00561 KSM_PARCOLL coll;
00562
00563
00564 if (count == NULL) {
00565 return MsgLog(KSM_INVARG, "NULL count");
00566 }
00567
00568
00569 if (zone_count == 0) {
00570 *count = 0;
00571 return status;
00572 }
00573
00574
00575 if ((keytype != KSM_TYPE_KSK) && (keytype != KSM_TYPE_ZSK)) {
00576 status = MsgLog(KME_UNKEYTYPE, keytype);
00577 return status;
00578 }
00579
00580
00581 status = KsmParameterCollection(&coll, policy_id);
00582 if (status != 0) {
00583 *count = -1;
00584 return status;
00585 }
00586
00587
00588 if (keytype == KSM_TYPE_KSK)
00589 {
00590 if (coll.ksklife == 0) {
00591 *count = coll.standbyksks + 1;
00592 }
00593 else if (rollover_scheme == KSM_ROLL_DNSKEY) {
00594 *count = ((interval + coll.pub_safety + coll.propdelay + coll.kskttl)/coll.ksklife) + coll.standbyksks + 1;
00595 }
00596 else if (rollover_scheme == KSM_ROLL_DS) {
00597 *count = ((interval + coll.pub_safety + coll.kskpropdelay + coll.dsttl)/coll.ksklife) + coll.standbyksks + 1;
00598 }
00599
00600
00601
00602
00603
00604
00605
00606
00607 }
00608 else if (keytype == KSM_TYPE_ZSK)
00609 {
00610 if (coll.zsklife == 0) {
00611 *count = coll.standbyzsks + 1;
00612 } else {
00613 *count = ((interval + coll.pub_safety)/coll.zsklife) + coll.standbyzsks + 1;
00614 }
00615 }
00616
00617 if (shared_keys == KSM_KEYS_NOT_SHARED) {
00618 *count *= zone_count;
00619 }
00620
00621 return status;
00622 }
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649 int KsmKeyCountQueue(int keytype, int* count, int zone_id)
00650 {
00651 int clause = 0;
00652 char* sql = NULL;
00653 int status = 0;
00654 char in[128];
00655 size_t nchar;
00656
00657
00658
00659 nchar = snprintf(in, sizeof(in), "(%d, %d, %d, %d, %d, %d, %d)",
00660 KSM_STATE_GENERATE, KSM_STATE_PUBLISH, KSM_STATE_READY, KSM_STATE_ACTIVE, KSM_STATE_DSSUB, KSM_STATE_DSPUBLISH, KSM_STATE_DSREADY);
00661 if (nchar >= sizeof(in)) {
00662 status = MsgLog(KME_BUFFEROVF, "KsmKeyCountQueue");
00663 return status;
00664 }
00665
00666 sql = DqsCountInit("KEYDATA_VIEW");
00667 DqsConditionInt(&sql, "KEYTYPE", DQS_COMPARE_EQ, keytype, clause++);
00668 DqsConditionKeyword(&sql, "STATE", DQS_COMPARE_IN, in, clause++);
00669 if (zone_id != -1) {
00670 DqsConditionInt(&sql, "ZONE_ID", DQS_COMPARE_EQ, zone_id, clause++);
00671 }
00672 DqsEnd(&sql);
00673
00674
00675
00676 status = DbIntQuery(DbHandle(), count, sql);
00677 DqsFree(sql);
00678
00679
00680
00681 if (status != 0) {
00682 status = MsgLog(KME_SQLFAIL, DbErrmsg(DbHandle()));
00683 }
00684
00685 return status;
00686 }
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728 int KsmKeyCountStillGood(int policy_id, int sm, int bits, int algorithm, int interval, const char* datetime, int *count, int keytype)
00729 {
00730 int where = 0;
00731 char* sql = NULL;
00732 int status = 0;
00733 char in[128];
00734 char buffer[512];
00735 size_t nchar;
00736 int total_interval;
00737 KSM_PARCOLL collection;
00738
00739
00740
00741
00742
00743
00744
00745 status = KsmParameterCollection(&collection, policy_id);
00746 if (status != 0) {
00747 return status;
00748 }
00749
00750 if (keytype == KSM_TYPE_ZSK)
00751 {
00752 total_interval = KsmParameterZskTtl(&collection) +
00753 KsmParameterPropagationDelay(&collection) +
00754 KsmParameterPubSafety(&collection) +
00755 interval;
00756 } else {
00757 total_interval = KsmParameterKskTtl(&collection) +
00758 KsmParameterKskPropagationDelay(&collection) +
00759 KsmParameterPubSafety(&collection) +
00760 interval;
00761 }
00762
00763 nchar = snprintf(in, sizeof(in), "(%d, %d, %d, %d, %d, %d, %d)",
00764 KSM_STATE_GENERATE, KSM_STATE_PUBLISH, KSM_STATE_READY, KSM_STATE_ACTIVE, KSM_STATE_DSSUB, KSM_STATE_DSPUBLISH, KSM_STATE_DSREADY);
00765 if (nchar >= sizeof(in)) {
00766 status = MsgLog(KME_BUFFEROVF, "KsmKeyCountStillGood");
00767 return status;
00768 }
00769
00770
00771
00772
00773 #ifdef USE_MYSQL
00774 nchar = snprintf(buffer, sizeof(buffer),
00775 "DATE_ADD('%s', INTERVAL %d SECOND)", datetime, total_interval);
00776 #else
00777 nchar = snprintf(buffer, sizeof(buffer),
00778 "DATETIME('%s', '+%d SECONDS')", datetime, total_interval);
00779 #endif
00780 if (nchar >= sizeof(buffer)) {
00781 status = MsgLog(KME_BUFFEROVF, "KsmKeyCountStillGood");
00782 return status;
00783 }
00784
00785
00786
00787 sql = DqsCountInit("KEYDATA_VIEW");
00788 if (policy_id != -1) {
00789 DqsConditionInt(&sql, "policy_id", DQS_COMPARE_EQ, policy_id, where++);
00790 }
00791 if (sm != -1) {
00792 DqsConditionInt(&sql, "securitymodule_id", DQS_COMPARE_EQ, sm, where++);
00793 }
00794 if (bits != -1) {
00795 DqsConditionInt(&sql, "size", DQS_COMPARE_EQ, bits, where++);
00796 }
00797 if (algorithm != -1) {
00798 DqsConditionInt(&sql, "algorithm", DQS_COMPARE_EQ, algorithm, where++);
00799 }
00800
00801 DqsConditionKeyword(&sql, "(STATE", DQS_COMPARE_IN, in, where++);
00802 StrAppend(&sql, " or STATE is NULL)");
00803
00804
00805 #ifdef USE_MYSQL
00806 StrAppend(&sql, " and (RETIRE > ");
00807 #else
00808 StrAppend(&sql, " and (DATETIME(RETIRE) > ");
00809 #endif
00810 StrAppend(&sql, buffer);
00811 StrAppend(&sql, " or RETIRE is NULL)");
00812
00813
00814 DqsEnd(&sql);
00815
00816
00817
00818 status = DbIntQuery(DbHandle(), count, sql);
00819 DqsFree(sql);
00820
00821
00822
00823 if (status != 0) {
00824 status = MsgLog(KME_SQLFAIL, DbErrmsg(DbHandle()));
00825 }
00826
00827 return status;
00828 }
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865 int KsmKeyGetUnallocated(int policy_id, int sm, int bits, int algorithm, int zone_id, int share_keys, int *keypair_id)
00866 {
00867
00868 int where = 0;
00869 char* sql = NULL;
00870 DB_RESULT result;
00871 DB_ROW row = NULL;
00872 int status = 0;
00873 char in_sql[1024];
00874 char in_sql2[1024];
00875
00876 if (share_keys == KSM_KEYS_NOT_SHARED) {
00877
00878 sql = DqsSpecifyInit("KEYDATA_VIEW","min(id)");
00879 DqsConditionInt(&sql, "policy_id", DQS_COMPARE_EQ, policy_id, where++);
00880 DqsConditionInt(&sql, "securitymodule_id", DQS_COMPARE_EQ, sm, where++);
00881 DqsConditionInt(&sql, "size", DQS_COMPARE_EQ, bits, where++);
00882 DqsConditionInt(&sql, "algorithm", DQS_COMPARE_EQ, algorithm, where++);
00883 DqsConditionKeyword(&sql, "zone_id", DQS_COMPARE_IS, "NULL", where++);
00884 } else {
00885 snprintf(in_sql, 1024, "(select id from KEYALLOC_VIEW where zone_id = %d)", zone_id);
00886 snprintf(in_sql2, 1024, "(select distinct id from KEYDATA_VIEW where policy_id = %d and state in (%d, %d))", policy_id, KSM_STATE_RETIRE, KSM_STATE_DEAD);
00887
00888
00889 sql = DqsSpecifyInit("KEYALLOC_VIEW","min(id)");
00890 DqsConditionInt(&sql, "policy_id", DQS_COMPARE_EQ, policy_id, where++);
00891 DqsConditionInt(&sql, "securitymodule_id", DQS_COMPARE_EQ, sm, where++);
00892 DqsConditionInt(&sql, "size", DQS_COMPARE_EQ, bits, where++);
00893 DqsConditionInt(&sql, "algorithm", DQS_COMPARE_EQ, algorithm, where++);
00894 DqsConditionKeyword(&sql, "zone_id", DQS_COMPARE_IS, "NULL", where++);
00895 DqsConditionKeyword(&sql, "id", DQS_COMPARE_NOT_IN, in_sql, where++);
00896 DqsConditionKeyword(&sql, "id", DQS_COMPARE_NOT_IN, in_sql2, where++);
00897 }
00898
00899 status = DbExecuteSql(DbHandle(), sql, &result);
00900 DqsFree(sql);
00901
00902 if (status != 0)
00903 {
00904 status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
00905 DbFreeResult(result);
00906 return status;
00907 }
00908
00909
00910 status = DbFetchRow(result, &row);
00911 if (status == 0) {
00912 DbInt(row, DB_KEYDATA_ID, keypair_id);
00913 }
00914 else if (status == -1) {}
00915
00916 else {
00917 status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
00918 }
00919
00920 DbFreeRow(row);
00921 DbFreeResult(result);
00922 return status;
00923 }
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941 int KsmMarkKeysAsDead(int zone_id)
00942 {
00943 int status = 0;
00944
00945 DB_RESULT result;
00946 KSM_KEYDATA data;
00947 char* sql = NULL;
00948 int clause = 0;
00949
00950
00951 sql = DqsSpecifyInit("KEYDATA_VIEW", DB_KEYDATA_FIELDS);
00952 DqsConditionInt(&sql, "state", DQS_COMPARE_LT, KSM_STATE_DEAD, clause++);
00953 DqsConditionInt(&sql, "state", DQS_COMPARE_GT, KSM_STATE_GENERATE, clause++);
00954 if (zone_id != -1) {
00955 DqsConditionInt(&sql, "zone_id", DQS_COMPARE_EQ, zone_id, clause++);
00956 }
00957 DqsEnd(&sql);
00958
00959
00960
00961 status = KsmKeyInitSql(&result, sql);
00962 if (status == 0) {
00963 status = KsmKey(result, &data);
00964 while (status == 0) {
00965
00966
00967 status = KsmKillKey(data.keypair_id);
00968 if (status == 0) {
00969 status = KsmKey(result, &data);
00970 }
00971 }
00972
00973
00974
00975 if (status == -1) {
00976 status = 0;
00977 }
00978
00979 KsmKeyEnd(result);
00980 }
00981
00982 return 0;
00983 }
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000 int KsmKillKey(int keypair_id)
01001 {
01002 int status = 0;
01003 char* sql = NULL;
01004 int set = 0;
01005 char* now = DtParseDateTimeString("now");
01006
01007
01008 if (now == NULL) {
01009 printf("Couldn't turn \"now\" into a date, quitting...\n");
01010 exit(1);
01011 }
01012
01013 sql = DusInit("dnsseckeys");
01014 DusSetInt(&sql, "STATE", KSM_STATE_DEAD, set++);
01015 DusSetString(&sql, "DEAD", now, set++);
01016 DusConditionInt(&sql, "ID", DQS_COMPARE_EQ, keypair_id, 0);
01017 DusEnd(&sql);
01018
01019
01020
01021 status = DbExecuteSqlNoResult(DbHandle(), sql);
01022 DusFree(sql);
01023
01024 StrFree(now);
01025
01026 return status;
01027 }
01028