int DERImg4DecodeManifest(const DERItem *a1, TheImg4Manifest *a2) { int rv; uint32_t var_14; if (a1 == NULL || a2 == NULL) { return DR_ParamErr; } if (a1->data == NULL || a1->length == 0) { return 0; } rv = DERParseSequence(a1, 5, DERImg4ManifestItemSpecs, a2, 0); if (rv) { return rv; } if (DERImg4DecodeTagCompare(&a2->magic, 'IM4M')) { return DR_UnexpectedTag; } rv = DERParseInteger(&a2->version, &var_14); if (rv) { return rv; } if (var_14) { return DR_UnexpectedTag; } return 0; }
static OSStatus ccrsa_pub_decode_apple(ccrsa_pub_ctx_t pubkey, size_t pkcs1_size, const uint8_t* pkcs1) { OSStatus result = errSecParam; DERItem keyItem = {(DERByte *)pkcs1, pkcs1_size}; DERRSAPubKeyApple decodedKey; require_noerr_action(DERParseSequence(&keyItem, DERNumRSAPubKeyAppleItemSpecs, DERRSAPubKeyAppleItemSpecs, &decodedKey, sizeof(decodedKey)), errOut, result = errSecDecode); // We could honor the recipricol, but we don't think this is used enough to care. // Don't bother exploding the below function to try to handle this case, it computes. require_noerr(ccrsa_pub_init(pubkey, decodedKey.modulus.length, decodedKey.modulus.data, decodedKey.pubExponent.length, decodedKey.pubExponent.data), errOut); result = errSecSuccess; errOut: return result; }
int DERImg4DecodeRestoreInfo(const DERItem *a1, TheImg4RestoreInfo *a2) { int rv; if (a1 == NULL) { return 0; } if (a2 == NULL) { return DR_ParamErr; } if (a1->data == NULL || a1->length == 0) { return 0; } rv = DERParseSequence(a1, 2, DERImg4RestoreInfoItemSpecs, a2, 0); if (rv) { return rv; } if (DERImg4DecodeTagCompare(&a2->magic, 'IM4R')) { return DR_UnexpectedTag; } return 0; }
void printSubjPubKeyInfo( const DERItem *content, int verbose) { DERReturn drtn; DERSubjPubKeyInfo pubKeyInfo; DERRSAPubKeyPKCS1 pkcs1Key; DERItem bitStringContents; DERByte numUnused; drtn = DERParseSequence(content, DERNumSubjPubKeyInfoItemSpecs, DERSubjPubKeyInfoItemSpecs, &pubKeyInfo, sizeof(pubKeyInfo)); if(drtn) { DERPerror("DERParseSequenceContent(pubKeyInfo)", drtn); return; } printItem("algId", IT_Branch, verbose, ASN1_CONSTR_SEQUENCE, &pubKeyInfo.algId); incrIndent(); printAlgId(&pubKeyInfo.algId, verbose); decrIndent(); printItem("pubKey", IT_Branch, verbose, ASN1_BIT_STRING, &pubKeyInfo.pubKey); /* * The contents of that bit string are a PKCS1 format RSA key. */ drtn = DERParseBitString(&pubKeyInfo.pubKey, &bitStringContents, &numUnused); if(drtn) { DERPerror("DERParseBitString(pubKeyInfo.pubKey)", drtn); decrIndent(); return; } drtn = DERParseSequence(&bitStringContents, DERNumRSAPubKeyPKCS1ItemSpecs, DERRSAPubKeyPKCS1ItemSpecs, &pkcs1Key, sizeof(pkcs1Key)); if(drtn) { DERPerror("DERParseSequenceContent(pubKeyBits)", drtn); decrIndent(); return; } incrIndent(); printItem("modulus", IT_Leaf, verbose, ASN1_INTEGER, &pkcs1Key.modulus); printItem("pubExponent", IT_Leaf, verbose, ASN1_INTEGER, &pkcs1Key.pubExponent); decrIndent(); }
OSStatus SecDHCreateFromParameters(const uint8_t *params, size_t params_len, SecDHContext *pdh) { DERReturn drtn; DERItem paramItem = {(DERByte *)params, params_len}; DER_DHParams decodedParams; uint32_t l; drtn = DERParseSequence(¶mItem, DER_NumDHParamsItemSpecs, DER_DHParamsItemSpecs, &decodedParams, sizeof(decodedParams)); if(drtn) return drtn; drtn = DERParseInteger(&decodedParams.l, &l); if(drtn) return drtn; cc_size n = ccn_nof_size(decodedParams.p.length); cc_size p_len = ccn_sizeof_n(n); size_t context_size = ccdh_gp_size(p_len)+ccdh_full_ctx_size(p_len); void *context = malloc(context_size); if(context==NULL) return errSecAllocate; bzero(context, context_size); ccdh_gp_t gp; gp.gp = context; CCDH_GP_N(gp) = n; CCDH_GP_L(gp) = l; if(ccn_read_uint(n, CCDH_GP_PRIME(gp), decodedParams.p.length, decodedParams.p.data)) goto errOut; if(decodedParams.recip.length) { if(ccn_read_uint(n+1, CCDH_GP_RECIP(gp), decodedParams.recip.length, decodedParams.recip.data)) goto errOut; gp.zp.zp->mod_prime = cczp_mod; } else { cczp_init(gp.zp); }; if(ccn_read_uint(n, CCDH_GP_G(gp), decodedParams.g.length, decodedParams.g.data)) goto errOut; *pdh = (SecDHContext) context; return errSecSuccess; errOut: SecDHDestroy(context); *pdh = NULL; return errSecInvalidKey; }
int DERImg4DecodePayload(const DERItem *a1, TheImg4Payload *a2) { int rv; if (a1 == NULL || a2 == NULL) { return DR_ParamErr; } #ifdef iOS10 rv = DERParseSequence(a1, 6, DERImg4PayloadItemSpecs, a2, 0); #else rv = DERParseSequence(a1, 5, DERImg4PayloadItemSpecs, a2, 0); #endif if (rv) { return rv; } if (DERImg4DecodeTagCompare(&a2->magic, 'IM4P')) { return DR_UnexpectedTag; } return 0; }
OSStatus SecDHCreateFromAlgorithmId(const uint8_t *alg, size_t alg_len, SecDHContext *pdh) { DERAlgorithmId algorithmId; DERItem algId; algId.data = (uint8_t *)alg; algId.length = alg_len; DERReturn drtn = DERParseSequence(&algId, DERNumAlgorithmIdItemSpecs, DERAlgorithmIdItemSpecs, &algorithmId, sizeof(algorithmId)); if (drtn != DR_Success) return der2OSStatus(drtn); return SecDHCreateFromParameters(algorithmId.params.data, algorithmId.params.length, pdh); }
static OSStatus ccrsa_full_decode(ccrsa_full_ctx_t fullkey, size_t pkcs1_size, const uint8_t* pkcs1) { OSStatus result = errSecParam; DERItem keyItem = {(DERByte *)pkcs1, pkcs1_size}; DERRSAKeyPair decodedKey; require_noerr_action(DERParseSequence(&keyItem, DERNumRSAKeyPairItemSpecs, DERRSAKeyPairItemSpecs, &decodedKey, sizeof(decodedKey)), errOut, result = errSecDecode); require_noerr(ccrsa_pub_init(fullkey, decodedKey.n.length, decodedKey.n.data, decodedKey.e.length, decodedKey.e.data), errOut); ccn_read_uint(ccrsa_ctx_n(fullkey), ccrsa_ctx_d(fullkey), decodedKey.d.length, decodedKey.d.data); { ccrsa_priv_ctx_t privkey = ccrsa_ctx_private(fullkey); CCZP_N(ccrsa_ctx_private_zp(privkey)) = ccn_nof((ccn_bitsof_n(ccrsa_ctx_n(fullkey)) / 2) + 1); CCZP_N(ccrsa_ctx_private_zq(privkey)) = cczp_n(ccrsa_ctx_private_zp(privkey)); // TODO: Actually remember decodedKey.d. require_noerr(ccrsa_priv_init(privkey, decodedKey.p.length, decodedKey.p.data, decodedKey.q.length, decodedKey.q.data, decodedKey.dp.length, decodedKey.dp.data, decodedKey.dq.length, decodedKey.dq.data, decodedKey.qInv.length, decodedKey.qInv.data), errOut); } result = errSecSuccess; errOut: return result; }
static OSStatus ccrsa_pub_decode(ccrsa_pub_ctx_t pubkey, size_t pkcs1_size, const uint8_t* pkcs1) { OSStatus result = errSecParam; DERItem keyItem = {(DERByte *)pkcs1, pkcs1_size}; DERRSAPubKeyPKCS1 decodedKey; require_noerr_action(DERParseSequence(&keyItem, DERNumRSAPubKeyPKCS1ItemSpecs, DERRSAPubKeyPKCS1ItemSpecs, &decodedKey, sizeof(decodedKey)), errOut, result = errSecDecode); require_noerr(ccrsa_pub_init(pubkey, decodedKey.modulus.length, decodedKey.modulus.data, decodedKey.pubExponent.length, decodedKey.pubExponent.data), errOut); result = errSecSuccess; errOut: return result; }
OSStatus sslDecodeDhParams( const SSLBuffer *blob, /* Input - PKCS-3 encoded */ SSLBuffer *prime, /* Output - wire format */ SSLBuffer *generator) /* Output - wire format */ { OSStatus ortn = noErr; DERReturn drtn; DERItem paramItem = {(DERByte *)blob->data, blob->length}; DER_DHParams decodedParams; drtn = DERParseSequence(¶mItem, DER_NumDHParamsItemSpecs, DER_DHParamsItemSpecs, &decodedParams, sizeof(decodedParams)); if(drtn) return drtn; prime->data = decodedParams.p.data; prime->length = decodedParams.p.length; generator->data = decodedParams.g.data; generator->length = decodedParams.g.length; return ortn; }
OSStatus SecDHCreateFromParameters(const uint8_t *params, size_t params_len, SecDHContext *pdh) { // We support DomainParameters as specified in PKCS#3 // (http://www.emc.com/emc-plus/rsa-labs/standards-initiatives/pkcs-3-diffie-hellman-key-agreement-standar.htm) // DHParameter ::= SEQUENCE { // prime INTEGER, -- p // base INTEGER, -- g // privateValueLength INTEGER OPTIONAL } DERReturn drtn; DERItem paramItem = {(DERByte *)params, params_len}; DER_DHParams decodedParams; uint32_t l = 0; drtn = DERParseSequence(¶mItem, DER_NumDHParamsItemSpecs, DER_DHParamsItemSpecs, &decodedParams, sizeof(decodedParams)); if(drtn) return drtn; if (decodedParams.l.length > 0) { drtn = DERParseInteger(&decodedParams.l, &l); if(drtn) return drtn; } cc_size n = ccn_nof_size(decodedParams.p.length); cc_size p_len = ccn_sizeof_n(n); size_t context_size = ccdh_gp_size(p_len)+ccdh_full_ctx_size(p_len); void *context = malloc(context_size); if(context==NULL) return errSecAllocate; bzero(context, context_size); ccdh_gp_t gp; gp.gp = context; CCDH_GP_N(gp) = n; CCDH_GP_L(gp) = l; if(ccn_read_uint(n, CCDH_GP_PRIME(gp), decodedParams.p.length, decodedParams.p.data)) goto errOut; if(decodedParams.recip.length) { if(ccn_read_uint(n+1, CCDH_GP_RECIP(gp), decodedParams.recip.length, decodedParams.recip.data)) goto errOut; CCZP_MOD_PRIME(gp.zp) = cczp_mod; } else { cczp_init(gp.zp); }; if(ccn_read_uint(n, CCDH_GP_G(gp), decodedParams.g.length, decodedParams.g.data)) goto errOut; *pdh = (SecDHContext) context; return errSecSuccess; errOut: SecDHDestroy(context); *pdh = NULL; return errSecInvalidKey; }
/* * 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; }
int main(int argc, char **argv) { unsigned char *crlData = NULL; unsigned crlDataLen = 0; DERSignedCertCrl signedCrl; DERTBSCrl tbs; DERReturn drtn; DERItem item; int verbose = 0; extern char *optarg; int arg; extern int optind; if(argc < 2) { usage(argv); } if(readFile(argv[1], &crlData, &crlDataLen)) { printf("***Error reading CRL from %s. Aborting.\n", argv[1]); exit(1); } optind = 2; while ((arg = getopt(argc, argv, "vh")) != -1) { switch (arg) { case 'v': verbose = 1; break; case 'h': usage(argv); } } if(optind != argc) { usage(argv); } /* Top level decode of signed CRL into 3 components */ item.data = crlData; item.length = crlDataLen; drtn = DERParseSequence(&item, DERNumSignedCertCrlItemSpecs, DERSignedCertCrlItemSpecs, &signedCrl, sizeof(signedCrl)); if(drtn) { DERPerror("DERParseSequence(SignedCrl)", drtn); exit(1); } printItem("TBSCrl", IT_Branch, verbose, ASN1_CONSTR_SEQUENCE, &signedCrl.tbs); incrIndent(); /* decode the TBSCrl - it was saved in full DER form */ drtn = DERParseSequence(&signedCrl.tbs, DERNumTBSCrlItemSpecs, DERTBSCrlItemSpecs, &tbs, sizeof(tbs)); if(drtn) { DERPerror("DERParseSequenceContent(TBSCrl)", drtn); exit(1); } if(tbs.version.data) { printItem("version", IT_Leaf, verbose, ASN1_INTEGER, &tbs.version); } printItem("tbsSigAlg", IT_Branch, verbose, ASN1_CONSTR_SEQUENCE, &tbs.tbsSigAlg); incrIndent(); printAlgId(&tbs.tbsSigAlg, verbose); decrIndent(); printItem("issuer", IT_Leaf, verbose, ASN1_CONSTR_SEQUENCE, &tbs.issuer); decodePrintItem("thisUpdate", IT_Leaf, verbose, &tbs.thisUpdate); decodePrintItem("nextUpdate", IT_Leaf, verbose, &tbs.nextUpdate); if(tbs.revokedCerts.data) { printItem("version", IT_Leaf, verbose, ASN1_CONSTR_SEQUENCE, &tbs.revokedCerts); incrIndent(); printRevokedCerts(&tbs.revokedCerts, verbose); decrIndent(); } if(tbs.extensions.data) { printItem("extensions", IT_Leaf, verbose, ASN1_CONSTRUCTED | ASN1_CONTEXT_SPECIFIC | 3, &tbs.extensions); } printItem("sigAlg", IT_Branch, verbose, ASN1_CONSTR_SEQUENCE, &signedCrl.sigAlg); incrIndent(); printAlgId(&signedCrl.sigAlg, verbose); decrIndent(); printItem("sig", IT_Leaf, verbose, ASN1_BIT_STRING, &signedCrl.sig); return 0; }
int main(int argc, char **argv) { unsigned char *certData = NULL; unsigned certDataLen = 0; DERSignedCertCrl signedCert; DERTBSCert tbs; DERReturn drtn; DERItem item; int verbose = 0; extern char *optarg; int arg; extern int optind; if(argc < 2) { usage(argv); } if(readFile(argv[1], &certData, &certDataLen)) { printf("***Error reading cert from %s. Aborting.\n", argv[1]); exit(1); } optind = 2; while ((arg = getopt(argc, argv, "vh")) != -1) { switch (arg) { case 'v': verbose = 1; break; case 'h': usage(argv); } } if(optind != argc) { usage(argv); } /* Top level decode of signed cert into 3 components */ item.data = certData; item.length = certDataLen; drtn = DERParseSequence(&item, DERNumSignedCertCrlItemSpecs, DERSignedCertCrlItemSpecs, &signedCert, sizeof(signedCert)); if(drtn) { DERPerror("DERParseSequence(SignedCert)", drtn); exit(1); } printItem("TBSCert", IT_Branch, verbose, ASN1_CONSTR_SEQUENCE, &signedCert.tbs); incrIndent(); /* decode the TBSCert - it was saved in full DER form */ drtn = DERParseSequence(&signedCert.tbs, DERNumTBSCertItemSpecs, DERTBSCertItemSpecs, &tbs, sizeof(tbs)); if(drtn) { DERPerror("DERParseSequenceContent(TBSCert)", drtn); exit(1); } if(tbs.version.data) { /* unwrap the explicitly tagged integer.... */ decodePrintItem("version", IT_Leaf, verbose, &tbs.version); } printItem("serialNum", IT_Leaf, verbose, ASN1_INTEGER, &tbs.serialNum); printItem("tbsSigAlg", IT_Branch, verbose, ASN1_CONSTR_SEQUENCE, &tbs.tbsSigAlg); incrIndent(); printAlgId(&tbs.tbsSigAlg, verbose); decrIndent(); printItem("issuer", IT_Leaf, verbose, ASN1_CONSTR_SEQUENCE, &tbs.issuer); printItem("subject", IT_Leaf, verbose, ASN1_CONSTR_SEQUENCE, &tbs.subject); printItem("validity", IT_Branch, verbose, ASN1_CONSTR_SEQUENCE, &tbs.validity); incrIndent(); printValidity(&tbs.validity, verbose); decrIndent(); printItem("subjectPubKey", IT_Branch, verbose, ASN1_CONSTR_SEQUENCE, &tbs.subjectPubKey); incrIndent(); printSubjPubKeyInfo(&tbs.subjectPubKey, verbose); decrIndent(); if(tbs.issuerID.data) { /* found tag is implicit context specific: tell printItem what it really is */ printItem("issuerID", IT_Leaf, verbose, ASN1_BIT_STRING, &tbs.issuerID); } if(tbs.subjectID.data) { printItem("subjectID", IT_Leaf, verbose, ASN1_BIT_STRING, &tbs.subjectID); } if(tbs.extensions.data) { printItem("extensions", IT_Leaf, verbose, ASN1_CONSTRUCTED | ASN1_CONTEXT_SPECIFIC | 3, &tbs.extensions); } decrIndent(); printItem("sigAlg", IT_Branch, verbose, ASN1_CONSTR_SEQUENCE, &signedCert.sigAlg); incrIndent(); printAlgId(&signedCert.sigAlg, verbose); decrIndent(); printItem("sig", IT_Leaf, verbose, ASN1_BIT_STRING, &signedCert.sig); return 0; }