BOOL CPackage::checkSignature() { CString csFile, csDigest, csRegDigest; BOOL bRes; // Read meta data digest in the registry and verify it if (!regReadPackageDigest( csRegDigest)) // No digest registered in Registry return FALSE; csFile.Format( _T( "%s\\%s\\%s"), getDownloadFolder(), m_csID, OCS_DOWNLOAD_METADATA); if (!fileDigest( csFile, csDigest)) // Unable to compute digest on meta data return FALSE; if (csRegDigest.Compare( csDigest) != 0) // Digest registered in Registry is not the same return FALSE; // Now, check ZIP digest if (m_uFrags > 0) { // Compute digest on build.zip file csFile.Format( _T( "%s\\%s\\%s"), getDownloadFolder(), m_csID, OCS_DOWNLOAD_BUILD); if (isBase64()) bRes = fileDigest( csFile, csDigest, m_csDigestAlgo); else if (isHexadecimal()) bRes = fileDigest( csFile, csDigest, m_csDigestAlgo, FALSE); else // Unsupported encoding return FALSE; // Digest compute successfully if (bRes && (m_csDigest.Compare( csDigest) == 0)) return TRUE; else return FALSE; } // No ZIP file return TRUE; }
/*! * decodeBase64() * * Input: inarray (input encoded char data, with 72 chars/line)) * insize (number of bytes in input array) * &outsize (<return> number of bytes in output byte array) * Return: bytea (decoded byte data), or null on error * * Notes: * (1) The input character data should have only 66 different characters: * The 64 character set for base64 encoding, plus the pad * character '=' and newlines for formatting with fixed line * lengths. If there are any other characters, the decoder * will declare the input data to be invalid and return NULL. * (2) The decoder ignores newlines and, for a valid input string, * stops reading input when a pad byte is found. */ l_uint8 * decodeBase64(const char *inarray, l_int32 insize, l_int32 *poutsize) { char inchar; l_uint8 *bytea; l_uint8 array3[3], array4[4]; l_int32 *rtable64; l_int32 i, j, outsize, in_index, out_index; PROCNAME("decodeBase64"); if (!poutsize) return (l_uint8 *)ERROR_PTR("&outsize not defined", procName, NULL); *poutsize = 0; if (!inarray) return (l_uint8 *)ERROR_PTR("inarray not defined", procName, NULL); if (insize <= 0) return (l_uint8 *)ERROR_PTR("insize not > 0", procName, NULL); /* Validate the input data */ for (i = 0; i < insize; i++) { inchar = inarray[i]; if (inchar == '\n') continue; if (isBase64(inchar) == 0 && inchar != '=') return (l_uint8 *)ERROR_PTR("invalid char in inarray", procName, NULL); } /* The input array typically is made with a newline every * MAX_BASE64_LINE input bytes. However, as a printed string, the * newlines would be stripped. So when we allocate the output * array, assume the input array is all data, but strip * out the newlines during decoding. This guarantees that * the allocated array is large enough. */ outsize = 3 * ((insize + 3) / 4) + 4; if ((bytea = (l_uint8 *)CALLOC(outsize, sizeof(l_uint8))) == NULL) return (l_uint8 *)ERROR_PTR("bytea not made", procName, NULL); /* The number of encoded input data bytes is always a multiple of 4. * Read all the data, until you reach either the end or * the first pad character '='. The data is processed in * units of 4 input bytes, generating 3 output decoded bytes * of binary data. Newlines are ignored. If there are no * pad bytes, i == 0 at the end of this section. */ rtable64 = genReverseTab64(); i = in_index = out_index = 0; for (in_index = 0; in_index < insize; in_index++) { inchar = inarray[in_index]; if (inchar == '\n') continue; if (inchar == '=') break; array4[i++] = rtable64[(unsigned char)inchar]; if (i < 4) { continue; } else { /* i == 4; convert 4 to 3 and save */ byteConvert4to3(array4, array3); for (j = 0; j < 3; j++) bytea[out_index++] = array3[j]; i = 0; } } /* If i > 0, we ran into pad bytes ('='). If i == 2, there are * two input pad bytes and one output data byte. If i == 3, * there is one input pad byte and two output data bytes. */ if (i > 0) { for (j = i; j < 4; j++) array4[j] = '\0'; /* zero the remaining input bytes */ byteConvert4to3(array4, array3); for (j = 0; j < i - 1; j++) bytea[out_index++] = array3[j]; } *poutsize = out_index; FREE(rtable64); return bytea; }
int main (int argc, char **argv) { int retval = 0; /* 0 - test succeeded. -1 - test failed */ SECStatus rv; PLOptState *optstate; char *program_name; char *input_file = NULL; /* read encrypted data from here (or create) */ char *output_file = NULL; /* write new encrypted data here */ char *log_file = NULL; /* write new encrypted data here */ FILE *inFile = stdin; FILE *outFile = stdout; FILE *logFile = NULL; PLOptStatus optstatus; secuPWData pwdata = { PW_NONE, NULL }; program_name = PL_strrchr(argv[0], '/'); program_name = program_name ? (program_name + 1) : argv[0]; optstate = PL_CreateOptState (argc, argv, "Hd:f:i:o:l:p:?"); if (optstate == NULL) { SECU_PrintError (program_name, "PL_CreateOptState failed"); return 1; } while ((optstatus = PL_GetNextOpt(optstate)) == PL_OPT_OK) { switch (optstate->option) { case '?': short_usage (program_name); return 1; case 'H': long_usage (program_name); return 1; case 'd': SECU_ConfigDirectory(optstate->value); break; case 'i': input_file = PL_strdup(optstate->value); break; case 'o': output_file = PL_strdup(optstate->value); break; case 'l': log_file = PL_strdup(optstate->value); break; case 'f': pwdata.source = PW_FROMFILE; pwdata.data = PL_strdup(optstate->value); break; case 'p': pwdata.source = PW_PLAINTEXT; pwdata.data = PL_strdup(optstate->value); break; } } PL_DestroyOptState(optstate); if (optstatus == PL_OPT_BAD) { short_usage (program_name); return 1; } if (input_file) { inFile = fopen(input_file,"r"); if (inFile == NULL) { perror(input_file); return 1; } PR_Free(input_file); } if (output_file) { outFile = fopen(output_file,"w+"); if (outFile == NULL) { perror(output_file); return 1; } PR_Free(output_file); } if (log_file) { if (log_file[0] == '-') logFile = stderr; else logFile = fopen(log_file,"w+"); if (logFile == NULL) { perror(log_file); return 1; } PR_Free(log_file); } /* * Initialize the Security libraries. */ PK11_SetPasswordFunc(SECU_GetModulePassword); rv = NSS_Init(SECU_ConfigDirectory(NULL)); if (rv != SECSuccess) { SECU_PrintError (program_name, "NSS_Init failed"); retval = 1; goto prdone; } /* Get the encrypted result, either from the input file * or from encrypting the plaintext value */ while (fgets(dataString, sizeof dataString, inFile)) { unsigned char c = dataString[0]; if (c == 'M' && isBase64(dataString)) { doDecrypt(dataString, outFile, logFile, &pwdata); } else if (c == '~' && isBase64(dataString + 1)) { doDecode(dataString, outFile, logFile); } else { fputs(dataString, outFile); } } if (pwdata.data) PR_Free(pwdata.data); fclose(outFile); fclose(inFile); if (logFile && logFile != stderr) { fclose(logFile); } if (NSS_Shutdown() != SECSuccess) { SECU_PrintError (program_name, "NSS_Shutdown failed"); exit(1); } prdone: PR_Cleanup (); return retval; }