javacommons/security/src/midpauthenticationmoduleimpl.cpp
changeset 79 2f468c1958d0
parent 76 4ad59aaee882
equal deleted inserted replaced
76:4ad59aaee882 79:2f468c1958d0
    52     {0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1a,0x05,0x00,0x04,0x14};
    52     {0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1a,0x05,0x00,0x04,0x14};
    53 
    53 
    54 /* forward declarations of local/private methods */
    54 /* forward declarations of local/private methods */
    55 static int verify_callback(int, X509_STORE_CTX *);
    55 static int verify_callback(int, X509_STORE_CTX *);
    56 int getErrCode(int);
    56 int getErrCode(int);
    57 int verifyCertChain(char **, int, const unsigned char *, int, vector<string> CAs, char *, char *, CERT_DETAILS*);
    57 int verifyCertChain(char **, int, const unsigned char *, int, vector<string> CAs, char *, char *, char *, CERT_DETAILS*);
    58 
    58 
    59 JNIEXPORT jobjectArray JNICALL Java_com_nokia_mj_impl_security_midp_authentication_AuthenticationModule__1validateChainsAndSignatures
    59 JNIEXPORT jobjectArray JNICALL Java_com_nokia_mj_impl_security_midp_authentication_AuthenticationModule__1validateChainsAndSignatures
    60 (JNIEnv * env, jobject, jobjectArray authInfos)
    60 (JNIEnv * env, jobject, jobjectArray authInfos)
    61 {
    61 {
    62     // get the roots from JavaCertStore
    62     // get the roots from JavaCertStore
    75     AUTH_CREDENTIALS * auth_credentials = NULL;
    75     AUTH_CREDENTIALS * auth_credentials = NULL;
    76     CERT_DETAILS* details = NULL;
    76     CERT_DETAILS* details = NULL;
    77     AUTH_INFO* authInfo = NULL;
    77     AUTH_INFO* authInfo = NULL;
    78     char * jar_hash = NULL;
    78     char * jar_hash = NULL;
    79     char * root_hash = NULL;
    79     char * root_hash = NULL;
       
    80     char * root_id = NULL;
    80     int validation_result = KDefault;
    81     int validation_result = KDefault;
    81     for (int i=0; i<len; i++)
    82     for (int i=0; i<len; i++)
    82     {
    83     {
    83         // validate the chain
    84         // validate the chain
    84         authInfo = new AUTH_INFO();
    85         authInfo = new AUTH_INFO();
    85         SecurityUtils::getAuthInfo(env, authInfos, i, authInfo);
    86         SecurityUtils::getAuthInfo(env, authInfos, i, authInfo);
    86         jar_hash = new char[2*SHA_1_DIGEST_LEN + 1];
    87         jar_hash = new char[2*SHA_1_DIGEST_LEN + 1];
    87         jar_hash[0] = '\0';
    88         jar_hash[0] = '\0';
    88         root_hash = new char[MD5_DIGEST_LEN + 1];
    89         root_hash = new char[MD5_DIGEST_LEN + 1];
    89         root_hash[0] = '\0';
    90         root_hash[0] = '\0';
       
    91         root_id = new char[2*SHA_1_DIGEST_LEN + 1];
       
    92         root_id[0] = '\0';
    90         details = new CERT_DETAILS();
    93         details = new CERT_DETAILS();
    91         int chain_verification_result = verifyCertChain(
    94         int chain_verification_result = verifyCertChain(
    92                                             authInfo->cert_chain, authInfo->cert_chain_len,
    95                                             authInfo->cert_chain, authInfo->cert_chain_len,
    93                                             (const unsigned char *)authInfo->signature,
    96                                             (const unsigned char *)authInfo->signature,
    94                                             authInfo->signature_len, CAs, jar_hash,
    97                                             authInfo->signature_len, CAs, jar_hash,
    95                                             root_hash, details);
    98                                             root_hash, root_id, details);
    96         if (chain_verification_result == KCertAndSignatureOk)
    99         if (chain_verification_result == KCertAndSignatureOk)
    97         {
   100         {
    98             validation_result = KCertAndSignatureOk;
   101             validation_result = KCertAndSignatureOk;
    99             auth_credentials = new AUTH_CREDENTIALS();
   102             auth_credentials = new AUTH_CREDENTIALS();
   100             auth_credentials->jar_hash = new char[2*SHA_1_DIGEST_LEN + 1];
   103             auth_credentials->jar_hash = new char[2*SHA_1_DIGEST_LEN + 1];
   101             auth_credentials->root_hash = new char[MD5_DIGEST_LEN + 1];
   104             auth_credentials->root_hash = new char[MD5_DIGEST_LEN + 1];
       
   105             auth_credentials->root_id = new char[2*SHA_1_DIGEST_LEN + 1];
   102             memmove(auth_credentials->jar_hash, jar_hash, 2*SHA_1_DIGEST_LEN + 1);
   106             memmove(auth_credentials->jar_hash, jar_hash, 2*SHA_1_DIGEST_LEN + 1);
   103             memmove(auth_credentials->root_hash, root_hash, MD5_DIGEST_LEN + 1);
   107             memmove(auth_credentials->root_hash, root_hash, MD5_DIGEST_LEN + 1);
       
   108             memmove(auth_credentials->root_id, root_id, 2*SHA_1_DIGEST_LEN + 1);
   104             auth_credentials->chain_index = i+1;
   109             auth_credentials->chain_index = i+1;
   105             auth_credentials->signing_cert = details;
   110             auth_credentials->signing_cert = details;
   106             all_auth_credentials.push_back(auth_credentials);
   111             all_auth_credentials.push_back(auth_credentials);
   107             auth_credentials->predefined_domain_category = details->domain_category;
   112             auth_credentials->predefined_domain_category = details->domain_category;
   108             // the domain info is coming shortly
   113             // the domain info is coming shortly
   113             details = NULL;
   118             details = NULL;
   114             delete[] jar_hash;
   119             delete[] jar_hash;
   115             jar_hash = NULL;
   120             jar_hash = NULL;
   116             delete[] root_hash;
   121             delete[] root_hash;
   117             root_hash = NULL;
   122             root_hash = NULL;
       
   123             delete[] root_id;
       
   124             root_id = NULL;
   118             // just record the failure of the chain validation
   125             // just record the failure of the chain validation
   119             if (chain_verification_result > validation_result)
   126             if (chain_verification_result > validation_result)
   120             {
   127             {
   121                 validation_result = chain_verification_result;
   128                 validation_result = chain_verification_result;
   122             }
   129             }
   177         all_auth_credentials[i]->domain_name = NULL;
   184         all_auth_credentials[i]->domain_name = NULL;
   178         all_auth_credentials[i]->domain_category = NULL;
   185         all_auth_credentials[i]->domain_category = NULL;
   179         std::string protection_domain_name;
   186         std::string protection_domain_name;
   180         std::string protection_domain_category;
   187         std::string protection_domain_category;
   181         JavaCertStoreHandler::retrieveRootProtDomainInfo(
   188         JavaCertStoreHandler::retrieveRootProtDomainInfo(
   182             all_auth_credentials[i]->root_hash,
   189             all_auth_credentials[i]->root_id,
   183             protection_domain_name,
   190             protection_domain_name,
   184             protection_domain_category);
   191             protection_domain_category);
       
   192         if (strcmp(protection_domain_name.c_str(),"") == 0)
       
   193         {
       
   194             // clean up the root_id
       
   195             delete[] all_auth_credentials[i]->root_id;
       
   196             all_auth_credentials[i]->root_id = NULL;
       
   197             JavaCertStoreHandler::retrieveRootProtDomainInfo(
       
   198                 all_auth_credentials[i]->root_hash,
       
   199                 protection_domain_name,
       
   200                 protection_domain_category);
       
   201         }
   185         if (strcmp(protection_domain_name.c_str(),""))
   202         if (strcmp(protection_domain_name.c_str(),""))
   186         {
   203         {
   187             // DeveloperCertificates: if domain_category is manufacturer and we have predefined_domain_category use the predefined one
   204             // DeveloperCertificates: if domain_category is manufacturer and we have predefined_domain_category use the predefined one
   188             // Get the domain constants from ApplicationInfo&policy
   205             // Get the domain constants from ApplicationInfo&policy
   189             if ((strcmp(protection_domain_category.c_str(),"MFD") == 0
   206             if ((strcmp(protection_domain_category.c_str(),"MFD") == 0
   399 }
   416 }
   400 
   417 
   401 int verifyCertChain(char **cert_chain, int no_certs,
   418 int verifyCertChain(char **cert_chain, int no_certs,
   402                     const unsigned char * sig, int sig_len,
   419                     const unsigned char * sig, int sig_len,
   403                     vector<string> CAs, char * jar_hash,
   420                     vector<string> CAs, char * jar_hash,
   404                     char * root_hash, CERT_DETAILS* details)
   421                     char * root_hash, char * root_id, CERT_DETAILS* details)
   405 {
   422 {
   406     X509 *end_entity_cert;
   423     X509 *end_entity_cert;
   407     X509_STORE_CTX *x509_ctx = NULL;
   424     X509_STORE_CTX *x509_ctx = NULL;
   408     X509_STORE *x509_store = NULL;
   425     X509_STORE *x509_store = NULL;
   409     STACK_OF(X509) *validated_certs_st = sk_X509_new_null();
   426     STACK_OF(X509) *validated_certs_st = sk_X509_new_null();
   492                         user_cert = SecurityUtils::readCert(cert_chain[no_certs-1], strlen(cert_chain[no_certs-1]), PEM);
   509                         user_cert = SecurityUtils::readCert(cert_chain[no_certs-1], strlen(cert_chain[no_certs-1]), PEM);
   493                     }
   510                     }
   494                     if (user_cert != NULL)
   511                     if (user_cert != NULL)
   495                     {
   512                     {
   496                         sprintf(root_hash,"%08lX",X509_issuer_name_hash(user_cert));
   513                         sprintf(root_hash,"%08lX",X509_issuer_name_hash(user_cert));
       
   514                         SecurityUtils::computePublicKeyHash(user_cert, root_id);
   497                         X509_free(user_cert);
   515                         X509_free(user_cert);
   498                         ret_code = KCertAndSignatureOk;
   516                         ret_code = KCertAndSignatureOk;
   499                     }
   517                     }
   500                 }
   518                 }
   501             }
   519             }
   542             {
   560             {
   543                 sprintf(root_hash,"%08lX",X509_issuer_name_hash(root));
   561                 sprintf(root_hash,"%08lX",X509_issuer_name_hash(root));
   544                 // no need to free the root explicitly since it will be 
   562                 // no need to free the root explicitly since it will be 
   545                 // freed when freeing all the roots from roots_certs_st 
   563                 // freed when freeing all the roots from roots_certs_st 
   546                 // stack
   564                 // stack
       
   565                 SecurityUtils::computePublicKeyHash(root, root_id);
   547             }
   566             }
   548         }
   567         }
   549         // add the '\0'
   568         // add the '\0'
   550         root_hash[MD5_DIGEST_LEN] = '\0';
   569         root_hash[MD5_DIGEST_LEN] = '\0';
       
   570         root_id[SHA_1_DIGEST_LEN] = '\0';
   551 
   571 
   552         // 1. get the public key of the signing cert
   572         // 1. get the public key of the signing cert
   553         // 2. decode the provided signature using the signing cert's public key
   573         // 2. decode the provided signature using the signing cert's public key
   554         // 3. parse the digest/decrypted signature
   574         // 3. parse the digest/decrypted signature
   555         EVP_PKEY *pkey = X509_get_pubkey(end_entity_cert);
   575         EVP_PKEY *pkey = X509_get_pubkey(end_entity_cert);