static int verify_digest(unsigned char* input, unsigned char *digest, int hash_size) { int ret = -1; X509_SIG *sig = NULL; uint32_t len = read_der_message_length(input); if(!len) { dprintf(CRITICAL, "boot_verifier: Signature length is invalid.\n"); return ret; } sig = d2i_X509_SIG(NULL, &input, len); if(sig == NULL) { dprintf(CRITICAL, "boot_verifier: Reading digest failed\n"); return ret; } if(sig->digest->length != SHA256_SIZE) { dprintf(CRITICAL, "boot_verifier: Digest length error.\n"); goto verify_digest_error; } if(memcmp(sig->digest->data, digest, hash_size) == 0) ret = 0; verify_digest_error: if(sig != NULL) X509_SIG_free(sig); return ret; }
EVP_PKEY * PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u) { char *nm = NULL; const unsigned char *p = NULL; unsigned char *data = NULL; long len; int slen; EVP_PKEY *ret = NULL; if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_EVP_PKEY, bp, cb, u)) return NULL; p = data; if (strcmp(nm, PEM_STRING_PKCS8INF) == 0) { PKCS8_PRIV_KEY_INFO *p8inf; p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len); if (!p8inf) goto p8err; ret = EVP_PKCS82PKEY(p8inf); if (x) { EVP_PKEY_free(*x); *x = ret; } PKCS8_PRIV_KEY_INFO_free(p8inf); } else if (strcmp(nm, PEM_STRING_PKCS8) == 0) { PKCS8_PRIV_KEY_INFO *p8inf; X509_SIG *p8; int klen; char psbuf[PEM_BUFSIZE]; p8 = d2i_X509_SIG(NULL, &p, len); if (!p8) goto p8err; if (cb) klen = cb(psbuf, PEM_BUFSIZE, 0, u); else klen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u); if (klen <= 0) { PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY, PEM_R_BAD_PASSWORD_READ); X509_SIG_free(p8); goto err; } p8inf = PKCS8_decrypt(p8, psbuf, klen); X509_SIG_free(p8); if (!p8inf) goto p8err; ret = EVP_PKCS82PKEY(p8inf); if (x) { EVP_PKEY_free(*x); *x = ret; } PKCS8_PRIV_KEY_INFO_free(p8inf); } else if ((slen = pem_check_suffix(nm, "PRIVATE KEY")) > 0) { const EVP_PKEY_ASN1_METHOD *ameth; ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen); if (!ameth || !ameth->old_priv_decode) goto p8err; ret = d2i_PrivateKey(ameth->pkey_id, x, &p, len); } p8err: if (ret == NULL) PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY, ERR_R_ASN1_LIB); err: free(nm); OPENSSL_cleanse(data, len); free(data); return (ret); }
EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u) { char *nm=NULL; const unsigned char *p=NULL; unsigned char *data=NULL; long len; EVP_PKEY *ret=NULL; if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_EVP_PKEY, bp, cb, u)) return NULL; p = data; if (strcmp(nm,PEM_STRING_RSA) == 0) ret=d2i_PrivateKey(EVP_PKEY_RSA,x,&p,len); else if (strcmp(nm,PEM_STRING_DSA) == 0) ret=d2i_PrivateKey(EVP_PKEY_DSA,x,&p,len); else if (strcmp(nm,PEM_STRING_ECPRIVATEKEY) == 0) ret=d2i_PrivateKey(EVP_PKEY_EC,x,&p,len); else if (strcmp(nm,PEM_STRING_PKCS8INF) == 0) { PKCS8_PRIV_KEY_INFO *p8inf; p8inf=d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len); if(!p8inf) goto p8err; ret = EVP_PKCS82PKEY(p8inf); if(x) { if(*x) EVP_PKEY_free((EVP_PKEY *)*x); *x = ret; } PKCS8_PRIV_KEY_INFO_free(p8inf); } else if (strcmp(nm,PEM_STRING_PKCS8) == 0) { PKCS8_PRIV_KEY_INFO *p8inf; X509_SIG *p8; int klen; char psbuf[PEM_BUFSIZE]; p8 = d2i_X509_SIG(NULL, &p, len); if(!p8) goto p8err; if (cb) klen=cb(psbuf,PEM_BUFSIZE,0,u); else klen=PEM_def_callback(psbuf,PEM_BUFSIZE,0,u); if (klen <= 0) { PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY, PEM_R_BAD_PASSWORD_READ); X509_SIG_free(p8); goto err; } p8inf = PKCS8_decrypt(p8, psbuf, klen); X509_SIG_free(p8); if(!p8inf) goto p8err; ret = EVP_PKCS82PKEY(p8inf); if(x) { if(*x) EVP_PKEY_free((EVP_PKEY *)*x); *x = ret; } PKCS8_PRIV_KEY_INFO_free(p8inf); } p8err: if (ret == NULL) PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY,ERR_R_ASN1_LIB); err: OPENSSL_free(nm); OPENSSL_cleanse(data, len); OPENSSL_free(data); return(ret); }
/* * Encrypted PKCS#8 decoder. It operates by just decrypting the given blob * into a new blob, which is returned as an EMBEDDED STORE_INFO. The whole * decoding process will then start over with the new blob. */ static OSSL_STORE_INFO *try_decode_PKCS8Encrypted(const char *pem_name, const char *pem_header, const unsigned char *blob, size_t len, void **pctx, int *matchcount, const UI_METHOD *ui_method, void *ui_data) { X509_SIG *p8 = NULL; char kbuf[PEM_BUFSIZE]; char *pass = NULL; const X509_ALGOR *dalg = NULL; const ASN1_OCTET_STRING *doct = NULL; OSSL_STORE_INFO *store_info = NULL; BUF_MEM *mem = NULL; unsigned char *new_data = NULL; int new_data_len; if (pem_name != NULL) { if (strcmp(pem_name, PEM_STRING_PKCS8) != 0) return NULL; *matchcount = 1; } if ((p8 = d2i_X509_SIG(NULL, &blob, len)) == NULL) return NULL; *matchcount = 1; if ((mem = BUF_MEM_new()) == NULL) { OSSL_STOREerr(OSSL_STORE_F_TRY_DECODE_PKCS8ENCRYPTED, ERR_R_MALLOC_FAILURE); goto nop8; } if ((pass = file_get_pass(ui_method, kbuf, PEM_BUFSIZE, "PKCS8 decrypt password", ui_data)) == NULL) { OSSL_STOREerr(OSSL_STORE_F_TRY_DECODE_PKCS8ENCRYPTED, OSSL_STORE_R_BAD_PASSWORD_READ); goto nop8; } X509_SIG_get0(p8, &dalg, &doct); if (!PKCS12_pbe_crypt(dalg, pass, strlen(pass), doct->data, doct->length, &new_data, &new_data_len, 0)) goto nop8; mem->data = (char *)new_data; mem->max = mem->length = (size_t)new_data_len; X509_SIG_free(p8); store_info = ossl_store_info_new_EMBEDDED(PEM_STRING_PKCS8INF, mem); if (store_info == NULL) { OSSL_STOREerr(OSSL_STORE_F_TRY_DECODE_PKCS8ENCRYPTED, ERR_R_MALLOC_FAILURE); goto nop8; } return store_info; nop8: X509_SIG_free(p8); BUF_MEM_free(mem); return NULL; }
int ccn_verify_signature(const unsigned char *msg, size_t size, const struct ccn_parsed_ContentObject *co, const struct ccn_pkey *verification_pubkey) { EVP_MD_CTX verc; EVP_MD_CTX *ver_ctx = &verc; X509_SIG *digest_info = NULL; MP_info *merkle_path_info = NULL; unsigned char *root_hash; size_t root_hash_size; int res; const EVP_MD *digest = EVP_md_null(); const EVP_MD *merkle_path_digest = EVP_md_null(); const unsigned char *signature_bits = NULL; size_t signature_bits_size = 0; const unsigned char *witness = NULL; size_t witness_size = 0; EVP_PKEY *pkey = (EVP_PKEY *)verification_pubkey; #ifdef DEBUG int x, h; #endif res = ccn_ref_tagged_BLOB(CCN_DTAG_SignatureBits, msg, co->offset[CCN_PCO_B_SignatureBits], co->offset[CCN_PCO_E_SignatureBits], &signature_bits, &signature_bits_size); if (res < 0) return (-1); if (co->offset[CCN_PCO_B_DigestAlgorithm] == co->offset[CCN_PCO_E_DigestAlgorithm]) { digest = EVP_sha256(); } else { /* XXX - figure out what algorithm the OID represents */ fprintf(stderr, "not a DigestAlgorithm I understand right now\n"); return (-1); } EVP_MD_CTX_init(ver_ctx); res = EVP_VerifyInit_ex(ver_ctx, digest, NULL); if (!res) return (-1); if (co->offset[CCN_PCO_B_Witness] != co->offset[CCN_PCO_E_Witness]) { /* The witness is a DigestInfo, where the octet-string therein encapsulates * a sequence of [integer (origin 1 node#), sequence of [octet-string]] * where the inner octet-string is the concatenated hashes on the merkle-path */ res = ccn_ref_tagged_BLOB(CCN_DTAG_Witness, msg, co->offset[CCN_PCO_B_Witness], co->offset[CCN_PCO_E_Witness], &witness, &witness_size); if (res < 0) return (-1); digest_info = d2i_X509_SIG(NULL, &witness, witness_size); /* digest_info->algor->algorithm->{length, data} * digest_info->digest->{length, type, data} */ /* ...2.2 is an MHT w/ SHA256 */ ASN1_OBJECT *merkle_hash_tree_oid = OBJ_txt2obj("1.2.840.113550.11.1.2.2", 1); if (0 != OBJ_cmp(digest_info->algor->algorithm, merkle_hash_tree_oid)) { fprintf(stderr, "A witness is present without an MHT OID!\n"); ASN1_OBJECT_free(merkle_hash_tree_oid); return (-1); } /* we're doing an MHT */ ASN1_OBJECT_free(merkle_hash_tree_oid); merkle_path_digest = EVP_sha256(); /* DER-encoded in the digest_info's digest ASN.1 octet string is the Merkle path info */ merkle_path_info = d2i_MP_info(NULL, (const unsigned char **)&(digest_info->digest->data), digest_info->digest->length); #ifdef DEBUG int node = ASN1_INTEGER_get(merkle_path_info->node); int hash_count = merkle_path_info->hashes->num; ASN1_OCTET_STRING *hash; fprintf(stderr, "A witness is present with an MHT OID\n"); fprintf(stderr, "This is node %d, with %d hashes\n", node, hash_count); for (h = 0; h < hash_count; h++) { hash = (ASN1_OCTET_STRING *)merkle_path_info->hashes->data[h]; fprintf(stderr, " hashes[%d] len = %d data = ", h, hash->length); for (x = 0; x < hash->length; x++) { fprintf(stderr, "%02x", hash->data[x]); } fprintf(stderr, "\n"); } #endif /* In the MHT signature case, we signed/verify the root hash */ root_hash_size = EVP_MD_size(merkle_path_digest); root_hash = calloc(1, root_hash_size); res = ccn_merkle_root_hash(msg, size, co, merkle_path_digest, merkle_path_info, root_hash, root_hash_size); res = EVP_VerifyUpdate(ver_ctx, root_hash, root_hash_size); res = EVP_VerifyFinal(ver_ctx, signature_bits, signature_bits_size, pkey); EVP_MD_CTX_cleanup(ver_ctx); } else { /* * In the simple signature case, we signed/verify from the name through * the end of the content. */ size_t signed_size = co->offset[CCN_PCO_E_Content] - co->offset[CCN_PCO_B_Name]; res = EVP_VerifyUpdate(ver_ctx, msg + co->offset[CCN_PCO_B_Name], signed_size); res = EVP_VerifyFinal(ver_ctx, signature_bits, signature_bits_size, pkey); EVP_MD_CTX_cleanup(ver_ctx); } if (res == 1) return (1); else return (0); }
int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len, unsigned char *sigbuf, unsigned int siglen, RSA *rsa) { int i,ret=0,sigtype; unsigned char *p,*s; X509_SIG *sig=NULL; if (siglen != (unsigned int)RSA_size(rsa)) { RSAerr(RSA_F_RSA_VERIFY,RSA_R_WRONG_SIGNATURE_LENGTH); return(0); } if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_verify) { return rsa->meth->rsa_verify(dtype, m, m_len, sigbuf, siglen, rsa); } s=(unsigned char *)OPENSSL_malloc((unsigned int)siglen); if (s == NULL) { RSAerr(RSA_F_RSA_VERIFY,ERR_R_MALLOC_FAILURE); goto err; } if((dtype == NID_md5_sha1) && (m_len != SSL_SIG_LENGTH) ) { RSAerr(RSA_F_RSA_VERIFY,RSA_R_INVALID_MESSAGE_LENGTH); goto err; } i=RSA_public_decrypt((int)siglen,sigbuf,s,rsa,RSA_PKCS1_PADDING); if (i <= 0) goto err; /* Special case: SSL signature */ if(dtype == NID_md5_sha1) { if((i != SSL_SIG_LENGTH) || memcmp(s, m, SSL_SIG_LENGTH)) RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE); else ret = 1; } else { p=s; sig=d2i_X509_SIG(NULL,&p,(long)i); if (sig == NULL) goto err; /* Excess data can be used to create forgeries */ if(p != s+i) { RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE); goto err; } /* Parameters to the signature algorithm can also be used to create forgeries */ if(sig->algor->parameter && ASN1_TYPE_get(sig->algor->parameter) != V_ASN1_NULL) { RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE); goto err; } sigtype=OBJ_obj2nid(sig->algor->algorithm); #ifdef RSA_DEBUG /* put a backward compatibility flag in EAY */ fprintf(stderr,"in(%s) expect(%s)\n",OBJ_nid2ln(sigtype), OBJ_nid2ln(dtype)); #endif if (sigtype != dtype) { if (((dtype == NID_md5) && (sigtype == NID_md5WithRSAEncryption)) || ((dtype == NID_md2) && (sigtype == NID_md2WithRSAEncryption))) { /* ok, we will let it through */ #if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16) fprintf(stderr,"signature has problems, re-make with post SSLeay045\n"); #endif } else { RSAerr(RSA_F_RSA_VERIFY, RSA_R_ALGORITHM_MISMATCH); goto err; } } if ( ((unsigned int)sig->digest->length != m_len) || (memcmp(m,sig->digest->data,m_len) != 0)) { RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE); } else ret=1; } err: if (sig != NULL) X509_SIG_free(sig); if (s != NULL) { OPENSSL_cleanse(s,(unsigned int)siglen); OPENSSL_free(s); } return(ret); }
int int_rsa_verify(int dtype, const unsigned char *m, unsigned int m_len, unsigned char *rm, size_t *prm_len, const unsigned char *sigbuf, size_t siglen, RSA *rsa) { int i, ret = 0, sigtype; unsigned char *s; X509_SIG *sig = NULL; if (siglen != (unsigned int)RSA_size(rsa)) { RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_WRONG_SIGNATURE_LENGTH); return (0); } if ((dtype == NID_md5_sha1) && rm) { i = RSA_public_decrypt((int)siglen, sigbuf, rm, rsa, RSA_PKCS1_PADDING); if (i <= 0) return 0; *prm_len = i; return 1; } s = OPENSSL_malloc((unsigned int)siglen); if (s == NULL) { RSAerr(RSA_F_INT_RSA_VERIFY, ERR_R_MALLOC_FAILURE); goto err; } if ((dtype == NID_md5_sha1) && (m_len != SSL_SIG_LENGTH)) { RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_MESSAGE_LENGTH); goto err; } i = RSA_public_decrypt((int)siglen, sigbuf, s, rsa, RSA_PKCS1_PADDING); if (i <= 0) goto err; /* * Oddball MDC2 case: signature can be OCTET STRING. check for correct * tag and length octets. */ if (dtype == NID_mdc2 && i == 18 && s[0] == 0x04 && s[1] == 0x10) { if (rm) { memcpy(rm, s + 2, 16); *prm_len = 16; ret = 1; } else if (memcmp(m, s + 2, 16)) RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); else ret = 1; } /* Special case: SSL signature */ if (dtype == NID_md5_sha1) { if ((i != SSL_SIG_LENGTH) || memcmp(s, m, SSL_SIG_LENGTH)) RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); else ret = 1; } else { const unsigned char *p = s; sig = d2i_X509_SIG(NULL, &p, (long)i); if (sig == NULL) goto err; /* Excess data can be used to create forgeries */ if (p != s + i || !rsa_check_digestinfo(sig, s, i)) { RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); goto err; } /* * Parameters to the signature algorithm can also be used to create * forgeries */ if (sig->algor->parameter && ASN1_TYPE_get(sig->algor->parameter) != V_ASN1_NULL) { RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); goto err; } sigtype = OBJ_obj2nid(sig->algor->algorithm); #ifdef RSA_DEBUG /* put a backward compatibility flag in EAY */ fprintf(stderr, "in(%s) expect(%s)\n", OBJ_nid2ln(sigtype), OBJ_nid2ln(dtype)); #endif if (sigtype != dtype) { RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_ALGORITHM_MISMATCH); goto err; } if (rm) { const EVP_MD *md; md = EVP_get_digestbynid(dtype); if (md && (EVP_MD_size(md) != sig->digest->length)) RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_DIGEST_LENGTH); else { memcpy(rm, sig->digest->data, sig->digest->length); *prm_len = sig->digest->length; ret = 1; } } else if (((unsigned int)sig->digest->length != m_len) || (memcmp(m, sig->digest->data, m_len) != 0)) { RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); } else ret = 1; } err: X509_SIG_free(sig); OPENSSL_clear_free(s, (unsigned int)siglen); return (ret); }
EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u) { char *nm = NULL; const unsigned char *p = NULL; unsigned char *data = NULL; long len; EVP_PKEY *ret = NULL; if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_EVP_PKEY, bp, cb, u)) return NULL; p = data; if (strcmp(nm, PEM_STRING_PKCS8INF) == 0) { PKCS8_PRIV_KEY_INFO *p8inf; p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len); if (!p8inf) goto p8err; ret = EVP_PKCS82PKEY(p8inf); if (x) { if (*x) EVP_PKEY_free((EVP_PKEY *)*x); *x = ret; } PKCS8_PRIV_KEY_INFO_free(p8inf); } else if (strcmp(nm, PEM_STRING_PKCS8) == 0) { PKCS8_PRIV_KEY_INFO *p8inf; X509_SIG *p8; int klen; char psbuf[PEM_BUFSIZE]; p8 = d2i_X509_SIG(NULL, &p, len); if (!p8) goto p8err; klen = 0; if (!cb) cb = PEM_def_callback; klen = cb(psbuf, PEM_BUFSIZE, 0, u); if (klen <= 0) { OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_PASSWORD_READ); X509_SIG_free(p8); goto err; } p8inf = PKCS8_decrypt(p8, psbuf, klen); X509_SIG_free(p8); OPENSSL_cleanse(psbuf, klen); if (!p8inf) goto p8err; ret = EVP_PKCS82PKEY(p8inf); if (x) { if (*x) EVP_PKEY_free((EVP_PKEY *)*x); *x = ret; } PKCS8_PRIV_KEY_INFO_free(p8inf); } else if (strcmp(nm, PEM_STRING_RSA) == 0) { /* TODO(davidben): d2i_PrivateKey parses PKCS#8 along with the * standalone format. This and the cases below probably should not * accept PKCS#8. */ ret = d2i_PrivateKey(EVP_PKEY_RSA, x, &p, len); } else if (strcmp(nm, PEM_STRING_EC) == 0) { ret = d2i_PrivateKey(EVP_PKEY_EC, x, &p, len); } else if (strcmp(nm, PEM_STRING_DSA) == 0) { ret = d2i_PrivateKey(EVP_PKEY_DSA, x, &p, len); } p8err: if (ret == NULL) OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB); err: OPENSSL_free(nm); OPENSSL_cleanse(data, len); OPENSSL_free(data); return (ret); }
/* PKCS12_handle_content_info parses a single PKCS#7 ContentInfo element in a * PKCS#12 structure. */ static int PKCS12_handle_content_info(CBS *content_info, unsigned depth, struct pkcs12_context *ctx) { CBS content_type, wrapped_contents, contents, content_infos; int nid, ret = 0; if (!CBS_get_asn1(content_info, &content_type, CBS_ASN1_OBJECT) || !CBS_get_asn1(content_info, &wrapped_contents, CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0)) { OPENSSL_PUT_ERROR(PKCS8, PKCS12_parse, PKCS8_R_BAD_PKCS12_DATA); goto err; } nid = OBJ_cbs2nid(&content_type); if (nid == NID_pkcs7_encrypted) { /* See https://tools.ietf.org/html/rfc2315#section-13. * * PKCS#7 encrypted data inside a PKCS#12 structure is generally an * encrypted certificate bag and it's generally encrypted with 40-bit * RC2-CBC. */ CBS version_bytes, eci, contents_type, ai, encrypted_contents; X509_ALGOR *algor = NULL; const uint8_t *inp; uint8_t *out; size_t out_len; if (!CBS_get_asn1(&wrapped_contents, &contents, CBS_ASN1_SEQUENCE) || !CBS_get_asn1(&contents, &version_bytes, CBS_ASN1_INTEGER) || /* EncryptedContentInfo, see * https://tools.ietf.org/html/rfc2315#section-10.1 */ !CBS_get_asn1(&contents, &eci, CBS_ASN1_SEQUENCE) || !CBS_get_asn1(&eci, &contents_type, CBS_ASN1_OBJECT) || /* AlgorithmIdentifier, see * https://tools.ietf.org/html/rfc5280#section-4.1.1.2 */ !CBS_get_asn1_element(&eci, &ai, CBS_ASN1_SEQUENCE) || !CBS_get_asn1(&eci, &encrypted_contents, CBS_ASN1_CONTEXT_SPECIFIC | 0)) { OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_info, PKCS8_R_BAD_PKCS12_DATA); goto err; } if (OBJ_cbs2nid(&contents_type) != NID_pkcs7_data) { OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_info, PKCS8_R_BAD_PKCS12_DATA); goto err; } inp = CBS_data(&ai); algor = d2i_X509_ALGOR(NULL, &inp, CBS_len(&ai)); if (algor == NULL) { goto err; } if (inp != CBS_data(&ai) + CBS_len(&ai)) { X509_ALGOR_free(algor); OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_info, PKCS8_R_BAD_PKCS12_DATA); goto err; } if (!pbe_crypt(algor, ctx->password, ctx->password_len, CBS_data(&encrypted_contents), CBS_len(&encrypted_contents), &out, &out_len, 0 /* decrypt */)) { X509_ALGOR_free(algor); goto err; } X509_ALGOR_free(algor); CBS_init(&content_infos, out, out_len); ret = PKCS12_handle_content_infos(&content_infos, depth + 1, ctx); OPENSSL_free(out); } else if (nid == NID_pkcs7_data) { CBS octet_string_contents; if (!CBS_get_asn1(&wrapped_contents, &octet_string_contents, CBS_ASN1_OCTETSTRING)) { OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_info, PKCS8_R_BAD_PKCS12_DATA); goto err; } ret = PKCS12_handle_content_infos(&octet_string_contents, depth + 1, ctx); } else if (nid == NID_pkcs8ShroudedKeyBag) { /* See ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-12/pkcs-12v1.pdf, section * 4.2.2. */ const uint8_t *inp = CBS_data(&wrapped_contents); PKCS8_PRIV_KEY_INFO *pki = NULL; X509_SIG *encrypted = NULL; if (*ctx->out_key) { OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_info, PKCS8_R_MULTIPLE_PRIVATE_KEYS_IN_PKCS12); goto err; } /* encrypted isn't actually an X.509 signature, but it has the same * structure as one and so |X509_SIG| is reused to store it. */ encrypted = d2i_X509_SIG(NULL, &inp, CBS_len(&wrapped_contents)); if (encrypted == NULL) { OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_info, PKCS8_R_BAD_PKCS12_DATA); goto err; } if (inp != CBS_data(&wrapped_contents) + CBS_len(&wrapped_contents)) { OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_info, PKCS8_R_BAD_PKCS12_DATA); X509_SIG_free(encrypted); goto err; } pki = PKCS8_decrypt_pbe(encrypted, ctx->password, ctx->password_len); X509_SIG_free(encrypted); if (pki == NULL) { goto err; } *ctx->out_key = EVP_PKCS82PKEY(pki); PKCS8_PRIV_KEY_INFO_free(pki); if (ctx->out_key == NULL) { goto err; } ret = 1; } else if (nid == NID_certBag) { CBS cert_bag, cert_type, wrapped_cert, cert; if (!CBS_get_asn1(&wrapped_contents, &cert_bag, CBS_ASN1_SEQUENCE) || !CBS_get_asn1(&cert_bag, &cert_type, CBS_ASN1_OBJECT) || !CBS_get_asn1(&cert_bag, &wrapped_cert, CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) || !CBS_get_asn1(&wrapped_cert, &cert, CBS_ASN1_OCTETSTRING)) { OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_info, PKCS8_R_BAD_PKCS12_DATA); goto err; } if (OBJ_cbs2nid(&cert_type) == NID_x509Certificate) { const uint8_t *inp = CBS_data(&cert); X509 *x509 = d2i_X509(NULL, &inp, CBS_len(&cert)); if (!x509) { OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_info, PKCS8_R_BAD_PKCS12_DATA); goto err; } if (inp != CBS_data(&cert) + CBS_len(&cert)) { OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_info, PKCS8_R_BAD_PKCS12_DATA); X509_free(x509); goto err; } if (0 == sk_X509_push(ctx->out_certs, x509)) { X509_free(x509); goto err; } } ret = 1; } else { /* Unknown element type - ignore it. */ ret = 1; } err: return ret; }
int int_rsa_verify(int dtype, const unsigned char *m, unsigned int m_len, unsigned char *rm, size_t *prm_len, const unsigned char *sigbuf, size_t siglen, RSA *rsa) { int i,ret=0,sigtype; unsigned char *s; X509_SIG *sig=NULL; if (siglen != (unsigned int)RSA_size(rsa)) { RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_WRONG_SIGNATURE_LENGTH); return(0); } if((dtype == NID_md5_sha1) && rm) { i = RSA_public_decrypt((int)siglen, sigbuf,rm,rsa,RSA_PKCS1_PADDING); if (i <= 0) return 0; *prm_len = i; return 1; } s=(unsigned char *)OPENSSL_malloc((unsigned int)siglen); if (s == NULL) { RSAerr(RSA_F_INT_RSA_VERIFY,ERR_R_MALLOC_FAILURE); goto err; } if((dtype == NID_md5_sha1) && (m_len != SSL_SIG_LENGTH) ) { RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_INVALID_MESSAGE_LENGTH); goto err; } i=RSA_public_decrypt((int)siglen,sigbuf,s,rsa,RSA_PKCS1_PADDING); if (i <= 0) goto err; /* Special case: SSL signature */ if(dtype == NID_md5_sha1) { if((i != SSL_SIG_LENGTH) || TINYCLR_SSL_MEMCMP(s, m, SSL_SIG_LENGTH)) RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE); else ret = 1; } else { const unsigned char *p=s; sig=d2i_X509_SIG(NULL,&p,(long)i); if (sig == NULL) goto err; /* Excess data can be used to create forgeries */ if(p != s+i) { RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE); goto err; } /* Parameters to the signature algorithm can also be used to create forgeries */ if(sig->algor->parameter && ASN1_TYPE_get(sig->algor->parameter) != V_ASN1_NULL) { RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE); goto err; } sigtype=OBJ_obj2nid(sig->algor->algorithm); #ifdef RSA_DEBUG /* put a backward compatibility flag in EAY */ TINYCLR_SSL_FPRINTF(OPENSSL_TYPE__FILE_STDERR,"in(%s) expect(%s)\n",OBJ_nid2ln(sigtype), OBJ_nid2ln(dtype)); #endif if (sigtype != dtype) { if (((dtype == NID_md5) && (sigtype == NID_md5WithRSAEncryption)) || ((dtype == NID_md2) && (sigtype == NID_md2WithRSAEncryption))) { /* ok, we will let it through */ #if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16) TINYCLR_SSL_FPRINTF(OPENSSL_TYPE__FILE_STDERR,"signature has problems, re-make with post SSLeay045\n"); #endif } else { RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_ALGORITHM_MISMATCH); goto err; } } if (rm) { const EVP_MD *md; md = EVP_get_digestbynid(dtype); if (md && (EVP_MD_size(md) != sig->digest->length)) RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_DIGEST_LENGTH); else { TINYCLR_SSL_MEMCPY(rm, sig->digest->data, sig->digest->length); *prm_len = sig->digest->length; ret = 1; } } else if (((unsigned int)sig->digest->length != m_len) || (TINYCLR_SSL_MEMCMP(m,sig->digest->data,m_len) != 0)) { RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE); } else ret=1; } err: if (sig != NULL) X509_SIG_free(sig); if (s != NULL) { OPENSSL_cleanse(s,(unsigned int)siglen); OPENSSL_free(s); } return(ret); }
int int_rsa_verify(int dtype, const unsigned char *m, unsigned int m_len, unsigned char *rm, size_t *prm_len, const unsigned char *sigbuf, size_t siglen, RSA *rsa) { int i, ret = 0, sigtype; unsigned char *s; X509_SIG *sig = NULL; if (siglen != (unsigned int)RSA_size(rsa)) { RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_WRONG_SIGNATURE_LENGTH); return 0; } if ((dtype == NID_md5_sha1) && rm) { i = RSA_public_decrypt((int)siglen, sigbuf, rm, rsa, RSA_PKCS1_PADDING); if (i <= 0) return 0; *prm_len = i; return 1; } s = malloc(siglen); if (s == NULL) { RSAerr(RSA_F_INT_RSA_VERIFY, ERR_R_MALLOC_FAILURE); goto err; } if (dtype == NID_md5_sha1 && m_len != SSL_SIG_LENGTH) { RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_MESSAGE_LENGTH); goto err; } i = RSA_public_decrypt((int)siglen, sigbuf, s, rsa, RSA_PKCS1_PADDING); if (i <= 0) goto err; /* Special case: SSL signature */ if (dtype == NID_md5_sha1) { if (i != SSL_SIG_LENGTH || memcmp(s, m, SSL_SIG_LENGTH)) RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); else ret = 1; } else { const unsigned char *p = s; sig = d2i_X509_SIG(NULL, &p, (long)i); if (sig == NULL) goto err; /* Excess data can be used to create forgeries */ if (p != s + i) { RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); goto err; } /* Parameters to the signature algorithm can also be used to create forgeries */ if (sig->algor->parameter && ASN1_TYPE_get(sig->algor->parameter) != V_ASN1_NULL) { RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); goto err; } sigtype = OBJ_obj2nid(sig->algor->algorithm); if (sigtype != dtype) { RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_ALGORITHM_MISMATCH); goto err; } if (rm) { const EVP_MD *md; md = EVP_get_digestbynid(dtype); if (md && (EVP_MD_size(md) != sig->digest->length)) RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_DIGEST_LENGTH); else { memcpy(rm, sig->digest->data, sig->digest->length); *prm_len = sig->digest->length; ret = 1; } } else if ((unsigned int)sig->digest->length != m_len || memcmp(m, sig->digest->data, m_len) != 0) { RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); } else ret = 1; } err: if (sig != NULL) X509_SIG_free(sig); if (s != NULL) { explicit_bzero(s, (unsigned int)siglen); free(s); } return ret; }
int ndn_verify_signature(const unsigned char *msg, size_t size, const struct ndn_parsed_ContentObject *co, const struct ndn_pkey *verification_pubkey) { EVP_MD_CTX verc; EVP_MD_CTX *ver_ctx = &verc; X509_SIG *digest_info = NULL; const unsigned char *dd = NULL; MP_info *merkle_path_info = NULL; unsigned char *root_hash = NULL; size_t root_hash_size; int res; const EVP_MD *digest = NULL; const EVP_MD *merkle_path_digest = NULL; const unsigned char *signature_bits = NULL; size_t signature_bits_size = 0; const unsigned char *witness = NULL; size_t witness_size = 0; const unsigned char *digest_algorithm = NULL; size_t digest_algorithm_size; EVP_PKEY *pkey = (EVP_PKEY *)verification_pubkey; res = ndn_ref_tagged_BLOB(NDN_DTAG_SignatureBits, msg, co->offset[NDN_PCO_B_SignatureBits], co->offset[NDN_PCO_E_SignatureBits], &signature_bits, &signature_bits_size); if (res < 0) return (-1); if (co->offset[NDN_PCO_B_DigestAlgorithm] == co->offset[NDN_PCO_E_DigestAlgorithm]) { digest_algorithm = (const unsigned char *)NDN_SIGNING_DEFAULT_DIGEST_ALGORITHM; } else { /* figure out what algorithm the OID represents */ res = ndn_ref_tagged_string(NDN_DTAG_DigestAlgorithm, msg, co->offset[NDN_PCO_B_DigestAlgorithm], co->offset[NDN_PCO_E_DigestAlgorithm], &digest_algorithm, &digest_algorithm_size); if (res < 0) return (-1); /* NOTE: since the element closer is a 0, and the element is well formed, * the string will be null terminated */ } digest = md_from_digest_and_pkey((const char *)digest_algorithm, verification_pubkey); EVP_MD_CTX_init(ver_ctx); res = EVP_VerifyInit_ex(ver_ctx, digest, NULL); if (!res) { EVP_MD_CTX_cleanup(ver_ctx); return (-1); } if (co->offset[NDN_PCO_B_Witness] != co->offset[NDN_PCO_E_Witness]) { /* The witness is a DigestInfo, where the octet-string therein encapsulates * a sequence of [integer (origin 1 node#), sequence of [octet-string]] * where the inner octet-string is the concatenated hashes on the merkle-path */ res = ndn_ref_tagged_BLOB(NDN_DTAG_Witness, msg, co->offset[NDN_PCO_B_Witness], co->offset[NDN_PCO_E_Witness], &witness, &witness_size); if (res < 0) { EVP_MD_CTX_cleanup(ver_ctx); return (-1); } digest_info = d2i_X509_SIG(NULL, &witness, witness_size); /* digest_info->algor->algorithm->{length, data} * digest_info->digest->{length, type, data} */ /* ...2.2 is an MHT w/ SHA256 */ ASN1_OBJECT *merkle_hash_tree_oid = OBJ_txt2obj("1.2.840.113550.11.1.2.2", 1); if (0 != OBJ_cmp(digest_info->algor->algorithm, merkle_hash_tree_oid)) { fprintf(stderr, "A witness is present without an MHT OID!\n"); EVP_MD_CTX_cleanup(ver_ctx); ASN1_OBJECT_free(merkle_hash_tree_oid); return (-1); } /* we're doing an MHT */ ASN1_OBJECT_free(merkle_hash_tree_oid); merkle_path_digest = EVP_sha256(); /* DER-encoded in the digest_info's digest ASN.1 octet string is the Merkle path info */ dd = digest_info->digest->data; merkle_path_info = d2i_MP_info(NULL, &dd, digest_info->digest->length); X509_SIG_free(digest_info); #ifdef DEBUG int x,h; int node = ASN1_INTEGER_get(merkle_path_info->node); int hash_count = sk_ASN1_OCTET_STRING_num(merkle_path_info->hashes); ASN1_OCTET_STRING *hash; fprintf(stderr, "A witness is present with an MHT OID\n"); fprintf(stderr, "This is node %d, with %d hashes\n", node, hash_count); for (h = 0; h < hash_count; h++) { hash = sk_ASN1_OCTET_STRING_value(merkle_path_info->hashes, h); fprintf(stderr, " hashes[%d] len = %d data = ", h, hash->length); for (x = 0; x < hash->length; x++) { fprintf(stderr, "%02x", hash->data[x]); } fprintf(stderr, "\n"); } #endif /* In the MHT signature case, we signed/verify the root hash */ root_hash_size = EVP_MD_size(merkle_path_digest); root_hash = calloc(1, root_hash_size); res = ndn_merkle_root_hash(msg, size, co, merkle_path_digest, merkle_path_info, root_hash, root_hash_size); MP_info_free(merkle_path_info); if (res < 0) { EVP_MD_CTX_cleanup(ver_ctx); free(root_hash); return(-1); } res = EVP_VerifyUpdate(ver_ctx, root_hash, root_hash_size); free(root_hash); if (res == 0) { EVP_MD_CTX_cleanup(ver_ctx); return(-1); } res = EVP_VerifyFinal(ver_ctx, signature_bits, signature_bits_size, pkey); EVP_MD_CTX_cleanup(ver_ctx); } else { /* * In the simple signature case, we signed/verify from the name through * the end of the content. */ size_t signed_size = co->offset[NDN_PCO_E_Content] - co->offset[NDN_PCO_B_Name]; res = EVP_VerifyUpdate(ver_ctx, msg + co->offset[NDN_PCO_B_Name], signed_size); if (res == 0) { EVP_MD_CTX_cleanup(ver_ctx); return(-1); } res = EVP_VerifyFinal(ver_ctx, signature_bits, signature_bits_size, pkey); EVP_MD_CTX_cleanup(ver_ctx); } return (res); }