Пример #1
0
/*
 * ShroudedKeyBag parser w/decrypt
 */
static int shroudedKeyBagParse(pkcs12_context * context, const NSS_P12_SafeBag *safeBag)
{
	p12DecodeLog("Found shrouded key bag");

	const NSS_P12_ShroudedKeyBag *keyBag = safeBag->bagValue.shroudedKeyBag;
    SecAsn1Item ptext = {0, NULL};
    require_noerr_quiet(p12Decrypt(context, &keyBag->algorithm, 
        &keyBag->encryptedData, &ptext), out);

    /* Decode PKCS#8 formatted private key */
    NSS_PrivateKeyInfo pki;
    memset(&pki, 0, sizeof(pki));
	require_noerr(decode_item(context, &ptext, kSecAsn1PrivateKeyInfoTemplate,
			&pki), out);
    DERItem algorithm = { pki.algorithm.algorithm.Data, pki.algorithm.algorithm.Length };
    require(DEROidCompare(&oidRsa, &algorithm), out);

    CFDataRef keyData = CFDataCreate(kCFAllocatorDefault, pki.privateKey.Data, pki.privateKey.Length);

    require_noerr(emit_item(context, safeBag->bagAttrs, CFSTR("key"), keyData), out);
    CFRelease(keyData);
    
    return 0;
out:
    return -1;
}
Пример #2
0
/*
 * Parse an encoded NSS_P12_SafeContents. This could be either 
 * present as plaintext in an AuthSafe or decrypted. 
 */
static int safeContentsParse(pkcs12_context * context, const SecAsn1Item *contentsBlob)
{
	p12DecodeLog("safeContentsParse");

	NSS_P12_SafeContents sc;
	memset(&sc, 0, sizeof(sc));
	require_noerr(decode_item(context, contentsBlob, NSS_P12_SafeContentsTemplate,
			&sc), out);

	unsigned numBags = nssArraySize((const void **)sc.bags);
    unsigned int dex;
	for(dex=0; dex<numBags; dex++) {
		NSS_P12_SafeBag *bag = sc.bags[dex];
		assert(bag != NULL);
		
		/* ensure that *something* is there */
		require(bag->bagValue.keyBag != NULL, out);
		
		/*
		 * Break out to individual bag type
		 */
		switch(bag->type) {
			case BT_ShroudedKeyBag:
				require_noerr(shroudedKeyBagParse(context, bag), out);
				break;
			case BT_CertBag:
				require_noerr(certBagParse(context, bag), out);
				break;

			case BT_KeyBag:
				/* keyBagParse(bag); */
                p12DecodeLog("Unhandled BT_KeyBag");
				break;
			case BT_CrlBag:
				/* crlBagParse(bag); */
                p12DecodeLog("Unhandled BT_CrlBag");
				break;
			case BT_SecretBag:
				/* secretBagParse(bag); */
                p12DecodeLog("Unhandled BT_SecretBag");
				break;
			case BT_SafeContentsBag:
				/* safeContentsBagParse(bag); */
                p12DecodeLog("Unhandled BT_SafeContentsBag");
				break;
			default:
                p12DecodeLog("Unknown bag type");
                goto out;
                break;
		}
	}
    return 0;
out:
    return -1;
}
Пример #3
0
 inline PyObject* decode_from_stream(const std::string& enc_rule, hu::InStream& stream) {
   PyObject* res = PyTuple_New(enc_rule.size());
   for(std::size_t i = 0; i < enc_rule.size(); ++i) {
     PyObject* v = decode_item(enc_rule[i], stream);
     if (v == NULL) {
       return NULL;
     }
     PyTuple_SET_ITEM(res, i, v);
   }
   return res;
 }
Пример #4
0
/*
 * Parse an SecAsn1AlgId specific to P12.
 * Decode the alg params as a NSS_P12_PBE_Params and parse and 
 * return the result if the pbeParams is non-NULL.
 */
static int algIdParse(pkcs12_context * context, 
	const SecAsn1AlgId *algId, NSS_P12_PBE_Params *pbeParams/*optional*/)
{
	p12DecodeLog("algIdParse");
	const SecAsn1Item *param = &algId->parameters;
	require(pbeParams, out);
    require(param && param->Length, out);
	memset(pbeParams, 0, sizeof(*pbeParams));
	require_noerr(decode_item(context, param, NSS_P12_PBE_ParamsTemplate, pbeParams), out);
    
    return 0;
out:
    return -1;
}
Пример #5
0
/*
 * Parse an encoded NSS_P12_AuthenticatedSafe
 */
static int authSafeParse(pkcs12_context * context, const SecAsn1Item *authSafeBlob)
{
    p12DecodeLog("authSafeParse");
    NSS_P12_AuthenticatedSafe authSafe;
    memset(&authSafe, 0, sizeof(authSafe));
    require_noerr(decode_item(context, authSafeBlob, 
        NSS_P12_AuthenticatedSafeTemplate, &authSafe), out);

    unsigned numInfos = nssArraySize((const void **)authSafe.info);
    unsigned int dex;
    for (dex=0; dex<numInfos; dex++) {
        NSS_P7_DecodedContentInfo *info = authSafe.info[dex];
        require_noerr_quiet(authSafeElementParse(context, info), out);
    }
    return 0;
out:
    return -1;
}
Пример #6
0
p12_error p12decode(pkcs12_context * context, CFDataRef cdpfx)
{
    int err = p12_decodeErr;
	NSS_P12_DecodedPFX pfx;
	memset(&pfx, 0, sizeof(pfx));
    SecAsn1Item raw_blob = { CFDataGetLength(cdpfx), (void*)CFDataGetBytePtr(cdpfx) };

    require_noerr_quiet(decode_item(context, &raw_blob, NSS_P12_DecodedPFXTemplate, &pfx), out);
	NSS_P7_DecodedContentInfo *dci = &pfx.authSafe;
    
    /* only support CT_Data at top level (password based integrity mode) */
	require(dci->type == CT_Data, out);
	require(pfx.macData, out);
    
	require_noerr_action_quiet(p12VerifyMac(context, &pfx), out, err = p12_passwordErr);
    require_noerr_quiet(authSafeParse(context, dci->content.data), out);
    
	return errSecSuccess;
out:
    return err;
}
Пример #7
0
static int emit_item(pkcs12_context * context, NSS_Attribute **attrs, 
    CFStringRef item_key, CFTypeRef item_value)
{
    int result = -1;
	/* parse attrs into friendlyName, localKeyId; ignoring generic attrs */
    CFMutableDictionaryRef attr_dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 
        0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
    require(attr_dict, out);
	unsigned numAttrs = nssArraySize((const void **)attrs);
    unsigned int dex;
	for(dex = 0; dex < numAttrs; dex++) {
		NSS_Attribute *attr = attrs[dex];
		unsigned numValues = nssArraySize((const void**)attr->attrValue);
		DERItem type = { attr->attrType.Data, attr->attrType.Length };
		if(DEROidCompare(&type, &oidFriendlyName)) {
			/* 
			 * BMP string (UniCode). Spec says only one legal value.
			 */
			require(numValues == 1, out);
            SecAsn1Item friendly_name_asn1;
			require_noerr(decode_item(context, attr->attrValue[0],
					kSecAsn1BMPStringTemplate, &friendly_name_asn1), out);
            CFStringRef friendly_name = CFStringCreateWithBytes(kCFAllocatorDefault, 
                friendly_name_asn1.Data, friendly_name_asn1.Length, 
                kCFStringEncodingUnicode, true);
            if (friendly_name) {
                CFDictionarySetValue(attr_dict, kSecImportItemLabel, friendly_name);
                CFRelease(friendly_name);
            }
		}
		else if(DEROidCompare(&type, &oidLocalKeyId)) {
			/* 
			 * Octet string. Spec says only one legal value.
			 */
			require(numValues == 1, out);
            SecAsn1Item local_key_id;
			require_noerr(decode_item(context, attr->attrValue[0],
					kSecAsn1OctetStringTemplate, &local_key_id), out);
            CFDataRef keyid = CFDataCreate(kCFAllocatorDefault, local_key_id.Data, local_key_id.Length);
            if (keyid) {
                CFDictionarySetValue(attr_dict, kSecImportItemKeyID, keyid);
                CFRelease(keyid);
            }
		}
	}

    CFTypeRef key = CFDictionaryGetValue(attr_dict, kSecImportItemKeyID);
    if (!key)
        key = CFDictionaryGetValue(attr_dict, kSecImportItemLabel);
    if (!key)
        key = item_value;

    CFMutableDictionaryRef item = (CFMutableDictionaryRef)CFDictionaryGetValue(context->items, key);
    if (item) {
        CFDictionarySetValue(item, item_key, item_value);
    } else {
        CFDictionarySetValue(attr_dict, item_key, item_value);
        CFDictionarySetValue(context->items, key, attr_dict);
    }
    result = 0;
out:
    CFReleaseSafe(attr_dict);
    return result;
}