示例#1
0
文件: img4.c 项目: big538/img4tool
int
DERImg4Decode(const DERItem *a1, DERItem *a2)
{
    int rv;
    DERDecodedInfo var_38;

    if (a1 == NULL || a2 == NULL) {
        return DR_ParamErr;
    }

    rv = DERDecodeItem(a1, &var_38);
    if (rv) {
        return rv;
    }

    if (var_38.tag != ASN1_CONSTR_SEQUENCE) {
        return DR_UnexpectedTag;
    }

    if (a1->data + a1->length != var_38.content.data + var_38.content.length) {
        return DR_BufOverflow;
    }

    rv = DERParseSequenceContent(&var_38.content, 4, DERImg4ItemSpecs, a2, 0);
    if (rv) {
        return rv;
    }

    if (DERImg4DecodeTagCompare(a2, 'IMG4')) {
        return DR_UnexpectedTag;
    }

    return 0;
}
int DERDecodeTimeStampResponse(
	const CSSM_DATA *contents,
    CSSM_DATA *derStatus,
    CSSM_DATA *derTimeStampToken,
	size_t			*numUsedBytes)      /* RETURNED */
{
    DERReturn drtn = DR_ParamErr;
    DERDecodedInfo decodedPackage;

    if (contents)
    {
        DERItem derContents = {.data = contents->Data, .length = contents->Length };
        DERTimeStampResp derResponse = {{0,},{0,}};
        DERReturn rx;
        require_noerr(DERDecodeItem(&derContents, &decodedPackage), badResponse);

        rx = DERParseSequenceContent(&decodedPackage.content,
            DERNumTimeStampRespItemSpecs, DERTimeStampRespItemSpecs, 
            &derResponse, 0);
        if (rx != DR_Success)
            goto badResponse;
/*
        require_noerr(DERParseSequenceContent(&decodedPackage.content,
            DERNumTimeStampRespItemSpecs, DERTimeStampRespItemSpecs, 
            &derResponse, 0), badResponse);
*/
        if (derStatus && derResponse.status.data)
        {
            derStatus->Data = malloc(derResponse.status.length);
            derStatus->Length = derResponse.status.length;
            memcpy(derStatus->Data, derResponse.status.data, derStatus->Length);
        }
        if (derTimeStampToken && derResponse.timeStampToken.data)
        {
            derTimeStampToken->Data = malloc(derResponse.timeStampToken.length);
            derTimeStampToken->Length = derResponse.timeStampToken.length;
            memcpy(derTimeStampToken->Data, derResponse.timeStampToken.data, derTimeStampToken->Length);
        }
    }

    drtn = DR_Success;
    
badResponse:
    if (numUsedBytes)
        *numUsedBytes = decodedPackage.content.length +
            decodedPackage.content.data - contents->Data;

    return drtn;
}
示例#3
0
static void	printValidity(
	DERItem *validity, 
	int verbose)
{
	DERReturn drtn;
	DERValidity derv;
	
	drtn = DERParseSequenceContent(validity,
		DERNumValidityItemSpecs, DERValidityItemSpecs,
		&derv, sizeof(derv));
	if(drtn) {
		DERPerror("DERParseSequenceContent(validity)", drtn);
		return;
	}
	decodePrintItem("notBefore", IT_Leaf, verbose, &derv.notBefore);
	decodePrintItem("notAfter",  IT_Leaf, verbose, &derv.notAfter);
	
}
示例#4
0
/* 
 * This is a SEQUENCE OF so we use the low-level DERDecodeSeq* routines to snag one entry 
 * at a time.
 */
static void	printRevokedCerts(
	DERItem *revokedCerts, 
	int verbose)
{
	DERReturn drtn;
	DERDecodedInfo currItem;
	DERSequence seq;
	unsigned certNum;
	DERRevokedCert revoked;
	
	drtn = DERDecodeSeqContentInit(revokedCerts, &seq);
	if(drtn) {
		DERPerror("DERDecodeSeqContentInit(revokedCerts)", drtn);
		return;
	}
	
	for(certNum=0; ; certNum++) {
		drtn = DERDecodeSeqNext(&seq, &currItem);
		switch(drtn) {
			case DR_EndOfSequence:
				/* normal termination */
				return;
			default:
				DERPerror("DERDecodeSeqNext", drtn);
				return;
			case DR_Success:
				doIndent();
				printf("revoked cert %u\n", certNum);
				incrIndent();
				drtn = DERParseSequenceContent(&currItem.content, 
					DERNumRevokedCertItemSpecs, DERRevokedCertItemSpecs,
					&revoked, sizeof(revoked));
				if(drtn) {
					DERPerror("DERParseSequenceContent(RevokedCert)", drtn);
					decrIndent();
					return;
				}
				printItem("serialNum", IT_Leaf, verbose, ASN1_INTEGER, &revoked.serialNum);
				decodePrintItem("revocationDate",  IT_Leaf, verbose, &revoked.revocationDate);
				printItem("extensions", IT_Branch, verbose, ASN1_CONSTR_SEQUENCE, &revoked.extensions);
				decrIndent();
		}
	}
}
示例#5
0
void printAlgId(
	const DERItem *content,
	int verbose)
{
	DERReturn drtn;
	DERAlgorithmId algId;
	
	drtn = DERParseSequenceContent(content,
		DERNumAlgorithmIdItemSpecs, DERAlgorithmIdItemSpecs,
		&algId, sizeof(algId));
	if(drtn) {
		DERPerror("DERParseSequenceContent(algId)", drtn);
		return;
	}
	printItem("alg", IT_Leaf, verbose, ASN1_OBJECT_ID, &algId.oid);
	if(algId.params.data) {
		printItem("params", IT_Leaf, verbose, algId.params.data[0], &algId.params);
	}
}
/* 
 * High level sequence parse, starting with top-level tag and content.
 * Top level tag must be ASN1_CONSTR_SEQUENCE - if it's not, and that's 
 * OK, use DERParseSequenceContent().
 */
DERReturn DERParseSequenceOf(
	const DERItem			*der,
	DERShort				numItems,	/* size of itemSpecs[] */
	const DERItemSpec		*itemSpecs,
	void					*dest,		/* DERDecodedInfo(s) here RETURNED */
	DERSize					*numDestItems)	/* output */
{
	DERReturn drtn;
	DERDecodedInfo topDecode;
	
	drtn = DERDecodeItem(der, &topDecode);
	if(drtn) {
		return drtn;
	}
	if(topDecode.tag != ASN1_CONSTR_SEQUENCE) {
		return DR_UnexpectedTag;
	}
	return DERParseSequenceContent(&topDecode.content,
		numItems, itemSpecs, dest, sizeToZero);
}
示例#7
0
文件: img4.c 项目: big538/img4tool
int
main(int argc, char **argv)
{
    int rv;
    const char *what;
    const char *filename;
    const char *outname;

    TheImg4 *img4;
    unsigned type;
    unsigned written;
    unsigned char ivkey[16 + 32];
    unsigned char *iv = NULL, *key = NULL;
    unsigned char *output = NULL;
    unsigned outlen = 0;
    int outdup = 0;

    DERItem item;
    unsigned char *data;
    size_t size;

    if (argc < 4) {
        fprintf(stderr, "usage: %s {-image|-extra|-keybag|-ticket} input output [ivkey]\n", argv[0]);
        return 1;
    }

    what = argv[1];
    filename = argv[2];
    outname = argv[3];
    if (argc > 4) {
        rv = str2hex(sizeof(ivkey), ivkey, argv[4]);
        if (rv == sizeof(ivkey)) {
            iv = ivkey;
            key = ivkey + 16;
        }
    }

    data = read_file(filename, 0, &size);
    if (data == NULL) {
        fprintf(stderr, "[e] cannot read '%s'\n", filename);
        return -1;
    }

    img4 = parse(data, size);
    if (!img4) {
        fprintf(stderr, "[e] cannot parse '%s'\n", filename);
        free(data);
        return -1;
    }

    rv = Img4DecodeGetPayloadType(img4, &type);
    if (rv) {
        fprintf(stderr, "[e] cannot identify '%s'\n", filename);
        goto err;
    }
    printf("%c%c%c%c\n", FOURCC(type));

    if (!strncmp(what, "-i", 2) || !strncmp(what, "-e", 2)) {
        int decompress;

        rv = Img4DecodeGetPayload(img4, &item);
        if (rv) {
            fprintf(stderr, "[e] cannot extract payload from '%s'\n", filename);
            goto err;
        }
        output = item.data;
        outlen = item.length;

        if (iv && key) {
            if (outlen & 15) {
                unsigned usize = (outlen + 15) & ~15;
                unsigned char *tmp = calloc(1, usize);
                if (!tmp) {
                    fprintf(stderr, "[e] out of memory %u\n", usize);
                    goto err;
                }
                memcpy(tmp, output, outlen);
                OUTSET(tmp);
            }

            rv = Img4DecodeGetPayloadKeybag(img4, &item);
            if (rv || item.length == 0) {
                fprintf(stderr, "[w] image '%s' has no keybag\n", filename);
            }
#ifdef USE_CORECRYPTO
            cccbc_one_shot(ccaes_cbc_decrypt_mode(), 32, key, iv, (outlen + 15) / 16, output, output);
#else
            AES_KEY decryptKey;
            AES_set_decrypt_key(key, 256, &decryptKey);
            AES_cbc_encrypt(output, output, (outlen + 15) & ~15, &decryptKey, iv, AES_DECRYPT);
#endif
        }

#ifdef iOS10
        if (img4->payload.compression.data && img4->payload.compression.length) {
            DERItem tmp[2];
            uint32_t deco = 0;
            uint64_t usize = 0;
            if (DERParseSequenceContent(&img4->payload.compression, 2, DERImg4PayloadItemSpecs10c, tmp, 0) ||
                DERParseInteger(&tmp[0], &deco) || DERParseInteger64(&tmp[1], &usize)) {
                fprintf(stderr, "[e] cannot get decompression info\n");
                goto err;
            }
            if (deco == 1 && what[1] == 'i') {
                size_t asize = lzfse_decode_scratch_size();
                unsigned char *dec, *aux = malloc(asize);
                if (!aux) {
                    fprintf(stderr, "[e] out of memory %zu\n", asize);
                    goto err;
                }
                dec = malloc(usize + 1);
                if (!dec) {
                    fprintf(stderr, "[e] out of memory %llu\n", usize + 1);
                    free(aux);
                    goto err;
                }
                outlen = lzfse_decode_buffer(dec, usize + 1, output, outlen, aux);
                free(aux);
                if (outlen != usize) {
                    fprintf(stderr, "[e] decompression error\n");
                    free(dec);
                    goto err;
                }
                OUTSET(dec);
            }
        }
#endif
        decompress = (DWORD_BE(output, 0) == 'comp' && DWORD_BE(output, 4) == 'lzss');
        if (decompress && what[1] == 'i') {
            uint32_t csize = DWORD_BE(output, 16);
            uint32_t usize = DWORD_BE(output, 12);
            uint32_t adler = DWORD_BE(output, 8);
            unsigned char *dec = malloc(usize);
            if (outlen > 0x180 + csize) {
                fprintf(stderr, "[i] extra 0x%x bytes after compressed chunk\n", outlen - 0x180 - csize);
            }
            if (!dec) {
                fprintf(stderr, "[e] out of memory %u\n", usize);
                goto err;
            }
            outlen = decompress_lzss(dec, output + 0x180, csize);
            if (adler != lzadler32(dec, outlen)) {
                fprintf(stderr, "[w] adler32 mismatch\n");
            }
            OUTSET(dec);
        } else if (decompress) {
            uint32_t csize = DWORD_BE(output, 16);
            uint32_t usize = outlen - 0x180 - csize;
            if (outlen > 0x180 + csize) {
                unsigned char *dec = malloc(usize);
                if (!dec) {
                    fprintf(stderr, "[e] out of memory %u\n", usize);
                    goto err;
                }
                memcpy(dec, output + 0x180 + csize, usize);
                outlen = usize;
                OUTSET(dec);
            } else {
                OUTSET(NULL);
            }
        } else if (what[1] == 'e') {
            OUTSET(NULL);
        }
        if (!output) {
            fprintf(stderr, "[e] nothing to do\n");
            goto err;
        }
    }
    if (!strncmp(what, "-k", 2)) {
        rv = Img4DecodeGetPayloadKeybag(img4, &item);
        if (rv == 0 && item.length) {
            output = item.data;
            outlen = item.length;
        } else {
            fprintf(stderr, "[e] image '%s' has no keybag\n", filename);
            goto err;
        }
    }
    if (!strncmp(what, "-t", 2)) {
        bool exists = false;
        rv = Img4DecodeManifestExists(img4, &exists);
        if (rv == 0 && exists) {
            output = img4->manifestRaw.data;
            outlen = img4->manifestRaw.length;
        } else {
            fprintf(stderr, "[e] image '%s' has no ticket\n", filename);
            goto err;
        }
    }

    written = write_file(outname, output, outlen);
    if (written != outlen) {
        fprintf(stderr, "[e] cannot write '%s'\n", outname);
        goto err;
    }

    rv = 0;
out:
    if (outdup) {
        free(output);
    }
    free(img4);
    free(data);
    return rv;

err:
    rv = -1;
    goto out;
}
示例#8
0
/*
 * Given a SSLCertificate cert, obtain its public key as a SSLPubKey.
 * Caller must sslFreePubKey and free the SSLPubKey itself.
 */
OSStatus sslPubKeyFromCert(
	SSLContext 				*ctx,
	const SSLCertificate	*cert,
	SSLPubKey               **pubKey) 		// RETURNED
{
    DERItem der;
    DERSignedCertCrl signedCert;
    DERTBSCert tbsCert;
	DERSubjPubKeyInfo pubKeyInfo;
	DERByte numUnused;
    DERItem pubKeyPkcs1;
    SSLPubKey *key;
	DERReturn drtn;
    RSAStatus rsaStatus;

    assert(cert);
	assert(pubKey != NULL);

    der.data = cert->derCert.data;
    der.length = cert->derCert.length;

	/* top level decode */
	drtn = DERParseSequence(&der, DERNumSignedCertCrlItemSpecs,
		DERSignedCertCrlItemSpecs, &signedCert, sizeof(signedCert));
	if(drtn)
		return errSSLBadCert;

	/* decode the TBSCert - it was saved in full DER form */
	drtn = DERParseSequence(&signedCert.tbs,
		DERNumTBSCertItemSpecs, DERTBSCertItemSpecs,
		&tbsCert, sizeof(tbsCert));
	if(drtn)
		return errSSLBadCert;

	/* sequence we're given: encoded DERSubjPubKeyInfo */
	drtn = DERParseSequenceContent(&tbsCert.subjectPubKey,
		DERNumSubjPubKeyInfoItemSpecs, DERSubjPubKeyInfoItemSpecs,
		&pubKeyInfo, sizeof(pubKeyInfo));
	if(drtn)
		return errSSLBadCert;

	/* @@@ verify that this is an RSA key by decoding the AlgId */

	/*
	 * The contents of pubKeyInfo.pubKey is a bit string whose contents
	 * are a PKCS1 format RSA key.
	 */
	drtn = DERParseBitString(&pubKeyInfo.pubKey, &pubKeyPkcs1, &numUnused);
	if(drtn)
		return errSSLBadCert;

#if TARGET_OS_IOS
    /* Now we have the public key in pkcs1 format.  Let's make a public key
       object out of it. */
    key = sslMalloc(sizeof(*key));
    rsaStatus = RSA_DecodePubKey(pubKeyPkcs1.data, pubKeyPkcs1.length,
        &key->rsaKey);
	if (rsaStatus) {
		sslFree(key);
	}
#else
	SecKeyRef rsaPubKeyRef = SecKeyCreateRSAPublicKey(NULL,
		pubKeyPkcs1.data, pubKeyPkcs1.length,
		kSecKeyEncodingRSAPublicParams);
	rsaStatus = (rsaPubKeyRef) ? 0 : 1;
	key = (SSLPubKey*)rsaPubKeyRef;
#endif
	if (rsaStatus) {
		return rsaStatusToSSL(rsaStatus);
	}

	*pubKey = key;
	return noErr;
}