QT中使用OPENSSL库的一些问题及解决(一)
问题场景:
读取pem格式证书及私钥文件用于自签发证书。
思路及问题:
一个自然的想法就是使用
X509 *PEM_read_X509(FILE *fp, X509 **x, pem_password_cb *cb, void *u);
EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u);
而要使用这两个函数,就要先使用C语言的文件读写获取文件指针,即
FILE *fp=fopen("certs/subca.pem", "r");//subca.pem放在源代码目录下的certs文件夹中
而此时就会出现一个问题——找不到文件,读取失败。
而使用绝对路径是可以成功的,显然问题在于QT中对于相对路径的理解。查找资料后发现,QT的当前目录默认在可执行文件(.exe文件)所在的文件夹(就是使用QDir::current()返回的路径),如果将certs文件夹放到该可执行文件所在目录下,那么上述语句可以成功。
但是由于该项目源代码需要上传至github,所以还是需要将文件放到源代码目录下,最好还是能直接读取到源文件目录下的文件。
于是想到把文件添加到资源中(resource),此时文件的路径变为:
:/certs/subca.pem // 在resource中 :/会被解析成绝对路径,且是只读的
这里在QT中会被解析成绝对路径,然而,该写法仅能用于QT系函数,第三方库函数无法解析。
解决及总结
最终解决的思路是在读文件阶段绕过fopen(),使用QT中的文件读取,但是此时没有文件指针,所以我们将读到的内容放到BIO结构中,然后使用
EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u);
X509 *PEM_read_bio_X509(BIO *bp, X509 **x, pem_password_cb *cb, void *u);
即可。
总结:
- QT中的相对路径是基于可执行文件目录,而非源文件目录。
- 添加进resource中的文件路径会被解析成绝对路径,且仅能在QT系函数中解析。