security/nss/cmd/dbtest/dbtest.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 /*
michael@0 6 ** dbtest.c
michael@0 7 **
michael@0 8 ** QA test for cert and key databases, especially to open
michael@0 9 ** database readonly (NSS_INIT_READONLY) and force initializations
michael@0 10 ** even if the databases cannot be opened (NSS_INIT_FORCEOPEN)
michael@0 11 **
michael@0 12 */
michael@0 13 #include <stdio.h>
michael@0 14 #include <string.h>
michael@0 15
michael@0 16 #if defined(WIN32)
michael@0 17 #include "fcntl.h"
michael@0 18 #include "io.h"
michael@0 19 #endif
michael@0 20
michael@0 21 #include "secutil.h"
michael@0 22 #include "pk11pub.h"
michael@0 23
michael@0 24 #if defined(XP_UNIX)
michael@0 25 #include <unistd.h>
michael@0 26 #endif
michael@0 27
michael@0 28 #include "nspr.h"
michael@0 29 #include "prtypes.h"
michael@0 30 #include "certdb.h"
michael@0 31 #include "nss.h"
michael@0 32 #include "../modutil/modutil.h"
michael@0 33
michael@0 34 #include "plgetopt.h"
michael@0 35
michael@0 36 static char *progName;
michael@0 37
michael@0 38 char *dbDir = NULL;
michael@0 39
michael@0 40 static char *dbName[]={"secmod.db", "cert8.db", "key3.db"};
michael@0 41 static char* dbprefix = "";
michael@0 42 static char* secmodName = "secmod.db";
michael@0 43 static char* userPassword = "";
michael@0 44 PRBool verbose;
michael@0 45
michael@0 46 static char *
michael@0 47 getPassword(PK11SlotInfo *slot, PRBool retry, void *arg)
michael@0 48 {
michael@0 49 int *success = (int *)arg;
michael@0 50
michael@0 51 if (retry) {
michael@0 52 *success = 0;
michael@0 53 return NULL;
michael@0 54 }
michael@0 55
michael@0 56 *success = 1;
michael@0 57 return PORT_Strdup(userPassword);
michael@0 58 }
michael@0 59
michael@0 60
michael@0 61 static void Usage(const char *progName)
michael@0 62 {
michael@0 63 printf("Usage: %s [-r] [-f] [-i] [-d dbdir ] \n",
michael@0 64 progName);
michael@0 65 printf("%-20s open database readonly (NSS_INIT_READONLY)\n", "-r");
michael@0 66 printf("%-20s Continue to force initializations even if the\n", "-f");
michael@0 67 printf("%-20s databases cannot be opened (NSS_INIT_FORCEOPEN)\n", " ");
michael@0 68 printf("%-20s Try to initialize the database\n", "-i");
michael@0 69 printf("%-20s Supply a password with which to initialize the db\n", "-p");
michael@0 70 printf("%-20s Directory with cert database (default is .\n",
michael@0 71 "-d certdir");
michael@0 72 exit(1);
michael@0 73 }
michael@0 74
michael@0 75 int main(int argc, char **argv)
michael@0 76 {
michael@0 77 PLOptState *optstate;
michael@0 78 PLOptStatus optstatus;
michael@0 79
michael@0 80 PRUint32 flags = 0;
michael@0 81 Error ret;
michael@0 82 SECStatus rv;
michael@0 83 char * dbString = NULL;
michael@0 84 PRBool doInitTest = PR_FALSE;
michael@0 85 int i;
michael@0 86
michael@0 87 progName = strrchr(argv[0], '/');
michael@0 88 if (!progName)
michael@0 89 progName = strrchr(argv[0], '\\');
michael@0 90 progName = progName ? progName+1 : argv[0];
michael@0 91
michael@0 92 optstate = PL_CreateOptState(argc, argv, "rfip:d:h");
michael@0 93
michael@0 94 while ((optstatus = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
michael@0 95 switch (optstate->option) {
michael@0 96 case 'h':
michael@0 97 default : Usage(progName); break;
michael@0 98
michael@0 99 case 'r': flags |= NSS_INIT_READONLY; break;
michael@0 100
michael@0 101 case 'f': flags |= NSS_INIT_FORCEOPEN; break;
michael@0 102
michael@0 103 case 'i': doInitTest = PR_TRUE; break;
michael@0 104
michael@0 105 case 'p':
michael@0 106 userPassword = PORT_Strdup(optstate->value);
michael@0 107 break;
michael@0 108
michael@0 109 case 'd':
michael@0 110 dbDir = PORT_Strdup(optstate->value);
michael@0 111 break;
michael@0 112
michael@0 113 }
michael@0 114 }
michael@0 115 if (optstatus == PL_OPT_BAD)
michael@0 116 Usage(progName);
michael@0 117
michael@0 118 if (!dbDir) {
michael@0 119 dbDir = SECU_DefaultSSLDir(); /* Look in $SSL_DIR */
michael@0 120 }
michael@0 121 dbDir = SECU_ConfigDirectory(dbDir);
michael@0 122 PR_fprintf(PR_STDERR, "dbdir selected is %s\n\n", dbDir);
michael@0 123
michael@0 124 if( dbDir[0] == '\0') {
michael@0 125 PR_fprintf(PR_STDERR, errStrings[DIR_DOESNT_EXIST_ERR], dbDir);
michael@0 126 ret= DIR_DOESNT_EXIST_ERR;
michael@0 127 goto loser;
michael@0 128 }
michael@0 129
michael@0 130
michael@0 131 PR_Init( PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
michael@0 132
michael@0 133 /* get the status of the directory and databases and output message */
michael@0 134 if(PR_Access(dbDir, PR_ACCESS_EXISTS) != PR_SUCCESS) {
michael@0 135 PR_fprintf(PR_STDERR, errStrings[DIR_DOESNT_EXIST_ERR], dbDir);
michael@0 136 } else if(PR_Access(dbDir, PR_ACCESS_READ_OK) != PR_SUCCESS) {
michael@0 137 PR_fprintf(PR_STDERR, errStrings[DIR_NOT_READABLE_ERR], dbDir);
michael@0 138 } else {
michael@0 139 if( !( flags & NSS_INIT_READONLY ) &&
michael@0 140 PR_Access(dbDir, PR_ACCESS_WRITE_OK) != PR_SUCCESS) {
michael@0 141 PR_fprintf(PR_STDERR, errStrings[DIR_NOT_WRITEABLE_ERR], dbDir);
michael@0 142 }
michael@0 143 if (!doInitTest) {
michael@0 144 for (i=0;i<3;i++) {
michael@0 145 dbString=PR_smprintf("%s/%s",dbDir,dbName[i]);
michael@0 146 PR_fprintf(PR_STDOUT, "database checked is %s\n",dbString);
michael@0 147 if(PR_Access(dbString, PR_ACCESS_EXISTS) != PR_SUCCESS) {
michael@0 148 PR_fprintf(PR_STDERR, errStrings[FILE_DOESNT_EXIST_ERR],
michael@0 149 dbString);
michael@0 150 } else if(PR_Access(dbString, PR_ACCESS_READ_OK) != PR_SUCCESS) {
michael@0 151 PR_fprintf(PR_STDERR, errStrings[FILE_NOT_READABLE_ERR],
michael@0 152 dbString);
michael@0 153 } else if( !( flags & NSS_INIT_READONLY ) &&
michael@0 154 PR_Access(dbString, PR_ACCESS_WRITE_OK) != PR_SUCCESS) {
michael@0 155 PR_fprintf(PR_STDERR, errStrings[FILE_NOT_WRITEABLE_ERR],
michael@0 156 dbString);
michael@0 157 }
michael@0 158 }
michael@0 159 }
michael@0 160 }
michael@0 161
michael@0 162
michael@0 163 rv = NSS_Initialize(SECU_ConfigDirectory(dbDir), dbprefix, dbprefix,
michael@0 164 secmodName, flags);
michael@0 165 if (rv != SECSuccess) {
michael@0 166 SECU_PrintPRandOSError(progName);
michael@0 167 ret=NSS_INITIALIZE_FAILED_ERR;
michael@0 168 } else {
michael@0 169 ret=SUCCESS;
michael@0 170 if (doInitTest) {
michael@0 171 PK11SlotInfo * slot = PK11_GetInternalKeySlot();
michael@0 172 SECStatus rv;
michael@0 173 int passwordSuccess = 0;
michael@0 174 int type = CKM_DES3_CBC;
michael@0 175 SECItem keyid = { 0, NULL, 0 };
michael@0 176 unsigned char keyIdData[] = { 0xff, 0xfe };
michael@0 177 PK11SymKey *key = NULL;
michael@0 178
michael@0 179 keyid.data = keyIdData;
michael@0 180 keyid.len = sizeof(keyIdData);
michael@0 181
michael@0 182 PK11_SetPasswordFunc(getPassword);
michael@0 183 rv = PK11_InitPin(slot, (char *)NULL, userPassword);
michael@0 184 if (rv != SECSuccess) {
michael@0 185 PR_fprintf(PR_STDERR, "Failed to Init DB: %s\n",
michael@0 186 SECU_Strerror(PORT_GetError()));
michael@0 187 ret = CHANGEPW_FAILED_ERR;
michael@0 188 }
michael@0 189 if (*userPassword && !PK11_IsLoggedIn(slot, &passwordSuccess)) {
michael@0 190 PR_fprintf(PR_STDERR, "New DB did not log in after init\n");
michael@0 191 ret = AUTHENTICATION_FAILED_ERR;
michael@0 192 }
michael@0 193 /* generate a symetric key */
michael@0 194 key = PK11_TokenKeyGen(slot, type, NULL, 0, &keyid,
michael@0 195 PR_TRUE, &passwordSuccess);
michael@0 196
michael@0 197 if (!key) {
michael@0 198 PR_fprintf(PR_STDERR, "Could not generated symetric key: %s\n",
michael@0 199 SECU_Strerror(PORT_GetError()));
michael@0 200 exit (UNSPECIFIED_ERR);
michael@0 201 }
michael@0 202 PK11_FreeSymKey(key);
michael@0 203 PK11_Logout(slot);
michael@0 204
michael@0 205 PK11_Authenticate(slot, PR_TRUE, &passwordSuccess);
michael@0 206
michael@0 207 if (*userPassword && !passwordSuccess) {
michael@0 208 PR_fprintf(PR_STDERR, "New DB Did not initalize\n");
michael@0 209 ret = AUTHENTICATION_FAILED_ERR;
michael@0 210 }
michael@0 211 key = PK11_FindFixedKey(slot, type, &keyid, &passwordSuccess);
michael@0 212
michael@0 213 if (!key) {
michael@0 214 PR_fprintf(PR_STDERR, "Could not find generated key: %s\n",
michael@0 215 SECU_Strerror(PORT_GetError()));
michael@0 216 ret = UNSPECIFIED_ERR;
michael@0 217 } else {
michael@0 218 PK11_FreeSymKey(key);
michael@0 219 }
michael@0 220 PK11_FreeSlot(slot);
michael@0 221 }
michael@0 222
michael@0 223 if (NSS_Shutdown() != SECSuccess) {
michael@0 224 PR_fprintf(PR_STDERR, "Could not find generated key: %s\n",
michael@0 225 SECU_Strerror(PORT_GetError()));
michael@0 226 exit(1);
michael@0 227 }
michael@0 228 }
michael@0 229
michael@0 230 loser:
michael@0 231 return ret;
michael@0 232 }
michael@0 233

mercurial