/* * Prepare a buffer for any padded CBC encryption algorithm, growing to the * appropriate boundary and filling with the appropriate padding. * blockSize must be a power of 2. * * NOTE: If arena is non-NULL, we re-allocate from there, otherwise * we assume (and use) XP memory (re)allocation. */ unsigned char * CBC_PadBuffer(PLArenaPool *arena, unsigned char *inbuf, unsigned int inlen, unsigned int *outlen, int blockSize) { unsigned char *outbuf; unsigned int des_len; unsigned int i; unsigned char des_pad_len; /* * We need from 1 to blockSize bytes -- we *always* grow. * The extra bytes contain the value of the length of the padding: * if we have 2 bytes of padding, then the padding is "0x02, 0x02". */ des_len = (inlen + blockSize) & ~(blockSize - 1); if (arena != NULL) { outbuf = (unsigned char *)PORT_ArenaGrow(arena, inbuf, inlen, des_len); } else { outbuf = (unsigned char *)PORT_Realloc(inbuf, des_len); } if (outbuf == NULL) { PORT_SetError(SEC_ERROR_NO_MEMORY); return NULL; } des_pad_len = des_len - inlen; for (i = inlen; i < des_len; i++) outbuf[i] = des_pad_len; *outlen = des_len; return outbuf; }
static SECStatus AppendStr(stringBuf *bufp, char *str) { char *buf; unsigned bufLen, bufSize, len; int size = 0; /* Figure out how much to grow buf by (add in the '\0') */ buf = bufp->buffer; bufLen = bufp->offset; len = PORT_Strlen(str); bufSize = bufLen + len; if (!buf) { bufSize++; size = PR_MAX(DEFAULT_BUFFER_SIZE,bufSize*2); buf = (char *) PORT_Alloc(size); bufp->size = size; } else if (bufp->size < bufSize) { size = bufSize*2; buf =(char *) PORT_Realloc(buf,size); bufp->size = size; } if (!buf) { PORT_SetError(SEC_ERROR_NO_MEMORY); return SECFailure; } bufp->buffer = buf; bufp->offset = bufSize; /* Concatenate str onto buf */ buf = buf + bufLen; if (bufLen) buf--; /* stomp on old '\0' */ PORT_Memcpy(buf, str, len+1); /* put in new null */ return SECSuccess; }
/* * copy desc and value into target. Target is known to be big enough to * hold desc +2 +value, which is good because the result of this will be * *desc"*value". We may, however, have to add some escapes for special * characters imbedded into value (rare). This string potentially comes from * a user, so we don't want the user overflowing the target buffer by using * excessive escapes. To prevent this we count the escapes we need to add and * try to expand the buffer with Realloc. */ static char * secmod_doDescCopy(char *target, int *targetLen, const char *desc, int descLen, char *value) { int diff, esc_len; esc_len = NSSUTIL_EscapeSize(value, '\"') - 1; diff = esc_len - strlen(value); if (diff > 0) { /* we need to escape... expand newSpecPtr as well to make sure * we don't overflow it */ char *newPtr = PORT_Realloc(target, *targetLen * diff); if (!newPtr) { return target; /* not enough space, just drop the whole copy */ } *targetLen += diff; target = newPtr; value = NSSUTIL_Escape(value, '\"'); if (value == NULL) { return target; /* couldn't escape value, just drop the copy */ } } PORT_Memcpy(target, desc, descLen); target += descLen; *target++='\"'; PORT_Memcpy(target, value, esc_len); target += esc_len; *target++='\"'; if (diff > 0) { PORT_Free(value); } return target; }
SECStatus SECITEM_ReallocItemV2(PLArenaPool *arena, SECItem *item, unsigned int newlen) { unsigned char *newdata = NULL; PORT_Assert(item); if (!item) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } if (item->len == newlen) { return SECSuccess; } if (!newlen) { if (!arena) { PORT_Free(item->data); } item->data = NULL; item->len = 0; return SECSuccess; } if (!item->data) { /* allocate fresh block of memory */ PORT_Assert(!item->len); if (arena) { newdata = PORT_ArenaAlloc(arena, newlen); } else { newdata = PORT_Alloc(newlen); } } else { /* reallocate or adjust existing block of memory */ if (arena) { if (item->len > newlen) { /* There's no need to realloc a shorter block from the arena, * because it would result in using even more memory! * Therefore we'll continue to use the old block and * set the item to the shorter size. */ item->len = newlen; return SECSuccess; } newdata = PORT_ArenaGrow(arena, item->data, item->len, newlen); } else { newdata = PORT_Realloc(item->data, newlen); } } if (!newdata) { PORT_SetError(SEC_ERROR_NO_MEMORY); return SECFailure; } item->len = newlen; item->data = newdata; return SECSuccess; }
static SECStatus sftkdb_growList(char ***pModuleList, int *useCount, int last) { char **newModuleList; *useCount += SECMOD_STEP; newModuleList = (char **)PORT_Realloc(*pModuleList, *useCount*sizeof(char *)); if (newModuleList == NULL) { return SECFailure; } PORT_Memset(&newModuleList[last],0, sizeof(char *)*SECMOD_STEP); *pModuleList = newModuleList; return SECSuccess; }
/* * Smart string cat functions. Automatically manage the memory. * The first parameter is the source string. If it's null, we * allocate memory for it. If it's not, we reallocate memory * so the the concanenated string fits. */ static char * sftkdb_DupnCat(char *baseString, const char *str, int str_len) { int len = (baseString ? PORT_Strlen(baseString) : 0) + 1; char *newString; len += str_len; newString = (char *) PORT_Realloc(baseString,len); if (newString == NULL) { PORT_Free(baseString); return NULL; } if (baseString == NULL) *newString = 0; return PORT_Strncat(newString,str, str_len); }
static SECStatus crmf_modify_control_array(CRMFCertRequest *inCertReq, int count) { if (count > 0) { void *dummy = PORT_Realloc(inCertReq->controls, sizeof(CRMFControl *) * (count + 2)); if (dummy == NULL) { return SECFailure; } inCertReq->controls = dummy; } else { inCertReq->controls = PORT_ZNewArray(CRMFControl *, 2); } return (inCertReq->controls == NULL) ? SECFailure : SECSuccess; }
/* * Smart string cat functions. Automatically manage the memory. * The first parameter is the destination string. If it's null, we * allocate memory for it. If it's not, we reallocate memory * so the the concanenated string fits. */ static char * nssutil_DupnCat(char *baseString, const char *str, int str_len) { int baseStringLen = baseString ? PORT_Strlen(baseString) : 0; int len = baseStringLen + 1; char *newString; len += str_len; newString = (char *) PORT_Realloc(baseString,len); if (newString == NULL) { PORT_Free(baseString); return NULL; } PORT_Memcpy(&newString[baseStringLen], str, str_len); newString[len - 1] = 0; return newString; }
/* ** Grow a buffer to hold newLen bytes of data. ** Called for both recv buffers and xmit buffers. ** Caller must hold xmitBufLock or recvBufLock, as appropriate. */ SECStatus sslBuffer_Grow(sslBuffer *b, unsigned int newLen) { newLen = PR_MAX(newLen, MAX_FRAGMENT_LENGTH + 2048); if (newLen > b->space) { unsigned char *newBuf; if (b->buf) { newBuf = (unsigned char *) PORT_Realloc(b->buf, newLen); } else { newBuf = (unsigned char *) PORT_Alloc(newLen); } if (!newBuf) { return SECFailure; } SSL_TRC(10, ("%d: SSL: grow buffer from %d to %d", SSL_GETPID(), b->space, newLen)); b->buf = newBuf; b->space = newLen; } return SECSuccess; }
SECStatus SECITEM_ReallocItem(PLArenaPool *arena, SECItem *item, unsigned int oldlen, unsigned int newlen) { PORT_Assert(item != NULL); if (item == NULL) { /* XXX Set error. But to what? */ return SECFailure; } /* * If no old length, degenerate to just plain alloc. */ if (oldlen == 0) { PORT_Assert(item->data == NULL || item->len == 0); if (newlen == 0) { /* Nothing to do. Weird, but not a failure. */ return SECSuccess; } item->len = newlen; if (arena != NULL) { item->data = PORT_ArenaAlloc(arena, newlen); } else { item->data = PORT_Alloc(newlen); } } else { if (arena != NULL) { item->data = PORT_ArenaGrow(arena, item->data, oldlen, newlen); } else { item->data = PORT_Realloc(item->data, newlen); } } if (item->data == NULL) { return SECFailure; } return SECSuccess; }
SECStatus secu_StdinToItem(SECItem *dst) { unsigned char buf[1000]; PRInt32 numBytes; PRBool notDone = PR_TRUE; dst->len = 0; dst->data = NULL; while (notDone) { numBytes = PR_Read(PR_STDIN, buf, sizeof(buf)); if (numBytes < 0) { return SECFailure; } if (numBytes == 0) break; if (dst->data) { unsigned char *p = dst->data; dst->data = (unsigned char *)PORT_Realloc(p, dst->len + numBytes); if (!dst->data) { PORT_Free(p); } } else { dst->data = (unsigned char *)PORT_Alloc(numBytes); } if (!dst->data) { return SECFailure; } PORT_Memcpy(dst->data + dst->len, buf, numBytes); dst->len += numBytes; } return SECSuccess; }
/* the content of an encrypted data content info is encrypted. * it is assumed that for encrypted data, that the data has already * been set and is in the "plainContent" field of the content info. * * cinfo is the content info to encrypt * * key is the key with which to perform the encryption. if the * algorithm is a password based encryption algorithm, the * key is actually a password which will be processed per * PKCS #5. * * in the event of an error, SECFailure is returned. SECSuccess * indicates a success. */ SECStatus SEC_PKCS7EncryptContents(PRArenaPool *poolp, SEC_PKCS7ContentInfo *cinfo, SECItem *key, void *wincx) { SECAlgorithmID *algid = NULL; SECItem * result = NULL; SECItem * src; SECItem * dest; SECItem * blocked_data = NULL; void * mark; void * cx; PK11SymKey * eKey = NULL; PK11SlotInfo * slot = NULL; CK_MECHANISM_TYPE cryptoMechType; int bs; SECStatus rv = SECFailure; SECItem *c_param = NULL; if((cinfo == NULL) || (key == NULL)) return SECFailure; if(SEC_PKCS7ContentType(cinfo) != SEC_OID_PKCS7_ENCRYPTED_DATA) return SECFailure; algid = SEC_PKCS7GetEncryptionAlgorithm(cinfo); if(algid == NULL) return SECFailure; if(poolp == NULL) poolp = cinfo->poolp; mark = PORT_ArenaMark(poolp); src = &cinfo->content.encryptedData->encContentInfo.plainContent; dest = &cinfo->content.encryptedData->encContentInfo.encContent; dest->data = (unsigned char*)PORT_ArenaZAlloc(poolp, (src->len + 64)); dest->len = (src->len + 64); if(dest->data == NULL) { rv = SECFailure; goto loser; } slot = PK11_GetInternalKeySlot(); if(slot == NULL) { rv = SECFailure; goto loser; } eKey = PK11_PBEKeyGen(slot, algid, key, PR_FALSE, wincx); if(eKey == NULL) { rv = SECFailure; goto loser; } cryptoMechType = PK11_GetPBECryptoMechanism(algid, &c_param, key); if (cryptoMechType == CKM_INVALID_MECHANISM) { rv = SECFailure; goto loser; } /* block according to PKCS 8 */ bs = PK11_GetBlockSize(cryptoMechType, c_param); rv = SECSuccess; if(bs) { char pad_char; pad_char = (char)(bs - (src->len % bs)); if(src->len % bs) { rv = SECSuccess; blocked_data = PK11_BlockData(src, bs); if(blocked_data) { PORT_Memset((blocked_data->data + blocked_data->len - (int)pad_char), pad_char, (int)pad_char); } else { rv = SECFailure; goto loser; } } else { blocked_data = SECITEM_DupItem(src); if(blocked_data) { blocked_data->data = (unsigned char*)PORT_Realloc( blocked_data->data, blocked_data->len + bs); if(blocked_data->data) { blocked_data->len += bs; PORT_Memset((blocked_data->data + src->len), (char)bs, bs); } else { rv = SECFailure; goto loser; } } else { rv = SECFailure; goto loser; } } } else { blocked_data = SECITEM_DupItem(src); if(!blocked_data) { rv = SECFailure; goto loser; } } cx = PK11_CreateContextBySymKey(cryptoMechType, CKA_ENCRYPT, eKey, c_param); if(cx == NULL) { rv = SECFailure; goto loser; } rv = PK11_CipherOp((PK11Context*)cx, dest->data, (int *)(&dest->len), (int)(src->len + 64), blocked_data->data, (int)blocked_data->len); PK11_DestroyContext((PK11Context*)cx, PR_TRUE); loser: /* let success fall through */ if(blocked_data != NULL) SECITEM_ZfreeItem(blocked_data, PR_TRUE); if(result != NULL) SECITEM_ZfreeItem(result, PR_TRUE); if(rv == SECFailure) PORT_ArenaRelease(poolp, mark); else PORT_ArenaUnmark(poolp, mark); if(eKey != NULL) PK11_FreeSymKey(eKey); if(slot != NULL) PK11_FreeSlot(slot); if(c_param != NULL) SECITEM_ZfreeItem(c_param, PR_TRUE); return rv; }
/* this function converts a password to unicode and encures that the * required double 0 byte be placed at the end of the string */ PRBool sec_pkcs12_convert_item_to_unicode(PRArenaPool *arena, SECItem *dest, SECItem *src, PRBool zeroTerm, PRBool asciiConvert, PRBool toUnicode) { PRBool success = PR_FALSE; if(!src || !dest) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return PR_FALSE; } dest->len = src->len * 3 + 2; if(arena) { dest->data = (unsigned char*)PORT_ArenaZAlloc(arena, dest->len); } else { dest->data = (unsigned char*)PORT_ZAlloc(dest->len); } if(!dest->data) { dest->len = 0; return PR_FALSE; } if(!asciiConvert) { success = PORT_UCS2_UTF8Conversion(toUnicode, src->data, src->len, dest->data, dest->len, &dest->len); } else { #ifndef IS_LITTLE_ENDIAN PRBool swapUnicode = PR_FALSE; #else PRBool swapUnicode = PR_TRUE; #endif success = PORT_UCS2_ASCIIConversion(toUnicode, src->data, src->len, dest->data, dest->len, &dest->len, swapUnicode); } if(!success) { if(!arena) { PORT_Free(dest->data); dest->data = NULL; dest->len = 0; } return PR_FALSE; } if((dest->data[dest->len-1] || dest->data[dest->len-2]) && zeroTerm) { if(dest->len + 2 > 3 * src->len) { if(arena) { dest->data = (unsigned char*)PORT_ArenaGrow(arena, dest->data, dest->len, dest->len + 2); } else { dest->data = (unsigned char*)PORT_Realloc(dest->data, dest->len + 2); } if(!dest->data) { return PR_FALSE; } } dest->len += 2; dest->data[dest->len-1] = dest->data[dest->len-2] = 0; } return PR_TRUE; }