示例#1
0
int crypto_init(cert_policy *policy) {
  SECStatus rv;

  DBG("Initializing NSS ...");
  if (NSS_IsInitialized()) {
    app_has_NSS = 1;
    /* we should save the app's password function */
    PK11_SetPasswordFunc(password_passthrough);
    DBG("...  NSS is initialized");
    return 0;
  }
  if (policy->nss_dir) {
    /* initialize with read only databases */
    DBG1("Initializing NSS ... database=%s", policy->nss_dir);
    rv = NSS_Init(policy->nss_dir);
  } else {
    /* not database secified */
    DBG("Initializing NSS ... with no db");
    rv = NSS_NoDB_Init(NULL);
  }

  if (rv != SECSuccess) {
    DBG1("NSS_Initialize failed: %s", SECU_Strerror(PR_GetError()));
    return -1;
  }
  /* register a callback */
  PK11_SetPasswordFunc(password_passthrough);

  if (policy->ocsp_policy == OCSP_ON) {
    CERT_EnableOCSPChecking(CERT_GetDefaultCertDB());
  }
  DBG("...  NSS Complete");
  return 0;
}
示例#2
0
static int nss_hash_init(void **pctx, SECOidTag hash_alg)
{
  PK11Context *ctx;

  /* we have to initialize NSS if not initialized alraedy */
#ifdef HAVE_NSS_INITCONTEXT
  if(!NSS_IsInitialized() && !nss_context) {
    static NSSInitParameters params;
    params.length = sizeof params;
    nss_context = NSS_InitContext("", "", "", "", &params, NSS_INIT_READONLY
        | NSS_INIT_NOCERTDB   | NSS_INIT_NOMODDB       | NSS_INIT_FORCEOPEN
        | NSS_INIT_NOROOTINIT | NSS_INIT_OPTIMIZESPACE | NSS_INIT_PK11RELOAD);
  }
#endif

  ctx = PK11_CreateDigestContext(hash_alg);
  if(!ctx)
    return /* failure */ 0;

  if(PK11_DigestBegin(ctx) != SECSuccess) {
    PK11_DestroyContext(ctx, PR_TRUE);
    return /* failure */ 0;
  }

  *pctx = ctx;
  return /* success */ 1;
}
示例#3
0
static X509*
nss_get_cert(NSS_CTX *ctx, const char *s) {
    X509 *x509 = NULL;
    CERTCertificate *cert = NULL;

    CALL_TRACE("nss_get_cert...\n");

    if (ctx == NULL) {
        NSSerr(NSS_F_GET_CERT, NSS_R_INVALID_ARGUMENT);
        goto done;
    }
    if (!NSS_IsInitialized()) {
        NSSerr(NSS_F_GET_CERT, NSS_R_DB_IS_NOT_INITIALIZED);
        goto done;
    }

    nss_debug(ctx, "search certificate '%s'", s);
    cert = PK11_FindCertFromNickname(s, NULL);
    nss_trace(ctx, "found certificate mem='%p'", cert);

    if (cert == NULL) goto done;

    x509 = X509_from_CERTCertificate(cert);

done:
    if (cert) CERT_DestroyCertificate(cert);

    nss_debug(ctx, "certificate %s", (x509 ? "found": "not found"));
    return(x509);
}
示例#4
0
static CURLcode nss_init_core(struct SessionHandle *data, const char *cert_dir)
{
  if(NSS_IsInitialized())
    return CURLE_OK;

  if(cert_dir) {
    SECStatus rv;
    const bool use_sql = NSS_VersionCheck("3.12.0");
    char *certpath = aprintf("%s%s", use_sql ? "sql:" : "", cert_dir);
    if(!certpath)
      return CURLE_OUT_OF_MEMORY;

    infof(data, "Initializing NSS with certpath: %s\n", certpath);
    rv = NSS_Initialize(certpath, "", "", "", NSS_INIT_READONLY);
    free(certpath);

    if(rv == SECSuccess)
      return CURLE_OK;

    infof(data, "Unable to initialize NSS database\n");
  }

  infof(data, "Initializing NSS with certpath: none\n");
  if(NSS_NoDB_Init(NULL) == SECSuccess)
    return CURLE_OK;

  infof(data, "Unable to initialize NSS\n");
  return CURLE_SSL_CACERT_BADFILE;
}
示例#5
0
文件: nss.c 项目: 3s3s/simple_server
static CURLcode nss_init_core(struct SessionHandle *data, const char *cert_dir)
{
#ifdef HAVE_NSS_INITCONTEXT
  NSSInitParameters initparams;

  if(nss_context != NULL)
    return CURLE_OK;

  memset((void *) &initparams, '\0', sizeof(initparams));
  initparams.length = sizeof(initparams);
#else /* HAVE_NSS_INITCONTEXT */
  SECStatus rv;

  if(NSS_IsInitialized())
    return CURLE_OK;
#endif

  if(cert_dir) {
    const bool use_sql = NSS_VersionCheck("3.12.0");
    char *certpath = aprintf("%s%s", use_sql ? "sql:" : "", cert_dir);
    if(!certpath)
      return CURLE_OUT_OF_MEMORY;

    infof(data, "Initializing NSS with certpath: %s\n", certpath);
#ifdef HAVE_NSS_INITCONTEXT
    nss_context = NSS_InitContext(certpath, "", "", "", &initparams,
            NSS_INIT_READONLY | NSS_INIT_PK11RELOAD);
    free(certpath);

    if(nss_context != NULL)
      return CURLE_OK;
#else /* HAVE_NSS_INITCONTEXT */
    rv = NSS_Initialize(certpath, "", "", "", NSS_INIT_READONLY);
    free(certpath);

    if(rv == SECSuccess)
      return CURLE_OK;
#endif

    infof(data, "Unable to initialize NSS database\n");
  }

  infof(data, "Initializing NSS with certpath: none\n");
#ifdef HAVE_NSS_INITCONTEXT
  nss_context = NSS_InitContext("", "", "", "", &initparams, NSS_INIT_READONLY
         | NSS_INIT_NOCERTDB   | NSS_INIT_NOMODDB       | NSS_INIT_FORCEOPEN
         | NSS_INIT_NOROOTINIT | NSS_INIT_OPTIMIZESPACE | NSS_INIT_PK11RELOAD);
  if(nss_context != NULL)
    return CURLE_OK;
#else /* HAVE_NSS_INITCONTEXT */
  if(NSS_NoDB_Init(NULL) == SECSuccess)
    return CURLE_OK;
#endif

  infof(data, "Unable to initialize NSS\n");
  return CURLE_SSL_CACERT_BADFILE;
}
示例#6
0
/**
 * Shutdown the crypto library and release resources.
 *
 * It is safe to shut down twice.
 */
static apr_status_t crypto_shutdown(void)
{
    if (NSS_IsInitialized()) {
        SECStatus s = NSS_Shutdown();
        if (s != SECSuccess) {
            return APR_EINIT;
        }
    }
    return APR_SUCCESS;
}
示例#7
0
文件: nss.c 项目: zcopley/curl
static CURLcode init_nss(struct SessionHandle *data)
{
  char *cert_dir;
  struct_stat st;
  if(initialized)
    return CURLE_OK;

  /* First we check if $SSL_DIR points to a valid dir */
  cert_dir = getenv("SSL_DIR");
  if(cert_dir) {
    if((stat(cert_dir, &st) != 0) ||
        (!S_ISDIR(st.st_mode))) {
      cert_dir = NULL;
    }
  }

  /* Now we check if the default location is a valid dir */
  if(!cert_dir) {
    if((stat(SSL_DIR, &st) == 0) &&
        (S_ISDIR(st.st_mode))) {
      cert_dir = (char *)SSL_DIR;
    }
  }

  if(!NSS_IsInitialized()) {
    SECStatus rv;
    initialized = 1;
    infof(data, "Initializing NSS with certpath: %s\n",
          cert_dir ? cert_dir : "none");
    if(!cert_dir) {
      rv = NSS_NoDB_Init(NULL);
    }
    else {
      char *certpath =
        PR_smprintf("%s%s", NSS_VersionCheck("3.12.0") ? "sql:" : "", cert_dir);
      rv = NSS_Initialize(certpath, "", "", "", NSS_INIT_READONLY);
      PR_smprintf_free(certpath);
    }
    if(rv != SECSuccess) {
      infof(data, "Unable to initialize NSS database\n");
      initialized = 0;
      return CURLE_SSL_CACERT_BADFILE;
    }
  }

  if(num_enabled_ciphers() == 0)
    NSS_SetDomesticPolicy();

  return CURLE_OK;
}
示例#8
0
void sipe_core_init(void)
{
	srand(time(NULL));
	sip_sec_init();

#ifdef ENABLE_NLS
	SIPE_DEBUG_INFO("bindtextdomain = %s",
			bindtextdomain(PACKAGE_NAME, LOCALEDIR));
	SIPE_DEBUG_INFO("bind_textdomain_codeset = %s",
			bind_textdomain_codeset(PACKAGE_NAME, "UTF-8"));
	textdomain(PACKAGE_NAME);
#endif
#ifdef HAVE_NSS
	if (!NSS_IsInitialized()) {
		NSS_NoDB_Init(".");
		SIPE_DEBUG_INFO_NOFORMAT("NSS initialised");
	}
#endif
#ifdef HAVE_GMIME
	g_mime_init(0);
#endif
}
示例#9
0
static
int
__pkcs11h_crypto_nss_initialize (
	IN void * const global_data
) {
	int ret = FALSE;

	if (NSS_IsInitialized ()) {
		*(int *)global_data = FALSE;
	}
	else {
		if (NSS_NoDB_Init (NULL) != SECSuccess) {
			goto cleanup;
		}
		*(int *)global_data = TRUE;
	}

	ret = TRUE;

cleanup:

	return ret;
}
示例#10
0
文件: nss.c 项目: 0w/moai-dev
CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
{
  PRInt32 err;
  PRFileDesc *model = NULL;
  PRBool ssl2, ssl3, tlsv1;
  struct SessionHandle *data = conn->data;
  curl_socket_t sockfd = conn->sock[sockindex];
  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
  SECStatus rv;
  char *certDir = NULL;
  int curlerr;
  const int *cipher_to_enable;

  curlerr = CURLE_SSL_CONNECT_ERROR;

  if (connssl->state == ssl_connection_complete)
    return CURLE_OK;

  connssl->data = data;

#ifdef HAVE_PK11_CREATEGENERICOBJECT
  connssl->cacert[0] = NULL;
  connssl->cacert[1] = NULL;
  connssl->key = NULL;
#endif

  /* FIXME. NSS doesn't support multiple databases open at the same time. */
  PR_Lock(nss_initlock);
  if(!initialized) {
    struct_stat st;

    /* First we check if $SSL_DIR points to a valid dir */
    certDir = getenv("SSL_DIR");
    if(certDir) {
      if((stat(certDir, &st) != 0) ||
              (!S_ISDIR(st.st_mode))) {
        certDir = NULL;
      }
    }

    /* Now we check if the default location is a valid dir */
    if(!certDir) {
      if((stat(SSL_DIR, &st) == 0) &&
              (S_ISDIR(st.st_mode))) {
        certDir = (char *)SSL_DIR;
      }
    }

    if (!NSS_IsInitialized()) {
      initialized = 1;
      infof(conn->data, "Initializing NSS with certpath: %s\n",
            certDir ? certDir : "none");
      if(!certDir) {
        rv = NSS_NoDB_Init(NULL);
      }
      else {
        char *certpath = PR_smprintf("%s%s",
                         NSS_VersionCheck("3.12.0") ? "sql:" : "",
                         certDir);
        rv = NSS_Initialize(certpath, "", "", "", NSS_INIT_READONLY);
        PR_smprintf_free(certpath);
      }
      if(rv != SECSuccess) {
        infof(conn->data, "Unable to initialize NSS database\n");
        curlerr = CURLE_SSL_CACERT_BADFILE;
        initialized = 0;
        PR_Unlock(nss_initlock);
        goto error;
      }
    }

    if(num_enabled_ciphers() == 0)
      NSS_SetDomesticPolicy();

#ifdef HAVE_PK11_CREATEGENERICOBJECT
    if(!mod) {
      char *configstring = aprintf("library=%s name=PEM", pem_library);
      if(!configstring) {
        PR_Unlock(nss_initlock);
        goto error;
      }
      mod = SECMOD_LoadUserModule(configstring, NULL, PR_FALSE);
      free(configstring);

      if(!mod || !mod->loaded) {
        if(mod) {
          SECMOD_DestroyModule(mod);
          mod = NULL;
        }
        infof(data, "WARNING: failed to load NSS PEM library %s. Using OpenSSL "
              "PEM certificates will not work.\n", pem_library);
      }
    }
#endif

    PK11_SetPasswordFunc(nss_get_password);

  }
  PR_Unlock(nss_initlock);

  model = PR_NewTCPSocket();
  if(!model)
    goto error;
  model = SSL_ImportFD(NULL, model);

  if(SSL_OptionSet(model, SSL_SECURITY, PR_TRUE) != SECSuccess)
    goto error;
  if(SSL_OptionSet(model, SSL_HANDSHAKE_AS_SERVER, PR_FALSE) != SECSuccess)
    goto error;
  if(SSL_OptionSet(model, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE) != SECSuccess)
    goto error;

  ssl2 = ssl3 = tlsv1 = PR_FALSE;

  switch (data->set.ssl.version) {
  default:
  case CURL_SSLVERSION_DEFAULT:
    ssl3 = tlsv1 = PR_TRUE;
    break;
  case CURL_SSLVERSION_TLSv1:
    tlsv1 = PR_TRUE;
    break;
  case CURL_SSLVERSION_SSLv2:
    ssl2 = PR_TRUE;
    break;
  case CURL_SSLVERSION_SSLv3:
    ssl3 = PR_TRUE;
    break;
  }

  if(SSL_OptionSet(model, SSL_ENABLE_SSL2, ssl2) != SECSuccess)
    goto error;
  if(SSL_OptionSet(model, SSL_ENABLE_SSL3, ssl3) != SECSuccess)
    goto error;
  if(SSL_OptionSet(model, SSL_ENABLE_TLS, tlsv1) != SECSuccess)
    goto error;

  if(SSL_OptionSet(model, SSL_V2_COMPATIBLE_HELLO, ssl2) != SECSuccess)
    goto error;

  /* enable all ciphers from enable_ciphers_by_default */
  cipher_to_enable = enable_ciphers_by_default;
  while (SSL_NULL_WITH_NULL_NULL != *cipher_to_enable) {
    if (SSL_CipherPrefSet(model, *cipher_to_enable, PR_TRUE) != SECSuccess) {
      curlerr = CURLE_SSL_CIPHER;
      goto error;
    }
    cipher_to_enable++;
  }

  if(data->set.ssl.cipher_list) {
    if(set_ciphers(data, model, data->set.ssl.cipher_list) != SECSuccess) {
      curlerr = CURLE_SSL_CIPHER;
      goto error;
    }
  }

  if(data->set.ssl.verifyhost == 1)
    infof(data, "warning: ignoring unsupported value (1) of ssl.verifyhost\n");

  data->set.ssl.certverifyresult=0; /* not checked yet */
  if(SSL_BadCertHook(model, (SSLBadCertHandler) BadCertHandler, conn)
     != SECSuccess) {
    goto error;
  }
  if(SSL_HandshakeCallback(model, (SSLHandshakeCallback) HandshakeCallback,
                           NULL) != SECSuccess)
    goto error;

  if(!data->set.ssl.verifypeer)
    /* skip the verifying of the peer */
    ;
  else if(data->set.ssl.CAfile) {
    int rc = nss_load_cert(&conn->ssl[sockindex], data->set.ssl.CAfile,
                           PR_TRUE);
    if(!rc) {
      curlerr = CURLE_SSL_CACERT_BADFILE;
      goto error;
    }
  }
  else if(data->set.ssl.CApath) {
    struct_stat st;
    PRDir      *dir;
    PRDirEntry *entry;

    if(stat(data->set.ssl.CApath, &st) == -1) {
      curlerr = CURLE_SSL_CACERT_BADFILE;
      goto error;
    }

    if(S_ISDIR(st.st_mode)) {
      int rc;

      dir = PR_OpenDir(data->set.ssl.CApath);
      do {
        entry = PR_ReadDir(dir, PR_SKIP_BOTH | PR_SKIP_HIDDEN);

        if(entry) {
          char fullpath[PATH_MAX];

          snprintf(fullpath, sizeof(fullpath), "%s/%s", data->set.ssl.CApath,
                   entry->name);
          rc = nss_load_cert(&conn->ssl[sockindex], fullpath, PR_TRUE);
          /* FIXME: check this return value! */
        }
        /* This is purposefully tolerant of errors so non-PEM files
         * can be in the same directory */
      } while(entry != NULL);
      PR_CloseDir(dir);
    }
  }
  infof(data,
        "  CAfile: %s\n"
        "  CApath: %s\n",
        data->set.ssl.CAfile ? data->set.ssl.CAfile : "none",
        data->set.ssl.CApath ? data->set.ssl.CApath : "none");

  if (data->set.ssl.CRLfile) {
    int rc = nss_load_crl(data->set.ssl.CRLfile, PR_FALSE);
    if (!rc) {
      curlerr = CURLE_SSL_CRL_BADFILE;
      goto error;
    }
    infof(data,
          "  CRLfile: %s\n",
          data->set.ssl.CRLfile ? data->set.ssl.CRLfile : "none");
  }

  if(data->set.str[STRING_CERT]) {
    bool nickname_alloc = FALSE;
    char *nickname = fmt_nickname(data->set.str[STRING_CERT], &nickname_alloc);
    if(!nickname)
      return CURLE_OUT_OF_MEMORY;

    if(!cert_stuff(conn, sockindex, data->set.str[STRING_CERT],
                    data->set.str[STRING_KEY])) {
      /* failf() is already done in cert_stuff() */
      if(nickname_alloc)
        free(nickname);
      return CURLE_SSL_CERTPROBLEM;
    }

    /* this "takes over" the pointer to the allocated name or makes a
       dup of it */
    connssl->client_nickname = nickname_alloc?nickname:strdup(nickname);
    if(!connssl->client_nickname)
      return CURLE_OUT_OF_MEMORY;

  }
  else
    connssl->client_nickname = NULL;

  if(SSL_GetClientAuthDataHook(model, SelectClientCert,
                               (void *)connssl) != SECSuccess) {
    curlerr = CURLE_SSL_CERTPROBLEM;
    goto error;
  }

  /* Import our model socket  onto the existing file descriptor */
  connssl->handle = PR_ImportTCPSocket(sockfd);
  connssl->handle = SSL_ImportFD(model, connssl->handle);
  if(!connssl->handle)
    goto error;
  PR_Close(model); /* We don't need this any more */

  /* This is the password associated with the cert that we're using */
  if (data->set.str[STRING_KEY_PASSWD]) {
      SSL_SetPKCS11PinArg(connssl->handle, data->set.str[STRING_KEY_PASSWD]);
  }

  /* Force handshake on next I/O */
  SSL_ResetHandshake(connssl->handle, /* asServer */ PR_FALSE);

  SSL_SetURL(connssl->handle, conn->host.name);

  /* Force the handshake now */
  if(SSL_ForceHandshakeWithTimeout(connssl->handle,
                                    PR_SecondsToInterval(HANDSHAKE_TIMEOUT))
      != SECSuccess) {
    if(conn->data->set.ssl.certverifyresult == SSL_ERROR_BAD_CERT_DOMAIN)
      curlerr = CURLE_PEER_FAILED_VERIFICATION;
    else if(conn->data->set.ssl.certverifyresult!=0)
      curlerr = CURLE_SSL_CACERT;
    goto error;
  }

  connssl->state = ssl_connection_complete;

  display_conn_info(conn, connssl->handle);

  if (data->set.str[STRING_SSL_ISSUERCERT]) {
    SECStatus ret;
    bool nickname_alloc = FALSE;
    char *nickname = fmt_nickname(data->set.str[STRING_SSL_ISSUERCERT],
                                  &nickname_alloc);

    if(!nickname)
      return CURLE_OUT_OF_MEMORY;

    ret = check_issuer_cert(connssl->handle, nickname);

    if(nickname_alloc)
      free(nickname);

    if(SECFailure == ret) {
      infof(data,"SSL certificate issuer check failed\n");
      curlerr = CURLE_SSL_ISSUER_ERROR;
      goto error;
    }
    else {
      infof(data, "SSL certificate issuer check ok\n");
    }
  }

  return CURLE_OK;

error:
  err = PR_GetError();
  infof(data, "NSS error %d\n", err);
  if(model)
    PR_Close(model);
  return curlerr;
}
示例#11
0
static int
nss_cmd_list_cert(NSS_CTX *ctx, long i) {
    int ret = 0;
    BIO  *out = NULL;
    void *wincx = NULL;

    CERTCertList     *list;
    CERTCertListNode *node;
    PK11CertListType  type;

    CALL_TRACE("nss_cmd_list_cert: %ld\n", i);

    if (ctx == NULL) {
        NSSerr(NSS_F_CMD_LIST_CERT, NSS_R_INVALID_ARGUMENT);
        goto done;
    }
    if (!NSS_IsInitialized()) {
        NSSerr(NSS_F_CMD_LIST_CERT, NSS_R_DB_IS_NOT_INITIALIZED);
        goto done;
    }

#if 0
softoken/secmodt.h:     PK11CertListUnique = 0,     /* get one instance of all certs */
softoken/secmodt.h:     PK11CertListUser = 1,       /* get all instances of user certs */
softoken/secmodt.h:     PK11CertListRootUnique = 2, /* get one instance of CA certs without a private key. */
softoken/secmodt.h:     PK11CertListCA = 3,         /* get all instances of CA certs */
softoken/secmodt.h:     PK11CertListCAUnique = 4,   /* get one instance of CA certs */
softoken/secmodt.h:     PK11CertListUserUnique = 5, /* get one instance of user certs */
softoken/secmodt.h:     PK11CertListAll = 6         /* get all instances of all certs */
#endif
    switch (i) {
    case 1: type = PK11CertListUser; break;
    case 2: type = PK11CertListCA  ; break;
    case 3: type = PK11CertListAll ; break;
    default:
        goto done;
        break;
    }

    out = BIO_new_fp(stdout, BIO_NOCLOSE);

    list = PK11_ListCerts(type, wincx);
    for (node = CERT_LIST_HEAD(list);
         !CERT_LIST_END(node, list);
         node = CERT_LIST_NEXT(node)
    ) {
        CERTCertificate *cert = node->cert;

        BIO_printf(out, "nickname='%s'\n"      , cert->nickname);
        BIO_printf(out, "  subject_name='%s'\n", cert->subjectName);
        /* NOTE:
         * - NSS cut long strings in cert->subjectName (?)
         * - RFC 3280 : For UTF8String or UniversalString at least four
         *   times the upper bound should be allowed.
         * => lets perform own output
         */
        BIO_printf_CERTName(out, &cert->subject, "    ");
        BIO_printf(out, "  email_addr  ='%s'\n", cert->emailAddr);
    }
    CERT_DestroyCertList(list);

    ret = 1;
done:
    if (out) BIO_free(out);
    return(ret);
}
示例#12
0
/**
 * Initialise the crypto library and perform one time initialisation.
 */
static apr_status_t crypto_init(apr_pool_t *pool, const char *params, int *rc)
{
    SECStatus s;
    const char *dir = NULL;
    const char *keyPrefix = NULL;
    const char *certPrefix = NULL;
    const char *secmod = NULL;
    int noinit = 0;
    PRUint32 flags = 0;

    struct {
        const char *field;
        const char *value;
        int set;
    } fields[] = {
        { "dir", NULL, 0 },
        { "key3", NULL, 0 },
        { "cert7", NULL, 0 },
        { "secmod", NULL, 0 },
        { "noinit", NULL, 0 },
        { NULL, NULL, 0 }
    };
    const char *ptr;
    size_t klen;
    char **elts = NULL;
    char *elt;
    int i = 0, j;
    apr_status_t status;

    if (params) {
        if (APR_SUCCESS != (status = apr_tokenize_to_argv(params, &elts, pool))) {
            return status;
        }
        while ((elt = elts[i])) {
            ptr = strchr(elt, '=');
            if (ptr) {
                for (klen = ptr - elt; klen && apr_isspace(elt[klen - 1]); --klen)
                    ;
                ptr++;
            }
            else {
                for (klen = strlen(elt); klen && apr_isspace(elt[klen - 1]); --klen)
                    ;
            }
            elt[klen] = 0;

            for (j = 0; fields[j].field != NULL; ++j) {
                if (klen && !strcasecmp(fields[j].field, elt)) {
                    fields[j].set = 1;
                    if (ptr) {
                        fields[j].value = ptr;
                    }
                    break;
                }
            }

            i++;
        }
        dir = fields[0].value;
        keyPrefix = fields[1].value;
        certPrefix = fields[2].value;
        secmod = fields[3].value;
        noinit = fields[4].set;
    }

    /* if we've been asked to bypass, do so here */
    if (noinit) {
        return APR_SUCCESS;
    }

    /* sanity check - we can only initialise NSS once */
    if (NSS_IsInitialized()) {
        return APR_EREINIT;
    }

    apr_pool_cleanup_register(pool, pool, crypto_shutdown_helper,
            apr_pool_cleanup_null);

    if (keyPrefix || certPrefix || secmod) {
        s = NSS_Initialize(dir, certPrefix, keyPrefix, secmod, flags);
    }
    else if (dir) {
        s = NSS_InitReadWrite(dir);
    }
    else {
        s = NSS_NoDB_Init(NULL);
    }
    if (s != SECSuccess) {
        if (rc) {
            *rc = PR_GetError();
        }
        return APR_ECRYPT;
    }

    return APR_SUCCESS;

}
示例#13
0
文件: camel.c 项目: Pecisk/eds-gtasks
gint
camel_init (const gchar *configdir,
            gboolean nss_init)
{
	CamelCertDB *certdb;
	gchar *path;

	if (initialised)
		return 0;

	bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");

	camel_debug_init ();

	if (nss_init) {
		static gchar v2_enabled = -1, weak_ciphers = -1;
		gchar *nss_configdir = NULL;
		gchar *nss_sql_configdir = NULL;
		SECStatus status = SECFailure;

#if NSS_VMAJOR < 3 || (NSS_VMAJOR == 3 && NSS_VMINOR < 14)
		/* NSS pre-3.14 has most of the ciphers disabled, thus enable
		 * weak ciphers, if it's compiled against such */
		weak_ciphers = 1;
#endif

		/* check camel-tcp-stream-ssl.c for the same "CAMEL_SSL_V2_ENABLE" */
		if (v2_enabled == -1)
			v2_enabled = g_strcmp0 (g_getenv ("CAMEL_SSL_V2_ENABLE"), "1") == 0 ? 1 : 0;
		if (weak_ciphers == -1)
			weak_ciphers = g_strcmp0 (g_getenv ("CAMEL_SSL_WEAK_CIPHERS"), "1") == 0 ? 1 : 0;

		if (nss_initlock == NULL) {
			PR_Init (PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 10);
			nss_initlock = PR_NewLock ();
		}
		PR_Lock (nss_initlock);

		if (NSS_IsInitialized ())
			goto skip_nss_init;

#ifndef G_OS_WIN32
		nss_configdir = g_strdup (configdir);
#else
		nss_configdir = g_win32_locale_filename_from_utf8 (configdir);
#endif

		if (nss_has_system_db ()) {
			nss_sql_configdir = g_strdup ("sql:" NSS_SYSTEM_DB );
		} else {
			/* On Windows, we use the Evolution configdir. On other
			 * operating systems we use ~/.pki/nssdb/, which is where
			 * the user-specific part of the "shared system db" is
			 * stored and is what Chrome uses too.
			 *
			 * We have to create the configdir if it does not exist,
			 * to prevent camel from bailing out on first run. */
#ifdef G_OS_WIN32
			g_mkdir_with_parents (configdir, 0700);
			nss_sql_configdir = g_strconcat (
				"sql:", nss_configdir, NULL);
#else
			gchar *user_nss_dir = g_build_filename (
				g_get_home_dir (), ".pki/nssdb", NULL );
			if (g_mkdir_with_parents (user_nss_dir, 0700))
				g_warning (
					"Failed to create SQL "
					"database directory %s: %s\n",
					user_nss_dir, strerror (errno));

			nss_sql_configdir = g_strconcat (
				"sql:", user_nss_dir, NULL);
			g_free (user_nss_dir);
#endif
		}

#if NSS_VMAJOR > 3 || (NSS_VMAJOR == 3 && NSS_VMINOR >= 12)
		/* See: https://wiki.mozilla.org/NSS_Shared_DB,
		 * particularly "Mode 3A".  Note that the target
		 * directory MUST EXIST. */
		status = NSS_InitWithMerge (
			nss_sql_configdir,	/* dest dir */
			"", "",			/* new DB name prefixes */
			SECMOD_DB,		/* secmod name */
			nss_configdir,		/* old DB dir */
			"", "",			/* old DB name prefixes */
			nss_configdir,		/* unique ID for old DB */
			"Evolution S/MIME",	/* UI name for old DB */
			0);			/* flags */

		if (status == SECFailure) {
			g_warning (
				"Failed to initialize NSS SQL database in %s: NSS error %d",
				nss_sql_configdir, PORT_GetError ());
			/* Fall back to opening the old DBM database */
		}
#endif
		/* Support old versions of libnss, pre-sqlite support. */
		if (status == SECFailure)
			status = NSS_InitReadWrite (nss_configdir);
		if (status == SECFailure) {
			/* Fall back to using volatile dbs? */
			status = NSS_NoDB_Init (nss_configdir);
			if (status == SECFailure) {
				g_free (nss_configdir);
				g_free (nss_sql_configdir);
				g_warning ("Failed to initialize NSS");
				PR_Unlock (nss_initlock);
				return -1;
			}
		}

		nss_initialized = TRUE;
skip_nss_init:

		NSS_SetDomesticPolicy ();

		if (weak_ciphers) {
			PRUint16 indx;

			/* enable SSL3/TLS cipher-suites */
			for (indx = 0; indx < SSL_NumImplementedCiphers; indx++) {
				if (!SSL_IS_SSL2_CIPHER (SSL_ImplementedCiphers[indx]) &&
				    SSL_ImplementedCiphers[indx] != SSL_RSA_WITH_NULL_SHA &&
				    SSL_ImplementedCiphers[indx] != SSL_RSA_WITH_NULL_MD5)
					SSL_CipherPrefSetDefault (SSL_ImplementedCiphers[indx], PR_TRUE);
			}
		}

		SSL_OptionSetDefault (SSL_ENABLE_SSL2, v2_enabled ? PR_TRUE : PR_FALSE);
		SSL_OptionSetDefault (SSL_V2_COMPATIBLE_HELLO, PR_FALSE);
		SSL_OptionSetDefault (SSL_ENABLE_SSL3, PR_TRUE);
		SSL_OptionSetDefault (SSL_ENABLE_TLS, PR_TRUE);

		PR_Unlock (nss_initlock);

		g_free (nss_configdir);
		g_free (nss_sql_configdir);
	}

	path = g_strdup_printf ("%s/camel-cert.db", configdir);
	certdb = camel_certdb_new ();
	camel_certdb_set_filename (certdb, path);
	g_free (path);

	/* if we fail to load, who cares? it'll just be a volatile certdb */
	camel_certdb_load (certdb);

	/* set this certdb as the default db */
	camel_certdb_set_default (certdb);

	g_object_unref (certdb);

	initialised = TRUE;

	return 0;
}
pubkey_error_code pubkey_from_base64 (const char *pubkstr, pubkey_data **dst) {
  /* This is the ugly part. Inspired by https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/nss_sample_code/NSS_Sample_Code_sample5 */

  if (!NSS_IsInitialized ()) {
    if (SECSuccess != NSS_NoDB_Init (".")) {
      return pubkey_ec_nss_internal;
    }
  }

  PK11SlotInfo *slot = PK11_GetInternalKeySlot ();
  if (slot == NULL) {
    return pubkey_ec_nss_internal;
  }

  SECItem der;
  der.data = NULL;
  der.len = 0;
  der.type = 0;
  if (SECSuccess != ATOB_ConvertAsciiToItem (&der, pubkstr)) {
    PK11_FreeSlot(slot);
    return pubkey_ec_nss_internal;
  }

  SECKEYPublicKey *pubkey = my_SECKEY_DecodeDERPublicKey (&der);
  pubkey_error_code ec = pubkey_ec_ok;
  if (!pubkey) {
    ec = pubkey_ec_nss_internal;
  }
  SECITEM_FreeItem (&der, 0);
//  if (!ec && rsaKey != pubkey->keyType) {
//    ec = pubkey_ec_nss_internal;
//  }
  if (!ec && (siUnsignedInteger != pubkey->u.rsa.modulus.type)) {
    ec = pubkey_ec_nss_internal;
  }
  if (!ec && (siUnsignedInteger != pubkey->u.rsa.publicExponent.type)) {
    ec = pubkey_ec_nss_internal;
  }
  if (!ec && (PUBKEY_USE_MAX_MOD_LEN < pubkey->u.rsa.modulus.len)) {
    ec = pubkey_ec_too_large;
  }
  if (!ec && (4 < pubkey->u.rsa.publicExponent.len)) {
    ec = pubkey_ec_too_large;
  }

  *dst = NULL;
  if (!ec) {
    *dst = malloc (sizeof (pubkey_data));
    if (!*dst) {
      ec = pubkey_ec_nss_internal; // Lie.
    }
  }

  if (!ec) {
    assert(*dst);
    (*dst)->exponent = 0;
    const unsigned int e_len = pubkey->u.rsa.publicExponent.len;
    for (unsigned int i = 0; i < e_len; ++i) {
      (*dst)->exponent <<= 8;
      (*dst)->exponent |= pubkey->u.rsa.publicExponent.data[i];
    }
    const unsigned int m_len = pubkey->u.rsa.modulus.len;
    assert (m_len <= PUBKEY_USE_MAX_MOD_LEN);
    (*dst)->modulus_length = m_len;
    memcpy ((*dst)->modulus, pubkey->u.rsa.modulus.data, m_len);
  }

  if (pubkey) {
    SECKEY_DestroyPublicKey (pubkey);
  }
  assert (slot);
  PK11_FreeSlot (slot);

  return ec;
}