C语言调用OpenSSL修改X509证书扩展后更改未生效如何解决
代码错误点及修复方案
核心错误点
- 操作了不可修改的const证书对象:你调用
parse_certificate返回的是const X509 *cert,const修饰的对象本身就是禁止修改的,你所有删除扩展、添加SCT的操作都作用在了这个只读对象上,修改行为未定义,实际上根本不会生效。你代码中X509_cmp( cert, certRef)已经返回0并打印FAILED!!!,就是修改未生效的明确信号。 - 错误操作只读扩展栈:
X509_get0_extensions返回的是X509内部的const STACK_OF(X509_EXTENSION),属于只读的内部引用,你直接对它调用X509v3_delete_ext属于非法操作,不会修改X509对象本身的扩展列表。正确的做法是直接使用X509对象的修改接口:用X509_get_ext_by_NID查找扩展索引,再用X509_delete_ext删除对应位置的扩展。 - 输出的证书对象错误:你最后调用
PEM_write_bio_X509输出的是原始的只读cert对象,而不是你修改后的对象,自然输出的内容和原始证书完全一致。 - 验证逻辑错误:你最后验证poison扩展是否存在时,直接把
X509_get_ext_by_NID的返回值(如果扩展已删除会返回-1)传入X509_get_ext,会必然返回空指针,导致你误以为操作失败,实际这是验证逻辑写反了:如果my_idx2 == -1才代表poison扩展已经被成功删除。
核心修复代码示例
// 1. 操作dup出来的非const对象certRef,不要操作原始只读cert int poison_idx; while ((poison_idx = X509_get_ext_by_NID(certRef, NID_ct_precert_poison, -1)) != -1) { X509_EXTENSION *ext = X509_delete_ext(certRef, poison_idx); X509_EXTENSION_free(ext); printf("删除一个poison扩展,索引:%d\n", poison_idx); } // 2. 把SCT扩展添加到修改后的certRef上 if( X509_add_ext(certRef, extSCT, -1)) { printf("Extension added\n"); X509_EXTENSION_free(extSCT); } // 3. 输出修改后的certRef,不是原始cert PEM_write_bio_X509(Cout, certRef); // 4. 正确验证poison扩展是否删除 int my_idx2 = X509_get_ext_by_NID(certRef, NID_ct_precert_poison, -1); if (my_idx2 == -1) { printf("poison扩展已成功删除\n"); } else { printf("poison扩展仍存在,索引:%d\n", my_idx2); }
内容的提问来源于stack exchange,提问作者PhoenixBlue
相关产品推荐
相关产品推荐

