Пример #1
0
/*
 * 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;
}
Пример #2
0
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;
}
Пример #3
0
/*
 * 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;
}
Пример #4
0
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;
}
Пример #5
0
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;
}
Пример #6
0
/*
 * 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);
}
Пример #7
0
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;
}
Пример #8
0
/*
 * 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;
}
Пример #9
0
/*
** 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;
}
Пример #10
0
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;
}
Пример #11
0
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;
}
Пример #12
0
/* 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;
}
Пример #13
0
/* 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;
}