Beispiel #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;
}
Beispiel #2
0
/* appends a shrouded key to a key bag.  this is used for exporting
 * to store externally wrapped keys.  it is used when importing to convert
 * old items to new
 */
SECStatus 
sec_pkcs12_append_shrouded_key(SEC_PKCS12BaggageItem *bag,
				SEC_PKCS12ESPVKItem *espvk)
{
    int size;
    void *mark = NULL, *dummy = NULL;

    if((bag == NULL) || (espvk == NULL))
	return SECFailure;

    mark = PORT_ArenaMark(bag->poolp);

    /* grow the list */
    size = (bag->nEspvks + 1) * sizeof(SEC_PKCS12ESPVKItem *);
    dummy = (SEC_PKCS12ESPVKItem **)PORT_ArenaGrow(bag->poolp,
	    				bag->espvks, size, 
	    				size + sizeof(SEC_PKCS12ESPVKItem *));
    bag->espvks = (SEC_PKCS12ESPVKItem**)dummy;
    if(dummy == NULL) {
	PORT_SetError(SEC_ERROR_NO_MEMORY);
	goto loser;
    }

    bag->espvks[bag->nEspvks] = espvk;
    bag->nEspvks++;
    bag->espvks[bag->nEspvks] = NULL;

    PORT_ArenaUnmark(bag->poolp, mark);
    return SECSuccess;

loser:
    PORT_ArenaRelease(bag->poolp, mark);
    return SECFailure;
}
Beispiel #3
0
/*
 * NSS_CMSArray_Add - add an element to the end of an array
 *
 * The array of pointers is either created (if array was empty before) or grown.
 */
SECStatus
NSS_CMSArray_Add(PRArenaPool *poolp, void ***array, void *obj)
{
    void **p;
    int n;
    void **dest;

    PORT_Assert(array != NULL);
    if (array == NULL)
	return SECFailure;

    if (*array == NULL) {
	dest = (void **)PORT_ArenaAlloc(poolp, 2 * sizeof(void *));
	n = 0;
    } else {
	n = 0; p = *array;
	while (*p++)
	    n++;
	dest = (void **)PORT_ArenaGrow (poolp, 
			      *array,
			      (n + 1) * sizeof(void *),
			      (n + 2) * sizeof(void *));
    }

    if (dest == NULL)
	return SECFailure;

    dest[n] = obj;
    dest[n+1] = NULL;
    *array = dest;
    return SECSuccess;
}
Beispiel #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;
}
Beispiel #5
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;
}
Beispiel #6
0
/*
 * SecCmsArrayAdd - add an element to the end of an array
 *
 * The array of pointers is either created (if array was empty before) or grown.
 */
OSStatus
SecCmsArrayAdd(PRArenaPool *poolp, void ***array, void *obj)
{
    void **p;
    int n;
    void **dest;

    PORT_Assert(array != NULL);
    if (array == NULL)
        return SECFailure;

    if (*array == NULL) {
        dest = (void **)PORT_ArenaAlloc(poolp, 2 * sizeof(void *));
        n = 0;
    } else {
        n = 0;
        p = *array;
        while (*p++)
            n++;
        if (n>=(int)((INT_MAX/sizeof(void *))-2)) {
            // Prevent under-allocation due to integer overflow
            return SECFailure;
        }
        dest = (void **)PORT_ArenaGrow (poolp,
                                        *array,
                                        (n + 1) * sizeof(void *),
                                        (n + 2) * sizeof(void *));
    }

    if (dest == NULL)
        return SECFailure;

    dest[n] = obj;
    dest[n+1] = NULL;
    *array = dest;
    return SECSuccess;
}
/* create a new external bag which is appended onto the list
 * of bags in baggage.  the bag is created in the same arena
 * as baggage
 */
SEC_PKCS12BaggageItem *
sec_pkcs12_create_external_bag(SEC_PKCS12Baggage *luggage)
{
    void *dummy, *mark;
    SEC_PKCS12BaggageItem *bag;

    if(luggage == NULL) {
	return NULL;
    }

    mark = PORT_ArenaMark(luggage->poolp);

    /* allocate space for null terminated bag list */
    if(luggage->bags == NULL) {
	luggage->bags=(SEC_PKCS12BaggageItem**)PORT_ArenaZAlloc(luggage->poolp, 
					sizeof(SEC_PKCS12BaggageItem *));
	if(luggage->bags == NULL) {
	    goto loser;
	}
	luggage->luggage_size = 0;
    }

    /* grow the list */    
    dummy = PORT_ArenaGrow(luggage->poolp, luggage->bags,
    			sizeof(SEC_PKCS12BaggageItem *) * (luggage->luggage_size + 1),
    			sizeof(SEC_PKCS12BaggageItem *) * (luggage->luggage_size + 2));
    if(dummy == NULL) {
	goto loser;
    }
    luggage->bags = (SEC_PKCS12BaggageItem**)dummy;

    luggage->bags[luggage->luggage_size] = 
    		(SEC_PKCS12BaggageItem *)PORT_ArenaZAlloc(luggage->poolp,
    							sizeof(SEC_PKCS12BaggageItem));
    if(luggage->bags[luggage->luggage_size] == NULL) {
	goto loser;
    }

    /* create new bag and append it to the end */
    bag = luggage->bags[luggage->luggage_size];
    bag->espvks = (SEC_PKCS12ESPVKItem **)PORT_ArenaZAlloc(
    						luggage->poolp,
    						sizeof(SEC_PKCS12ESPVKItem *));
    bag->unencSecrets = (SEC_PKCS12SafeBag **)PORT_ArenaZAlloc(
    						luggage->poolp,
    						sizeof(SEC_PKCS12SafeBag *));
    if((bag->espvks == NULL) || (bag->unencSecrets == NULL)) {
	goto loser;
    }

    bag->poolp = luggage->poolp;
    luggage->luggage_size++;
    luggage->bags[luggage->luggage_size] = NULL;
    bag->espvks[0] = NULL;
    bag->unencSecrets[0] = NULL;
    bag->nEspvks = bag->nSecrets = 0;

    PORT_ArenaUnmark(luggage->poolp, mark);
    return bag;

loser:
    PORT_ArenaRelease(luggage->poolp, mark);
    PORT_SetError(SEC_ERROR_NO_MEMORY);
    return NULL;
}
Beispiel #8
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;
}