0

ファイルtestSmimeMsg.txtに次のようなメッセージがあります:

ABC is our biggest acquisition ever and as you can imagine, customers
and partners alike are eager to hear how we plan to integrate it into
XYZ.  Specifically, how are we going to bring the two traditionally
separate silos of desktop and mobile together?
To help explain our vision for uniting we released a
video describing our architecture and
technology integration plans.  Definitely watch the video to learn more,
and the rest of this blog will give you a summary of our plans and a bit
more color on certain areas.

次のコマンドを使用して、明確な署名付きメッセージを作成します。

$ openssl smime -sign -in testSmimeMsg.txt -out testSmimeClearTextMessage.txt -signer sender.pem

sender.pem は .p12 ファイルから生成され、CERTIFICATE および RSA PRIVATE KEY コンテンツを含みます。次に、次のコマンドを使用して、作成したばかりの署名付きメッセージを確認します。

$ openssl smime -verify -in testSmimeClearTextMessage.txt -noverify -out testSmimeVerifiedClearTextMessage.txt

結果は検証成功で、testSmimeVerifiedClearTextMessage.txt の内容は testSmimeMsg.txt と同じです。完全!ここで、PKCS7_verify() メソッドで同じことを確認したいとしましょう。Cコード

jbyteArray aw_SMIME_Verify_Signature_And_Get_Message(JNIEnv *env, jobject obj, jbyteArray signedMsg, jstring senderCertPath, jstring rootCertPath)
{
    //SenderCertPath and rootCertPath are currently NULL. For now, I just want openssl
    //to extract the signer cert from message and verify message. Root certificate and chain
    //of trust verification etc is ignored for now.

    jbyteArray cmsContent = NULL;


    PKCS7 *pkcs7 = NULL;

    OpenSSL_add_all_algorithms();
    ERR_load_crypto_strings();
    ERR_load_X509_strings();
    ERR_load_PKCS7_strings();
    ERR_load_BIO_strings();

    pkcs7 = getP7FromEncryptedMessage_SMIME(env, signedMsg); //this works. pkcs7 is non null.

    if (pkcs7 == NULL) {
        LOGE ("aw_SMIME_Verify_Signature_And_Get_Message: Error reading p7 from message. Returning");
        goto exit_free;
    }
    cmsContent = verify_Signature_And_Get_Message(env, pkcs7, senderCertPath, rootCertPath);

    exit_free:
    if (pkcs7) {
        PKCS7_free(pkcs7);
        pkcs7 = NULL;
    }

    return cmsContent;
}

------------------------------
PKCS7 *getP7FromEncryptedMessage_SMIME(JNIEnv *env, jbyteArray encryptedSMIMEMessage) {

    BIO *in = NULL;
    int encryptedMessageLength = 0;
    const unsigned char *encryptedBuf = NULL;
    PKCS7 *p7 = NULL;

    //obtain the p7 structure from the encrypted message
    encryptedMessageLength = env->GetArrayLength(encryptedSMIMEMessage);                    //get size of encrypted message byte[]
    encryptedBuf = (const unsigned char *)env->GetByteArrayElements(encryptedSMIMEMessage, 0);                                              //create a buffer of that size
    in = BIO_new(BIO_s_mem());
    BIO_set_mem_eof_return(in, 0);
    BIO_write(in, encryptedBuf, encryptedMessageLength);                                    //create a BIO with the char* of encrypted message

    p7 = SMIME_read_PKCS7(in, NULL);                                            //get the p7 structure

    if(in) {
        BIO_free(in);
    }
    if (encryptedBuf) {
        env->ReleaseByteArrayElements(encryptedSMIMEMessage, (jbyte *)encryptedBuf, 0);
    }

    return p7;

}
----------------------
jbyteArray verify_Signature_And_Get_Message(JNIEnv *env, PKCS7 *pkcs7, jstring senderCertPath, jstring rootCertPath)
{
    X509* rootCert = NULL;
    X509* senderCert = NULL;
    STACK_OF(X509) *st1 = NULL;
    X509_STORE* m_store = NULL;
    BIO *out = BIO_new(BIO_s_mem());
    BIO_set_fp(out, stdout, BIO_NOCLOSE);
    BUF_MEM *bptr = NULL;
    jbyteArray cmsContent = NULL;
    int cmsLen = 0;

    if(rootCertPath != NULL) {
        rootCert = getCertificateFromPath(env, rootCertPath);
        m_store = X509_STORE_new();
        //TODO: check what to be in cert store
        X509_STORE_add_cert(m_store,rootCert);
    }

    if(senderCertPath != NULL) {
        senderCert = getCertificateFromPath(env, senderCertPath);
        st1 = sk_X509_new_null();
        sk_X509_push(st1, senderCert);
    }
    //st1 and m_store are NULL as they are not used for now.
    int verifyResult = PKCS7_verify( pkcs7, st1, m_store, NULL, out, PKCS7_NOVERIFY);
    if(verifyResult != 1) {   //FAILS HERE!!!!
        LOGE ("verify_Signature_And_Get_Message: Error verifying signer certificate. Returning");
        LOGE(ERR_error_string(ERR_get_error(), NULL));
        goto exit_free;
    }
    BIO_get_mem_ptr(out, &bptr);

    cmsLen = bptr->length;
    cmsContent = env->NewByteArray(cmsLen);
    env->SetByteArrayRegion(cmsContent, 0, cmsLen, (jbyte *)bptr->data);

    exit_free:
    if (serverCert) {
        X509_free(serverCert);
        serverCert = NULL;
    }
    if (rootCert) {
        X509_free(rootCert);
        rootCert = NULL;
    }
    if (m_store) {
        X509_STORE_free(m_store);
        m_store = NULL;
    }
    if (st1) {
        sk_X509_pop_free(st1, X509_free);
    }
    if (out) {
        BIO_free_all(out);
        out = NULL;
    }

    return cmsContent;
}

実行すると、エラーが発生します:

 verify_Signature_And_Get_Message: Error verifying signer certificate. Returning
 error:2107507A:PKCS7 routines:PKCS7_verify:no content

誰かが何が悪いのか教えてもらえますか? コードを変更せずに署名付きデータメッセージを渡すと、機能することに注意してください。検証が成功し、プレーンテキスト データが返されますが、クリア署名されたデータを送信すると失敗します。助けてください。

4

1 に答える 1