/* * Create a new OSP provider object per process * return 0 success, others failure */ int ospSetupProvider(void) { OSPTPRIVATEKEY privatekey; OSPTCERT localcert; OSPTCERT cacert; OSPTCERT* cacerts[1]; int result; cacerts[0] = &cacert; if ((result = OSPPInit(_osp_crypto_hw)) != 0) { LM_ERR("failed to initalize OSP (%i)\n", result); } else if (OSPPUtilLoadPEMPrivateKey(_osp_private_key, &privatekey) != 0) { LM_ERR("failed to load private key from '%s'\n", _osp_private_key); } else if (OSPPUtilLoadPEMCert(_osp_local_certificate, &localcert) != 0) { LM_ERR("failed to load local certificate from '%s'\n",_osp_local_certificate); } else if (OSPPUtilLoadPEMCert(_osp_ca_certificate, &cacert) != 0) { LM_ERR("failed to load CA certificate from '%s'\n", _osp_ca_certificate); } else { result = OSPPProviderNew( _osp_sp_number, (const char**)_osp_sp_uris, _osp_sp_weights, "http://localhost:1234", &privatekey, &localcert, 1, (const OSPTCERT**)cacerts, 1, _osp_ssl_lifetime, _osp_sp_number, _osp_persistence, _osp_retry_delay, _osp_retry_limit, _osp_timeout, "", "", &_osp_provider); if (result != 0) { LM_ERR("failed to create provider (%i)\n", result); } else { LM_DBG("created new (per process) provider '%d'\n", _osp_provider); result = 0; } } /* * Free space allocated while loading crypto information from PEM-encoded files. * There are some problems to free the memory, do not free them */ if (privatekey.PrivateKeyData != NULL) { //free(privatekey.PrivateKeyData); } if (localcert.CertData != NULL) { //free(localcert.CertData); } if (cacert.CertData != NULL) { //free(localcert.CertData); } return result; }
static int osp_build(struct cw_config *cfg, char *cat) { OSPTCERT TheAuthCert[MAX_CERTS]; unsigned char Reqbuf[4096],LocalBuf[4096],AuthBuf[MAX_CERTS][4096]; struct cw_variable *v; struct osp_provider *osp; int x,length,errorcode=0; int mallocd=0,i; char *cacerts[MAX_CERTS]; const char *servicepoints[MAX_SERVICEPOINTS]; OSPTPRIVATEKEY privatekey; OSPTCERT localcert; OSPTCERT *authCerts[MAX_CERTS]; cw_mutex_lock(&osplock); osp = providers; while(osp) { if (!strcasecmp(osp->name, cat)) break; osp = osp->next; } cw_mutex_unlock(&osplock); if (!osp) { mallocd = 1; osp = malloc(sizeof(struct osp_provider)); if (!osp) { cw_log(LOG_WARNING, "Out of memory!\n"); return -1; } memset(osp, 0, sizeof(struct osp_provider)); osp->handle = -1; } cw_copy_string(osp->name, cat, sizeof(osp->name)); snprintf(osp->localpvtkey, sizeof(osp->localpvtkey) ,"%s/%s-privatekey.pem", cw_config_CW_KEY_DIR, cat); snprintf(osp->localcert, sizeof(osp->localpvtkey), "%s/%s-localcert.pem", cw_config_CW_KEY_DIR, cat); osp->maxconnections=OSP_DEFAULT_MAX_CONNECTIONS; osp->retrydelay = OSP_DEFAULT_RETRY_DELAY; osp->retrylimit = OSP_DEFAULT_RETRY_LIMIT; osp->timeout = OSP_DEFAULT_TIMEOUT; osp->source[0] = '\0'; cw_log(LOG_DEBUG, "Building OSP Provider '%s'\n", cat); v = cw_variable_browse(cfg, cat); while(v) { if (!strcasecmp(v->name, "privatekey")) { if (v->value[0] == '/') cw_copy_string(osp->localpvtkey, v->value, sizeof(osp->localpvtkey)); else snprintf(osp->localpvtkey, sizeof(osp->localpvtkey), "%s/%s", cw_config_CW_KEY_DIR , v->value); } else if (!strcasecmp(v->name, "localcert")) { if (v->value[0] == '/') cw_copy_string(osp->localcert, v->value, sizeof(osp->localcert)); else snprintf(osp->localcert, sizeof(osp->localcert), "%s/%s", cw_config_CW_KEY_DIR, v->value); } else if (!strcasecmp(v->name, "cacert")) { if (osp->cacount < MAX_CERTS) { if (v->value[0] == '/') cw_copy_string(osp->cacerts[osp->cacount], v->value, sizeof(osp->cacerts[0])); else snprintf(osp->cacerts[osp->cacount], sizeof(osp->cacerts[0]), "%s/%s", cw_config_CW_KEY_DIR, v->value); osp->cacount++; } else cw_log(LOG_WARNING, "Too many CA Certificates at line %d\n", v->lineno); } else if (!strcasecmp(v->name, "servicepoint")) { if (osp->spcount < MAX_SERVICEPOINTS) { cw_copy_string(osp->servicepoints[osp->spcount], v->value, sizeof(osp->servicepoints[0])); osp->spcount++; } else cw_log(LOG_WARNING, "Too many Service points at line %d\n", v->lineno); } else if (!strcasecmp(v->name, "maxconnections")) { if ((sscanf(v->value, "%d", &x) == 1) && (x > 0) && (x <= 1000)) { osp->maxconnections = x; } else cw_log(LOG_WARNING, "maxconnections should be an integer from 1 to 1000, not '%s' at line %d\n", v->value, v->lineno); } else if (!strcasecmp(v->name, "retrydelay")) { if ((sscanf(v->value, "%d", &x) == 1) && (x >= 0) && (x <= 10)) { osp->retrydelay = x; } else cw_log(LOG_WARNING, "retrydelay should be an integer from 0 to 10, not '%s' at line %d\n", v->value, v->lineno); } else if (!strcasecmp(v->name, "retrylimit")) { if ((sscanf(v->value, "%d", &x) == 1) && (x >= 0) && (x <= 100)) { osp->retrylimit = x; } else cw_log(LOG_WARNING, "retrylimit should be an integer from 0 to 100, not '%s' at line %d\n", v->value, v->lineno); } else if (!strcasecmp(v->name, "timeout")) { if ((sscanf(v->value, "%d", &x) == 1) && (x >= 200) && (x <= 10000)) { osp->timeout = x; } else cw_log(LOG_WARNING, "timeout should be an integer from 200 to 10000, not '%s' at line %d\n", v->value, v->lineno); } else if (!strcasecmp(v->name, "source")) { cw_copy_string(osp->source, v->value, sizeof(osp->source)); } v = v->next; } if (osp->cacount < 1) { snprintf(osp->cacerts[osp->cacount], sizeof(osp->cacerts[0]), "%s/%s-cacert.pem", cw_config_CW_KEY_DIR, cat); osp->cacount++; } for (x=0;x<osp->cacount;x++) cacerts[x] = osp->cacerts[x]; for (x=0;x<osp->spcount;x++) servicepoints[x] = osp->servicepoints[x]; cw_mutex_lock(&osplock); osp->dead = 0; if (osp->handle > -1) { cw_log(LOG_DEBUG, "Deleting old handle for '%s'\n", osp->name); OSPPProviderDelete(osp->handle, 0); } length = 0; cw_log(LOG_DEBUG, "Loading private key for '%s' (%s)\n", osp->name, osp->localpvtkey); errorcode = loadPemPrivateKey(osp->localpvtkey,Reqbuf,&length); if (errorcode == 0) { privatekey.PrivateKeyData = Reqbuf; privatekey.PrivateKeyLength = length; } else { return -1; } length = 0; cw_log(LOG_DEBUG, "Loading local cert for '%s' (%s)\n", osp->name, osp->localcert); errorcode = loadPemCert(osp->localcert,LocalBuf,&length); if (errorcode == 0) { localcert.CertData = LocalBuf; localcert.CertDataLength = length; } else { return -1; } for (i=0;i<osp->cacount;i++) { length = 0; cw_log(LOG_DEBUG, "Loading CA cert %d for '%s' (%s)\n", i + 1, osp->name, osp->cacerts[i]); errorcode = loadPemCert(osp->cacerts[i],AuthBuf[i],&length); if (errorcode == 0) { TheAuthCert[i].CertData = AuthBuf[i]; TheAuthCert[i].CertDataLength = length; authCerts[i] = &(TheAuthCert[i]); } else { return -1; } } cw_log(LOG_DEBUG, "Creating provider handle for '%s'\n", osp->name); cw_log(LOG_DEBUG, "Service point '%s %d'\n", servicepoints[0], osp->spcount); if (OSPPProviderNew(osp->spcount, servicepoints, NULL, "localhost", &privatekey, &localcert, osp->cacount, (const OSPTCERT **)authCerts, 1, 300, osp->maxconnections, 1, osp->retrydelay, osp->retrylimit, osp->timeout, "", "", &osp->handle)) { cw_log(LOG_WARNING, "Unable to initialize provider '%s'\n", cat); osp->dead = 1; } if (mallocd) { osp->next = providers; providers = osp; } cw_mutex_unlock(&osplock); return 0; }