unsigned char *sss_base64_decode(TALLOC_CTX *mem_ctx, const char *inbuf, size_t *outbufsize) { int ret; unsigned char *b64decoded = NULL; unsigned int size; unsigned char *outbuf; /* initialize NSS if needed */ ret = nspr_nss_init(); if (ret != EOK) { return NULL; } b64decoded = ATOB_AsciiToData(inbuf, &size); if (!b64decoded) return NULL; outbuf = talloc_memdup(mem_ctx, b64decoded, size); PORT_Free(b64decoded); if (!outbuf) return NULL; *outbufsize = size; return outbuf; }
/* Convert ascii string back into bytes. Returns number of bytes */ unsigned int PE_str_to_bytes(unsigned char *bytes, char *cstr) { unsigned int tmplen; unsigned char* tmp = ATOB_AsciiToData(cstr, &tmplen); if (tmp == NULL) { purple_debug(PURPLE_DEBUG_ERROR, "pidgin-encryption", _("Invalid Base64 data, length %u\n"), (unsigned)strlen(cstr)); return 0; } memcpy(bytes, tmp, tmplen); PORT_Free(tmp); return tmplen; }
void PE_str_to_nonce(Nonce* nonce, char* nonce_str) { unsigned int tmp_len; unsigned char* tmp_bin; tmp_bin = ATOB_AsciiToData(nonce_str, &tmp_len); if (tmp_len != sizeof(Nonce)) { PORT_Free(tmp_bin); memset(nonce, 0, sizeof(Nonce)); purple_debug(PURPLE_DEBUG_ERROR, "pidgin-encryption", "Error parsing RSANSS nonce\n"); return; } memcpy(nonce, tmp_bin, sizeof(Nonce)); PORT_Free(tmp_bin); }
/* * @param(IN) sshaTagedHashedText the password field from the keyfile line * @param(OUT) saltsize number of bytes for the salt at end of password field * @return the salt(in binary format). Callers of this function MUST free * this salt. */ char* getSalt(const char*sshaTagedHashedText,int& saltSize) { const char* p = strstr(sshaTagedHashedText,SSHA_TAG); if (p==NULL) return NULL; p = sshaTagedHashedText + strlen(SSHA_TAG); int len=0; unsigned char *pHashed = ATOB_AsciiToData(p,(unsigned int*)&len); if (len<=SHA1_LENGTH || pHashed==NULL) return NULL; saltSize = len-SHA1_LENGTH; char *salt = (char *)MALLOC(saltSize +1); memcpy(salt, pHashed + SHA1_LENGTH, saltSize); salt[saltSize] = '\0'; PORT_Free(pHashed); return salt; }
static PQGParams * decode_pqg_params(char *aStr) { unsigned char *buf = nullptr; unsigned int len; PLArenaPool *arena = nullptr; PQGParams *params = nullptr; SECStatus status; arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (!arena) return nullptr; params = static_cast<PQGParams*>(PORT_ArenaZAlloc(arena, sizeof(PQGParams))); if (!params) goto loser; params->arena = arena; buf = ATOB_AsciiToData(aStr, &len); if ((!buf) || (len == 0)) goto loser; status = SEC_ASN1Decode(arena, params, SECKEY_PQGParamsTemplate, (const char*)buf, len); if (status != SECSuccess) goto loser; return params; loser: if (arena) { PORT_FreeArena(arena, false); } if (buf) { PR_Free(buf); } return nullptr; }
/*************************************************************************** * * v e r i f y _ g l o b a l */ static int verify_global(JAR *jar) { FILE *fp; JAR_Context *ctx; JAR_Item *it; JAR_Digest *globaldig; char *ext; unsigned char *md5_digest, *sha1_digest; unsigned int sha1_length, md5_length; int retval = 0; char buf[BUFSIZ]; ctx = JAR_find(jar, "*", jarTypePhy); while (JAR_find_next(ctx, &it) >= 0) { if (!PORT_Strncmp(it->pathname, "META-INF", 8)) { for (ext = it->pathname; *ext; ext++) ; while (ext > it->pathname && *ext != '.') ext--; if (verbosity >= 0) { if (!PORT_Strcasecmp(ext, ".rsa")) { PR_fprintf(outputFD, "found a RSA signature file: %s\n", it->pathname); } if (!PORT_Strcasecmp(ext, ".dsa")) { PR_fprintf(outputFD, "found a DSA signature file: %s\n", it->pathname); } if (!PORT_Strcasecmp(ext, ".mf")) { PR_fprintf(outputFD, "found a MF master manifest file: %s\n", it->pathname); } } if (!PORT_Strcasecmp(ext, ".sf")) { if (verbosity >= 0) { PR_fprintf(outputFD, "found a SF signature manifest file: %s\n", it->pathname); } rm_dash_r(TMP_OUTPUT); if (JAR_extract(jar, it->pathname, TMP_OUTPUT) < 0) { PR_fprintf(errorFD, "%s: error extracting %s\n", PROGRAM_NAME, it->pathname); errorCount++; retval = -1; continue; } md5_digest = NULL; sha1_digest = NULL; if ((fp = fopen(TMP_OUTPUT, "rb")) != NULL) { while (fgets(buf, BUFSIZ, fp)) { char *s; if (*buf == 0 || *buf == '\n' || *buf == '\r') break; for (s = buf; *s && *s != '\n' && *s != '\r'; s++) ; *s = 0; if (!PORT_Strncmp(buf, "MD5-Digest: ", 12)) { md5_digest = ATOB_AsciiToData(buf + 12, &md5_length); } if (!PORT_Strncmp(buf, "SHA1-Digest: ", 13)) { sha1_digest = ATOB_AsciiToData(buf + 13, &sha1_length); } if (!PORT_Strncmp(buf, "SHA-Digest: ", 12)) { sha1_digest = ATOB_AsciiToData(buf + 12, &sha1_length); } } globaldig = jar->globalmeta; if (globaldig && md5_digest && verbosity >= 0) { PR_fprintf(outputFD, " md5 digest on global metainfo: %s\n", PORT_Memcmp(md5_digest, globaldig->md5, MD5_LENGTH) ? "no match" : "match"); } if (globaldig && sha1_digest && verbosity >= 0) { PR_fprintf(outputFD, " sha digest on global metainfo: %s\n", PORT_Memcmp(sha1_digest, globaldig->sha1, SHA1_LENGTH) ? "no match" : "match"); } if (globaldig == NULL && verbosity >= 0) { PR_fprintf(outputFD, "global metadigest is not available, strange.\n"); } PORT_Free(md5_digest); PORT_Free(sha1_digest); fclose(fp); } } } } JAR_find_end(ctx); return retval; }
/** * Imports a base64 encoded signature into a MAR file * * @param src The path of the source MAR file * @param sigIndex The index of the signature to import * @param base64SigFile A file which contains the signature to import * @param dest The path of the destination MAR file with replaced signature * @return 0 on success * -1 on error */ int import_signature(const char *src, uint32_t sigIndex, const char *base64SigFile, const char *dest) { int rv = -1; FILE *fpSrc = NULL; FILE *fpDest = NULL; FILE *fpSigFile = NULL; uint32_t i; uint32_t signatureCount, signatureLen, signatureAlgorithmID, numChunks, leftOver; char buf[BLOCKSIZE]; uint64_t sizeOfSrcMAR, sizeOfBase64EncodedFile; char *passedInSignatureB64 = NULL; uint8_t *passedInSignatureRaw = NULL; uint8_t *extractedMARSignature = NULL; unsigned int passedInSignatureLenRaw; if (!src || !dest) { fprintf(stderr, "ERROR: Invalid parameter passed in.\n"); goto failure; } fpSrc = fopen(src, "rb"); if (!fpSrc) { fprintf(stderr, "ERROR: could not open source file: %s\n", src); goto failure; } fpDest = fopen(dest, "wb"); if (!fpDest) { fprintf(stderr, "ERROR: could not open dest file: %s\n", dest); goto failure; } fpSigFile = fopen(base64SigFile , "rb"); if (!fpSigFile) { fprintf(stderr, "ERROR: could not open sig file: %s\n", base64SigFile); goto failure; } /* Get the src file size */ if (fseeko(fpSrc, 0, SEEK_END)) { fprintf(stderr, "ERROR: Could not seek to end of src file.\n"); goto failure; } sizeOfSrcMAR = ftello(fpSrc); if (fseeko(fpSrc, 0, SEEK_SET)) { fprintf(stderr, "ERROR: Could not seek to start of src file.\n"); goto failure; } /* Get the sig file size */ if (fseeko(fpSigFile, 0, SEEK_END)) { fprintf(stderr, "ERROR: Could not seek to end of sig file.\n"); goto failure; } sizeOfBase64EncodedFile= ftello(fpSigFile); if (fseeko(fpSigFile, 0, SEEK_SET)) { fprintf(stderr, "ERROR: Could not seek to start of sig file.\n"); goto failure; } /* Read in the base64 encoded signature to import */ passedInSignatureB64 = malloc(sizeOfBase64EncodedFile + 1); passedInSignatureB64[sizeOfBase64EncodedFile] = '\0'; if (fread(passedInSignatureB64, sizeOfBase64EncodedFile, 1, fpSigFile) != 1) { fprintf(stderr, "ERROR: Could read b64 sig file.\n"); goto failure; } /* Decode the base64 encoded data */ passedInSignatureRaw = ATOB_AsciiToData(passedInSignatureB64, &passedInSignatureLenRaw); if (!passedInSignatureRaw) { fprintf(stderr, "ERROR: could not obtain base64 decoded data\n"); goto failure; } /* Read everything up until the signature block offset and write it out */ if (ReadAndWrite(fpSrc, fpDest, buf, SIGNATURE_BLOCK_OFFSET, "signature block offset")) { goto failure; } /* Get the number of signatures */ if (ReadAndWrite(fpSrc, fpDest, &signatureCount, sizeof(signatureCount), "signature count")) { goto failure; } signatureCount = ntohl(signatureCount); if (signatureCount > MAX_SIGNATURES) { fprintf(stderr, "ERROR: Signature count was out of range\n"); goto failure; } if (sigIndex >= signatureCount) { fprintf(stderr, "ERROR: Signature index was out of range\n"); goto failure; } /* Read and write the whole signature block, but if we reach the signature offset, then we should replace it with the specified base64 decoded signature */ for (i = 0; i < signatureCount; i++) { /* Read/Write the signature algorithm ID */ if (ReadAndWrite(fpSrc, fpDest, &signatureAlgorithmID, sizeof(signatureAlgorithmID), "sig algorithm ID")) { goto failure; } /* Read/Write the signature length */ if (ReadAndWrite(fpSrc, fpDest, &signatureLen, sizeof(signatureLen), "sig length")) { goto failure; } signatureLen = ntohl(signatureLen); /* Get the signature */ if (extractedMARSignature) { free(extractedMARSignature); } extractedMARSignature = malloc(signatureLen); if (sigIndex == i) { if (passedInSignatureLenRaw != signatureLen) { fprintf(stderr, "ERROR: Signature length must be the same\n"); goto failure; } if (fread(extractedMARSignature, signatureLen, 1, fpSrc) != 1) { fprintf(stderr, "ERROR: Could not read signature\n"); goto failure; } if (fwrite(passedInSignatureRaw, passedInSignatureLenRaw, 1, fpDest) != 1) { fprintf(stderr, "ERROR: Could not write signature\n"); goto failure; } } else { if (ReadAndWrite(fpSrc, fpDest, extractedMARSignature, signatureLen, "signature")) { goto failure; } } } /* We replaced the signature so let's just skip past the rest o the file. */ numChunks = (sizeOfSrcMAR - ftello(fpSrc)) / BLOCKSIZE; leftOver = (sizeOfSrcMAR - ftello(fpSrc)) % BLOCKSIZE; /* Read each file and write it to the MAR file */ for (i = 0; i < numChunks; ++i) { if (ReadAndWrite(fpSrc, fpDest, buf, BLOCKSIZE, "content block")) { goto failure; } } if (ReadAndWrite(fpSrc, fpDest, buf, leftOver, "left over content block")) { goto failure; } rv = 0; failure: if (fpSrc) { fclose(fpSrc); } if (fpDest) { fclose(fpDest); } if (fpSigFile) { fclose(fpSigFile); } if (rv) { remove(dest); } if (extractedMARSignature) { free(extractedMARSignature); } if (passedInSignatureB64) { free(passedInSignatureB64); } if (passedInSignatureRaw) { PORT_Free(passedInSignatureRaw); } return rv; }
SECStatus AddKeyFromFile(const char* basePath, const char* filename) { const char* PRIVATE_KEY_HEADER = "-----BEGIN PRIVATE KEY-----"; const char* PRIVATE_KEY_FOOTER = "-----END PRIVATE KEY-----"; char buf[16384] = { 0 }; SECStatus rv = ReadFileToBuffer(basePath, filename, buf); if (rv != SECSuccess) { return rv; } if (strncmp(buf, PRIVATE_KEY_HEADER, strlen(PRIVATE_KEY_HEADER)) != 0) { PR_fprintf(PR_STDERR, "invalid key - not importing\n"); return SECFailure; } const char* bufPtr = buf + strlen(PRIVATE_KEY_HEADER); size_t bufLen = strlen(buf); char base64[16384] = { 0 }; char* base64Ptr = base64; while (bufPtr < buf + bufLen) { if (strncmp(bufPtr, PRIVATE_KEY_FOOTER, strlen(PRIVATE_KEY_FOOTER)) == 0) { break; } if (*bufPtr != '\r' && *bufPtr != '\n') { *base64Ptr = *bufPtr; base64Ptr++; } bufPtr++; } unsigned int binLength; UniquePORTString bin( reinterpret_cast<char*>(ATOB_AsciiToData(base64, &binLength))); if (!bin || binLength == 0) { PrintPRError("ATOB_AsciiToData failed"); return SECFailure; } ScopedSECItem secitem(::SECITEM_AllocItem(nullptr, nullptr, binLength)); if (!secitem) { PrintPRError("SECITEM_AllocItem failed"); return SECFailure; } PORT_Memcpy(secitem->data, bin.get(), binLength); ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot()); if (!slot) { PrintPRError("PK11_GetInternalKeySlot failed"); return SECFailure; } if (PK11_NeedUserInit(slot)) { if (PK11_InitPin(slot, nullptr, nullptr) != SECSuccess) { PrintPRError("PK11_InitPin failed"); return SECFailure; } } SECKEYPrivateKey* privateKey; if (PK11_ImportDERPrivateKeyInfoAndReturnKey(slot, secitem, nullptr, nullptr, true, false, KU_ALL, &privateKey, nullptr) != SECSuccess) { PrintPRError("PK11_ImportDERPrivateKeyInfoAndReturnKey failed"); return SECFailure; } SECKEY_DestroyPrivateKey(privateKey); return SECSuccess; }
static void parse_signature(pesign_context *ctx, uint8_t **data, unsigned int *datalen) { int rc; char *sig; size_t siglen; rc = read_file(ctx->insigfd, &sig, &siglen); if (rc < 0) { fprintf(stderr, "pesign: could not read signature.\n"); exit(1); } close(ctx->insigfd); ctx->insigfd = -1; unsigned char *der; unsigned int derlen; /* XXX FIXME: ignoring length for now */ char *base64 = strstr(sig, sig_begin_marker); if (base64) { base64 += strlen(sig_begin_marker); char *end = strstr(base64, sig_end_marker); if (!end) { fprintf(stderr, "pesign: Invalid signature.\n"); exit(1); } derlen = end - base64; base64[derlen] = '\0'; der = ATOB_AsciiToData(base64, &derlen); } else { der = PORT_Alloc(siglen); memmove(der, sig, siglen); derlen = siglen; } free(sig); *data = der; *datalen = derlen; #if 0 SEC_PKCS7DecoderContext *dc = NULL; saw_content = 0; dc = SEC_PKCS7DecoderStart(handle_bytes, NULL, NULL, NULL, NULL, NULL, decryption_allowed); if (dc == NULL) { decoder_error: fprintf(stderr, "pesign: Invalid signature.\n"); PORT_Free(der); exit(1); } SECStatus status = SEC_PKCS7DecoderUpdate(dc, (char *)der, derlen); if (status != SECSuccess) goto decoder_error; SEC_PKCS7ContentInfo *cinfo = SEC_PKCS7DecoderFinish(dc); if (!cinfo) goto decoder_error; ctx->cinfo = cinfo; PORT_Free(der); #endif }
/* * read an old style ascii or binary certificate chain */ SECStatus CERT_DecodeCertPackage(char *certbuf, int certlen, CERTImportCertificateFunc f, void *arg) { unsigned char *cp; unsigned char *bincert = NULL; char * ascCert = NULL; SECStatus rv; if ( certbuf == NULL ) { return(SECFailure); } cp = (unsigned char *)certbuf; /* is a DER encoded certificate of some type? */ if ( ( *cp & 0x1f ) == SEC_ASN1_SEQUENCE ) { SECItem certitem; SECItem *pcertitem = &certitem; int seqLen, seqLenLen; cp++; if ( *cp & 0x80) { /* Multibyte length */ seqLenLen = cp[0] & 0x7f; switch (seqLenLen) { case 4: seqLen = ((unsigned long)cp[1]<<24) | ((unsigned long)cp[2]<<16) | (cp[3]<<8) | cp[4]; break; case 3: seqLen = ((unsigned long)cp[1]<<16) | (cp[2]<<8) | cp[3]; break; case 2: seqLen = (cp[1]<<8) | cp[2]; break; case 1: seqLen = cp[1]; break; default: /* indefinite length */ seqLen = 0; } cp += ( seqLenLen + 1 ); } else { seqLenLen = 0; seqLen = *cp; cp++; } /* check entire length if definite length */ if ( seqLen || seqLenLen ) { if ( certlen != ( seqLen + seqLenLen + 2 ) ) { if (certlen > ( seqLen + seqLenLen + 2 )) PORT_SetError(SEC_ERROR_EXTRA_INPUT); else PORT_SetError(SEC_ERROR_INPUT_LEN); goto notder; } } /* check the type string */ /* netscape wrapped DER cert */ if ( ( cp[0] == SEC_ASN1_OCTET_STRING ) && ( cp[1] == CERTIFICATE_TYPE_LEN ) && ( PORT_Strcmp((char *)&cp[2], CERTIFICATE_TYPE_STRING) ) ) { cp += ( CERTIFICATE_TYPE_LEN + 2 ); /* it had better be a certificate by now!! */ certitem.data = cp; certitem.len = certlen - ( cp - (unsigned char *)certbuf ); rv = (* f)(arg, &pcertitem, 1); return(rv); } else if ( cp[0] == SEC_ASN1_OBJECT_ID ) { SECOidData *oiddata; SECItem oiditem; /* XXX - assume DER encoding of OID len!! */ oiditem.len = cp[1]; oiditem.data = (unsigned char *)&cp[2]; oiddata = SECOID_FindOID(&oiditem); if ( oiddata == NULL ) { return(SECFailure); } certitem.data = (unsigned char*)certbuf; certitem.len = certlen; switch ( oiddata->offset ) { case SEC_OID_PKCS7_SIGNED_DATA: return(SEC_ReadPKCS7Certs(&certitem, f, arg)); break; case SEC_OID_NS_TYPE_CERT_SEQUENCE: return(SEC_ReadCertSequence(&certitem, f, arg)); break; default: break; } } else { /* it had better be a certificate by now!! */ certitem.data = (unsigned char*)certbuf; certitem.len = certlen; rv = (* f)(arg, &pcertitem, 1); return(rv); } } /* now look for a netscape base64 ascii encoded cert */ notder: { unsigned char *certbegin = NULL; unsigned char *certend = NULL; char *pc; int cl; /* Convert the ASCII data into a nul-terminated string */ ascCert = (char *)PORT_Alloc(certlen + 1); if (!ascCert) { rv = SECFailure; goto loser; } PORT_Memcpy(ascCert, certbuf, certlen); ascCert[certlen] = '\0'; pc = PORT_Strchr(ascCert, '\n'); /* find an EOL */ if (!pc) { /* maybe this is a MAC file */ pc = ascCert; while (*pc && NULL != (pc = PORT_Strchr(pc, '\r'))) { *pc++ = '\n'; } } cp = (unsigned char *)ascCert; cl = certlen; /* find the beginning marker */ while ( cl > NS_CERT_HEADER_LEN ) { if ( !PORT_Strncasecmp((char *)cp, NS_CERT_HEADER, NS_CERT_HEADER_LEN) ) { cl -= NS_CERT_HEADER_LEN; cp += NS_CERT_HEADER_LEN; certbegin = cp; break; } /* skip to next eol */ do { cp++; cl--; } while ( ( *cp != '\n') && cl ); /* skip all blank lines */ while ( ( *cp == '\n') && cl ) { cp++; cl--; } } if ( certbegin ) { /* find the ending marker */ while ( cl > NS_CERT_TRAILER_LEN ) { if ( !PORT_Strncasecmp((char *)cp, NS_CERT_TRAILER, NS_CERT_TRAILER_LEN) ) { certend = (unsigned char *)cp; break; } /* skip to next eol */ do { cp++; cl--; } while ( ( *cp != '\n') && cl ); /* skip all blank lines */ while ( ( *cp == '\n') && cl ) { cp++; cl--; } } } if ( certbegin && certend ) { unsigned int binLen; *certend = 0; /* convert to binary */ bincert = ATOB_AsciiToData(certbegin, &binLen); if (!bincert) { rv = SECFailure; goto loser; } /* now recurse to decode the binary */ rv = CERT_DecodeCertPackage((char *)bincert, binLen, f, arg); } else { rv = SECFailure; } } loser: if ( bincert ) { PORT_Free(bincert); } if ( ascCert ) { PORT_Free(ascCert); } return(rv); }