Exemplo n.º 1
0
char * PKI_CONFIG_find ( char *dir, char *name )
{
	struct dirent *dd = NULL;
	DIR *dirp = NULL;
	URL *url = NULL;

	int found = 0;
	char *ret = NULL;

	/* Check input */
	if( !dir || !name )
	{
		PKI_ERROR(PKI_ERR_PARAM_NULL, NULL);
		return (PKI_ERR);
	}

	if ((url = URL_new(dir)) == NULL)
	{
		PKI_log_debug("Dir [%s] is not a valid URI", dir );
		return (PKI_ERR);
	}

	if (url->proto != URI_PROTO_FILE)
	{
		PKI_log_debug("URL is not a file, skipping!", dir );
		return (PKI_ERR);
	}

	if ((dirp = opendir(url->addr)) == NULL)
	{
		PKI_log_debug("Can not open directory [%s]", url->addr );
		return (PKI_ERR);
	}
	else
	{
		while(( dd = readdir( dirp )) != NULL )
		{
			long len;
			char *filename = NULL;

			filename = dd->d_name;
			len = (long) strlen( filename );

			PKI_log_debug("Processing file [%s]", filename );

			if (len < 4 || strcmp(".xml", filename +len-4) != 0)
			{
				PKI_log_debug("Skipping %s", filename );
				continue;
			}
			else
			{
				char fullpath[BUFF_MAX_SIZE];
				size_t fullsize = 0;

				PKI_CONFIG *tmp_cfg = NULL;
				char *tmp_name = NULL;

				snprintf(fullpath, BUFF_MAX_SIZE,
					"%s/%s", url->addr, filename );

				PKI_log_debug("Opening File %s", fullpath );

				// Check the allowed size
				fullsize = strlen(url->addr) + strlen( filename ) + 1;
				if (fullsize > BUFF_MAX_SIZE) continue;
				
				if ((tmp_cfg = PKI_CONFIG_load(fullpath)) == NULL)
				{
					PKI_log_debug("Can not load %s", fullpath );
					continue;
				}

				PKI_log_debug("Getting Name Param... ");
				tmp_name = PKI_CONFIG_get_value(tmp_cfg, "/*/name");
				PKI_CONFIG_free(tmp_cfg);

				if (tmp_name != NULL)
				{
					PKI_log_debug("Got Name::%s", tmp_name);
					if (strcmp_nocase(tmp_name, name) == 0)
					{
						PKI_Free(tmp_name);
						tmp_name = NULL; // Safety

						found = 1;
						ret = strdup(fullpath);
						PKI_log_debug("File successfully loaded %s", fullpath );
						break;
					}
					PKI_Free(tmp_name);
					tmp_name = NULL; // Safety
				}
				else PKI_log_debug("No Name found!");
			}
		}
		closedir( dirp );
	}

	// Let's free the URL memory
	if (url) URL_free(url);

	// If found, let's return it
	if (found == 1) return ret;

	// If not found, we return NULL
	return NULL;
}
Exemplo n.º 2
0
PKI_X509_CERT * PKI_X509_CERT_new (const PKI_X509_CERT    * ca_cert, 
                                   const PKI_X509_KEYPAIR * kPair,
                                   const PKI_X509_REQ     * req,
                                   const char             * subj_s, 
                                   const char             * serial_s,
                                   uint64_t                 validity,
                                   const PKI_X509_PROFILE * conf,
                                   const PKI_ALGOR        * algor,
                                   const PKI_CONFIG       * oids,
                                   HSM *hsm ) {
  PKI_X509_CERT *ret = NULL;
  PKI_X509_CERT_VALUE *val = NULL;
  PKI_X509_NAME *subj = NULL;
  PKI_X509_NAME *issuer = NULL;
  PKI_DIGEST_ALG *digest = NULL;
  PKI_X509_KEYPAIR_VALUE *signingKey = NULL;
  PKI_TOKEN *tk = NULL;

  PKI_X509_KEYPAIR_VALUE  *certPubKeyVal = NULL;

  int rv = 0;
  int ver = 2;

  int64_t notBeforeVal = 0;

  ASN1_INTEGER *serial = NULL;

  char *ver_s = NULL;

  /* Check if the REQUIRED PKEY has been passed */
  if (!kPair || !kPair->value) {
    PKI_ERROR(PKI_ERR_PARAM_NULL, NULL);
    return (NULL);
  };

  signingKey = kPair->value;

  /* TODO: This has to be fixed, to work on every option */
  if ( subj_s )
  {
    subj = PKI_X509_NAME_new ( subj_s );
  }
  else if (conf || req)
  {
    char *tmp_s = NULL;

    // Let's use the configuration option first
    if (conf) {

      // Get the value of the DN, if present
      if ((tmp_s = PKI_CONFIG_get_value( conf, 
                                 "/profile/subject/dn")) != NULL ) {
        // Builds from the DN in the config  
        subj = PKI_X509_NAME_new(tmp_s);
        PKI_Free ( tmp_s );
      }
    }

    // If we still do not have a name, let's check
    // the request for one
    if (req && !subj) {

      const PKI_X509_NAME * req_subj = NULL;

      // Copy the name from the request
      if ((req_subj = PKI_X509_REQ_get_data(req, 
				    PKI_X509_DATA_SUBJECT)) != NULL) {
        subj = PKI_X509_NAME_dup(req_subj);
      }
    }

    // If no name is provided, let's use an empty one
    // TODO: Shall we remove this and fail instead ?
    if (!subj) subj = PKI_X509_NAME_new( "" );
  }
  else
  {
    struct utsname myself;
    char tmp_name[1024];

    if (uname(&myself) < 0) {
      subj = PKI_X509_NAME_new( "" );
    } else {
      sprintf( tmp_name, "CN=%s", myself.nodename );
      subj = PKI_X509_NAME_new( tmp_name );
    }
  }

  if (!subj) {
    PKI_ERROR(PKI_ERR_X509_CERT_CREATE_SUBJECT, subj_s );
    goto err;
  }

  if( ca_cert ) {
    const PKI_X509_NAME *ca_subject = NULL;

    /* Let's get the ca_cert subject and dup that data */
    // ca_subject = (PKI_X509_NAME *) 
    //     X509_get_subject_name( (X509 *) ca_cert );
    ca_subject = PKI_X509_CERT_get_data( ca_cert, 
        PKI_X509_DATA_SUBJECT );

    if( ca_subject ) {
      issuer = (PKI_X509_NAME *) X509_NAME_dup((X509_NAME *)ca_subject);
    } else {
      PKI_ERROR(PKI_ERR_X509_CERT_CREATE_ISSUER, NULL);
      goto err;
    }

  } else {
    issuer = (PKI_X509_NAME *) X509_NAME_dup((X509_NAME *) subj);
  }

  if( !issuer ) {
    PKI_ERROR(PKI_ERR_X509_CERT_CREATE_ISSUER, NULL);
    goto err;
  }

  if(( ret = PKI_X509_CERT_new_null()) == NULL ) {
    PKI_ERROR(PKI_ERR_OBJECT_CREATE, NULL);
    goto err;
  }

  /* Alloc memory structure for the Certificate */
  if((ret->value = ret->cb->create()) == NULL ) {
    PKI_ERROR(PKI_ERR_OBJECT_CREATE, NULL);
    return (NULL);
  }

  val = ret->value;

  if(( ver_s = PKI_CONFIG_get_value( conf, "/profile/version")) != NULL ) {
    ver = atoi( ver_s ) - 1;
    if ( ver < 0 ) 
      ver = 0;
    PKI_Free ( ver_s );
  } else {
    ver = 2;
  };

  if (!X509_set_version(val,ver)) {
    PKI_ERROR(PKI_ERR_X509_CERT_CREATE_VERSION, NULL);
    goto err;
  }

  if (serial_s) {
    char * tmp_s = (char *) serial_s;
    serial = s2i_ASN1_INTEGER(NULL, tmp_s);
  } else {
    // If cacert we assume it is a normal cert - let's create a
    // random serial number, otherwise - it's a self-signed, use
    // the usual 'fake' 0
    if ( ca_cert ) {
      unsigned char bytes[11];
      RAND_bytes(bytes, sizeof(bytes));
      bytes[0] = 0;

      serial = PKI_INTEGER_new_bin(bytes, sizeof(bytes));
    } else {
      serial = s2i_ASN1_INTEGER( NULL, "0");
    };
  };

  if(!X509_set_serialNumber( val, serial )) {
    PKI_ERROR(PKI_ERR_X509_CERT_CREATE_SERIAL, serial_s);
    goto err;
  }

  /* Set the issuer Name */
  // rv = X509_set_issuer_name((X509 *) ret, (X509_NAME *) issuer);
  if(!X509_set_issuer_name( val, (X509_NAME *) issuer)) {
    PKI_ERROR(PKI_ERR_X509_CERT_CREATE_ISSUER, NULL);
    goto err;
  }

  /* Set the subject Name */
  if(!X509_set_subject_name(val, (X509_NAME *) subj)) {
    PKI_ERROR(PKI_ERR_X509_CERT_CREATE_SUBJECT, NULL);
    goto err;
  }

  /* Set the start date (notBefore) */
  if (conf)
  {
    int years = 0;
    int days  = 0;
    int hours = 0;
    int mins  = 0;
    int secs  = 0;

    char *tmp_s = NULL;

    if(( tmp_s = PKI_CONFIG_get_value( conf, 
        "/profile/notBefore/years")) != NULL ) {
      years = atoi( tmp_s );
      PKI_Free ( tmp_s );
    };

    if(( tmp_s = PKI_CONFIG_get_value( conf, 
        "/profile/notBefore/days")) != NULL ) {
      days = atoi( tmp_s );
      PKI_Free ( tmp_s );
    };

    if(( tmp_s = PKI_CONFIG_get_value( conf, 
        "/profile/notBefore/hours")) != NULL ) {
      hours = atoi( tmp_s );
      PKI_Free ( tmp_s );
    };

    if(( tmp_s = PKI_CONFIG_get_value( conf, 
        "/profile/notBefore/minutes")) != NULL ) {
      mins = atoi( tmp_s );
      PKI_Free ( tmp_s );
    };

    if(( tmp_s = PKI_CONFIG_get_value( conf, 
        "/profile/notBefore/seconds")) != NULL ) {
      secs = atoi( tmp_s );
      PKI_Free ( tmp_s );
    };

    notBeforeVal =   secs +
            ( mins * 60 ) + 
            ( hours * 3600 ) + 
            ( days   * 3600 * 24 ) + 
            ( years * 3600 * 24 * 365 );
  };

  /* Set the validity (notAfter) */
  if( conf && validity == 0 )
  {
    long long years = 0;
    long long days  = 0;
    long long hours = 0;
    long long mins  = 0;
    long long secs  = 0;

    char *tmp_s = NULL;

    if(( tmp_s = PKI_CONFIG_get_value( conf, 
        "/profile/validity/years")) != NULL ) {
      years = atoll( tmp_s );
      PKI_Free ( tmp_s );
    };

    if(( tmp_s = PKI_CONFIG_get_value( conf, 
        "/profile/validity/days")) != NULL ) {
      days = atoll( tmp_s );
      PKI_Free ( tmp_s );
    };

    if(( tmp_s = PKI_CONFIG_get_value( conf, 
        "/profile/validity/hours")) != NULL ) {
      hours = atoll( tmp_s );
      PKI_Free ( tmp_s );
    };

    if(( tmp_s = PKI_CONFIG_get_value( conf, 
        "/profile/validity/minutes")) != NULL ) {
      mins = atoll( tmp_s );
      PKI_Free ( tmp_s );
    };

    if(( tmp_s = PKI_CONFIG_get_value( conf, 
        "/profile/validity/minutes")) != NULL ) {
      secs = atoll( tmp_s );
      PKI_Free ( tmp_s );
    };

    validity =   (unsigned long long) secs +
          (unsigned long long) ( mins   * 60 ) + 
          (unsigned long long) ( hours * 3600 ) + 
          (unsigned long long) ( days   * 3600 * 24 ) + 
          (unsigned long long) ( years * 3600 * 24 * 365 );
  };

  if (validity <= 0) validity = 30 * 3600 * 24;

#if ( LIBPKI_OS_BITS == LIBPKI_OS32 )
  long notBeforeVal32 = (long) notBeforeVal;
  if (X509_gmtime_adj(X509_get_notBefore(val), notBeforeVal32 ) == NULL)
  {
#else
  if (X509_gmtime_adj(X509_get_notBefore(val), notBeforeVal ) == NULL)
  {
#endif
    PKI_ERROR(PKI_ERR_X509_CERT_CREATE_NOTBEFORE, NULL);
    goto err;
  }

  /* Set the end date in a year */
  if (X509_gmtime_adj(X509_get_notAfter(val),(long int) validity) == NULL)
  {
    PKI_DEBUG("ERROR: can not set notAfter field!");
    goto err;
  }

  /* Copy the PKEY if it is in the request, otherwise use the
     public part of the PKI_X509_CERT */
  if (req)
  {
    certPubKeyVal = (PKI_X509_KEYPAIR_VALUE *) 
       PKI_X509_REQ_get_data(req, PKI_X509_DATA_KEYPAIR_VALUE);

    if( !certPubKeyVal ) {
      PKI_DEBUG("ERROR, can not get pubkey from req!");
      goto err;
    }
  }
  else
  {
    /* Self Signed -- Same Public Key! */
    certPubKeyVal = signingKey;
  }

  if (!ca_cert && conf)
  {
    char *tmp_s = NULL;

    if(( tmp_s = PKI_X509_PROFILE_get_value( conf, 
        "/profile/keyParams/algorithm")) != NULL )
    {
      PKI_ALGOR *myAlg = NULL;
      PKI_DIGEST_ALG *dgst = NULL;

      if((myAlg = PKI_ALGOR_get_by_name( tmp_s )) != NULL )
      {
        if(!algor) algor = myAlg;

        if((dgst = PKI_ALGOR_get_digest( myAlg )) != NULL )
        {
          PKI_DEBUG("Got Signing Algorithm: %s, %s",
            PKI_DIGEST_ALG_get_parsed(dgst), PKI_ALGOR_get_parsed(myAlg));
          digest = dgst;
        }
        else
        {
          PKI_DEBUG("Can not parse digest algorithm from %s", tmp_s);
        }
      }
      else
      {
        PKI_DEBUG("Can not parse key algorithm from %s", tmp_s);
      }
      PKI_Free ( tmp_s );
    }
  }

  if (conf)
  {
    PKI_KEYPARAMS *kParams = NULL;
    PKI_SCHEME_ID scheme;

    scheme = PKI_ALGOR_get_scheme( algor );

    kParams = PKI_KEYPARAMS_new(scheme, conf);
    if (kParams)
    {
      /* Sets the point compression */
      switch ( kParams->scheme )
      {
#ifdef ENABLE_ECDSA
        case PKI_SCHEME_ECDSA:
            if ( (int) kParams->ec.form > 0 )
            {
# if OPENSSL_VERSION_NUMBER < 0x1010000fL
              EC_KEY_set_conv_form(certPubKeyVal->pkey.ec, 
              			   (point_conversion_form_t) kParams->ec.form);
# else
              EC_KEY_set_conv_form(EVP_PKEY_get0_EC_KEY(certPubKeyVal), 
              (point_conversion_form_t) kParams->ec.form);
# endif
            }
          if ( kParams->ec.asn1flags > -1 )
          {
# if OPENSSL_VERSION_NUMBER < 0x1010000fL
            EC_KEY_set_asn1_flag(certPubKeyVal->pkey.ec,
              kParams->ec.asn1flags );
# else
            EC_KEY_set_asn1_flag(EVP_PKEY_get0_EC_KEY(certPubKeyVal),
              kParams->ec.asn1flags );
# endif
          }
          break;
#endif
        case PKI_SCHEME_RSA:
        case PKI_SCHEME_DSA:
          break;

        default:
          // Nothing to do
          PKI_ERROR(PKI_ERR_GENERAL, "Signing Scheme Uknown %d!", kParams->scheme);
          break;
      }
    }
  }

  if (!X509_set_pubkey(val, certPubKeyVal))
  {
    PKI_DEBUG("ERROR, can not set pubkey in cert!");
    goto err;
  }

  if (conf)
  {
    if((tk = PKI_TOKEN_new_null()) == NULL )
    {
      PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL);
      goto err;
    }

    PKI_TOKEN_set_cert(tk, ret);

    if (ca_cert) {
      PKI_TOKEN_set_cacert(tk, (PKI_X509_CERT *)ca_cert);
    } else {
      PKI_TOKEN_set_cacert(tk, (PKI_X509_CERT *)ret);
    }

    if (req) PKI_TOKEN_set_req(tk, (PKI_X509_REQ *)req );
    if (kPair) PKI_TOKEN_set_keypair ( tk, (PKI_X509_KEYPAIR *)kPair );

    rv = PKI_X509_EXTENSIONS_cert_add_profile(conf, oids, ret, tk);
    if (rv != PKI_OK)
    {
      PKI_DEBUG( "ERROR, can not set extensions!");

      tk->cert = NULL;
      tk->cacert = NULL;
      tk->req = NULL;
      tk->keypair = NULL;

      PKI_TOKEN_free ( tk );

      goto err;
    }

    // Cleanup for the token (used only to add extensions)
    tk->cert = NULL;
    tk->cacert = NULL;
    tk->req = NULL;
    tk->keypair = NULL;
    PKI_TOKEN_free ( tk );
  }

  if (!digest)
  {
    if (!algor)
    {
      PKI_log_debug("Getting the Digest Algorithm from the CA cert");

      // Let's get the Digest Algorithm from the CA Cert
      if (ca_cert)
      {
        if((algor = PKI_X509_CERT_get_data(ca_cert,
              PKI_X509_DATA_ALGORITHM )) == NULL)
        {
          PKI_log_err("Can not retrieve DATA algorithm from CA cert");
        }
      }
    }

    // If we have an Algor from either the passed argument or
    // the CA Certificate, extract the digest from it. Otherwise
    // get the digest from the signing key
    if (algor)
    {
      if((digest = PKI_ALGOR_get_digest(algor)) == NULL )
      {
        PKI_log_err("Can not get digest from algor");
      }
    }

    // Check, if still no digest, let's try from the signing Key
    if (digest == NULL)
    {
      if ((digest = PKI_DIGEST_ALG_get_by_key( kPair )) == NULL)
      {
        PKI_log_err("Can not infer digest algor from the key pair");
      }
    }
  }

  // No Digest Here ? We failed...
  if (digest == NULL)
  {
    PKI_log_err("PKI_X509_CERT_new()::Can not get the digest!");
    return( NULL );
  }

  // Sign the data
  if (PKI_X509_sign(ret, digest, kPair) == PKI_ERR)
  {
    PKI_log_err ("Can not sign certificate [%s]",
      ERR_error_string(ERR_get_error(), NULL ));
    PKI_X509_CERT_free ( ret );
    return NULL;
  }

#if ( OPENSSL_VERSION_NUMBER >= 0x0090900f )

# if OPENSSL_VERSION_NUMBER < 0x1010000fL
  PKI_X509_CERT_VALUE *cVal = (PKI_X509_CERT_VALUE *) ret->value;

  if (cVal && cVal->cert_info)
  {
    PKI_log_debug("Signature = %s", 
      PKI_ALGOR_get_parsed(cVal->cert_info->signature));
  }
# endif

  //  PKI_X509_CINF_FULL *cFull = NULL;
  //  cFull = (PKI_X509_CINF_FULL *) cVal->cert_info;
  //  cFull->enc.modified = 1;
#endif

  return ret;

err:

  if (ret) PKI_X509_CERT_free(ret);
  if (subj) PKI_X509_NAME_free(subj);
  if (issuer) PKI_X509_NAME_free(issuer);

  return NULL;
}

/*!
 * \brief Signs a PKI_X509_CERT
 */

int PKI_X509_CERT_sign(PKI_X509_CERT *cert, PKI_X509_KEYPAIR *kp,
    PKI_DIGEST_ALG *digest) {

  const PKI_ALGOR *alg = NULL;

  if( !cert || !cert->value || !kp || !kp->value ) {
    PKI_ERROR(PKI_ERR_PARAM_NULL, NULL);
    return PKI_ERR;
  }

  if(!digest) {
    if((alg = PKI_X509_CERT_get_data(cert, PKI_X509_DATA_ALGORITHM))!=NULL) {
      digest = PKI_ALGOR_get_digest ( alg );
    }
  }

  if(!digest) {
    if((digest = PKI_DIGEST_ALG_get_by_key(kp)) == NULL) {
      PKI_log_err("PKI_X509_CERT_new()::Can not get digest algor "
          "from key");
      return PKI_ERR;
    }
  }

  if( PKI_X509_sign(cert, digest, kp) == PKI_ERR) {
    PKI_log_err ("PKI_X509_CERT_new()::Can not sign certificate [%s]",
      ERR_error_string(ERR_get_error(), NULL ));
    return PKI_ERR;
  }

  return PKI_OK;
};

/*!
 * \brief Signs a PKI_X509_CERT by using a configured PKI_TOKEN
 */

int PKI_X509_CERT_sign_tk ( PKI_X509_CERT *cert, PKI_TOKEN *tk,
    PKI_DIGEST_ALG *digest) {

  PKI_X509_KEYPAIR *kp = NULL;

  if( !cert || !cert->value || !tk ) {
    PKI_ERROR(PKI_ERR_PARAM_NULL, NULL);
    return PKI_ERR;
  };

  if( PKI_TOKEN_login( tk ) == PKI_ERR ) {
    PKI_ERROR(PKI_ERR_HSM_LOGIN, NULL);
    return PKI_ERR;
  };

  if((kp = PKI_TOKEN_get_keypair( tk )) == NULL ) {
    return PKI_ERR;
  };

  return PKI_X509_CERT_sign ( cert, kp, digest );
};
Exemplo n.º 3
0
int OCSPD_build_ca_list ( OCSPD_CONFIG *handler,
			PKI_CONFIG_STACK *ca_conf_sk) {

	int i = 0;
	PKI_STACK *ca_list = NULL;

	PKI_log_debug("Building CA List");

	if ( !ca_conf_sk ) {
		PKI_log( PKI_LOG_ERR, "No stack of ca configs!");
		return ( PKI_ERR );
	}

	if((ca_list = PKI_STACK_new((void (*))CA_LIST_ENTRY_free)) == NULL ) {
		PKI_log_err ( "Memory Error");
	return ( PKI_ERR );
	}

	for (i = 0; i < PKI_STACK_CONFIG_elements( ca_conf_sk ); i++)
	{
		char *tmp_s = NULL;
		URL *tmp_url = NULL;
		PKI_X509_CERT *tmp_cert = NULL;

		CA_LIST_ENTRY *ca = NULL;
		PKI_CONFIG *cnf = NULL;

		/* Get the current Configureation file */
		cnf = PKI_STACK_CONFIG_get_num( ca_conf_sk, i );
		if (!cnf) continue;

		/* Get the CA cert from the cfg file itself */
		if((tmp_s = PKI_CONFIG_get_value( cnf, "/caConfig/caCertValue" )) == NULL )
		{
			/* Get the CA parsed url */
			if((tmp_url = URL_new( PKI_CONFIG_get_value( cnf, "/caConfig/caCertUrl" ))) == NULL )
			{
				/* Error, can not parse url data */
				PKI_log( PKI_LOG_ERR, "Can not parse CA cert url (%s)", 
					PKI_CONFIG_get_value(cnf, "/caConfig/caCertUrl"));

				continue;
			}

			if((tmp_cert = PKI_X509_CERT_get_url(tmp_url, NULL, NULL ))== NULL)
			{
				PKI_log_err("Can not get CA cert from (%s)", tmp_url);
				URL_free (tmp_url);

				continue;
			}
		}
		else
		{
			PKI_X509_CERT_STACK *cc_sk = NULL;
			PKI_MEM *mm = NULL;

			if((mm = PKI_MEM_new_null()) == NULL )
			{
				PKI_Free(tmp_s);
				continue;
			}

			PKI_MEM_add ( mm, tmp_s, strlen(tmp_s));

			if((cc_sk=PKI_X509_CERT_STACK_get_mem(mm, NULL)) == NULL )
			{
				PKI_log_err ( "Can not parse cert from /caConfig/caCertValue");
				PKI_Free(tmp_s);

				continue;
			}

			if ((tmp_cert = PKI_STACK_X509_CERT_pop( cc_sk )) == NULL )
			{
				PKI_log_err ( "No elements on stack from /caConfig/caCertValue");

				PKI_STACK_X509_CERT_free_all(cc_sk);
				PKI_Free(tmp_s);

				continue;
			}

			PKI_STACK_X509_CERT_free ( cc_sk );
			PKI_Free(tmp_s);
		}

		/* OCSPD create the CA entry */
		if ((ca = CA_LIST_ENTRY_new()) == NULL )
		{
			PKI_log_err ( "CA List structure init error");

			/* remember to do THIS!!!! */
			if( tmp_url ) URL_free ( tmp_url );
			if( tmp_cert ) PKI_X509_CERT_free ( tmp_cert );

			continue;
		}

		ca->ca_cert = tmp_cert;
		tmp_cert = NULL;

		ca->ca_url = tmp_url;
		tmp_url = NULL;

		ca->ca_id = PKI_CONFIG_get_value( cnf, "/caConfig/name" );
		ca->cid = CA_ENTRY_CERTID_new ( ca->ca_cert, handler->digest );

		/* Get the CRL URL and the CRL itself */
		if((tmp_s = PKI_CONFIG_get_value(cnf, "/caConfig/crlUrl")) == NULL)
		{
			PKI_STACK *cdp_sk = NULL;

			/* Now let's get it from PRQP */

			/* Now from the Certificate */
			
			if((cdp_sk = PKI_X509_CERT_get_cdp (ca->ca_cert)) ==NULL)
			{
				// No source for the CRL Distribution Point
				PKI_log_err ( "ERROR::Can not find the CDP for %s, skipping CA", ca->ca_id );

				CA_LIST_ENTRY_free ( ca );
				continue;
			}

			while ((tmp_s = PKI_STACK_pop ( cdp_sk )) != NULL)
			{
				if ((ca->crl_url = URL_new ( tmp_s )) == NULL )
				{
					PKI_log_err( "URL %s not in the right format!");
					CA_LIST_ENTRY_free ( ca );
					continue;
				}
				else if( tmp_s ) PKI_Free ( tmp_s );

				break;
			}
		}
		else
		{
			PKI_log_debug("Got CRL Url -> %s", tmp_s );

			if((ca->crl_url = URL_new ( tmp_s )) == NULL )
			{
				PKI_log_err ("Error Parsing CRL URL [%s] for CA [%s]", ca->ca_id, tmp_s);

				CA_LIST_ENTRY_free ( ca );
				PKI_Free(tmp_s);

				continue;
			}

			PKI_Free(tmp_s);
		}

		if(OCSPD_load_crl ( ca, handler ) == PKI_ERR )
		{
			PKI_log_err ( "Can not get CRL for %s", ca->ca_id);
			CA_LIST_ENTRY_free ( ca );

			continue;
		}

		/* If the Server has a Token to be used with this CA, let's
                   load it */
		if((tmp_s = PKI_CONFIG_get_value ( cnf, "/caConfig/serverToken" )) == NULL)
		{
			/* No token in config, let's see if a specific cert
			   is configured */
			ca->token = NULL;

			if((tmp_s = PKI_CONFIG_get_value ( cnf, "/caConfig/serverCertUrl" )) == NULL )
			{
				/* No cert is configured, we will use the defaults */
				ca->server_cert = NULL;
			}
			else
			{
				/* The Server's cert URL is found, let's load the certificate */
				if ((tmp_cert = PKI_X509_CERT_get ( tmp_s, NULL, NULL )) == NULL )
				{
					PKI_log_err("Can not get server's cert from %s!", tmp_s );

					CA_LIST_ENTRY_free ( ca );
					PKI_Free(tmp_s);

					continue;
				}
				else
				{
					ca->server_cert = tmp_cert;
				}

				PKI_Free(tmp_s);
			}
		}
		else
		{
			/* A Token for this CA is found - we do not load
 			   it to avoid problems with Thread Initialization */
			ca->server_cert = NULL;
			ca->token_name = tmp_s;
			ca->token = PKI_TOKEN_new_null();

			if ((tmp_s = PKI_CONFIG_get_value ( cnf, "/caConfig/pkiConfigDir" )) != NULL) {
				ca->token_config_dir = strdup( tmp_s );
				PKI_Free(tmp_s);
			}
			else
			{
				ca->token_config_dir = strdup(handler->token_config_dir);
			}
		}

		if((tmp_s = PKI_CONFIG_get_value ( cnf, "/caConfig/caCompromised" )) == NULL) {
			ca->compromised = 0;
		}
		else
		{
			ca->compromised = atoi(tmp_s);
			PKI_Free(tmp_s);
		}

		/* Responder Id Type */
		if ((tmp_s = PKI_CONFIG_get_value(cnf, "/caConfig/responderIdType")) != NULL)
		{
			if (strncmp_nocase(tmp_s, "keyid", 5) == 0) 
			{
				ca->response_id_type = PKI_X509_OCSP_RESPID_TYPE_BY_KEYID;
			}
			else if (strncmp_nocase(tmp_s, "name", 4) == 0)
			{
				ca->response_id_type = PKI_X509_OCSP_RESPID_TYPE_BY_NAME;
			}
			else
			{
				PKI_log_err("Can not parse responderIdType: %s (allowed 'keyid' or 'name')", tmp_s);
				exit(1);
			}

			PKI_Free(tmp_s);
		}
		else
		{
			// Default Value
			ca->response_id_type = PKI_X509_OCSP_RESPID_TYPE_BY_NAME;
		}

		// Now let's add the CA_LIST_ENTRY to the list of configured CAs
		PKI_STACK_push ( ca_list, ca );

	}

	handler->ca_list = ca_list;

	return ( PKI_OK );
}
Exemplo n.º 4
0
PKI_X509_CRL *PKI_X509_CRL_new(const PKI_X509_KEYPAIR *k,
             const PKI_X509_CERT *cert, 
             const char * crlNumber_s,
             unsigned long validity,
             const PKI_X509_CRL_ENTRY_STACK *sk, 
             const PKI_X509_PROFILE *profile,
             const PKI_CONFIG *oids,
             HSM *hsm) {

  PKI_X509_CRL *ret = NULL;
  PKI_X509_CRL_VALUE *val = NULL;
  ASN1_INTEGER *crlNumber = NULL;
  ASN1_TIME *time = NULL;
  int rv = PKI_OK;
  int i = 0;

  char * tmp_s = NULL;

  PKI_X509_CRL_ENTRY *entry = NULL;

  PKI_DIGEST_ALG *dgst = NULL;

  long long lastUpdateVal  = 0;
  long long nextUpdateVal  = 0;

  /* Checks for the Key and its internal value */
  if( !k || !k->value ) return NULL;

  /* checks for the certificate and its internal value */
  if( !cert || !cert->value ) return ( NULL );

  if(( ret = PKI_X509_CRL_new_null()) == NULL ) {
    PKI_ERROR(PKI_ERR_OBJECT_CREATE, NULL);
    goto err;
  }

  /* Alloc memory structure for the Certificate */
  if((ret->value = ret->cb->create()) == NULL ) {
    PKI_ERROR(PKI_ERR_OBJECT_CREATE, NULL);
    goto err;
  }

  val = ret->value;

  if ( !crlNumber_s && profile ) {

    if(( tmp_s = PKI_CONFIG_get_value( profile, 
        "/profile/crlNumber")) != NULL ) {
      crlNumber = PKI_INTEGER_new_char ( tmp_s );
      PKI_Free ( tmp_s );
    };
  } else if ( crlNumber_s ) {
    crlNumber = PKI_INTEGER_new_char( crlNumber_s );

    // Let's add the CRLSerial extension
    X509_CRL_add1_ext_i2d(val, NID_crl_number, crlNumber, 0, 0);
  };

  /* Set the start date (notBefore) */
  if (profile)
  {
    int years = 0;
    int days  = 0;
    int hours = 0;
    int mins  = 0;
    int secs  = 0;

    if(( tmp_s = PKI_CONFIG_get_value( profile, 
        "/profile/notBefore/years")) != NULL ) {
      years = atoi( tmp_s );
      PKI_Free ( tmp_s );
    };

    if(( tmp_s = PKI_CONFIG_get_value( profile, 
        "/profile/notBefore/days")) != NULL ) {
      days = atoi( tmp_s );
      PKI_Free ( tmp_s );
    };

    if(( tmp_s = PKI_CONFIG_get_value( profile, 
        "/profile/notBefore/hours")) != NULL ) {
      hours = atoi( tmp_s );
      PKI_Free ( tmp_s );
    };

    if(( tmp_s = PKI_CONFIG_get_value( profile, 
        "/profile/notBefore/minutes")) != NULL ) {
      mins = atoi( tmp_s );
      PKI_Free ( tmp_s );
    };

    if(( tmp_s = PKI_CONFIG_get_value( profile, 
        "/profile/notBefore/minutes")) != NULL ) {
      secs = atoi( tmp_s );
      PKI_Free ( tmp_s );
    };

    lastUpdateVal = secs +
            ( mins * 60 ) + 
            ( hours * 3600 ) + 
            ( days   * 3600 * 24 ) + 
            ( years * 3600 * 24 * 365 );
  } 
  else 
  {
    // Sets lastUpdate to current time
    lastUpdateVal = 0;
  };

  if ( profile && validity <= 0 ) {
    long long years = 0;
    long long days = 0;
    long long hours = 0;
    long long mins = 0;
    long long secs = 0;

    if((tmp_s = PKI_CONFIG_get_value ( profile,
          "/profile/validity/years")) != NULL ) {
      years = atoll( tmp_s );
      PKI_Free(tmp_s);
    }

    if((tmp_s = PKI_CONFIG_get_value ( profile,
          "/profile/validity/days")) != NULL ) {
      days = atoll( tmp_s );
      PKI_Free( tmp_s );
    }

    if((tmp_s = PKI_CONFIG_get_value ( profile,
          "/profile/validity/hours")) != NULL ) {
      hours = atoll( tmp_s );
      PKI_Free( tmp_s );
    }

    if((tmp_s = PKI_CONFIG_get_value ( profile,
          "/profile/validity/mins")) != NULL ) {
      mins = atoll( tmp_s );
      PKI_Free ( tmp_s );
    }

    if((tmp_s = PKI_CONFIG_get_value ( profile,
          "/profile/validity/secs")) != NULL ) {
      secs = atoll( tmp_s );
      PKI_Free ( tmp_s );
    }

    nextUpdateVal = secs + 
        60 * ( mins + 
          60 * (hours + 
            24 * ( days + 
              365 * years 
                 )
               )
            );
  } 
  else
  {
    nextUpdateVal = (long long) validity;
  };

  /* Generates a new time for lastUpdate field */
  if((time = PKI_TIME_new( lastUpdateVal )) == NULL ) {
    PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL);
    goto err;
  };

  /* Set the Last Update field */
  if(X509_CRL_set_lastUpdate( val, time ) == 0 ) {
    PKI_log_err ( "ERROR, can not set lastUpdate field in CRL");
    goto err;
  }
  PKI_TIME_free ( time );
  time = NULL; // Memory

  /* Generates a new time for lastUpdate field */
  if((time = PKI_TIME_new( nextUpdateVal )) == NULL ) {
    PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL);
    goto err;
  };

  /* Set the nextUpdate field */
  if(X509_CRL_set_nextUpdate( val, time ) == 0 ) {
    PKI_log_err ( "ERROR, can not set lastUpdate field in CRL");
    goto err;
  }
  PKI_TIME_free ( time );
  time = NULL; // Memory

  /* Now we need to add the CRL issuer name and details */
  if (X509_CRL_set_issuer_name( val, 
        X509_get_subject_name(cert->value)) == 0) {
    PKI_log_debug( "Can not set CRL issuer name");
    goto err;
  }

  if ( sk ) {
    /* Adds the list of revoked certificates */
    for(i=0; i < PKI_STACK_X509_CRL_ENTRY_elements(sk); i++ ) {
      PKI_log_debug("CRL::ADDING ENTRY %d\n", i );

      entry = PKI_STACK_X509_CRL_ENTRY_get_num(sk, i);
      if(!entry) break;

      X509_CRL_add0_revoked(val, entry);
    };
  }

  /* Sorts the CRL entries */
  X509_CRL_sort ( val );

  /*
  if((ret = PKI_X509_new_value( PKI_DATATYPE_X509_CRL, val, hsm)) == NULL ) {
    PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL);
    X509_CRL_free ( val );
    return ( NULL );
  }
  */

  /* Get the extensions from the profile */
  if( profile ) {
    PKI_TOKEN * tk;

    if((tk = PKI_TOKEN_new_null()) == NULL ) {
      PKI_log_err ( "Memory allocation failure");
      PKI_X509_CRL_free ( ret );
      return NULL;
    }

    PKI_TOKEN_set_cert(tk, (PKI_X509_CERT *)cert);
    PKI_TOKEN_set_keypair(tk, (PKI_X509_KEYPAIR *)k);

    if(PKI_X509_EXTENSIONS_crl_add_profile( profile, oids, ret, tk) == 0 ) {
          PKI_log_debug( "ERROR, can not set extensions!");
      PKI_X509_CRL_free ( ret );

      tk->cert = NULL;
      tk->keypair = NULL;
      PKI_TOKEN_free ( tk );

      return ( NULL );
    }
    tk->cert = NULL;
    tk->keypair = NULL;
    PKI_TOKEN_free ( tk );
  }

  /* Get the Digest Algorithm */
  if( (dgst = PKI_DIGEST_ALG_get_by_key( k )) == NULL ) {
    PKI_log_err("Can not get digest algor from keypair!");
    goto err;
  }
  
  rv = PKI_X509_sign ( ret, dgst, k );

  if ( rv == PKI_ERR ) {
    PKI_log_debug ("ERROR, can not sign CRL!");
    goto err;
  }

  return( ret );

err:

  if ( time ) PKI_TIME_free ( time );
  if ( ret ) PKI_X509_CRL_free ( ret );
  return NULL;
}
Exemplo n.º 5
0
/* Functions */
OCSPD_CONFIG * OCSPD_load_config(char *configfile)
{
	OCSPD_CONFIG *h = NULL;
	PKI_CONFIG *cnf = NULL;
	PKI_CONFIG_STACK *ca_config_stack = NULL;

	char *tmp_s = NULL;
	char *tmp_s2 = NULL;

	int i;

	/* Check for the environment variable PRQP_CONF */
	if (configfile == NULL) configfile = getenv("OCSPD_CONF");

	/* If not, check for the default CONFIG_FILE */
	if (configfile == NULL) configfile = CONFIG_FILE;

	if( !configfile ) {
		/* No config file is available */
		PKI_log(PKI_LOG_ERR, "No config file provided!");
		return (NULL);
	}

	/* Load the config file */
	if(( cnf = PKI_CONFIG_load ( configfile )) == NULL ) {
		PKI_log( PKI_LOG_ERR, "Can not load config file [%s]!",
			configfile );
		return (NULL);
	}
	if(( h = (OCSPD_CONFIG *)PKI_Malloc(sizeof(OCSPD_CONFIG))) == NULL) {
		PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL);
		goto err;
	}

	/* Set the group and user string to NULL */
	h->user = NULL;
	h->group = NULL;

	/* Set the PRQPD verbose status */
	h->verbose   = 0;
	h->debug     = 0;
	h->nthreads  = 5;
	h->http_proto = "1.0";
	h->max_timeout_secs = 5;

	h->crl_auto_reload = 3600;
	h->crl_reload_expired = 1;
	h->crl_check_validity = 600;

	/* Copy the config filename so that it could be re-loaded on SIGHUP */
	h->cnf_filename = strdup( configfile );

	/* Initialize the COND variables and MUTEXES */
	for( i = 0; i < sizeof ( h->mutexes ) / sizeof( PKI_MUTEX ); i++ )
	{
		PKI_MUTEX_init ( &h->mutexes[i] );
	}

	for( i = 0; i < sizeof ( h->condVars ) / sizeof( PKI_COND ); i++)
	{
		PKI_COND_init ( &h->condVars[i] );
	}

	PKI_RWLOCK_init ( &h->crl_lock );

	/* Token Initialization */
	if (( tmp_s = PKI_CONFIG_get_value( cnf, "/serverConfig/general/pkiConfigDir")) == NULL)
	{
		PKI_log_err("Missing pkiConfigDir in configuration!");
		return NULL;
	}
	else 
	{
		if ((tmp_s2 = PKI_CONFIG_get_value( cnf, "/serverConfig/general/token" )) != NULL)
		{
			h->token_name = strdup( tmp_s2 );
			h->token_config_dir = strdup ( tmp_s );

			if ((h->token = PKI_TOKEN_new_null()) == NULL)
			{
				PKI_log( PKI_LOG_ERR, "Memory error for new token");
				exit(1);
			}

			PKI_Free(tmp_s2);
		}
		else
		{
			PKI_log_err("No General Token provided in configuration.");

			PKI_Free(tmp_s);
			return NULL;
		}

		PKI_Free(tmp_s);
	}

	/* Thread configuration */
	if((tmp_s = PKI_CONFIG_get_value(cnf, "/serverConfig/general/spawnThreads")) != NULL)
	{
		int t = 0;
		if((t = atoi( tmp_s )) > 0 ) h->nthreads = t;

		PKI_Free(tmp_s);
	}

	if((tmp_s = PKI_CONFIG_get_value( cnf, "/serverConfig/general/caConfigDir")) != NULL)
	{
		h->ca_config_dir = strdup(tmp_s);

		ca_config_stack = PKI_CONFIG_load_dir(h->ca_config_dir, NULL);
		if (ca_config_stack == NULL)
		{
			PKI_log( PKI_LOG_ERR, "Can't load caConfigDir (%s)", h->ca_config_dir);
			PKI_Free(tmp_s);

			goto err;
		}

		PKI_Free(tmp_s);
	}
	else
	{
		PKI_log( PKI_LOG_ERR, "/serverConfig/general/caConfigDir needed in conf!\n");
		goto err;
	}

	/* Pid File */
	if((tmp_s = PKI_CONFIG_get_value( cnf, "/serverConfig/general/pidFile")) != NULL )
	{
		h->pidfile = strdup(tmp_s);

		PKI_Free(tmp_s);
	}

	/* AutoReload timeout */
	if((tmp_s = PKI_CONFIG_get_value( cnf, 
		"/serverConfig/general/crlAutoReload")) != NULL)
	{
		h->crl_auto_reload = atoi(tmp_s);

		if( h->crl_auto_reload <= 0 )
		{
			h->crl_auto_reload = 0;
			PKI_log(PKI_LOG_INFO, "Auto Reload Disabled");
		}

		PKI_Free(tmp_s);
	}

	/* CRL validity check timeout */
	if((tmp_s = PKI_CONFIG_get_value( cnf, 
			"/serverConfig/general/crlCheckValidity")) != NULL )
	{
		h->crl_check_validity = atoi(tmp_s);
		if ( h->crl_check_validity <= 0 )
		{
			h->crl_check_validity = 0;
			PKI_log(PKI_LOG_INFO, "CRL check validity disabled");
		}

		PKI_Free(tmp_s);
	}

	/* AutoReload timeout */
	if ((tmp_s = PKI_CONFIG_get_value( cnf, 
				"/serverConfig/general/crlReloadExpired")) != NULL )
	{
		if (strncmp_nocase(tmp_s, "n", 1) == 0)
		{
			h->crl_reload_expired = 0;
			PKI_log(PKI_LOG_INFO, "Expired CRLs Reload Disabled");
		}

		PKI_Free(tmp_s);
	}

	/* Server Privileges */
	if ((tmp_s = PKI_CONFIG_get_value(cnf, "/serverConfig/security/user")) != NULL)
	{
		h->user = strdup(tmp_s);
		PKI_Free(tmp_s);
	}

	if ((tmp_s = PKI_CONFIG_get_value( cnf, "/serverConfig/security/group" )) != NULL)
	{
		h->group = strdup(tmp_s);
		PKI_Free(tmp_s);
	}

	if ((tmp_s = PKI_CONFIG_get_value( cnf, "/serverConfig/security/chrootDir" )) != NULL )
	{
		h->chroot_dir = strdup(tmp_s);
		PKI_Free(tmp_s);
	}

	/* Bind Address */
	if((tmp_s = PKI_CONFIG_get_value( cnf, "/serverConfig/network/bindAddress" )) == NULL)
	{
		// If not bindAddress, let's use the universal one
		tmp_s = strdup("http://0.0.0.0:2560");
	}

	if ((h->bindUrl = URL_new( tmp_s )) == NULL)
	{
		PKI_log( PKI_LOG_ERR, "Can't parse bindAddress (%s)", tmp_s );
		PKI_Free(tmp_s);

		goto err;
	}

	// We need to free the tmp_s
	PKI_Free(tmp_s);

	/* HTTP Version */
	if((tmp_s = PKI_CONFIG_get_value( cnf, "/serverConfig/network/httpProtocol")) != NULL)
	{
		h->http_proto = strdup(tmp_s);
		PKI_Free(tmp_s);
	}

	/* Timeout for incoming connections */
	if((tmp_s = PKI_CONFIG_get_value( cnf, "/serverConfig/network/timeOut")) != NULL )
	{
		long t = 0;

		if ((t = atol( tmp_s )) > 0) h->max_timeout_secs = (unsigned int) t;
		PKI_Free(tmp_s);
	}

	/* Maximum Request Size */
	if((tmp_s = PKI_CONFIG_get_value( cnf,
				"/serverConfig/response/maxReqSize" )) != NULL ) {
		int t = 0;

		if((t = atoi( tmp_s )) > 0 ) {
			h->max_req_size = t;
		}
		PKI_Free(tmp_s);
	}


	// Default
	h->digest = PKI_DIGEST_ALG_SHA1;

	/* Digest Algorithm to be used */
	if ((tmp_s = PKI_CONFIG_get_value(cnf, "/serverConfig/response/digestAlgorithm" )) != NULL)
	{
		h->digest = PKI_DIGEST_ALG_get_by_name( tmp_s );

		if (!h->digest) 
		{
			PKI_log_err("Can not parse response digest algorithm: %s", tmp_s);
			exit(1);
		}
		else PKI_log_debug("Selected response digest algorithm: %s", tmp_s);

		PKI_Free(tmp_s);
	}

	/* Signing Digest Algorithm to be used */
	if((tmp_s = PKI_CONFIG_get_value( cnf,
			"/serverConfig/response/signatureDigestAlgorithm" )) == NULL)
	{
		PKI_log_debug("No specific signature digest algorithm selected.");
		h->sigDigest = NULL;
	}
	else
	{
		h->sigDigest = PKI_DIGEST_ALG_get_by_name( tmp_s );

		if (!h->sigDigest) 
		{
			PKI_log_err("Can not parse signing digest algorithm: %s", tmp_s);
			exit(1);
		}
		else PKI_log_debug("Selected signature digest algorithm: %s", tmp_s);

		PKI_Free(tmp_s);
	}

	/* Now Parse the PRQP Response Section */
	if ((tmp_s = PKI_CONFIG_get_value( cnf, "/serverConfig/response/validity/days" )) != NULL)
	{
		h->ndays = atoi(tmp_s);
		PKI_Free(tmp_s);
	}

	if ((tmp_s = PKI_CONFIG_get_value( cnf, "/serverConfig/response/validity/mins" )) != NULL)
	{
		h->nmin = atoi(tmp_s);
		PKI_Free(tmp_s);
	}

	h->set_nextUpdate = h->ndays * 3600 + h->nmin * 60;

	/* Database Options */
	if ((tmp_s = PKI_CONFIG_get_value( cnf, "/serverConfig/general/dbUrl")) != NULL)
	{
		if ((h->db_url = URL_new ( tmp_s )) == NULL)
		{
			PKI_log_err ( "Database Url not parsable (%s)", tmp_s );
			PKI_Free(tmp_s);
			goto err;
		}

		PKI_Free(tmp_s);
	}

	/* Database Persistant */
	if ((tmp_s = PKI_CONFIG_get_value( cnf, "/serverConfig/general/dbPersistant")) != NULL)
	{
		if (strncmp_nocase ( "n", tmp_s, 1 ) == 0 )
			h->db_persistant = 0;
		else 
			h->db_persistant = 1;

		PKI_Free(tmp_s);
	}

	/* Now we should load the CA configuration files and generate the
	   CERT_ID for the different CAs */
	if ((OCSPD_build_ca_list( h, ca_config_stack )) == PKI_ERR )
	{

		PKI_log(PKI_LOG_ERR, "Can not build CA list!");
		if (ca_config_stack) PKI_STACK_CONFIG_free ( ca_config_stack );
		goto err;
	}

	if (ca_config_stack) PKI_STACK_CONFIG_free ( ca_config_stack );

	return ( h );

err:
	if( ca_config_stack ) PKI_STACK_CONFIG_free ( ca_config_stack );
	if( cnf ) PKI_CONFIG_free ( cnf );
	if( h ) PKI_Free ( h );

	return( NULL );
}