Beispiel #1
0
SECStatus
crmf_encode_unsigned_integer(PLArenaPool *poolp, SECItem *dest,
                             unsigned long value) 
{
    SECItem *dummy;

    dummy = SEC_ASN1EncodeUnsignedInteger(poolp, dest, value);
    PORT_Assert (dummy == dest);
    if (dummy != dest) {
        return SECFailure;
    }
    return SECSuccess;
}
Beispiel #2
0
SECStatus CERT_EncodeBasicConstraintValue
   (PRArenaPool *arena, CERTBasicConstraints *value, SECItem *encodedValue)
{
    EncodedContext encodeContext;
    PRArenaPool *our_pool = NULL;   
    SECStatus rv = SECSuccess;

    do {
	PORT_Memset (&encodeContext, 0, sizeof (encodeContext));
	if (!value->isCA && value->pathLenConstraint >= 0) {
	    PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID);
	    GEN_BREAK (SECFailure);
	}

        encodeContext.arena = arena;
	if (value->isCA == PR_TRUE) {
	    encodeContext.isCA.data =  &hexTrue ;
	    encodeContext.isCA.len = 1;
	}

	/* If the pathLenConstraint is less than 0, then it should be
	 * omitted from the encoding.
	 */
	if (value->isCA && value->pathLenConstraint >= 0) {
	    our_pool = PORT_NewArena (SEC_ASN1_DEFAULT_ARENA_SIZE);
	    if (our_pool == NULL) {
		PORT_SetError (SEC_ERROR_NO_MEMORY);
		GEN_BREAK (SECFailure);
	    }
	    if (SEC_ASN1EncodeUnsignedInteger
		(our_pool, &encodeContext.pathLenConstraint,
		 (unsigned long)value->pathLenConstraint) == NULL) {
		PORT_SetError (SEC_ERROR_NO_MEMORY);
		GEN_BREAK (SECFailure);
	    }
	}
	if (SEC_ASN1EncodeItem (arena, encodedValue, &encodeContext,
				CERTBasicConstraintsTemplate) == NULL) {
	    GEN_BREAK (SECFailure);
	}
    } while (0);
    if (our_pool)
	PORT_FreeArena (our_pool, PR_FALSE);
    return(rv);

}
/* turn a PKCS #11 parameter into a DER Encoded Algorithm ID */
SECStatus
PK11_ParamToAlgid(SECOidTag algTag, SECItem *param, 
				PRArenaPool *arena, SECAlgorithmID *algid) {
    CK_RC2_CBC_PARAMS *rc2_params;
    sec_rc2cbcParameter rc2;
    CK_RC5_CBC_PARAMS *rc5_params;
    sec_rc5cbcParameter rc5;
    CK_MECHANISM_TYPE type = PK11_AlgtagToMechanism(algTag);
    SECItem *newParams = NULL;
    SECStatus rv = SECFailure;
    unsigned long rc2version;

    switch (type) {
    case CKM_RC4:
    case CKM_SEED_ECB:
    case CKM_CAMELLIA_ECB:
    case CKM_AES_ECB:
    case CKM_DES_ECB:
    case CKM_DES3_ECB:
    case CKM_IDEA_ECB:
    case CKM_CDMF_ECB:
    case CKM_CAST_ECB:
    case CKM_CAST3_ECB:
    case CKM_CAST5_ECB:
	newParams = NULL;
	rv = SECSuccess;
	break;
    case CKM_RC2_ECB:
	break;
    case CKM_RC2_CBC:
    case CKM_RC2_CBC_PAD:
	rc2_params = (CK_RC2_CBC_PARAMS *)param->data;
	rc2version = rc2_unmap(rc2_params->ulEffectiveBits);
	if (SEC_ASN1EncodeUnsignedInteger (NULL, &(rc2.rc2ParameterVersion),
					   rc2version) == NULL)
	    break;
	rc2.iv.data = rc2_params->iv;
	rc2.iv.len = sizeof(rc2_params->iv);
	newParams = SEC_ASN1EncodeItem (NULL, NULL, &rc2,
                                         sec_rc2cbc_parameter_template);
        PORT_Free(rc2.rc2ParameterVersion.data);
	if (newParams == NULL)
	    break;
	rv = SECSuccess;
	break;

    case CKM_RC5_ECB: /* well not really... */
	break;
    case CKM_RC5_CBC:
    case CKM_RC5_CBC_PAD:
	rc5_params = (CK_RC5_CBC_PARAMS *)param->data;
	if (SEC_ASN1EncodeUnsignedInteger (NULL, &rc5.version, RC5_V10) == NULL)
	    break;
	if (SEC_ASN1EncodeUnsignedInteger (NULL, &rc5.blockSizeInBits, 
					rc5_params->ulWordsize*8) == NULL) {
            PORT_Free(rc5.version.data);
	    break;
	}
	if (SEC_ASN1EncodeUnsignedInteger (NULL, &rc5.rounds, 
					rc5_params->ulWordsize*8) == NULL) {
            PORT_Free(rc5.blockSizeInBits.data);
            PORT_Free(rc5.version.data);
	    break;
	}
	rc5.iv.data = rc5_params->pIv;
	rc5.iv.len = rc5_params->ulIvLen;
	newParams = SEC_ASN1EncodeItem (NULL, NULL, &rc5,
                                         sec_rc5cbc_parameter_template);
        PORT_Free(rc5.version.data);
        PORT_Free(rc5.blockSizeInBits.data);
        PORT_Free(rc5.rounds.data);
	if (newParams == NULL)
	    break;
	rv = SECSuccess;
	break;
    case CKM_PBE_MD2_DES_CBC:
    case CKM_PBE_MD5_DES_CBC:
    case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
    case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
    case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
    case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
    case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC:
    case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4:
    case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4:
    case CKM_PBE_SHA1_DES3_EDE_CBC:
    case CKM_PBE_SHA1_DES2_EDE_CBC:
    case CKM_PBE_SHA1_RC2_40_CBC:
    case CKM_PBE_SHA1_RC2_128_CBC:
    case CKM_PBE_SHA1_RC4_40:
    case CKM_PBE_SHA1_RC4_128:
	return PBE_PK11ParamToAlgid(algTag, param, arena, algid);
    default:
	if (pk11_lookup(type)->iv == 0) {
	    rv = SECSuccess;
	    newParams = NULL;
	    break;
	}
    case CKM_SEED_CBC:
    case CKM_CAMELLIA_CBC:
    case CKM_AES_CBC:
    case CKM_DES_CBC:
    case CKM_DES3_CBC:
    case CKM_IDEA_CBC:
    case CKM_CDMF_CBC:
    case CKM_CAST_CBC:
    case CKM_CAST3_CBC:
    case CKM_CAST5_CBC:
    case CKM_DES_CBC_PAD:
    case CKM_DES3_CBC_PAD:
    case CKM_IDEA_CBC_PAD:
    case CKM_CDMF_CBC_PAD:
    case CKM_CAST_CBC_PAD:
    case CKM_CAST3_CBC_PAD:
    case CKM_CAST5_CBC_PAD:
    case CKM_SKIPJACK_CBC64:
    case CKM_SKIPJACK_ECB64:
    case CKM_SKIPJACK_OFB64:
    case CKM_SKIPJACK_CFB64:
    case CKM_SKIPJACK_CFB32:
    case CKM_SKIPJACK_CFB16:
    case CKM_SKIPJACK_CFB8:
    case CKM_BATON_ECB128:
    case CKM_BATON_ECB96:
    case CKM_BATON_CBC128:
    case CKM_BATON_COUNTER:
    case CKM_BATON_SHUFFLE:
    case CKM_JUNIPER_ECB128:
    case CKM_JUNIPER_CBC128:
    case CKM_JUNIPER_COUNTER:
    case CKM_JUNIPER_SHUFFLE:
	newParams = SEC_ASN1EncodeItem(NULL,NULL,param,
                                       SEC_ASN1_GET(SEC_OctetStringTemplate) );
	if (newParams == NULL)
	    break;
	rv = SECSuccess;
	break;
    }

    if (rv !=  SECSuccess) {
	if (newParams) SECITEM_FreeItem(newParams,PR_TRUE);
	return rv;
    }

    rv = SECOID_SetAlgorithmID(arena, algid, algTag, newParams);
    SECITEM_FreeItem(newParams,PR_TRUE);
    return rv;
}
Beispiel #4
0
static SecCmsCipherContext *
SecCmsCipherContextStart(PRArenaPool *poolp, SecSymmetricKeyRef key, SECAlgorithmID *algid, PRBool encrypt)
{
    SecCmsCipherContext *cc;
    CSSM_CC_HANDLE ciphercc = 0;
    SECOidData *oidData;
    SECOidTag algtag;
    CSSM_ALGORITHMS algorithm;
    CSSM_PADDING padding = CSSM_PADDING_PKCS7;
    CSSM_ENCRYPT_MODE mode;
    CSSM_CSP_HANDLE cspHandle;
    const CSSM_KEY *cssmKey;
    OSStatus rv;
    uint8 ivbuf[8];
    CSSM_DATA initVector = { sizeof(ivbuf), ivbuf };
    //CSSM_CONTEXT_ATTRIBUTE contextAttribute = { CSSM_ATTRIBUTE_ALG_PARAMS, sizeof(CSSM_DATA_PTR) };

    rv = SecKeyGetCSPHandle(key, &cspHandle);
    if (rv)
	goto loser;
    rv = SecKeyGetCSSMKey(key, &cssmKey);
    if (rv)
	goto loser;

    // @@@ Add support for PBE based stuff

    oidData = SECOID_FindOID(&algid->algorithm);
    if (!oidData)
	goto loser;
    algtag = oidData->offset;
    algorithm = oidData->cssmAlgorithm;
    if (!algorithm)
	goto loser;

    switch (algtag)
    {
    case SEC_OID_RC2_CBC:
    case SEC_OID_RC4:
    case SEC_OID_DES_EDE3_CBC:
    case SEC_OID_DES_EDE:
    case SEC_OID_DES_CBC:
    case SEC_OID_RC5_CBC_PAD:
    case SEC_OID_AES_128_CBC:
    case SEC_OID_AES_192_CBC:
    case SEC_OID_AES_256_CBC:
    case SEC_OID_FORTEZZA_SKIPJACK:
	mode = CSSM_ALGMODE_CBCPadIV8;
	break;

    case SEC_OID_DES_ECB:
    case SEC_OID_AES_128_ECB:
    case SEC_OID_AES_192_ECB:
    case SEC_OID_AES_256_ECB:
	mode = CSSM_ALGMODE_ECBPad;
	break;

    case SEC_OID_DES_OFB:
	mode = CSSM_ALGMODE_OFBPadIV8;
	break;

    case SEC_OID_DES_CFB:
	mode = CSSM_ALGMODE_CFBPadIV8;
	break;

    default:
	goto loser;
    }

    if (encrypt)
    {
	CSSM_CC_HANDLE randomcc;
	//SECItem *parameters;

	// Generate random initVector
	if (CSSM_CSP_CreateRandomGenContext(cspHandle,
		CSSM_ALGID_APPLE_YARROW,
		NULL, /* seed*/
		initVector.Length,
		&randomcc))
	    goto loser;

	if (CSSM_GenerateRandom(randomcc, &initVector))
	    goto loser;
	CSSM_DeleteContext(randomcc);

	// Put IV into algid.parameters
	switch (algtag)
	{
	case SEC_OID_RC4:
	case SEC_OID_DES_EDE3_CBC:
	case SEC_OID_DES_EDE:
	case SEC_OID_DES_CBC:
	case SEC_OID_AES_128_CBC:
	case SEC_OID_AES_192_CBC:
	case SEC_OID_AES_256_CBC:
	case SEC_OID_FORTEZZA_SKIPJACK:
	case SEC_OID_DES_ECB:
	case SEC_OID_AES_128_ECB:
	case SEC_OID_AES_192_ECB:
	case SEC_OID_AES_256_ECB:
	case SEC_OID_DES_OFB:
	case SEC_OID_DES_CFB:
	    /* Just encode the initVector as an octet string. */
	    if (!SEC_ASN1EncodeItem(poolp, &algid->parameters,
				    &initVector, SEC_OctetStringTemplate))
		goto loser;
	    break;
    
	case SEC_OID_RC2_CBC:
	{
	    sec_rc2cbcParameter rc2 = {};
	    unsigned long rc2version;
	    SECItem *newParams;

	    rc2.iv = initVector;
	    rc2version = rc2_unmap(cssmKey->KeyHeader.LogicalKeySizeInBits);
	    if (!SEC_ASN1EncodeUnsignedInteger (NULL, &(rc2.rc2ParameterVersion),
					       rc2version))
		goto loser;
	    newParams = SEC_ASN1EncodeItem (poolp, &algid->parameters, &rc2,
				sec_rc2cbc_parameter_template);
	    PORT_Free(rc2.rc2ParameterVersion.Data);
	    if (newParams == NULL)
		goto loser;
	    break;
	}
	case SEC_OID_RC5_CBC_PAD:
	default:
	    // @@@ Implement rc5 params stuff.
	    goto loser;
	    break;
	}
    }
    else
    {
	// Extract IV from algid.parameters
	// Put IV into algid.parameters
	switch (algtag)
	{
	case SEC_OID_RC4:
	case SEC_OID_DES_EDE3_CBC:
	case SEC_OID_DES_EDE:
	case SEC_OID_DES_CBC:
	case SEC_OID_AES_128_CBC:
	case SEC_OID_AES_192_CBC:
	case SEC_OID_AES_256_CBC:
	case SEC_OID_FORTEZZA_SKIPJACK:
	case SEC_OID_DES_ECB:
	case SEC_OID_AES_128_ECB:
	case SEC_OID_AES_192_ECB:
	case SEC_OID_AES_256_ECB:
	case SEC_OID_DES_OFB:
	case SEC_OID_DES_CFB:
	{
	    CSSM_DATA iv = {};
	    /* Just decode the initVector from an octet string. */
	    rv = SEC_ASN1DecodeItem(NULL, &iv, SEC_OctetStringTemplate, &(algid->parameters));
	    if (rv)
		goto loser;
	    if (initVector.Length != iv.Length) {
		PORT_Free(iv.Data);
		goto loser;
	    }
	    memcpy(initVector.Data, iv.Data, initVector.Length);
	    PORT_Free(iv.Data);
	    break;
	}
	case SEC_OID_RC2_CBC:
	{
	    sec_rc2cbcParameter rc2 = {};
	    unsigned long ulEffectiveBits;

	    rv = SEC_ASN1DecodeItem(NULL, &rc2 ,sec_rc2cbc_parameter_template,
							    &(algid->parameters));
	    if (rv)
		goto loser;

	    if (initVector.Length != rc2.iv.Length) {
		PORT_Free(rc2.iv.Data);
		PORT_Free(rc2.rc2ParameterVersion.Data);
		goto loser;
	    }
	    memcpy(initVector.Data, rc2.iv.Data, initVector.Length);
	    PORT_Free(rc2.iv.Data);

	    ulEffectiveBits = rc2_map(&rc2.rc2ParameterVersion);
	    PORT_Free(rc2.rc2ParameterVersion.Data);
	    if (ulEffectiveBits != cssmKey->KeyHeader.LogicalKeySizeInBits)
		goto loser;
	    break;
	}
	case SEC_OID_RC5_CBC_PAD:
	default:
	    // @@@ Implement rc5 params stuff.
	    goto loser;
	    break;
	}
    }

    if (CSSM_CSP_CreateSymmetricContext(cspHandle,
	    algorithm,
	    mode,
	    NULL, /* accessCred */
	    cssmKey,
	    &initVector,
	    padding,
	    NULL, /* reserved */
	    &ciphercc))
	goto loser;

    if (encrypt)
	rv = CSSM_EncryptDataInit(ciphercc);
    else
	rv = CSSM_DecryptDataInit(ciphercc);
    if (rv)
	goto loser;

    cc = (SecCmsCipherContext *)PORT_ZAlloc(sizeof(SecCmsCipherContext));
    if (cc == NULL)
	goto loser;

    cc->cc = ciphercc;
    cc->encrypt = encrypt;

    return cc;
loser:
    if (ciphercc)
	CSSM_DeleteContext(ciphercc);

    return NULL;
}