1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/cmd/dbtest/dbtest.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,233 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +/* 1.9 +** dbtest.c 1.10 +** 1.11 +** QA test for cert and key databases, especially to open 1.12 +** database readonly (NSS_INIT_READONLY) and force initializations 1.13 +** even if the databases cannot be opened (NSS_INIT_FORCEOPEN) 1.14 +** 1.15 +*/ 1.16 +#include <stdio.h> 1.17 +#include <string.h> 1.18 + 1.19 +#if defined(WIN32) 1.20 +#include "fcntl.h" 1.21 +#include "io.h" 1.22 +#endif 1.23 + 1.24 +#include "secutil.h" 1.25 +#include "pk11pub.h" 1.26 + 1.27 +#if defined(XP_UNIX) 1.28 +#include <unistd.h> 1.29 +#endif 1.30 + 1.31 +#include "nspr.h" 1.32 +#include "prtypes.h" 1.33 +#include "certdb.h" 1.34 +#include "nss.h" 1.35 +#include "../modutil/modutil.h" 1.36 + 1.37 +#include "plgetopt.h" 1.38 + 1.39 +static char *progName; 1.40 + 1.41 +char *dbDir = NULL; 1.42 + 1.43 +static char *dbName[]={"secmod.db", "cert8.db", "key3.db"}; 1.44 +static char* dbprefix = ""; 1.45 +static char* secmodName = "secmod.db"; 1.46 +static char* userPassword = ""; 1.47 +PRBool verbose; 1.48 + 1.49 +static char * 1.50 +getPassword(PK11SlotInfo *slot, PRBool retry, void *arg) 1.51 +{ 1.52 + int *success = (int *)arg; 1.53 + 1.54 + if (retry) { 1.55 + *success = 0; 1.56 + return NULL; 1.57 + } 1.58 + 1.59 + *success = 1; 1.60 + return PORT_Strdup(userPassword); 1.61 +} 1.62 + 1.63 + 1.64 +static void Usage(const char *progName) 1.65 +{ 1.66 + printf("Usage: %s [-r] [-f] [-i] [-d dbdir ] \n", 1.67 + progName); 1.68 + printf("%-20s open database readonly (NSS_INIT_READONLY)\n", "-r"); 1.69 + printf("%-20s Continue to force initializations even if the\n", "-f"); 1.70 + printf("%-20s databases cannot be opened (NSS_INIT_FORCEOPEN)\n", " "); 1.71 + printf("%-20s Try to initialize the database\n", "-i"); 1.72 + printf("%-20s Supply a password with which to initialize the db\n", "-p"); 1.73 + printf("%-20s Directory with cert database (default is .\n", 1.74 + "-d certdir"); 1.75 + exit(1); 1.76 +} 1.77 + 1.78 +int main(int argc, char **argv) 1.79 +{ 1.80 + PLOptState *optstate; 1.81 + PLOptStatus optstatus; 1.82 + 1.83 + PRUint32 flags = 0; 1.84 + Error ret; 1.85 + SECStatus rv; 1.86 + char * dbString = NULL; 1.87 + PRBool doInitTest = PR_FALSE; 1.88 + int i; 1.89 + 1.90 + progName = strrchr(argv[0], '/'); 1.91 + if (!progName) 1.92 + progName = strrchr(argv[0], '\\'); 1.93 + progName = progName ? progName+1 : argv[0]; 1.94 + 1.95 + optstate = PL_CreateOptState(argc, argv, "rfip:d:h"); 1.96 + 1.97 + while ((optstatus = PL_GetNextOpt(optstate)) == PL_OPT_OK) { 1.98 + switch (optstate->option) { 1.99 + case 'h': 1.100 + default : Usage(progName); break; 1.101 + 1.102 + case 'r': flags |= NSS_INIT_READONLY; break; 1.103 + 1.104 + case 'f': flags |= NSS_INIT_FORCEOPEN; break; 1.105 + 1.106 + case 'i': doInitTest = PR_TRUE; break; 1.107 + 1.108 + case 'p': 1.109 + userPassword = PORT_Strdup(optstate->value); 1.110 + break; 1.111 + 1.112 + case 'd': 1.113 + dbDir = PORT_Strdup(optstate->value); 1.114 + break; 1.115 + 1.116 + } 1.117 + } 1.118 + if (optstatus == PL_OPT_BAD) 1.119 + Usage(progName); 1.120 + 1.121 + if (!dbDir) { 1.122 + dbDir = SECU_DefaultSSLDir(); /* Look in $SSL_DIR */ 1.123 + } 1.124 + dbDir = SECU_ConfigDirectory(dbDir); 1.125 + PR_fprintf(PR_STDERR, "dbdir selected is %s\n\n", dbDir); 1.126 + 1.127 + if( dbDir[0] == '\0') { 1.128 + PR_fprintf(PR_STDERR, errStrings[DIR_DOESNT_EXIST_ERR], dbDir); 1.129 + ret= DIR_DOESNT_EXIST_ERR; 1.130 + goto loser; 1.131 + } 1.132 + 1.133 + 1.134 + PR_Init( PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); 1.135 + 1.136 + /* get the status of the directory and databases and output message */ 1.137 + if(PR_Access(dbDir, PR_ACCESS_EXISTS) != PR_SUCCESS) { 1.138 + PR_fprintf(PR_STDERR, errStrings[DIR_DOESNT_EXIST_ERR], dbDir); 1.139 + } else if(PR_Access(dbDir, PR_ACCESS_READ_OK) != PR_SUCCESS) { 1.140 + PR_fprintf(PR_STDERR, errStrings[DIR_NOT_READABLE_ERR], dbDir); 1.141 + } else { 1.142 + if( !( flags & NSS_INIT_READONLY ) && 1.143 + PR_Access(dbDir, PR_ACCESS_WRITE_OK) != PR_SUCCESS) { 1.144 + PR_fprintf(PR_STDERR, errStrings[DIR_NOT_WRITEABLE_ERR], dbDir); 1.145 + } 1.146 + if (!doInitTest) { 1.147 + for (i=0;i<3;i++) { 1.148 + dbString=PR_smprintf("%s/%s",dbDir,dbName[i]); 1.149 + PR_fprintf(PR_STDOUT, "database checked is %s\n",dbString); 1.150 + if(PR_Access(dbString, PR_ACCESS_EXISTS) != PR_SUCCESS) { 1.151 + PR_fprintf(PR_STDERR, errStrings[FILE_DOESNT_EXIST_ERR], 1.152 + dbString); 1.153 + } else if(PR_Access(dbString, PR_ACCESS_READ_OK) != PR_SUCCESS) { 1.154 + PR_fprintf(PR_STDERR, errStrings[FILE_NOT_READABLE_ERR], 1.155 + dbString); 1.156 + } else if( !( flags & NSS_INIT_READONLY ) && 1.157 + PR_Access(dbString, PR_ACCESS_WRITE_OK) != PR_SUCCESS) { 1.158 + PR_fprintf(PR_STDERR, errStrings[FILE_NOT_WRITEABLE_ERR], 1.159 + dbString); 1.160 + } 1.161 + } 1.162 + } 1.163 + } 1.164 + 1.165 + 1.166 + rv = NSS_Initialize(SECU_ConfigDirectory(dbDir), dbprefix, dbprefix, 1.167 + secmodName, flags); 1.168 + if (rv != SECSuccess) { 1.169 + SECU_PrintPRandOSError(progName); 1.170 + ret=NSS_INITIALIZE_FAILED_ERR; 1.171 + } else { 1.172 + ret=SUCCESS; 1.173 + if (doInitTest) { 1.174 + PK11SlotInfo * slot = PK11_GetInternalKeySlot(); 1.175 + SECStatus rv; 1.176 + int passwordSuccess = 0; 1.177 + int type = CKM_DES3_CBC; 1.178 + SECItem keyid = { 0, NULL, 0 }; 1.179 + unsigned char keyIdData[] = { 0xff, 0xfe }; 1.180 + PK11SymKey *key = NULL; 1.181 + 1.182 + keyid.data = keyIdData; 1.183 + keyid.len = sizeof(keyIdData); 1.184 + 1.185 + PK11_SetPasswordFunc(getPassword); 1.186 + rv = PK11_InitPin(slot, (char *)NULL, userPassword); 1.187 + if (rv != SECSuccess) { 1.188 + PR_fprintf(PR_STDERR, "Failed to Init DB: %s\n", 1.189 + SECU_Strerror(PORT_GetError())); 1.190 + ret = CHANGEPW_FAILED_ERR; 1.191 + } 1.192 + if (*userPassword && !PK11_IsLoggedIn(slot, &passwordSuccess)) { 1.193 + PR_fprintf(PR_STDERR, "New DB did not log in after init\n"); 1.194 + ret = AUTHENTICATION_FAILED_ERR; 1.195 + } 1.196 + /* generate a symetric key */ 1.197 + key = PK11_TokenKeyGen(slot, type, NULL, 0, &keyid, 1.198 + PR_TRUE, &passwordSuccess); 1.199 + 1.200 + if (!key) { 1.201 + PR_fprintf(PR_STDERR, "Could not generated symetric key: %s\n", 1.202 + SECU_Strerror(PORT_GetError())); 1.203 + exit (UNSPECIFIED_ERR); 1.204 + } 1.205 + PK11_FreeSymKey(key); 1.206 + PK11_Logout(slot); 1.207 + 1.208 + PK11_Authenticate(slot, PR_TRUE, &passwordSuccess); 1.209 + 1.210 + if (*userPassword && !passwordSuccess) { 1.211 + PR_fprintf(PR_STDERR, "New DB Did not initalize\n"); 1.212 + ret = AUTHENTICATION_FAILED_ERR; 1.213 + } 1.214 + key = PK11_FindFixedKey(slot, type, &keyid, &passwordSuccess); 1.215 + 1.216 + if (!key) { 1.217 + PR_fprintf(PR_STDERR, "Could not find generated key: %s\n", 1.218 + SECU_Strerror(PORT_GetError())); 1.219 + ret = UNSPECIFIED_ERR; 1.220 + } else { 1.221 + PK11_FreeSymKey(key); 1.222 + } 1.223 + PK11_FreeSlot(slot); 1.224 + } 1.225 + 1.226 + if (NSS_Shutdown() != SECSuccess) { 1.227 + PR_fprintf(PR_STDERR, "Could not find generated key: %s\n", 1.228 + SECU_Strerror(PORT_GetError())); 1.229 + exit(1); 1.230 + } 1.231 + } 1.232 + 1.233 +loser: 1.234 + return ret; 1.235 +} 1.236 +