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 |
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(); |
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); |