📄 security.cxx
字号:
Security::CertificateInfoContainerBaseSecurity::getRootCertDescriptions() const{ // !kh! // need to be implemented. assert(0); // TODO return CertificateInfoContainer();}voidBaseSecurity::addRootCertPEM(const Data& x509PEMEncodedRootCerts){ assert( mRootTlsCerts && mRootSslCerts );#if 1 addCertPEM(RootCert,Data::Empty,x509PEMEncodedRootCerts,false);#else assert( !x509PEMEncodedRootCerts.empty() ); static X509_LOOKUP_METHOD x509_pemstring_lookup = { "Load cert from PEM string into cache", NULL, /* new */ NULL, /* free */ NULL, /* init */ NULL, /* shutdown */ pemstring_ctrl,/* ctrl */ NULL, /* get_by_subject */ NULL, /* get_by_issuer_serial */ NULL, /* get_by_fingerprint */ NULL, /* get_by_alias */ }; if (mRootCerts == 0) { mRootCerts = X509_STORE_new(); } assert( mRootCerts ); X509_LOOKUP* lookup = X509_STORE_add_lookup(mRootCerts, &x509_pemstring_lookup); if (lookup == NULL) throw Exception("Error in BaseSecurity::addRootCertPEM()", __FILE__,__LINE__); // !kh! // bug, no error handling here. X509_LOOKUP_ctrl(lookup, X509_L_FILE_LOAD, x509PEMEncodedRootCerts.c_str(), 0, 0);#endif}voidBaseSecurity::addDomainCertPEM(const Data& domainName, const Data& certPEM){ addCertPEM(DomainCert, domainName, certPEM, true);}voidBaseSecurity::addDomainCertDER(const Data& domainName, const Data& certDER){ addCertDER(DomainCert, domainName, certDER, true);}boolBaseSecurity::hasDomainCert(const Data& domainName) const{ return hasCert(DomainCert, domainName);}voidBaseSecurity::removeDomainCert(const Data& domainName){ return removeCert(DomainCert, domainName);}DataBaseSecurity::getDomainCertDER(const Data& domainName) const{ return getCertDER(DomainCert, domainName);}voidBaseSecurity::addDomainPrivateKeyPEM(const Data& domainName, const Data& privateKeyPEM){ addPrivateKeyPEM(DomainPrivateKey, domainName, privateKeyPEM, true);}boolBaseSecurity::hasDomainPrivateKey(const Data& domainName) const{ return hasPrivateKey(DomainPrivateKey, domainName);}voidBaseSecurity::removeDomainPrivateKey(const Data& domainName){ removePrivateKey(DomainPrivateKey, domainName);}DataBaseSecurity::getDomainPrivateKeyPEM(const Data& domainName) const{ return getPrivateKeyPEM(DomainPrivateKey, domainName);}voidBaseSecurity::addUserCertPEM(const Data& aor, const Data& certPEM){ addCertPEM(UserCert, aor, certPEM, true);}voidBaseSecurity::addUserCertDER(const Data& aor, const Data& certDER){ addCertDER(UserCert, aor, certDER, true);}boolBaseSecurity::hasUserCert(const Data& aor) const{ return hasCert(UserCert, aor);}voidBaseSecurity::removeUserCert(const Data& aor){ removeCert(UserCert, aor);}DataBaseSecurity::getUserCertDER(const Data& aor) const{ return getCertDER(UserCert, aor);}voidBaseSecurity::setUserPassPhrase(const Data& aor, const Data& passPhrase){ assert(!aor.empty()); PassPhraseMap::iterator iter = mUserPassPhrases.find(aor); if (iter == mUserPassPhrases.end()) { mUserPassPhrases.insert(std::make_pair(aor, passPhrase)); }}boolBaseSecurity::hasUserPassPhrase(const Data& aor) const{ assert(aor.empty()); PassPhraseMap::const_iterator iter = mUserPassPhrases.find(aor); if (iter == mUserPassPhrases.end()) { return false; } else { return true; }}voidBaseSecurity::removeUserPassPhrase(const Data& aor){ assert(aor.empty()); PassPhraseMap::iterator iter = mUserPassPhrases.find(aor); if(iter != mUserPassPhrases.end()) { mUserPassPhrases.erase(iter); }}DataBaseSecurity::getUserPassPhrase(const Data& aor) const{ assert(aor.empty()); PassPhraseMap::const_iterator iter = mUserPassPhrases.find(aor); if(iter == mUserPassPhrases.end()) { return iter->second; } else { return Data::Empty; }}voidBaseSecurity::addUserPrivateKeyPEM(const Data& aor, const Data& cert){ addPrivateKeyPEM(UserPrivateKey, aor, cert, true);}voidBaseSecurity::addUserPrivateKeyDER(const Data& aor, const Data& cert){ addPrivateKeyDER(UserPrivateKey, aor, cert, true);}boolBaseSecurity::hasUserPrivateKey(const Data& aor) const{ return hasPrivateKey(UserPrivateKey, aor);}voidBaseSecurity::removeUserPrivateKey(const Data& aor){ removePrivateKey(UserPrivateKey, aor);}DataBaseSecurity::getUserPrivateKeyPEM(const Data& aor) const{ return getPrivateKeyPEM(UserPrivateKey, aor);}DataBaseSecurity::getUserPrivateKeyDER(const Data& aor) const{ return getPrivateKeyDER(UserPrivateKey, aor);}voidBaseSecurity::generateUserCert (const Data& pAor, int expireDays, int keyLen ){ int ret; InfoLog( <<"Generating new user cert for " << pAor ); Data domain; Data aor; try { Uri uri( Data("sip:")+pAor ); aor = uri.getAor(); domain = uri.host(); } catch (...) { ErrLog( <<"Invalid aor passed to generateUserCert"); throw Exception("Bad aor passed to generateUserCert", __FILE__,__LINE__); } // Make sure that necessary algorithms exist: assert(EVP_sha1()); RSA* rsa = RSA_generate_key(keyLen, RSA_F4, NULL, NULL); assert(rsa); // couldn't make key pair EVP_PKEY* privkey = EVP_PKEY_new(); assert(privkey); ret = EVP_PKEY_set1_RSA(privkey, rsa); assert(ret); X509* cert = X509_new(); assert(cert); X509_NAME* subject = X509_NAME_new(); X509_EXTENSION* ext = X509_EXTENSION_new(); // set version to X509v3 (starts from 0) X509_set_version(cert, 2L); int serial = Random::getRandom(); // get an int worth of randomness assert(sizeof(int)==4); ASN1_INTEGER_set(X509_get_serialNumber(cert),serial); ret = X509_NAME_add_entry_by_txt( subject, "O", MBSTRING_ASC, (unsigned char *) domain.data(), domain.size(), -1, 0); assert(ret); ret = X509_NAME_add_entry_by_txt( subject, "CN", MBSTRING_ASC, (unsigned char *) aor.data(), aor.size(), -1, 0); assert(ret); ret = X509_set_issuer_name(cert, subject); assert(ret); ret = X509_set_subject_name(cert, subject); assert(ret); const long duration = 60*60*24*expireDays; X509_gmtime_adj(X509_get_notBefore(cert),0); X509_gmtime_adj(X509_get_notAfter(cert), duration); ret = X509_set_pubkey(cert, privkey); assert(ret); Data subjectAltNameStr = Data("URI:sip:") + aor + Data(",URI:im:")+aor + Data(",URI:pres:")+aor; ext = X509V3_EXT_conf_nid( NULL , NULL , NID_subject_alt_name, (char*) subjectAltNameStr.c_str() ); X509_add_ext( cert, ext, -1); X509_EXTENSION_free(ext); static char CA_FALSE[] = "CA:FALSE"; ext = X509V3_EXT_conf_nid(NULL, NULL, NID_basic_constraints, CA_FALSE); ret = X509_add_ext( cert, ext, -1); assert(ret); X509_EXTENSION_free(ext); // TODO add extensions NID_subject_key_identifier and NID_authority_key_identifier ret = X509_sign(cert, privkey, EVP_sha1()); assert(ret); addCertX509( UserCert, aor, cert, true /* write */ ); addPrivateKeyPKEY( UserPrivateKey, aor, privkey, true /* write */ );}MultipartSignedContents*BaseSecurity::sign(const Data& senderAor, Contents* contents){ assert( contents ); // form the multipart MultipartSignedContents* multi = new MultipartSignedContents; multi->header(h_ContentType).param( p_micalg ) = "sha1"; multi->header(h_ContentType).param( p_protocol ) = "application/pkcs7-signature"; // add the main body to it Contents* body = contents->clone(); multi->parts().push_back( body ); Data bodyData; DataStream strm( bodyData ); body->encodeHeaders( strm ); body->encode( strm ); strm.flush(); DebugLog( << "signing data <" << bodyData.escaped() << ">" ); //Security::dumpAsn("resip-sign-out-data",bodyData); const char* p = bodyData.data(); int s = bodyData.size(); BIO* in=BIO_new_mem_buf( (void*)p,s); assert(in); DebugLog( << "created in BIO"); BIO* out = BIO_new(BIO_s_mem()); // TODO - mem leak assert(out); DebugLog( << "created out BIO" ); STACK_OF(X509)* chain = sk_X509_new_null(); assert(chain); DebugLog( << "searching for cert/key for <" << senderAor << ">" ); if (mUserCerts.count(senderAor) == 0 || mUserPrivateKeys.count(senderAor) == 0) { BIO_free(in); BIO_free(out); sk_X509_free(chain); WarningLog (<< "Tried to sign with no cert or private key for " << senderAor); throw Exception("No cert or private key to sign with",__FILE__,__LINE__); } X509* publicCert = mUserCerts[senderAor]; EVP_PKEY* privateKey = mUserPrivateKeys[senderAor]; int rv = X509_check_private_key(publicCert, privateKey); assert(rv); // compute the signature int flags = 0; flags |= PKCS7_BINARY; flags |= PKCS7_DETACHED; if ( true ) // don't do caps { flags |= PKCS7_NOSMIMECAP; flags |= PKCS7_NOATTR; } if ( true ) // don't do certs { flags |= PKCS7_NOCERTS; } PKCS7* pkcs7 = PKCS7_sign( publicCert, privateKey, chain, in, flags); if ( !pkcs7 ) { BIO_free(in); BIO_free(out); sk_X509_free(chain); ErrLog( << "Error creating PKCS7 signature object" ); return 0; } DebugLog( << "created PKCS7 signature object " ); i2d_PKCS7_bio(out,pkcs7); BIO_flush(out); char* outBuf=0; long size = BIO_get_mem_data(out,&outBuf); assert( size > 0 ); Data outData(outBuf,size); static char RESIP_SIGN_OUT_SIG[] = "resip-sign-out-sig"; Security::dumpAsn(RESIP_SIGN_OUT_SIG,outData); Pkcs7SignedContents* sigBody = new Pkcs7SignedContents( outData ); assert( sigBody ); // add the signature to it sigBody->header(h_ContentType).param( p_name ) = "smime.p7s"; sigBody->header(h_ContentDisposition).param( p_handling ) = "required"; sigBody->header(h_ContentDisposition).param( p_filename ) = "smime.p7s"; sigBody->header(h_ContentDisposition).value() = "attachment" ; sigBody->header(h_ContentTransferEncoding).value() = "binary"; multi->parts().push_back( sigBody ); assert( multi->parts().size() == 2 ); BIO_free(in); BIO_free(out); sk_X509_free(chain); return multi;}Pkcs7Contents*BaseSecurity::encrypt(Contents* bodyIn, const Data& recipCertName ){ assert( bodyIn ); int flags = 0 ; flags |= PKCS7_BINARY; flags |= PKCS7_NOCERTS; Data bodyData; DataStream strm(bodyData); bodyIn->encodeHeaders(strm); bodyIn->encode( strm ); strm.flush(); InfoLog( << "body data to encrypt is <" << bodyData.escaped() << ">" ); const char* p = bodyData.data(); int s = bodyData.size(); BIO* in = BIO_new_mem_buf( (void*)p,s); assert(in); DebugLog( << "created in BIO"); BIO* out = BIO_new(BIO_s_mem()); assert(out); DebugLog( << "created out BIO" ); InfoLog( << "target cert name is <" << recipCertName << ">" ); if (mUserCerts.count(recipCertName) == 0) { BIO_free(in); BIO_free(out); WarningLog (<< "Tried to encrypt with no cert or private key for " << recipCertName); throw Exception("No cert or private key to encrypt with",__FILE__,__LINE__); } X509* cert = mUserCerts[recipCertName]; assert(cert); STACK_OF(X509) *certs = sk_X509_new_null(); assert(certs); sk_X509_push(certs, cert);// if you think you need to change the following few lines, please email fluffy// the value of OPENSSL_VERSION_NUMBER ( in opensslv.h ) and the signature of// PKCS_encrypt found ( in pkcs7.h ) and the OS you are using
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -