Ejemplo n.º 1
0
/* type is a 'bitmap' of acceptable string types.
 */
ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a, const unsigned char **pp,
	     long length, int type)
	{
	ASN1_STRING *ret=NULL;
	const unsigned char *p;
	unsigned char *s;
	long len;
	int inf,tag,xclass;
	int i=0;

	p= *pp;
	inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
	if (inf & 0x80) goto err;

	if (tag >= 32)
		{
		i=ASN1_R_TAG_VALUE_TOO_HIGH;
		goto err;
		}
	if (!(ASN1_tag2bit(tag) & type))
		{
		i=ASN1_R_WRONG_TYPE;
		goto err;
		}

	/* If a bit-string, exit early */
	if (tag == V_ASN1_BIT_STRING)
		return(d2i_ASN1_BIT_STRING(a,pp,length));

	if ((a == NULL) || ((*a) == NULL))
		{
		if ((ret=ASN1_STRING_new()) == NULL) return(NULL);
		}
	else
		ret=(*a);

	if (len != 0)
		{
		s=(unsigned char *)OPENSSL_malloc((int)len+1);
		if (s == NULL)
			{
			i=ERR_R_MALLOC_FAILURE;
			goto err;
			}
		memcpy(s,p,(int)len);
		s[len]='\0';
		p+=len;
		}
	else
		s=NULL;

	if (ret->data != NULL) OPENSSL_free(ret->data);
	ret->length=(int)len;
	ret->data=s;
	ret->type=tag;
	if (a != NULL) (*a)=ret;
	*pp=p;
	return(ret);
err:
	OPENSSL_PUT_ERROR(ASN1, i);
	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
		ASN1_STRING_free(ret);
	return(NULL);
	}
Ejemplo n.º 2
0
int test_builtin(BIO *out) {
  size_t n = 0;
  EC_KEY *eckey = NULL, *wrong_eckey = NULL;
  EC_GROUP *group;
  ECDSA_SIG *ecdsa_sig = NULL;
  unsigned char digest[20], wrong_digest[20];
  unsigned char *signature = NULL;
  const unsigned char *sig_ptr;
  unsigned char *sig_ptr2;
  unsigned char *raw_buf = NULL;
  unsigned int sig_len, degree, r_len, s_len, bn_len, buf_len;
  int nid, ret = 0;

  /* fill digest values with some random data */
  if (!RAND_pseudo_bytes(digest, 20) || !RAND_pseudo_bytes(wrong_digest, 20)) {
    BIO_printf(out, "ERROR: unable to get random data\n");
    goto builtin_err;
  }

  /* create and verify a ecdsa signature with every availble curve
   * (with ) */
  BIO_printf(out,
             "\ntesting ECDSA_sign() and ECDSA_verify() "
             "with some internal curves:\n");

  static const int kCurveNIDs[] = {NID_secp224r1, NID_X9_62_prime256v1,
                                   NID_secp384r1, NID_secp521r1, NID_undef};

  /* now create and verify a signature for every curve */
  for (n = 0; kCurveNIDs[n] != NID_undef; n++) {
    unsigned char dirt, offset;

    nid = kCurveNIDs[n];
    /* create new ecdsa key (== EC_KEY) */
    eckey = EC_KEY_new();
    if (eckey == NULL) {
      goto builtin_err;
    }
    group = EC_GROUP_new_by_curve_name(nid);
    if (group == NULL) {
      goto builtin_err;
    }
    if (!EC_KEY_set_group(eckey, group)) {
      goto builtin_err;
    }
    EC_GROUP_free(group);
    degree = EC_GROUP_get_degree(EC_KEY_get0_group(eckey));
    if (degree < 160) {
      /* Too small to test. */
      EC_KEY_free(eckey);
      eckey = NULL;
      continue;
    }

    BIO_printf(out, "%s: ", OBJ_nid2sn(nid));
    /* create key */
    if (!EC_KEY_generate_key(eckey)) {
      BIO_printf(out, " failed\n");
      goto builtin_err;
    }
    /* create second key */
    wrong_eckey = EC_KEY_new();
    if (wrong_eckey == NULL) {
      goto builtin_err;
    }
    group = EC_GROUP_new_by_curve_name(nid);
    if (group == NULL) {
      goto builtin_err;
    }
    if (EC_KEY_set_group(wrong_eckey, group) == 0) {
      goto builtin_err;
    }
    EC_GROUP_free(group);
    if (!EC_KEY_generate_key(wrong_eckey)) {
      BIO_printf(out, " failed\n");
      goto builtin_err;
    }

    BIO_printf(out, ".");
    (void)BIO_flush(out);
    /* check key */
    if (!EC_KEY_check_key(eckey)) {
      BIO_printf(out, " failed\n");
      goto builtin_err;
    }
    BIO_printf(out, ".");
    (void)BIO_flush(out);
    /* create signature */
    sig_len = ECDSA_size(eckey);
    signature = OPENSSL_malloc(sig_len);
    if (signature == NULL) {
      goto builtin_err;
    }
    if (!ECDSA_sign(0, digest, 20, signature, &sig_len, eckey)) {
      BIO_printf(out, " failed\n");
      goto builtin_err;
    }
    BIO_printf(out, ".");
    (void)BIO_flush(out);
    /* verify signature */
    if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1) {
      BIO_printf(out, " failed\n");
      goto builtin_err;
    }
    BIO_printf(out, ".");
    (void)BIO_flush(out);
    /* verify signature with the wrong key */
    if (ECDSA_verify(0, digest, 20, signature, sig_len, wrong_eckey) == 1) {
      BIO_printf(out, " failed\n");
      goto builtin_err;
    }
    BIO_printf(out, ".");
    (void)BIO_flush(out);
    /* wrong digest */
    if (ECDSA_verify(0, wrong_digest, 20, signature, sig_len, eckey) == 1) {
      BIO_printf(out, " failed\n");
      goto builtin_err;
    }
    BIO_printf(out, ".");
    (void)BIO_flush(out);
    /* wrong length */
    if (ECDSA_verify(0, digest, 20, signature, sig_len - 1, eckey) == 1) {
      BIO_printf(out, " failed\n");
      goto builtin_err;
    }
    BIO_printf(out, ".");
    (void)BIO_flush(out);

    /* Modify a single byte of the signature: to ensure we don't
     * garble the ASN1 structure, we read the raw signature and
     * modify a byte in one of the bignums directly. */
    sig_ptr = signature;
    ecdsa_sig = d2i_ECDSA_SIG(NULL, &sig_ptr, sig_len);
    if (ecdsa_sig == NULL) {
      BIO_printf(out, " failed\n");
      goto builtin_err;
    }

    /* Store the two BIGNUMs in raw_buf. */
    r_len = BN_num_bytes(ecdsa_sig->r);
    s_len = BN_num_bytes(ecdsa_sig->s);
    bn_len = (degree + 7) / 8;
    if (r_len > bn_len || s_len > bn_len) {
      BIO_printf(out, " failed\n");
      goto builtin_err;
    }
    buf_len = 2 * bn_len;
    raw_buf = OPENSSL_malloc(buf_len);
    if (raw_buf == NULL) {
      goto builtin_err;
    }
    /* Pad the bignums with leading zeroes. */
    memset(raw_buf, 0, buf_len);
    BN_bn2bin(ecdsa_sig->r, raw_buf + bn_len - r_len);
    BN_bn2bin(ecdsa_sig->s, raw_buf + buf_len - s_len);

    /* Modify a single byte in the buffer. */
    offset = raw_buf[10] % buf_len;
    dirt = raw_buf[11] ? raw_buf[11] : 1;
    raw_buf[offset] ^= dirt;
    /* Now read the BIGNUMs back in from raw_buf. */
    if (BN_bin2bn(raw_buf, bn_len, ecdsa_sig->r) == NULL ||
        BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL) {
      goto builtin_err;
    }

    sig_ptr2 = signature;
    sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2);
    if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) == 1) {
      BIO_printf(out, " failed\n");
      goto builtin_err;
    }
    /* Sanity check: undo the modification and verify signature. */
    raw_buf[offset] ^= dirt;
    if (BN_bin2bn(raw_buf, bn_len, ecdsa_sig->r) == NULL ||
        BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL) {
      goto builtin_err;
    }

    sig_ptr2 = signature;
    sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2);
    if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1) {
      BIO_printf(out, " failed\n");
      goto builtin_err;
    }
    BIO_printf(out, ".");
    (void)BIO_flush(out);

    BIO_printf(out, " ok\n");
    /* cleanup */
    /* clean bogus errors */
    ERR_clear_error();
    OPENSSL_free(signature);
    signature = NULL;
    EC_KEY_free(eckey);
    eckey = NULL;
    EC_KEY_free(wrong_eckey);
    wrong_eckey = NULL;
    ECDSA_SIG_free(ecdsa_sig);
    ecdsa_sig = NULL;
    OPENSSL_free(raw_buf);
    raw_buf = NULL;
  }

  ret = 1;
builtin_err:
  if (eckey)
    EC_KEY_free(eckey);
  if (wrong_eckey)
    EC_KEY_free(wrong_eckey);
  if (ecdsa_sig)
    ECDSA_SIG_free(ecdsa_sig);
  if (signature)
    OPENSSL_free(signature);
  if (raw_buf)
    OPENSSL_free(raw_buf);

  return ret;
}
Ejemplo n.º 3
0
int OCSP_parse_url(char *url, char **phost, char **pport, char **ppath, int *pssl)
	{
	char *p, *buf;

	char *host, *port;

	*phost = NULL;
	*pport = NULL;
	*ppath = NULL;

	/* dup the buffer since we are going to mess with it */
	buf = BUF_strdup(url);
	if (!buf) goto mem_err;

	/* Check for initial colon */
	p = strchr(buf, ':');

	if (!p) goto parse_err;

	*(p++) = '\0';

	if (!strcmp(buf, "http"))
		{
		*pssl = 0;
		port = "80";
		}
	else if (!strcmp(buf, "https"))
		{
		*pssl = 1;
		port = "443";
		}
	else
		goto parse_err;

	/* Check for double slash */
	if ((p[0] != '/') || (p[1] != '/'))
		goto parse_err;

	p += 2;

	host = p;

	/* Check for trailing part of path */

	p = strchr(p, '/');

	if (!p) 
		*ppath = BUF_strdup("/");
	else
		{
		*ppath = BUF_strdup(p);
		/* Set start of path to 0 so hostname is valid */
		*p = '\0';
		}

	if (!*ppath) goto mem_err;

	/* Look for optional ':' for port number */
	if ((p = strchr(host, ':')))
		{
		*p = 0;
		port = p + 1;
		}
	else
		{
		/* Not found: set default port */
		if (*pssl) port = "443";
		else port = "80";
		}

	*pport = BUF_strdup(port);
	if (!*pport) goto mem_err;

	*phost = BUF_strdup(host);

	if (!*phost) goto mem_err;

	OPENSSL_free(buf);

	return 1;

	mem_err:
	OCSPerr(OCSP_F_OCSP_PARSE_URL, ERR_R_MALLOC_FAILURE);
	goto err;

	parse_err:
	OCSPerr(OCSP_F_OCSP_PARSE_URL, OCSP_R_ERROR_PARSING_URL);


	err:
	if (buf) OPENSSL_free(buf);
	if (*ppath) OPENSSL_free(*ppath);
	if (*pport) OPENSSL_free(*pport);
	if (*phost) OPENSSL_free(*phost);
	return 0;

	}
Ejemplo n.º 4
0
static int
vg_prefix_context_add_patterns(vg_context_t *vcp,
			       const char ** const patterns, int npatterns)
{
	vg_prefix_context_t *vcpp = (vg_prefix_context_t *) vcp;
	prefix_case_iter_t caseiter;
	vg_prefix_t *vp, *vp2;
	BN_CTX *bnctx;
	BIGNUM bntmp, bntmp2, bntmp3;
	BIGNUM *ranges[4];
	int ret = 0;
	int i, impossible = 0;
	int case_impossible;
	unsigned long npfx;
	char *dbuf;

	bnctx = BN_CTX_new();
	BN_init(&bntmp);
	BN_init(&bntmp2);
	BN_init(&bntmp3);

	npfx = 0;
	for (i = 0; i < npatterns; i++) {
		if (!vcpp->vcp_caseinsensitive) {
			vp = NULL;
			ret = get_prefix_ranges(vcpp->base.vc_addrtype,
						patterns[i],
						ranges, bnctx);
			if (!ret) {
				vp = vg_prefix_add_ranges(&vcpp->vcp_avlroot,
							  patterns[i],
							  ranges, NULL);
			}

		} else {
			/* Case-enumerate the prefix */
			if (!prefix_case_iter_init(&caseiter, patterns[i])) {
				fprintf(stderr,
					"Prefix '%s' is too long\n",
					patterns[i]);
				continue;
			}

			if (caseiter.ci_nbits > 16) {
				fprintf(stderr,
					"WARNING: Prefix '%s' has "
					"2^%d case-varied derivatives\n",
					patterns[i], caseiter.ci_nbits);
			}

			case_impossible = 0;
			vp = NULL;
			do {
				ret = get_prefix_ranges(vcpp->base.vc_addrtype,
							caseiter.ci_prefix,
							ranges, bnctx);
				if (ret == -2) {
					case_impossible++;
					ret = 0;
					continue;
				}
				if (ret)
					break;
				vp2 = vg_prefix_add_ranges(&vcpp->vcp_avlroot,
							   patterns[i],
							   ranges,
							   vp);
				if (!vp2) {
					ret = -1;
					break;
				}
				if (!vp)
					vp = vp2;

			} while (prefix_case_iter_next(&caseiter));

			if (!vp && case_impossible)
				ret = -2;

			if (ret && vp) {
				vg_prefix_delete(&vcpp->vcp_avlroot, vp);
				vp = NULL;
			}
		}

		if (ret == -2) {
			fprintf(stderr,
				"Prefix '%s' not possible\n", patterns[i]);
			impossible++;
		}

		if (!vp)
			continue;

		npfx++;

		/* Determine the probability of finding a match */
		vg_prefix_range_sum(vp, &bntmp, &bntmp2);
		BN_add(&bntmp2, &vcpp->vcp_difficulty, &bntmp);
		BN_copy(&vcpp->vcp_difficulty, &bntmp2);

		if (vcp->vc_verbose > 1) {
			BN_clear(&bntmp2);
			BN_set_bit(&bntmp2, 192);
			BN_div(&bntmp3, NULL, &bntmp2, &bntmp, bnctx);

			dbuf = BN_bn2dec(&bntmp3);
			fprintf(stderr,
				"Prefix difficulty: %20s %s\n",
				dbuf, patterns[i]);
			OPENSSL_free(dbuf);
		}
	}

	vcpp->base.vc_npatterns += npfx;
	vcpp->base.vc_npatterns_start += npfx;

	if (!npfx && impossible) {
		const char *ats = "bitcoin", *bw = "\"1\"";
		switch (vcpp->base.vc_addrtype) {
		case 5:
			ats = "bitcoin script";
			bw = "\"3\"";
			break;
		case 48:
                        ats = "litecoin";
                        bw = "\"L\"";
                        break;
		case 111:
			ats = "testnet";
			bw = "\"m\" or \"n\"";
			break;
		case 52:
			ats = "namecoin";
			bw = "\"M\" or \"N\"";
			break;
		default:
			break;
		}
		fprintf(stderr,
			"Hint: valid %s addresses begin with %s\n", ats, bw);
	}

	if (npfx)
		vg_prefix_context_next_difficulty(vcpp, &bntmp, &bntmp2, bnctx);

	ret = (npfx != 0);

	BN_clear_free(&bntmp);
	BN_clear_free(&bntmp2);
	BN_clear_free(&bntmp3);
	BN_CTX_free(bnctx);
	return ret;
}
Ejemplo n.º 5
0
static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) {
  uint8_t *buffer = NULL;
  const char *ecstr;
  size_t buf_len = 0, i;
  int ret = 0, reason = ERR_R_BIO_LIB;
  BIGNUM *order = NULL;
  BN_CTX *ctx = NULL;
  const EC_GROUP *group;
  const EC_POINT *public_key;
  const BIGNUM *priv_key;
  uint8_t *pub_key_bytes = NULL;
  size_t pub_key_bytes_len = 0;

  if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) {
    reason = ERR_R_PASSED_NULL_PARAMETER;
    goto err;
  }

  ctx = BN_CTX_new();
  if (ctx == NULL) {
    reason = ERR_R_MALLOC_FAILURE;
    goto err;
  }

  if (ktype > 0) {
    public_key = EC_KEY_get0_public_key(x);
    if (public_key != NULL) {
      pub_key_bytes_len = EC_POINT_point2oct(
          group, public_key, EC_KEY_get_conv_form(x), NULL, 0, ctx);
      if (pub_key_bytes_len == 0) {
        reason = ERR_R_MALLOC_FAILURE;
        goto err;
      }
      pub_key_bytes = OPENSSL_malloc(pub_key_bytes_len);
      if (pub_key_bytes == NULL) {
        reason = ERR_R_MALLOC_FAILURE;
        goto err;
      }
      pub_key_bytes_len =
          EC_POINT_point2oct(group, public_key, EC_KEY_get_conv_form(x),
                             pub_key_bytes, pub_key_bytes_len, ctx);
      if (pub_key_bytes_len == 0) {
        reason = ERR_R_MALLOC_FAILURE;
        goto err;
      }
      buf_len = pub_key_bytes_len;
    }
  }

  if (ktype == 2) {
    priv_key = EC_KEY_get0_private_key(x);
    if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len) {
      buf_len = i;
    }
  } else {
    priv_key = NULL;
  }

  if (ktype > 0) {
    buf_len += 10;
    if ((buffer = OPENSSL_malloc(buf_len)) == NULL) {
      reason = ERR_R_MALLOC_FAILURE;
      goto err;
    }
  }
  if (ktype == 2) {
    ecstr = "Private-Key";
  } else if (ktype == 1) {
    ecstr = "Public-Key";
  } else {
    ecstr = "ECDSA-Parameters";
  }

  if (!BIO_indent(bp, off, 128)) {
    goto err;
  }
  order = BN_new();
  if (order == NULL || !EC_GROUP_get_order(group, order, NULL) ||
      BIO_printf(bp, "%s: (%d bit)\n", ecstr, BN_num_bits(order)) <= 0) {
    goto err;
  }

  if ((priv_key != NULL) &&
      !ASN1_bn_print(bp, "priv:", priv_key, buffer, off)) {
    goto err;
  }
  if (pub_key_bytes != NULL) {
    BIO_hexdump(bp, pub_key_bytes, pub_key_bytes_len, off);
  }
  /* TODO(fork): implement */
  /*
  if (!ECPKParameters_print(bp, group, off))
    goto err; */
  ret = 1;

err:
  if (!ret) {
    OPENSSL_PUT_ERROR(EVP, reason);
  }
  OPENSSL_free(pub_key_bytes);
  BN_free(order);
  BN_CTX_free(ctx);
  OPENSSL_free(buffer);
  return ret;
}
Ejemplo n.º 6
0
int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp,
		       void *x, const EVP_CIPHER *enc, unsigned char *kstr,
		       int klen, pem_password_cb *callback, void *u)
	{
	EVP_CIPHER_CTX ctx;
	int dsize=0,i,j,ret=0;
	unsigned char *p,*data=NULL;
	const char *objstr=NULL;
	char buf[PEM_BUFSIZE];
	unsigned char key[EVP_MAX_KEY_LENGTH];
	unsigned char iv[EVP_MAX_IV_LENGTH];
	
	if (enc != NULL)
		{
		objstr=OBJ_nid2sn(EVP_CIPHER_nid(enc));
		if (objstr == NULL)
			{
			PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,PEM_R_UNSUPPORTED_CIPHER);
			goto err;
			}
		}

	if ((dsize=i2d(x,NULL)) < 0)
		{
		PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,ERR_R_ASN1_LIB);
		dsize=0;
		goto err;
		}
	/* dzise + 8 bytes are needed */
	/* actually it needs the cipher block size extra... */
	data=(unsigned char *)OPENSSL_malloc((unsigned int)dsize+20);
	if (data == NULL)
		{
		PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,ERR_R_MALLOC_FAILURE);
		goto err;
		}
	p=data;
	i=i2d(x,&p);

	if (enc != NULL)
		{
		if (kstr == NULL)
			{
			if (callback == NULL)
				klen=PEM_def_callback(buf,PEM_BUFSIZE,1,u);
			else
				klen=(*callback)(buf,PEM_BUFSIZE,1,u);
			if (klen <= 0)
				{
				PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,PEM_R_READ_KEY);
				goto err;
				}
#ifdef CHARSET_EBCDIC
			/* Convert the pass phrase from EBCDIC */
			ebcdic2ascii(buf, buf, klen);
#endif
			kstr=(unsigned char *)buf;
			}
		RAND_add(data,i,0);/* put in the RSA key. */
		OPENSSL_assert(enc->iv_len <= (int)sizeof(iv));
		if (RAND_pseudo_bytes(iv,enc->iv_len) < 0) /* Generate a salt */
			goto err;
		/* The 'iv' is used as the iv and as a salt.  It is
		 * NOT taken from the BytesToKey function */
		EVP_BytesToKey(enc,EVP_md5(),iv,kstr,klen,1,key,NULL);

		if (kstr == (unsigned char *)buf) OPENSSL_cleanse(buf,PEM_BUFSIZE);

		OPENSSL_assert(strlen(objstr)+23+2*enc->iv_len+13 <= sizeof buf);

		buf[0]='\0';
		PEM_proc_type(buf,PEM_TYPE_ENCRYPTED);
		PEM_dek_info(buf,objstr,enc->iv_len,(char *)iv);
		/* k=strlen(buf); */

		EVP_CIPHER_CTX_init(&ctx);
		EVP_EncryptInit_ex(&ctx,enc,NULL,key,iv);
		EVP_EncryptUpdate(&ctx,data,&j,data,i);
		EVP_EncryptFinal_ex(&ctx,&(data[j]),&i);
		EVP_CIPHER_CTX_cleanup(&ctx);
		i+=j;
		ret=1;
		}
	else
		{
		ret=1;
		buf[0]='\0';
		}
	i=PEM_write_bio(bp,name,buf,data,i);
	if (i <= 0) ret=0;
err:
	OPENSSL_cleanse(key,sizeof(key));
	OPENSSL_cleanse(iv,sizeof(iv));
	OPENSSL_cleanse((char *)&ctx,sizeof(ctx));
	OPENSSL_cleanse(buf,PEM_BUFSIZE);
	if (data != NULL)
		{
		OPENSSL_cleanse(data,(unsigned int)dsize);
		OPENSSL_free(data);
		}
	return(ret);
	}
Ejemplo n.º 7
0
Archivo: init.c Proyecto: ciz/openssl
void OPENSSL_cleanup(void)
{
    OPENSSL_INIT_STOP *currhandler, *lasthandler;
    CRYPTO_THREAD_LOCAL key;

    /* If we've not been inited then no need to deinit */
    if (!base_inited)
        return;

    /* Might be explicitly called and also by atexit */
    if (stopped)
        return;
    stopped = 1;

    /*
     * Thread stop may not get automatically called by the thread library for
     * the very last thread in some situations, so call it directly.
     */
    ossl_init_thread_stop(ossl_init_get_thread_local(0));

    currhandler = stop_handlers;
    while (currhandler != NULL) {
        currhandler->handler();
        lasthandler = currhandler;
        currhandler = currhandler->next;
        OPENSSL_free(lasthandler);
    }
    stop_handlers = NULL;

    CRYPTO_THREAD_lock_free(init_lock);
    init_lock = NULL;

    /*
     * We assume we are single-threaded for this function, i.e. no race
     * conditions for the various "*_inited" vars below.
     */

#ifndef OPENSSL_NO_COMP
    if (zlib_inited) {
#ifdef OPENSSL_INIT_DEBUG
        fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
                        "comp_zlib_cleanup_int()\n");
#endif
        comp_zlib_cleanup_int();
    }
#endif

    if (async_inited) {
# ifdef OPENSSL_INIT_DEBUG
        fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
                        "async_deinit()\n");
# endif
        async_deinit();
    }

    if (load_crypto_strings_inited) {
#ifdef OPENSSL_INIT_DEBUG
        fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
                        "err_free_strings_int()\n");
#endif
        err_free_strings_int();
    }

    key = destructor_key.value;
    destructor_key.sane = -1;
    CRYPTO_THREAD_cleanup_local(&key);

#ifdef OPENSSL_INIT_DEBUG
    fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
                    "rand_cleanup_int()\n");
    fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
                    "conf_modules_free_int()\n");
#ifndef OPENSSL_NO_ENGINE
    fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
                    "engine_cleanup_int()\n");
#endif
    fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
                    "crypto_cleanup_all_ex_data_int()\n");
    fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
                    "bio_sock_cleanup_int()\n");
    fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
                    "bio_cleanup()\n");
    fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
                    "evp_cleanup_int()\n");
    fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
                    "obj_cleanup_int()\n");
    fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
                    "err_cleanup()\n");
#endif
    /*
     * Note that cleanup order is important:
     * - rand_cleanup_int could call an ENGINE's RAND cleanup function so
     * must be called before engine_cleanup_int()
     * - ENGINEs use CRYPTO_EX_DATA and therefore, must be cleaned up
     * before the ex data handlers are wiped in CRYPTO_cleanup_all_ex_data().
     * - conf_modules_free_int() can end up in ENGINE code so must be called
     * before engine_cleanup_int()
     * - ENGINEs and additional EVP algorithms might use added OIDs names so
     * obj_cleanup_int() must be called last
     */
    rand_cleanup_int();
    rand_drbg_cleanup_int();
    conf_modules_free_int();
#ifndef OPENSSL_NO_ENGINE
    engine_cleanup_int();
#endif
    ossl_store_cleanup_int();
    crypto_cleanup_all_ex_data_int();
    bio_cleanup();
    evp_cleanup_int();
    obj_cleanup_int();
    err_cleanup();

    CRYPTO_secure_malloc_done();

    base_inited = 0;
}
Ejemplo n.º 8
0
static int ssl_set_cert(CERT *c, X509 *x)
	{
	EVP_PKEY *pkey;
	int i;

	pkey=X509_get_pubkey(x);
	if (pkey == NULL)
		{
		SSLerr(SSL_F_SSL_SET_CERT,SSL_R_X509_LIB);
		return(0);
		}

	i=ssl_cert_type(x,pkey);
	if (i < 0)
		{
		SSLerr(SSL_F_SSL_SET_CERT,SSL_R_UNKNOWN_CERTIFICATE_TYPE);
		EVP_PKEY_free(pkey);
		return(0);
		}

	if (c->pkeys[i].privatekey != NULL)
		{
		EVP_PKEY_copy_parameters(pkey,c->pkeys[i].privatekey);
		ERR_clear_error();

#ifndef OPENSSL_NO_RSA
		/* Don't check the public/private key, this is mostly
		 * for smart cards. */
		if ((c->pkeys[i].privatekey->type == EVP_PKEY_RSA) &&
			(RSA_flags(c->pkeys[i].privatekey->pkey.rsa) &
			 RSA_METHOD_FLAG_NO_CHECK))
			 ;
		else
#endif /* OPENSSL_NO_RSA */
		if (!X509_check_private_key(x,c->pkeys[i].privatekey))
			{
			/* don't fail for a cert/key mismatch, just free
			 * current private key (when switching to a different
			 * cert & key, first this function should be used,
			 * then ssl_set_pkey */
			EVP_PKEY_free(c->pkeys[i].privatekey);
			c->pkeys[i].privatekey=NULL;
			/* clear error queue */
			ERR_clear_error();
			}
		}

	EVP_PKEY_free(pkey);

	if (c->pkeys[i].x509 != NULL)
		X509_free(c->pkeys[i].x509);
	CRYPTO_add(&x->references,1,CRYPTO_LOCK_X509);
	c->pkeys[i].x509=x;
#ifndef OPENSSL_NO_TLSEXT
	/* Free the old authz data, if it exists. */
	if (c->pkeys[i].authz != NULL)
		{
		OPENSSL_free(c->pkeys[i].authz);
		c->pkeys[i].authz = NULL;
		c->pkeys[i].authz_length = 0;
		}

	/* Free the old serverinfo data, if it exists. */
	if (c->pkeys[i].serverinfo != NULL)
		{
		OPENSSL_free(c->pkeys[i].serverinfo);
		c->pkeys[i].serverinfo = NULL;
		c->pkeys[i].serverinfo_length = 0;
		}
#endif
	c->key= &(c->pkeys[i]);

	c->valid=0;
	return(1);
	}
Ejemplo n.º 9
0
/// Logon Proof command handler
bool AuthSocket::_HandleLogonProof()
{
    DEBUG_LOG("Entering _HandleLogonProof");
    ///- Read the packet
    if (ibuf.GetLength() < sizeof(sAuthLogonProof_C))
        return false;
    sAuthLogonProof_C lp;
    ibuf.Read((char *)&lp, sizeof(sAuthLogonProof_C));

    ///- Check if the client has one of the expected version numbers
    bool valid_version = false;
    int accepted_versions[] = EXPECTED_MANGOS_CLIENT_BUILD;
    for(int i = 0; accepted_versions[i]; ++i)
    {
        if(_build == accepted_versions[i])
        {
            valid_version = true;
            break;
        }
    }

    /// <ul><li> If the client has no valid version
    if(!valid_version)
    {
        ///- Check if we have the apropriate patch on the disk

        // 24 = len("./patches/65535enGB.mpq")+1
        char tmp[24];
        // No buffer overflow (fixed length of arguments)
        sprintf(tmp, "./patches/%d%s.mpq", _build, _localizationName.c_str());
        // This will be closed at the destruction of the AuthSocket (client disconnection)
        FILE *pFile = fopen(tmp, "rb");

        if(!pFile)
        {
            ByteBuffer pkt;
            pkt << (uint8) AUTH_LOGON_CHALLENGE;
            pkt << (uint8) 0x00;
            pkt << (uint8) REALM_AUTH_WRONG_BUILD_NUMBER;
            DEBUG_LOG("[AuthChallenge] %u is not a valid client version!", _build);
            DEBUG_LOG("[AuthChallenge] Patch %s not found", tmp);
            SendBuf((char const*)pkt.contents(), pkt.size());
            return true;
        }
        else                                                // have patch
        {
            pPatch = pFile;
            XFER_INIT xferh;

            ///- Get the MD5 hash of the patch file (get it from preloaded Patcher cache or calculate it)
            if(PatchesCache.GetHash(tmp, (uint8*)&xferh.md5))
            {
                DEBUG_LOG("\n[AuthChallenge] Found precached patch info for patch %s", tmp);
            }
            else
            {                                               // calculate patch md5
                printf("\n[AuthChallenge] Patch info for %s was not cached.", tmp);
                PatchesCache.LoadPatchMD5(tmp);
                PatchesCache.GetHash(tmp, (uint8*)&xferh.md5);
            }

            ///- Send a packet to the client with the file length and MD5 hash
            uint8 data[2] = { AUTH_LOGON_PROOF, REALM_AUTH_UPDATE_CLIENT };
            SendBuf((const char*)data, sizeof(data));

            memcpy(&xferh, "0\x05Patch", 7);
            xferh.cmd = XFER_INITIATE;
            fseek(pPatch, 0, SEEK_END);
            xferh.file_size = ftell(pPatch);

            SendBuf((const char*)&xferh, sizeof(xferh));
            return true;
        }
    }
    /// </ul>

    ///- Continue the SRP6 calculation based on data received from the client
    BigNumber A;

    A.SetBinary(lp.A, 32);

    // SRP safeguard: abort if A==0
    if (A.isZero())
        return false;

    Sha1Hash sha;
    sha.UpdateBigNumbers(&A, &B, NULL);
    sha.Finalize();
    BigNumber u;
    u.SetBinary(sha.GetDigest(), 20);
    BigNumber S = (A * (v.ModExp(u, N))).ModExp(b, N);

    uint8 t[32];
    uint8 t1[16];
    uint8 vK[40];
    memcpy(t, S.AsByteArray(32), 32);
    for (int i = 0; i < 16; ++i)
    {
        t1[i] = t[i * 2];
    }
    sha.Initialize();
    sha.UpdateData(t1, 16);
    sha.Finalize();
    for (int i = 0; i < 20; ++i)
    {
        vK[i * 2] = sha.GetDigest()[i];
    }
    for (int i = 0; i < 16; ++i)
    {
        t1[i] = t[i * 2 + 1];
    }
    sha.Initialize();
    sha.UpdateData(t1, 16);
    sha.Finalize();
    for (int i = 0; i < 20; ++i)
    {
        vK[i * 2 + 1] = sha.GetDigest()[i];
    }
    K.SetBinary(vK, 40);

    uint8 hash[20];

    sha.Initialize();
    sha.UpdateBigNumbers(&N, NULL);
    sha.Finalize();
    memcpy(hash, sha.GetDigest(), 20);
    sha.Initialize();
    sha.UpdateBigNumbers(&g, NULL);
    sha.Finalize();
    for (int i = 0; i < 20; ++i)
    {
        hash[i] ^= sha.GetDigest()[i];
    }
    BigNumber t3;
    t3.SetBinary(hash, 20);

    sha.Initialize();
    sha.UpdateData(_login);
    sha.Finalize();
    uint8 t4[SHA_DIGEST_LENGTH];
    memcpy(t4, sha.GetDigest(), SHA_DIGEST_LENGTH);

    sha.Initialize();
    sha.UpdateBigNumbers(&t3, NULL);
    sha.UpdateData(t4, SHA_DIGEST_LENGTH);
    sha.UpdateBigNumbers(&s, &A, &B, &K, NULL);
    sha.Finalize();
    BigNumber M;
    M.SetBinary(sha.GetDigest(), 20);

    ///- Check if SRP6 results match (password is correct), else send an error
    if (!memcmp(M.AsByteArray(), lp.M1, 20))
    {
        sLog.outBasic("User '%s' successfully authenticated", _login.c_str());

        ///- Update the sessionkey, last_ip, last login time and reset number of failed logins in the account table for this account
        // No SQL injection (escaped user name) and IP address as received by socket
        const char* K_hex = K.AsHexStr();
        loginDatabase.PExecute("UPDATE account SET sessionkey = '%s', last_ip = '%s', last_login = NOW(), locale = '%u', failed_logins = 0 WHERE username = '******'", K_hex, GetRemoteAddress().c_str(), GetLocaleByName(_localizationName), _safelogin.c_str() );
        OPENSSL_free((void*)K_hex);

        ///- Finish SRP6 and send the final result to the client
        sha.Initialize();
        sha.UpdateBigNumbers(&A, &M, &K, NULL);
        sha.Finalize();

        sAuthLogonProof_S proof;
        memcpy(proof.M2, sha.GetDigest(), 20);
        proof.cmd = AUTH_LOGON_PROOF;
        proof.error = 0;
        proof.unk2 = 0x00;

        SendBuf((char *)&proof, sizeof(proof));

        ///- Set _authed to true!
        _authed = true;
    }
    else
    {
        char data[4]= { AUTH_LOGON_PROOF, REALM_AUTH_NO_MATCH, 3, 0};
        SendBuf(data, sizeof(data));
        sLog.outBasic("[AuthChallenge] account %s tried to login with wrong password!",_login.c_str ());

        uint32 MaxWrongPassCount = sConfig.GetIntDefault("WrongPass.MaxCount", 0);
        if(MaxWrongPassCount > 0)
        {
            //Increment number of failed logins by one and if it reaches the limit temporarily ban that account or IP
            loginDatabase.PExecute("UPDATE account SET failed_logins = failed_logins + 1 WHERE username = '******'",_safelogin.c_str());

            if(QueryResult *loginfail = loginDatabase.PQuery("SELECT id, failed_logins FROM account WHERE username = '******'", _safelogin.c_str()))
            {
                Field* fields = loginfail->Fetch();
                uint32 failed_logins = fields[1].GetUInt32();

                if( failed_logins >= MaxWrongPassCount )
                {
                    uint32 WrongPassBanTime = sConfig.GetIntDefault("WrongPass.BanTime", 600);
                    bool WrongPassBanType = sConfig.GetBoolDefault("WrongPass.BanType", false);

                    if(WrongPassBanType)
                    {
                        uint32 acc_id = fields[0].GetUInt32();
                        loginDatabase.PExecute("INSERT INTO account_banned VALUES ('%u',UNIX_TIMESTAMP(),UNIX_TIMESTAMP()+'%u','MaNGOS realmd','Failed login autoban',1)",
                            acc_id, WrongPassBanTime);
                        sLog.outBasic("[AuthChallenge] account %s got banned for '%u' seconds because it failed to authenticate '%u' times",
                            _login.c_str(), WrongPassBanTime, failed_logins);
                    }
                    else
                    {
                        std::string current_ip = GetRemoteAddress();
                        loginDatabase.escape_string(current_ip);
                        loginDatabase.PExecute("INSERT INTO ip_banned VALUES ('%s',UNIX_TIMESTAMP(),UNIX_TIMESTAMP()+'%u','MaNGOS realmd','Failed login autoban')",
                            current_ip.c_str(), WrongPassBanTime);
                        sLog.outBasic("[AuthChallenge] IP %s got banned for '%u' seconds because account %s failed to authenticate '%u' times",
                            current_ip.c_str(), WrongPassBanTime, _login.c_str(), failed_logins);
                    }
                }
                delete loginfail;
            }
        }
    }
    return true;
}
Ejemplo n.º 10
0
/*! \brief
* creates a FILE * from the fd passed by the accept thread.
* This operation is potentially expensive (certificate verification),
* so we do it in the child thread context.
*
* \note must decrement ref count before returning NULL on error
*/
static void *handle_tcptls_connection(void *data)
{
	struct ast_tcptls_session_instance *tcptls_session = data;
#ifdef DO_SSL
	int (*ssl_setup)(SSL *) = (tcptls_session->client) ? SSL_connect : SSL_accept;
	int ret;
	char err[256];
#endif

	/*
	* open a FILE * as appropriate.
	*/
	if (!tcptls_session->parent->tls_cfg) {
		if ((tcptls_session->f = fdopen(tcptls_session->fd, "w+"))) {
			if(setvbuf(tcptls_session->f, NULL, _IONBF, 0)) {
				ast_tcptls_close_session_file(tcptls_session);
			}
		}
	}
#ifdef DO_SSL
	else if ( (tcptls_session->ssl = SSL_new(tcptls_session->parent->tls_cfg->ssl_ctx)) ) {
		SSL_set_fd(tcptls_session->ssl, tcptls_session->fd);
		if ((ret = ssl_setup(tcptls_session->ssl)) <= 0) {
			ast_verb(2, "Problem setting up ssl connection: %s\n", ERR_error_string(ERR_get_error(), err));
		} else {
#if defined(HAVE_FUNOPEN)	/* the BSD interface */
			tcptls_session->f = funopen(tcptls_session->ssl, ssl_read, ssl_write, NULL, ssl_close);

#elif defined(HAVE_FOPENCOOKIE)	/* the glibc/linux interface */
			static const cookie_io_functions_t cookie_funcs = {
				ssl_read, ssl_write, NULL, ssl_close
			};
			tcptls_session->f = fopencookie(tcptls_session->ssl, "w+", cookie_funcs);
#else
			/* could add other methods here */
			ast_debug(2, "no tcptls_session->f methods attempted!");
#endif
			if ((tcptls_session->client && !ast_test_flag(&tcptls_session->parent->tls_cfg->flags, AST_SSL_DONT_VERIFY_SERVER))
				|| (!tcptls_session->client && ast_test_flag(&tcptls_session->parent->tls_cfg->flags, AST_SSL_VERIFY_CLIENT))) {
				X509 *peer;
				long res;
				peer = SSL_get_peer_certificate(tcptls_session->ssl);
				if (!peer)
					ast_log(LOG_WARNING, "No peer SSL certificate\n");
				res = SSL_get_verify_result(tcptls_session->ssl);
				if (res != X509_V_OK)
					ast_log(LOG_ERROR, "Certificate did not verify: %s\n", X509_verify_cert_error_string(res));
				if (!ast_test_flag(&tcptls_session->parent->tls_cfg->flags, AST_SSL_IGNORE_COMMON_NAME)) {
					ASN1_STRING *str;
					unsigned char *str2;
					X509_NAME *name = X509_get_subject_name(peer);
					int pos = -1;
					int found = 0;

					for (;;) {
						/* Walk the certificate to check all available "Common Name" */
						/* XXX Probably should do a gethostbyname on the hostname and compare that as well */
						pos = X509_NAME_get_index_by_NID(name, NID_commonName, pos);
						if (pos < 0)
							break;
						str = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, pos));
						ASN1_STRING_to_UTF8(&str2, str);
						if (str2) {
							if (!strcasecmp(tcptls_session->parent->hostname, (char *) str2))
								found = 1;
							ast_debug(3, "SSL Common Name compare s1='%s' s2='%s'\n", tcptls_session->parent->hostname, str2);
							OPENSSL_free(str2);
						}
						if (found)
							break;
					}
					if (!found) {
						ast_log(LOG_ERROR, "Certificate common name did not match (%s)\n", tcptls_session->parent->hostname);
						if (peer) {
							X509_free(peer);
						}
						ast_tcptls_close_session_file(tcptls_session);
						ao2_ref(tcptls_session, -1);
						return NULL;
					}
				}
				if (peer)
					X509_free(peer);
			}
		}
		if (!tcptls_session->f)	/* no success opening descriptor stacking */
			SSL_free(tcptls_session->ssl);
   }
#endif /* DO_SSL */

	if (!tcptls_session->f) {
		ast_tcptls_close_session_file(tcptls_session);
		ast_log(LOG_WARNING, "FILE * open failed!\n");
#ifndef DO_SSL
		if (tcptls_session->parent->tls_cfg) {
			ast_log(LOG_WARNING, "Attempted a TLS connection without OpenSSL support.  This will not work!\n");
		}
#endif
		ao2_ref(tcptls_session, -1);
		return NULL;
	}

	if (tcptls_session && tcptls_session->parent->worker_fn)
		return tcptls_session->parent->worker_fn(tcptls_session);
	else
		return tcptls_session;
}
Ejemplo n.º 11
0
int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file)
	{
	unsigned char *serverinfo = NULL;
	size_t serverinfo_length = 0;
	unsigned char* extension = 0;
	long extension_length = 0;
	char* name = NULL;
	char* header = NULL;
	int ret = 0;
	BIO *bin = NULL;
	size_t num_extensions = 0;

	if (ctx == NULL || file == NULL)
		{
		SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE,ERR_R_PASSED_NULL_PARAMETER);
		goto end;
		}

	bin = BIO_new(BIO_s_file_internal());
	if (bin == NULL)
		{
		SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_BUF_LIB);
		goto end;
		}
	if (BIO_read_filename(bin, file) <= 0)
		{
		SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_SYS_LIB);
		goto end;
		}

	for (num_extensions=0;; num_extensions++)
		{
		if (PEM_read_bio(bin, &name, &header, &extension, &extension_length) == 0)
			{
			/* There must be at least one extension in this file */
			if (num_extensions == 0)
				{
				SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_PEM_LIB);
				goto end;
				}
			else /* End of file, we're done */
				break;
			}
		/* Check that the decoded PEM data is plausible (valid length field) */
		if (extension_length < 4 || (extension[2] << 8) + extension[3] != extension_length - 4)
			{
				SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_PEM_LIB);
				goto end;
			}
		/* Append the decoded extension to the serverinfo buffer */
		serverinfo = OPENSSL_realloc(serverinfo, serverinfo_length + extension_length);
		if (serverinfo == NULL)
			{
			SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_MALLOC_FAILURE);
			goto end;
			}
		memcpy(serverinfo + serverinfo_length, extension, extension_length);
		serverinfo_length += extension_length;

		OPENSSL_free(name); name = NULL;
		OPENSSL_free(header); header = NULL;
		OPENSSL_free(extension); extension = NULL;
		}

	ret = SSL_CTX_use_serverinfo(ctx, serverinfo, serverinfo_length);
end:
	/* SSL_CTX_use_serverinfo makes a local copy of the serverinfo. */
	OPENSSL_free(name);
	OPENSSL_free(header);
	OPENSSL_free(extension);
	OPENSSL_free(serverinfo);
	if (bin != NULL)
		BIO_free(bin);
	return ret;
	}
Ejemplo n.º 12
0
static EVP_PKEY_CTX *init_ctx(int *pkeysize,
                              const char *keyfile, int keyform, int key_type,
                              char *passinarg, int pkey_op, ENGINE *e,
                              const int engine_impl)
{
    EVP_PKEY *pkey = NULL;
    EVP_PKEY_CTX *ctx = NULL;
    ENGINE *impl = NULL;
    char *passin = NULL;
    int rv = -1;
    X509 *x;
    if (((pkey_op == EVP_PKEY_OP_SIGN) || (pkey_op == EVP_PKEY_OP_DECRYPT)
         || (pkey_op == EVP_PKEY_OP_DERIVE))
        && (key_type != KEY_PRIVKEY)) {
        BIO_printf(bio_err, "A private key is needed for this operation\n");
        goto end;
    }
    if (!app_passwd(passinarg, NULL, &passin, NULL)) {
        BIO_printf(bio_err, "Error getting password\n");
        goto end;
    }
    switch (key_type) {
    case KEY_PRIVKEY:
        pkey = load_key(keyfile, keyform, 0, passin, e, "Private Key");
        break;

    case KEY_PUBKEY:
        pkey = load_pubkey(keyfile, keyform, 0, NULL, e, "Public Key");
        break;

    case KEY_CERT:
        x = load_cert(keyfile, keyform, NULL, e, "Certificate");
        if (x) {
            pkey = X509_get_pubkey(x);
            X509_free(x);
        }
        break;

    }

    *pkeysize = EVP_PKEY_size(pkey);

    if (!pkey)
        goto end;

#ifndef OPENSSL_NO_ENGINE
    if (engine_impl)
        impl = e;
#endif
    
    ctx = EVP_PKEY_CTX_new(pkey, impl);

    EVP_PKEY_free(pkey);

    if (ctx == NULL)
        goto end;

    switch (pkey_op) {
    case EVP_PKEY_OP_SIGN:
        rv = EVP_PKEY_sign_init(ctx);
        break;

    case EVP_PKEY_OP_VERIFY:
        rv = EVP_PKEY_verify_init(ctx);
        break;

    case EVP_PKEY_OP_VERIFYRECOVER:
        rv = EVP_PKEY_verify_recover_init(ctx);
        break;

    case EVP_PKEY_OP_ENCRYPT:
        rv = EVP_PKEY_encrypt_init(ctx);
        break;

    case EVP_PKEY_OP_DECRYPT:
        rv = EVP_PKEY_decrypt_init(ctx);
        break;

    case EVP_PKEY_OP_DERIVE:
        rv = EVP_PKEY_derive_init(ctx);
        break;
    }

    if (rv <= 0) {
        EVP_PKEY_CTX_free(ctx);
        ctx = NULL;
    }

 end:
    OPENSSL_free(passin);
    return ctx;

}
Ejemplo n.º 13
0
int pkeyutl_main(int argc, char **argv)
{
    BIO *in = NULL, *out = NULL;
    ENGINE *e = NULL;
    EVP_PKEY_CTX *ctx = NULL;
    char *infile = NULL, *outfile = NULL, *sigfile = NULL, *passinarg = NULL;
    char hexdump = 0, asn1parse = 0, rev = 0, *prog;
    unsigned char *buf_in = NULL, *buf_out = NULL, *sig = NULL;
    OPTION_CHOICE o;
    int buf_inlen = 0, siglen = -1, keyform = FORMAT_PEM, peerform =
        FORMAT_PEM;
    int keysize = -1, pkey_op = EVP_PKEY_OP_SIGN, key_type = KEY_PRIVKEY;
    int engine_impl = 0;
    int ret = 1, rv = -1;
    size_t buf_outlen;
    const char *inkey = NULL;
    const char *peerkey = NULL;
    STACK_OF(OPENSSL_STRING) *pkeyopts = NULL;

    prog = opt_init(argc, argv, pkeyutl_options);
    while ((o = opt_next()) != OPT_EOF) {
        switch (o) {
        case OPT_EOF:
        case OPT_ERR:
 opthelp:
            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
            goto end;
        case OPT_HELP:
            opt_help(pkeyutl_options);
            ret = 0;
            goto end;
        case OPT_IN:
            infile = opt_arg();
            break;
        case OPT_OUT:
            outfile = opt_arg();
            break;
        case OPT_SIGFILE:
            sigfile = opt_arg();
            break;
        case OPT_ENGINE_IMPL:
            engine_impl = 1;
            break;
        case OPT_INKEY:
            inkey = opt_arg();
            break;
        case OPT_PEERKEY:
            peerkey = opt_arg();
            break;
        case OPT_PASSIN:
            passinarg = opt_arg();
            break;
        case OPT_PEERFORM:
            if (!opt_format(opt_arg(), OPT_FMT_PDE, &peerform))
                goto opthelp;
            break;
        case OPT_KEYFORM:
            if (!opt_format(opt_arg(), OPT_FMT_PDE, &keyform))
                goto opthelp;
            break;
        case OPT_ENGINE:
            e = setup_engine(opt_arg(), 0);
            break;
        case OPT_PUBIN:
            key_type = KEY_PUBKEY;
            break;
        case OPT_CERTIN:
            key_type = KEY_CERT;
            break;
        case OPT_ASN1PARSE:
            asn1parse = 1;
            break;
        case OPT_HEXDUMP:
            hexdump = 1;
            break;
        case OPT_SIGN:
            pkey_op = EVP_PKEY_OP_SIGN;
            break;
        case OPT_VERIFY:
            pkey_op = EVP_PKEY_OP_VERIFY;
            break;
        case OPT_VERIFYRECOVER:
            pkey_op = EVP_PKEY_OP_VERIFYRECOVER;
            break;
        case OPT_ENCRYPT:
            pkey_op = EVP_PKEY_OP_ENCRYPT;
            break;
        case OPT_DECRYPT:
            pkey_op = EVP_PKEY_OP_DECRYPT;
            break;
        case OPT_DERIVE:
            pkey_op = EVP_PKEY_OP_DERIVE;
            break;
        case OPT_REV:
            rev = 1;
            break;
        case OPT_PKEYOPT:
            if ((pkeyopts == NULL &&
                 (pkeyopts = sk_OPENSSL_STRING_new_null()) == NULL) ||
                sk_OPENSSL_STRING_push(pkeyopts, *++argv) == 0) {
                BIO_puts(bio_err, "out of memory\n");
                goto end;
            }
            break;
        }
    }
    argc = opt_num_rest();
    argv = opt_rest();

    if (inkey == NULL ||
        (peerkey != NULL && pkey_op != EVP_PKEY_OP_DERIVE))
        goto opthelp;

    ctx = init_ctx(&keysize, inkey, keyform, key_type,
                   passinarg, pkey_op, e, engine_impl);
    if (ctx == NULL) {
        BIO_printf(bio_err, "%s: Error initializing context\n", prog);
        ERR_print_errors(bio_err);
        goto end;
    }
    if (peerkey != NULL && !setup_peer(ctx, peerform, peerkey, e)) {
        BIO_printf(bio_err, "%s: Error setting up peer key\n", prog);
        ERR_print_errors(bio_err);
        goto end;
    }
    if (pkeyopts != NULL) {
        int num = sk_OPENSSL_STRING_num(pkeyopts);
        int i;

        for (i = 0; i < num; ++i) {
            const char *opt = sk_OPENSSL_STRING_value(pkeyopts, i);

            if (pkey_ctrl_string(ctx, opt) <= 0) {
                BIO_printf(bio_err, "%s: Can't set parameter:\n", prog);
                ERR_print_errors(bio_err);
                goto end;
            }
        }
    }

    if (sigfile && (pkey_op != EVP_PKEY_OP_VERIFY)) {
        BIO_printf(bio_err,
                   "%s: Signature file specified for non verify\n", prog);
        goto end;
    }

    if (!sigfile && (pkey_op == EVP_PKEY_OP_VERIFY)) {
        BIO_printf(bio_err,
                   "%s: No signature file specified for verify\n", prog);
        goto end;
    }

/* FIXME: seed PRNG only if needed */
    app_RAND_load_file(NULL, 0);

    if (pkey_op != EVP_PKEY_OP_DERIVE) {
        in = bio_open_default(infile, 'r', FORMAT_BINARY);
        if (in == NULL)
            goto end;
    }
    out = bio_open_default(outfile, 'w', FORMAT_BINARY);
    if (out == NULL)
        goto end;

    if (sigfile) {
        BIO *sigbio = BIO_new_file(sigfile, "rb");
        if (!sigbio) {
            BIO_printf(bio_err, "Can't open signature file %s\n", sigfile);
            goto end;
        }
        siglen = bio_to_mem(&sig, keysize * 10, sigbio);
        BIO_free(sigbio);
        if (siglen < 0) {
            BIO_printf(bio_err, "Error reading signature data\n");
            goto end;
        }
    }

    if (in) {
        /* Read the input data */
        buf_inlen = bio_to_mem(&buf_in, keysize * 10, in);
        if (buf_inlen < 0) {
            BIO_printf(bio_err, "Error reading input Data\n");
            exit(1);
        }
        if (rev) {
            size_t i;
            unsigned char ctmp;
            size_t l = (size_t)buf_inlen;
            for (i = 0; i < l / 2; i++) {
                ctmp = buf_in[i];
                buf_in[i] = buf_in[l - 1 - i];
                buf_in[l - 1 - i] = ctmp;
            }
        }
    }

    if (pkey_op == EVP_PKEY_OP_VERIFY) {
        rv = EVP_PKEY_verify(ctx, sig, (size_t)siglen,
                             buf_in, (size_t)buf_inlen);
        if (rv == 1) {
            BIO_puts(out, "Signature Verified Successfully\n");
            ret = 0;
        } else
            BIO_puts(out, "Signature Verification Failure\n");
        goto end;
    }
    rv = do_keyop(ctx, pkey_op, NULL, (size_t *)&buf_outlen,
                  buf_in, (size_t)buf_inlen);
    if (rv > 0 && buf_outlen != 0) {
        buf_out = app_malloc(buf_outlen, "buffer output");
        rv = do_keyop(ctx, pkey_op,
                      buf_out, (size_t *)&buf_outlen,
                      buf_in, (size_t)buf_inlen);
    }
    if (rv < 0) {
        ERR_print_errors(bio_err);
        goto end;
    }
    ret = 0;

    if (asn1parse) {
        if (!ASN1_parse_dump(out, buf_out, buf_outlen, 1, -1))
            ERR_print_errors(bio_err);
    } else if (hexdump)
        BIO_dump(out, (char *)buf_out, buf_outlen);
    else
        BIO_write(out, buf_out, buf_outlen);

 end:
    EVP_PKEY_CTX_free(ctx);
    BIO_free(in);
    BIO_free_all(out);
    OPENSSL_free(buf_in);
    OPENSSL_free(buf_out);
    OPENSSL_free(sig);
    sk_OPENSSL_STRING_free(pkeyopts);
    return ret;
}
Ejemplo n.º 14
0
static void ui_free_method_data(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
                                int idx, long argl, void *argp)
{
    OPENSSL_free(ptr);
}
Ejemplo n.º 15
0
void CT_POLICY_EVAL_CTX_free(CT_POLICY_EVAL_CTX *ctx)
{
    OPENSSL_free(ctx);
}
Ejemplo n.º 16
0
/// Logon Proof command handler
bool AuthSocket::_HandleLogonProof()
{
    DEBUG_LOG("Entering _HandleLogonProof");
    ///- Read the packet
    sAuthLogonProof_C lp;
    if(!recv((char *)&lp, sizeof(sAuthLogonProof_C)))
        return false;

    ///- Check if the client has one of the expected version numbers
    bool valid_version = FindBuildInfo(_build) != NULL;

    /// <ul><li> If the client has no valid version
    if(!valid_version)
    {
        if (this->patch_ != ACE_INVALID_HANDLE)
            return false;

        ///- Check if we have the apropriate patch on the disk
        // file looks like: 65535enGB.mpq
        char tmp[64];

        snprintf(tmp, 24, "./patches/%d%s.mpq", _build, _localizationName.c_str());

        char filename[PATH_MAX];
        if (ACE_OS::realpath(tmp, filename) != NULL)
        {
            patch_ = ACE_OS::open(filename, GENERIC_READ | FILE_FLAG_SEQUENTIAL_SCAN);
        }

        if (patch_ == ACE_INVALID_HANDLE)
        {
            // no patch found
            ByteBuffer pkt;
            pkt << (uint8) AUTH_LOGON_CHALLENGE;
            pkt << (uint8) 0x00;
            pkt << (uint8) WOW_FAIL_VERSION_INVALID;
            DEBUG_LOG("[AuthChallenge] %u is not a valid client version!", _build);
            DEBUG_LOG("[AuthChallenge] Patch %s not found", tmp);
            send((char const*)pkt.contents(), pkt.size());
            return true;
        }

        XFER_INIT xferh;

        ACE_OFF_T file_size = ACE_OS::filesize(this->patch_);

        if (file_size == -1)
        {
            close_connection();
            return false;
        }

        if (!PatchCache::instance()->GetHash(tmp, (uint8*)&xferh.md5))
        {
            // calculate patch md5, happens if patch was added while realmd was running
            PatchCache::instance()->LoadPatchMD5(tmp);
            PatchCache::instance()->GetHash(tmp, (uint8*)&xferh.md5);
        }

        uint8 data[2] = { AUTH_LOGON_PROOF, WOW_FAIL_VERSION_UPDATE};
        send((const char*)data, sizeof(data));

        memcpy(&xferh, "0\x05Patch", 7);
        xferh.cmd = XFER_INITIATE;
        xferh.file_size = file_size;

        send((const char*)&xferh, sizeof(xferh));
        return true;
    }
    /// </ul>

    ///- Continue the SRP6 calculation based on data received from the client
    BigNumber A;

    A.SetBinary(lp.A, 32);

    // SRP safeguard: abort if A==0
    if (A.isZero())
        return false;

    Sha1Hash sha;
    sha.UpdateBigNumbers(&A, &B, NULL);
    sha.Finalize();
    BigNumber u;
    u.SetBinary(sha.GetDigest(), 20);
    BigNumber S = (A * (v.ModExp(u, N))).ModExp(b, N);

    uint8 t[32];
    uint8 t1[16];
    uint8 vK[40];
    memcpy(t, S.AsByteArray(32), 32);
    for (int i = 0; i < 16; ++i)
    {
        t1[i] = t[i * 2];
    }
    sha.Initialize();
    sha.UpdateData(t1, 16);
    sha.Finalize();
    for (int i = 0; i < 20; ++i)
    {
        vK[i * 2] = sha.GetDigest()[i];
    }
    for (int i = 0; i < 16; ++i)
    {
        t1[i] = t[i * 2 + 1];
    }
    sha.Initialize();
    sha.UpdateData(t1, 16);
    sha.Finalize();
    for (int i = 0; i < 20; ++i)
    {
        vK[i * 2 + 1] = sha.GetDigest()[i];
    }
    K.SetBinary(vK, 40);

    uint8 hash[20];

    sha.Initialize();
    sha.UpdateBigNumbers(&N, NULL);
    sha.Finalize();
    memcpy(hash, sha.GetDigest(), 20);
    sha.Initialize();
    sha.UpdateBigNumbers(&g, NULL);
    sha.Finalize();
    for (int i = 0; i < 20; ++i)
    {
        hash[i] ^= sha.GetDigest()[i];
    }
    BigNumber t3;
    t3.SetBinary(hash, 20);

    sha.Initialize();
    sha.UpdateData(_login);
    sha.Finalize();
    uint8 t4[SHA_DIGEST_LENGTH];
    memcpy(t4, sha.GetDigest(), SHA_DIGEST_LENGTH);

    sha.Initialize();
    sha.UpdateBigNumbers(&t3, NULL);
    sha.UpdateData(t4, SHA_DIGEST_LENGTH);
    sha.UpdateBigNumbers(&s, &A, &B, &K, NULL);
    sha.Finalize();
    BigNumber M;
    M.SetBinary(sha.GetDigest(), 20);

    ///- Check if SRP6 results match (password is correct), else send an error
    if (!memcmp(M.AsByteArray(), lp.M1, 20))
    {
        BASIC_LOG("User '%s' successfully authenticated", _login.c_str());

        ///- Update the sessionkey, last_ip, last login time and reset number of failed logins in the account table for this account
        // No SQL injection (escaped user name) and IP address as received by socket
        const char* K_hex = K.AsHexStr();
        loginDatabase.PExecute("UPDATE account SET sessionkey = '%s', last_ip = '%s', last_login = NOW(), locale = '%u', failed_logins = 0 WHERE username = '******'", K_hex, get_remote_address().c_str(), GetLocaleByName(_localizationName), _safelogin.c_str() );
        OPENSSL_free((void*)K_hex);

        ///- Finish SRP6 and send the final result to the client
        sha.Initialize();
        sha.UpdateBigNumbers(&A, &M, &K, NULL);
        sha.Finalize();

        SendProof(sha);

        ///- Set _authed to true!
        _authed = true;
    }
    else
    {
        char data[4]= { AUTH_LOGON_PROOF, WOW_FAIL_UNKNOWN_ACCOUNT, 3, 0};
        send(data, sizeof(data));
        BASIC_LOG("[AuthChallenge] account %s tried to login with wrong password!",_login.c_str ());

        uint32 MaxWrongPassCount = sConfig.GetIntDefault("WrongPass.MaxCount", 0);
        if(MaxWrongPassCount > 0)
        {
            //Increment number of failed logins by one and if it reaches the limit temporarily ban that account or IP
            loginDatabase.PExecute("UPDATE account SET failed_logins = failed_logins + 1 WHERE username = '******'",_safelogin.c_str());

            if(QueryResult *loginfail = loginDatabase.PQuery("SELECT id, failed_logins FROM account WHERE username = '******'", _safelogin.c_str()))
            {
                Field* fields = loginfail->Fetch();
                uint32 failed_logins = fields[1].GetUInt32();

                if( failed_logins >= MaxWrongPassCount )
                {
                    uint32 WrongPassBanTime = sConfig.GetIntDefault("WrongPass.BanTime", 600);
                    bool WrongPassBanType = sConfig.GetBoolDefault("WrongPass.BanType", false);

                    if(WrongPassBanType)
                    {
                        uint32 acc_id = fields[0].GetUInt32();
                        loginDatabase.PExecute("INSERT INTO account_banned VALUES ('%u',UNIX_TIMESTAMP(),UNIX_TIMESTAMP()+'%u','MaNGOS realmd','Failed login autoban',1)",
                            acc_id, WrongPassBanTime);
                        BASIC_LOG("[AuthChallenge] account %s got banned for '%u' seconds because it failed to authenticate '%u' times",
                            _login.c_str(), WrongPassBanTime, failed_logins);
                    }
                    else
                    {
                        std::string current_ip = get_remote_address();
                        loginDatabase.escape_string(current_ip);
                        loginDatabase.PExecute("INSERT INTO ip_banned VALUES ('%s',UNIX_TIMESTAMP(),UNIX_TIMESTAMP()+'%u','MaNGOS realmd','Failed login autoban')",
                            current_ip.c_str(), WrongPassBanTime);
                        BASIC_LOG("[AuthChallenge] IP %s got banned for '%u' seconds because account %s failed to authenticate '%u' times",
                            current_ip.c_str(), WrongPassBanTime, _login.c_str(), failed_logins);
                    }
                }
                delete loginfail;
            }
        }
    }
    return true;
}
Ejemplo n.º 17
0
int MAIN(int argc, char **argv)
	{
	ENGINE *e = NULL;
	char **args;
	char *host = NULL, *port = NULL, *path = "/";
	char *reqin = NULL, *respin = NULL;
	char *reqout = NULL, *respout = NULL;
	char *signfile = NULL, *keyfile = NULL;
	char *rsignfile = NULL, *rkeyfile = NULL;
	char *outfile = NULL;
	int add_nonce = 1, noverify = 0, use_ssl = -1;
	STACK_OF(CONF_VALUE) *headers = NULL;
	OCSP_REQUEST *req = NULL;
	OCSP_RESPONSE *resp = NULL;
	OCSP_BASICRESP *bs = NULL;
	X509 *issuer = NULL, *cert = NULL;
	X509 *signer = NULL, *rsigner = NULL;
	EVP_PKEY *key = NULL, *rkey = NULL;
	BIO *acbio = NULL, *cbio = NULL;
	BIO *derbio = NULL;
	BIO *out = NULL;
	int req_timeout = -1;
	int req_text = 0, resp_text = 0;
	long nsec = MAX_VALIDITY_PERIOD, maxage = -1;
	char *CAfile = NULL, *CApath = NULL;
	X509_STORE *store = NULL;
	STACK_OF(X509) *sign_other = NULL, *verify_other = NULL, *rother = NULL;
	char *sign_certfile = NULL, *verify_certfile = NULL, *rcertfile = NULL;
	unsigned long sign_flags = 0, verify_flags = 0, rflags = 0;
	int ret = 1;
	int accept_count = -1;
	int badarg = 0;
	int i;
	int ignore_err = 0;
	STACK_OF(OPENSSL_STRING) *reqnames = NULL;
	STACK_OF(OCSP_CERTID) *ids = NULL;

	X509 *rca_cert = NULL;
	char *ridx_filename = NULL;
	char *rca_filename = NULL;
	CA_DB *rdb = NULL;
	int nmin = 0, ndays = -1;
	const EVP_MD *cert_id_md = NULL;

	if (bio_err == NULL) bio_err = BIO_new_fp(OPENSSL_TYPE__FILE_STDERR, BIO_NOCLOSE);

	if (!load_config(bio_err, NULL))
		goto end;
	SSL_load_error_strings();
	OpenSSL_add_ssl_algorithms();
	args = argv + 1;
	reqnames = sk_OPENSSL_STRING_new_null();
	ids = sk_OCSP_CERTID_new_null();
	while (!badarg && *args && *args[0] == '-')
		{
		if (!TINYCLR_SSL_STRCMP(*args, "-out"))
			{
			if (args[1])
				{
				args++;
				outfile = *args;
				}
			else badarg = 1;
			}
		else if (!TINYCLR_SSL_STRCMP(*args, "-timeout"))
			{
			if (args[1])
				{
				args++;
				req_timeout = atol(*args);
				if (req_timeout < 0)
					{
					BIO_printf(bio_err,
						"Illegal timeout value %s\n",
						*args);
					badarg = 1;
					}
				}
			else badarg = 1;
			}
		else if (!TINYCLR_SSL_STRCMP(*args, "-url"))
			{
			if (args[1])
				{
				args++;
				if (!OCSP_parse_url(*args, &host, &port, &path, &use_ssl))
					{
					BIO_printf(bio_err, "Error parsing URL\n");
					badarg = 1;
					}
				}
			else badarg = 1;
			}
		else if (!TINYCLR_SSL_STRCMP(*args, "-host"))
			{
			if (args[1])
				{
				args++;
				host = *args;
				}
			else badarg = 1;
			}
		else if (!TINYCLR_SSL_STRCMP(*args, "-port"))
			{
			if (args[1])
				{
				args++;
				port = *args;
				}
			else badarg = 1;
			}
		else if (!TINYCLR_SSL_STRCMP(*args, "-header"))
			{
			if (args[1] && args[2])
				{
				if (!X509V3_add_value(args[1], args[2], &headers))
					goto end;
				args += 2;
				}
			else badarg = 1;
			}
		else if (!TINYCLR_SSL_STRCMP(*args, "-ignore_err"))
			ignore_err = 1;
		else if (!TINYCLR_SSL_STRCMP(*args, "-noverify"))
			noverify = 1;
		else if (!TINYCLR_SSL_STRCMP(*args, "-nonce"))
			add_nonce = 2;
		else if (!TINYCLR_SSL_STRCMP(*args, "-no_nonce"))
			add_nonce = 0;
		else if (!TINYCLR_SSL_STRCMP(*args, "-resp_no_certs"))
			rflags |= OCSP_NOCERTS;
		else if (!TINYCLR_SSL_STRCMP(*args, "-resp_key_id"))
			rflags |= OCSP_RESPID_KEY;
		else if (!TINYCLR_SSL_STRCMP(*args, "-no_certs"))
			sign_flags |= OCSP_NOCERTS;
		else if (!TINYCLR_SSL_STRCMP(*args, "-no_signature_verify"))
			verify_flags |= OCSP_NOSIGS;
		else if (!TINYCLR_SSL_STRCMP(*args, "-no_cert_verify"))
			verify_flags |= OCSP_NOVERIFY;
		else if (!TINYCLR_SSL_STRCMP(*args, "-no_chain"))
			verify_flags |= OCSP_NOCHAIN;
		else if (!TINYCLR_SSL_STRCMP(*args, "-no_cert_checks"))
			verify_flags |= OCSP_NOCHECKS;
		else if (!TINYCLR_SSL_STRCMP(*args, "-no_explicit"))
			verify_flags |= OCSP_NOEXPLICIT;
		else if (!TINYCLR_SSL_STRCMP(*args, "-trust_other"))
			verify_flags |= OCSP_TRUSTOTHER;
		else if (!TINYCLR_SSL_STRCMP(*args, "-no_intern"))
			verify_flags |= OCSP_NOINTERN;
		else if (!TINYCLR_SSL_STRCMP(*args, "-text"))
			{
			req_text = 1;
			resp_text = 1;
			}
		else if (!TINYCLR_SSL_STRCMP(*args, "-req_text"))
			req_text = 1;
		else if (!TINYCLR_SSL_STRCMP(*args, "-resp_text"))
			resp_text = 1;
		else if (!TINYCLR_SSL_STRCMP(*args, "-reqin"))
			{
			if (args[1])
				{
				args++;
				reqin = *args;
				}
			else badarg = 1;
			}
		else if (!TINYCLR_SSL_STRCMP(*args, "-respin"))
			{
			if (args[1])
				{
				args++;
				respin = *args;
				}
			else badarg = 1;
			}
		else if (!TINYCLR_SSL_STRCMP(*args, "-signer"))
			{
			if (args[1])
				{
				args++;
				signfile = *args;
				}
			else badarg = 1;
			}
		else if (!TINYCLR_SSL_STRCMP (*args, "-VAfile"))
			{
			if (args[1])
				{
				args++;
				verify_certfile = *args;
				verify_flags |= OCSP_TRUSTOTHER;
				}
			else badarg = 1;
			}
		else if (!TINYCLR_SSL_STRCMP(*args, "-sign_other"))
			{
			if (args[1])
				{
				args++;
				sign_certfile = *args;
				}
			else badarg = 1;
			}
		else if (!TINYCLR_SSL_STRCMP(*args, "-verify_other"))
			{
			if (args[1])
				{
				args++;
				verify_certfile = *args;
				}
			else badarg = 1;
			}
		else if (!TINYCLR_SSL_STRCMP (*args, "-CAfile"))
			{
			if (args[1])
				{
				args++;
				CAfile = *args;
				}
			else badarg = 1;
			}
		else if (!TINYCLR_SSL_STRCMP (*args, "-CApath"))
			{
			if (args[1])
				{
				args++;
				CApath = *args;
				}
			else badarg = 1;
			}
		else if (!TINYCLR_SSL_STRCMP (*args, "-validity_period"))
			{
			if (args[1])
				{
				args++;
				nsec = atol(*args);
				if (nsec < 0)
					{
					BIO_printf(bio_err,
						"Illegal validity period %s\n",
						*args);
					badarg = 1;
					}
				}
			else badarg = 1;
			}
		else if (!TINYCLR_SSL_STRCMP (*args, "-status_age"))
			{
			if (args[1])
				{
				args++;
				maxage = atol(*args);
				if (maxage < 0)
					{
					BIO_printf(bio_err,
						"Illegal validity age %s\n",
						*args);
					badarg = 1;
					}
				}
			else badarg = 1;
			}
		 else if (!TINYCLR_SSL_STRCMP(*args, "-signkey"))
			{
			if (args[1])
				{
				args++;
				keyfile = *args;
				}
			else badarg = 1;
			}
		else if (!TINYCLR_SSL_STRCMP(*args, "-reqout"))
			{
			if (args[1])
				{
				args++;
				reqout = *args;
				}
			else badarg = 1;
			}
		else if (!TINYCLR_SSL_STRCMP(*args, "-respout"))
			{
			if (args[1])
				{
				args++;
				respout = *args;
				}
			else badarg = 1;
			}
		 else if (!TINYCLR_SSL_STRCMP(*args, "-path"))
			{
			if (args[1])
				{
				args++;
				path = *args;
				}
			else badarg = 1;
			}
		else if (!TINYCLR_SSL_STRCMP(*args, "-issuer"))
			{
			if (args[1])
				{
				args++;
				X509_free(issuer);
				issuer = load_cert(bio_err, *args, FORMAT_PEM,
					NULL, e, "issuer certificate");
				if(!issuer) goto end;
				}
			else badarg = 1;
			}
		else if (!TINYCLR_SSL_STRCMP (*args, "-cert"))
			{
			if (args[1])
				{
				args++;
				X509_free(cert);
				cert = load_cert(bio_err, *args, FORMAT_PEM,
					NULL, e, "certificate");
				if(!cert) goto end;
				if (!cert_id_md) cert_id_md = EVP_sha1();
				if(!add_ocsp_cert(&req, cert, cert_id_md, issuer, ids))
					goto end;
				if(!sk_OPENSSL_STRING_push(reqnames, *args))
					goto end;
				}
			else badarg = 1;
			}
		else if (!TINYCLR_SSL_STRCMP(*args, "-serial"))
			{
			if (args[1])
				{
				args++;
				if (!cert_id_md) cert_id_md = EVP_sha1();
				if(!add_ocsp_serial(&req, *args, cert_id_md, issuer, ids))
					goto end;
				if(!sk_OPENSSL_STRING_push(reqnames, *args))
					goto end;
				}
			else badarg = 1;
			}
		else if (!TINYCLR_SSL_STRCMP(*args, "-index"))
			{
			if (args[1])
				{
				args++;
				ridx_filename = *args;
				}
			else badarg = 1;
			}
		else if (!TINYCLR_SSL_STRCMP(*args, "-CA"))
			{
			if (args[1])
				{
				args++;
				rca_filename = *args;
				}
			else badarg = 1;
			}
		else if (!TINYCLR_SSL_STRCMP (*args, "-nmin"))
			{
			if (args[1])
				{
				args++;
				nmin = atol(*args);
				if (nmin < 0)
					{
					BIO_printf(bio_err,
						"Illegal update period %s\n",
						*args);
					badarg = 1;
					}
				}
				if (ndays == -1)
					ndays = 0;
			else badarg = 1;
			}
		else if (!TINYCLR_SSL_STRCMP (*args, "-nrequest"))
			{
			if (args[1])
				{
				args++;
				accept_count = atol(*args);
				if (accept_count < 0)
					{
					BIO_printf(bio_err,
						"Illegal accept count %s\n",
						*args);
					badarg = 1;
					}
				}
			else badarg = 1;
			}
		else if (!TINYCLR_SSL_STRCMP (*args, "-ndays"))
			{
			if (args[1])
				{
				args++;
				ndays = atol(*args);
				if (ndays < 0)
					{
					BIO_printf(bio_err,
						"Illegal update period %s\n",
						*args);
					badarg = 1;
					}
				}
			else badarg = 1;
			}
		else if (!TINYCLR_SSL_STRCMP(*args, "-rsigner"))
			{
			if (args[1])
				{
				args++;
				rsignfile = *args;
				}
			else badarg = 1;
			}
		else if (!TINYCLR_SSL_STRCMP(*args, "-rkey"))
			{
			if (args[1])
				{
				args++;
				rkeyfile = *args;
				}
			else badarg = 1;
			}
		else if (!TINYCLR_SSL_STRCMP(*args, "-rother"))
			{
			if (args[1])
				{
				args++;
				rcertfile = *args;
				}
			else badarg = 1;
			}
		else if ((cert_id_md = EVP_get_digestbyname((*args)+1))==NULL)
			{
			badarg = 1;
			}
		args++;
		}

	/* Have we anything to do? */
	if (!req && !reqin && !respin && !(port && ridx_filename)) badarg = 1;

	if (badarg)
		{
		BIO_printf (bio_err, "OCSP utility\n");
		BIO_printf (bio_err, "Usage ocsp [options]\n");
		BIO_printf (bio_err, "where options are\n");
		BIO_printf (bio_err, "-out file          output filename\n");
		BIO_printf (bio_err, "-issuer file       issuer certificate\n");
		BIO_printf (bio_err, "-cert file         certificate to check\n");
		BIO_printf (bio_err, "-serial n          serial number to check\n");
		BIO_printf (bio_err, "-signer file       certificate to sign OCSP request with\n");
		BIO_printf (bio_err, "-signkey file      private key to sign OCSP request with\n");
		BIO_printf (bio_err, "-sign_other file   additional certificates to include in signed request\n");
		BIO_printf (bio_err, "-no_certs          don't include any certificates in signed request\n");
		BIO_printf (bio_err, "-req_text          print text form of request\n");
		BIO_printf (bio_err, "-resp_text         print text form of response\n");
		BIO_printf (bio_err, "-text              print text form of request and response\n");
		BIO_printf (bio_err, "-reqout file       write DER encoded OCSP request to \"file\"\n");
		BIO_printf (bio_err, "-respout file      write DER encoded OCSP reponse to \"file\"\n");
		BIO_printf (bio_err, "-reqin file        read DER encoded OCSP request from \"file\"\n");
		BIO_printf (bio_err, "-respin file       read DER encoded OCSP reponse from \"file\"\n");
		BIO_printf (bio_err, "-nonce             add OCSP nonce to request\n");
		BIO_printf (bio_err, "-no_nonce          don't add OCSP nonce to request\n");
		BIO_printf (bio_err, "-url URL           OCSP responder URL\n");
		BIO_printf (bio_err, "-host host:n       send OCSP request to host on port n\n");
		BIO_printf (bio_err, "-path              path to use in OCSP request\n");
		BIO_printf (bio_err, "-CApath dir        trusted certificates directory\n");
		BIO_printf (bio_err, "-CAfile file       trusted certificates file\n");
		BIO_printf (bio_err, "-VAfile file       validator certificates file\n");
		BIO_printf (bio_err, "-validity_period n maximum validity discrepancy in seconds\n");
		BIO_printf (bio_err, "-status_age n      maximum status age in seconds\n");
		BIO_printf (bio_err, "-noverify          don't verify response at all\n");
		BIO_printf (bio_err, "-verify_other file additional certificates to search for signer\n");
		BIO_printf (bio_err, "-trust_other       don't verify additional certificates\n");
		BIO_printf (bio_err, "-no_intern         don't search certificates contained in response for signer\n");
		BIO_printf (bio_err, "-no_signature_verify don't check signature on response\n");
		BIO_printf (bio_err, "-no_cert_verify    don't check signing certificate\n");
		BIO_printf (bio_err, "-no_chain          don't chain verify response\n");
		BIO_printf (bio_err, "-no_cert_checks    don't do additional checks on signing certificate\n");
		BIO_printf (bio_err, "-port num		 port to run responder on\n");
		BIO_printf (bio_err, "-index file	 certificate status index file\n");
		BIO_printf (bio_err, "-CA file		 CA certificate\n");
		BIO_printf (bio_err, "-rsigner file	 responder certificate to sign responses with\n");
		BIO_printf (bio_err, "-rkey file	 responder key to sign responses with\n");
		BIO_printf (bio_err, "-rother file	 other certificates to include in response\n");
		BIO_printf (bio_err, "-resp_no_certs     don't include any certificates in response\n");
		BIO_printf (bio_err, "-nmin n	 	 number of minutes before next update\n");
		BIO_printf (bio_err, "-ndays n	 	 number of days before next update\n");
		BIO_printf (bio_err, "-resp_key_id       identify reponse by signing certificate key ID\n");
		BIO_printf (bio_err, "-nrequest n        number of requests to accept (default unlimited)\n");
		BIO_printf (bio_err, "-<dgst alg>     use specified digest in the request");
		goto end;
		}

	if(outfile) out = BIO_new_file(outfile, "w");
	else out = BIO_new_fp(OPENSSL_TYPE__FILE_STDOUT, BIO_NOCLOSE);

	if(!out)
		{
		BIO_printf(bio_err, "Error opening output file\n");
		goto end;
		}

	if (!req && (add_nonce != 2)) add_nonce = 0;

	if (!req && reqin)
		{
		derbio = BIO_new_file(reqin, "rb");
		if (!derbio)
			{
			BIO_printf(bio_err, "Error Opening OCSP request file\n");
			goto end;
			}
		req = d2i_OCSP_REQUEST_bio(derbio, NULL);
		BIO_free(derbio);
		if(!req)
			{
			BIO_printf(bio_err, "Error reading OCSP request\n");
			goto end;
			}
		}

	if (!req && port)
		{
		acbio = init_responder(port);
		if (!acbio)
			goto end;
		}

	if (rsignfile && !rdb)
		{
		if (!rkeyfile) rkeyfile = rsignfile;
		rsigner = load_cert(bio_err, rsignfile, FORMAT_PEM,
			NULL, e, "responder certificate");
		if (!rsigner)
			{
			BIO_printf(bio_err, "Error loading responder certificate\n");
			goto end;
			}
		rca_cert = load_cert(bio_err, rca_filename, FORMAT_PEM,
			NULL, e, "CA certificate");
		if (rcertfile)
			{
			rother = load_certs(bio_err, rcertfile, FORMAT_PEM,
				NULL, e, "responder other certificates");
			if (!rother) goto end;
			}
		rkey = load_key(bio_err, rkeyfile, FORMAT_PEM, 0, NULL, NULL,
			"responder private key");
		if (!rkey)
			goto end;
		}
	if(acbio)
		BIO_printf(bio_err, "Waiting for OCSP client connections...\n");

	redo_accept:

	if (acbio)
		{
		if (!do_responder(&req, &cbio, acbio, port))
			goto end;
		if (!req)
			{
			resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL);
			send_ocsp_response(cbio, resp);
			goto done_resp;
			}
		}

	if (!req && (signfile || reqout || host || add_nonce || ridx_filename))
		{
		BIO_printf(bio_err, "Need an OCSP request for this operation!\n");
		goto end;
		}

	if (req && add_nonce) OCSP_request_add1_nonce(req, NULL, -1);

	if (signfile)
		{
		if (!keyfile) keyfile = signfile;
		signer = load_cert(bio_err, signfile, FORMAT_PEM,
			NULL, e, "signer certificate");
		if (!signer)
			{
			BIO_printf(bio_err, "Error loading signer certificate\n");
			goto end;
			}
		if (sign_certfile)
			{
			sign_other = load_certs(bio_err, sign_certfile, FORMAT_PEM,
				NULL, e, "signer certificates");
			if (!sign_other) goto end;
			}
		key = load_key(bio_err, keyfile, FORMAT_PEM, 0, NULL, NULL,
			"signer private key");
		if (!key)
			goto end;

		if (!OCSP_request_sign(req, signer, key, NULL, sign_other, sign_flags))
			{
			BIO_printf(bio_err, "Error signing OCSP request\n");
			goto end;
			}
		}

	if (req_text && req) OCSP_REQUEST_print(out, req, 0);

	if (reqout)
		{
		derbio = BIO_new_file(reqout, "wb");
		if(!derbio)
			{
			BIO_printf(bio_err, "Error opening file %s\n", reqout);
			goto end;
			}
		i2d_OCSP_REQUEST_bio(derbio, req);
		BIO_free(derbio);
		}

	if (ridx_filename && (!rkey || !rsigner || !rca_cert))
		{
		BIO_printf(bio_err, "Need a responder certificate, key and CA for this operation!\n");
		goto end;
		}

	if (ridx_filename && !rdb)
		{
		rdb = load_index(ridx_filename, NULL);
		if (!rdb) goto end;
		if (!index_index(rdb)) goto end;
		}

	if (rdb)
		{
		i = make_ocsp_response(&resp, req, rdb, rca_cert, rsigner, rkey, rother, rflags, nmin, ndays);
		if (cbio)
			send_ocsp_response(cbio, resp);
		}
	else if (host)
		{
#ifndef OPENSSL_NO_SOCK
		resp = process_responder(bio_err, req, host, path,
					port, use_ssl, headers, req_timeout);
		if (!resp)
			goto end;
#else
		BIO_printf(bio_err, "Error creating connect BIO - sockets not supported.\n");
		goto end;
#endif
		}
	else if (respin)
		{
		derbio = BIO_new_file(respin, "rb");
		if (!derbio)
			{
			BIO_printf(bio_err, "Error Opening OCSP response file\n");
			goto end;
			}
		resp = d2i_OCSP_RESPONSE_bio(derbio, NULL);
		BIO_free(derbio);
		if(!resp)
			{
			BIO_printf(bio_err, "Error reading OCSP response\n");
			goto end;
			}
	
		}
	else
		{
		ret = 0;
		goto end;
		}

	done_resp:

	if (respout)
		{
		derbio = BIO_new_file(respout, "wb");
		if(!derbio)
			{
			BIO_printf(bio_err, "Error opening file %s\n", respout);
			goto end;
			}
		i2d_OCSP_RESPONSE_bio(derbio, resp);
		BIO_free(derbio);
		}

	i = OCSP_response_status(resp);

	if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL)
		{
		BIO_printf(out, "Responder Error: %s (%d)\n",
				OCSP_response_status_str(i), i);
		if (ignore_err)
			goto redo_accept;
		ret = 0;
		goto end;
		}

	if (resp_text) OCSP_RESPONSE_print(out, resp, 0);

	/* If running as responder don't verify our own response */
	if (cbio)
		{
		if (accept_count > 0)
			accept_count--;
		/* Redo if more connections needed */
		if (accept_count)
			{
			BIO_free_all(cbio);
			cbio = NULL;
			OCSP_REQUEST_free(req);
			req = NULL;
			OCSP_RESPONSE_free(resp);
			resp = NULL;
			goto redo_accept;
			}
		goto end;
		}

	if (!store)
		store = setup_verify(bio_err, CAfile, CApath);
	if (!store)
		goto end;
	if (verify_certfile)
		{
		verify_other = load_certs(bio_err, verify_certfile, FORMAT_PEM,
			NULL, e, "validator certificate");
		if (!verify_other) goto end;
		}

	bs = OCSP_response_get1_basic(resp);

	if (!bs)
		{
		BIO_printf(bio_err, "Error parsing response\n");
		goto end;
		}

	if (!noverify)
		{
		if (req && ((i = OCSP_check_nonce(req, bs)) <= 0))
			{
			if (i == -1)
				BIO_printf(bio_err, "WARNING: no nonce in response\n");
			else
				{
				BIO_printf(bio_err, "Nonce Verify error\n");
				goto end;
				}
			}

		i = OCSP_basic_verify(bs, verify_other, store, verify_flags);
                if (i < 0) i = OCSP_basic_verify(bs, NULL, store, 0);

		if(i <= 0)
			{
			BIO_printf(bio_err, "Response Verify Failure\n");
			ERR_print_errors(bio_err);
			}
		else
			BIO_printf(bio_err, "Response verify OK\n");

		}

	if (!print_ocsp_summary(out, bs, req, reqnames, ids, nsec, maxage))
		goto end;

	ret = 0;

end:
	ERR_print_errors(bio_err);
	X509_free(signer);
	X509_STORE_free(store);
	EVP_PKEY_free(key);
	EVP_PKEY_free(rkey);
	X509_free(issuer);
	X509_free(cert);
	X509_free(rsigner);
	X509_free(rca_cert);
	free_index(rdb);
	BIO_free_all(cbio);
	BIO_free_all(acbio);
	BIO_free(out);
	OCSP_REQUEST_free(req);
	OCSP_RESPONSE_free(resp);
	OCSP_BASICRESP_free(bs);
	sk_OPENSSL_STRING_free(reqnames);
	sk_OCSP_CERTID_free(ids);
	sk_X509_pop_free(sign_other, X509_free);
	sk_X509_pop_free(verify_other, X509_free);
	sk_CONF_VALUE_pop_free(headers, X509V3_conf_free);

	if (use_ssl != -1)
		{
		OPENSSL_free(host);
		OPENSSL_free(port);
		OPENSSL_free(path);
		}

	OPENSSL_EXIT(ret);
}
Ejemplo n.º 18
0
static void policy_map_free(X509_POLICY_REF * map)
{
    OPENSSL_free(map);
}
Ejemplo n.º 19
0
int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,
	     long *len)
	{
	EVP_ENCODE_CTX ctx;
	int end=0,i,k,bl=0,hl=0,nohead=0;
	char buf[256];
	BUF_MEM *nameB;
	BUF_MEM *headerB;
	BUF_MEM *dataB,*tmpB;
	
	nameB=BUF_MEM_new();
	headerB=BUF_MEM_new();
	dataB=BUF_MEM_new();
	if ((nameB == NULL) || (headerB == NULL) || (dataB == NULL))
		{
		BUF_MEM_free(nameB);
		BUF_MEM_free(headerB);
		BUF_MEM_free(dataB);
		PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE);
		return(0);
		}

	buf[254]='\0';
	for (;;)
		{
		i=BIO_gets(bp,buf,254);

		if (i <= 0)
			{
			PEMerr(PEM_F_PEM_READ_BIO,PEM_R_NO_START_LINE);
			goto err;
			}

		while ((i >= 0) && (buf[i] <= ' ')) i--;
		buf[++i]='\n'; buf[++i]='\0';

		if (strncmp(buf,"-----BEGIN ",11) == 0)
			{
			i=strlen(&(buf[11]));

			if (strncmp(&(buf[11+i-6]),"-----\n",6) != 0)
				continue;
			if (!BUF_MEM_grow(nameB,i+9))
				{
				PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE);
				goto err;
				}
			memcpy(nameB->data,&(buf[11]),i-6);
			nameB->data[i-6]='\0';
			break;
			}
		}
	hl=0;
	if (!BUF_MEM_grow(headerB,256))
		{ PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE); goto err; }
	headerB->data[0]='\0';
	for (;;)
		{
		i=BIO_gets(bp,buf,254);
		if (i <= 0) break;

		while ((i >= 0) && (buf[i] <= ' ')) i--;
		buf[++i]='\n'; buf[++i]='\0';

		if (buf[0] == '\n') break;
		if (!BUF_MEM_grow(headerB,hl+i+9))
			{ PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE); goto err; }
		if (strncmp(buf,"-----END ",9) == 0)
			{
			nohead=1;
			break;
			}
		memcpy(&(headerB->data[hl]),buf,i);
		headerB->data[hl+i]='\0';
		hl+=i;
		}

	bl=0;
	if (!BUF_MEM_grow(dataB,1024))
		{ PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE); goto err; }
	dataB->data[0]='\0';
	if (!nohead)
		{
		for (;;)
			{
			i=BIO_gets(bp,buf,254);
			if (i <= 0) break;

			while ((i >= 0) && (buf[i] <= ' ')) i--;
			buf[++i]='\n'; buf[++i]='\0';

			if (i != 65) end=1;
			if (strncmp(buf,"-----END ",9) == 0)
				break;
			if (i > 65) break;
			if (!BUF_MEM_grow_clean(dataB,i+bl+9))
				{
				PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE);
				goto err;
				}
			memcpy(&(dataB->data[bl]),buf,i);
			dataB->data[bl+i]='\0';
			bl+=i;
			if (end)
				{
				buf[0]='\0';
				i=BIO_gets(bp,buf,254);
				if (i <= 0) break;

				while ((i >= 0) && (buf[i] <= ' ')) i--;
				buf[++i]='\n'; buf[++i]='\0';

				break;
				}
			}
		}
	else
		{
		tmpB=headerB;
		headerB=dataB;
		dataB=tmpB;
		bl=hl;
		}
	i=strlen(nameB->data);
	if (	(strncmp(buf,"-----END ",9) != 0) ||
		(strncmp(nameB->data,&(buf[9]),i) != 0) ||
		(strncmp(&(buf[9+i]),"-----\n",6) != 0))
		{
		PEMerr(PEM_F_PEM_READ_BIO,PEM_R_BAD_END_LINE);
		goto err;
		}

	EVP_DecodeInit(&ctx);
	i=EVP_DecodeUpdate(&ctx,
		(unsigned char *)dataB->data,&bl,
		(unsigned char *)dataB->data,bl);
	if (i < 0)
		{
		PEMerr(PEM_F_PEM_READ_BIO,PEM_R_BAD_BASE64_DECODE);
		goto err;
		}
	i=EVP_DecodeFinal(&ctx,(unsigned char *)&(dataB->data[bl]),&k);
	if (i < 0)
		{
		PEMerr(PEM_F_PEM_READ_BIO,PEM_R_BAD_BASE64_DECODE);
		goto err;
		}
	bl+=k;

	if (bl == 0) goto err;
	*name=nameB->data;
	*header=headerB->data;
	*data=(unsigned char *)dataB->data;
	*len=bl;
	OPENSSL_free(nameB);
	OPENSSL_free(headerB);
	OPENSSL_free(dataB);
	return(1);
err:
	BUF_MEM_free(nameB);
	BUF_MEM_free(headerB);
	BUF_MEM_free(dataB);
	return(0);
	}
Ejemplo n.º 20
0
/* Allocate the SCEP_MSG structures */
SCEP_MSG *SCEP_MSG_new( int messageType, X509 *cert, EVP_PKEY *pkey,
		X509 *recip_cert, SCEP_MSG *inMsg, X509_REQ *req,
		X509 *issued_cert, SCEP_ISSUER_AND_SUBJECT *cert_info,
		PKCS7_ISSUER_AND_SERIAL *ias, X509_CRL *crl, X509 *cacert,
		EVP_CIPHER cipher ) {

	SCEP_MSG *msg = NULL;
	PKCS7_SIGNER_INFO *si = NULL;
	EVP_MD *dgst=NULL;

	unsigned char *raw_data = NULL;
	int envelope = 0;
	long raw_len = 0;

	BIO *debug_bio = NULL;
	BIO *p7ebio = NULL;
	BIO *inbio = NULL;

	char buf[256];

        if ((debug_bio=BIO_new(BIO_s_file())) != NULL)
		BIO_set_fp(debug_bio,stderr,BIO_NOCLOSE|BIO_FP_TEXT);

	//if( !cert || !pkey || !recip_cert )
	if( !cert || !pkey )
		return NULL;

	if (debug)
		BIO_printf( debug_bio, "%s:%d: [Debug Info] Generating New SCEP-Message...\n", __FILE__, __LINE__);

	/* Allocate memory and initialize structures */
	if((msg = SCEP_MSG_new_null()) == NULL) return NULL;
	if (debug)
		BIO_printf( debug_bio, "%s:%d: [Debug Info] Allocate memory\n", __FILE__, __LINE__);
	
	/* Signed Infos */
	dgst = (EVP_MD *) EVP_get_digestbyname("md5");
	if( (si = PKCS7_SIGNER_INFO_new()) == NULL ) goto err;
	if(!PKCS7_SIGNER_INFO_set(si, cert, pkey, dgst)) goto err;
	sk_PKCS7_SIGNER_INFO_push( msg->sk_signer_info, si );
	msg->signer_ias = si->issuer_and_serial;

	if (debug)
		BIO_printf( debug_bio, "%s:%d: [Debug Info] signer infos set\n", __FILE__, __LINE__);

	/* If pkey, let's add to the message structure to ease
	 * message encryption (enveloped data content creation) */
	SCEP_MSG_set_pkey ( msg, pkey );
	// msg->signer_pkey = pkey;

	if (debug)
		BIO_printf( debug_bio, "%s:%d: [Debug Info] encryption key set\n", __FILE__, __LINE__);

	/* If not explicit, we guess the certificate to be present
	 * in the passed inMsg structure, if any. Otherwise ERROR! */
	if( !recip_cert && inMsg ) recip_cert = inMsg->signer_cert;

	/* Set the messageType */
	SCEP_set_messageType ( msg, messageType );

	if (debug)
		BIO_printf( debug_bio, "%s:%d: [Debug Info] message type set\n", __FILE__, __LINE__);
	switch( messageType ) {
		case MSG_CERTREP:
			if (debug)
		        	BIO_printf( debug_bio, "%s:%d: [Debug Info] Actions for CERTREP\n", __FILE__, __LINE__);
			msg->env_data.NID_p7data = NID_pkcs7_signed;
                        msg->env_data.p7 = PKCS7_new();
                        PKCS7_set_type( msg->env_data.p7, NID_pkcs7_signed );
                        PKCS7_content_new( msg->env_data.p7, NID_pkcs7_data );
			if( issued_cert ) {
				if (debug)
					BIO_printf( debug_bio, 
						"%s:%d: creating inner degenerated PKCS7... \n", 
						__FILE__, __LINE__);
				/* Adds issued certificate */
				PKCS7_add_certificate( msg->env_data.p7, issued_cert );
//				PKCS7_add_certificate( msg->env_data.p7, cert );
				envelope = 1;
				if (debug)
					BIO_printf( debug_bio, "%s:%d: done \n", __FILE__, __LINE__);
			} else if( crl ) {
				if (debug)
					BIO_printf( debug_bio, 
						"%s:%d: Adding CRL ... \n", 
						__FILE__, __LINE__);
				/* Adds crl */
				PKCS7_add_crl( msg->env_data.p7, crl );
				envelope = 1;
				if (debug)
				        BIO_printf( debug_bio, "%s:%d: done \n", __FILE__, __LINE__);
				
			} 
			if (debug)
				BIO_printf( debug_bio, "%s:%d: [Debug Info] done\n", __FILE__, __LINE__);
			break;
		case MSG_PKCSREQ:
			if (debug)
				BIO_printf( debug_bio, "%s:%d: [Debug Info] Actions for PKCSREQ\n", __FILE__, __LINE__);
			/* The inner pkcs7 structure is signed
			 * and enveloped and the data is to be
			 * the X509_REQ passed */
			msg->env_data.NID_p7data = 
			 	NID_pkcs7_signedAndEnveloped;

			if( req ) { 
				msg->env_data.content.req = req;

				/* Ask for the data p7 to be generated and
				 * encrypted */
				envelope = 1;
			}
			if (debug)
				BIO_printf( debug_bio, "%s:%d: [Debug Info] done\n", __FILE__, __LINE__);
			break;
		case MSG_GETCRL:
			if (debug)
			{
				BIO_printf( debug_bio, "%s:%d: [Debug Info] Actions for GETCRL\n", __FILE__, __LINE__);
				BIO_printf( debug_bio, "%s:%d: [Debug Info] done\n", __FILE__, __LINE__);
			}
			break;
		case MSG_GETCERT:
			if (debug)
				BIO_printf( debug_bio, "%s:%d: [Debug Info] Actions for GETCERT\n", __FILE__, __LINE__);
			msg->env_data.NID_p7data = 
				NID_pkcs7_signedAndEnveloped;
			/* If it is a query for a general certificate
			 * the CAcert should be included in the enveloped
			 * data*/
			/* Otherwise, if it is a request for its own
			 * certificate, the self-signed certificate should
			 * be included */
			// if( cacert )
			// 	msg->env_data.cacert = cacert;

			/* Issuer and Serial should be present ! */
			if( !ias ) goto err;
			msg->env_data.content.ias = ias;
			envelope = 1;
			if (debug)
				BIO_printf( debug_bio, "%s:%d: [Debug Info] done\n", __FILE__, __LINE__);
			break;
		case MSG_GETCERTINITIAL:
			if (debug)
				BIO_printf( debug_bio, "%s:%d: [Debug Info] Actions for GETCERTINITIAL\n", __FILE__, __LINE__);
			msg->env_data.NID_p7data = NID_pkcs7_signed;
			if (debug)
				BIO_printf( debug_bio, "%s:%d: [Debug Info] done\n", __FILE__, __LINE__);
			break;
		case MSG_V2REQUEST: /* Not currently handled */
			if (debug) {
				BIO_printf( debug_bio, "%s:%d: [Debug Info] Actions for V2REQUEST\n", __FILE__, __LINE__);
				BIO_printf( debug_bio, "%s:%d: [Debug Info] done\n", __FILE__, __LINE__);
			}
		default:
			goto err;
	}
	
	if (debug)
		BIO_printf( debug_bio, "%s:%d: Debug ... \n", __FILE__, __LINE__);

	/* If different from NULL, we have to encode something */
	if( envelope == 1 ) {
		if (debug)
			BIO_printf( debug_bio, "%s:%d: [Debug Info] encode\n", __FILE__, __LINE__);
		/* Encrypt the message data */
		if( !SCEP_MSG_encrypt( msg, recip_cert, cipher )) goto err;
		if (debug)
			BIO_printf( debug_bio, "%s:%d: [Debug Info] done\n", __FILE__, __LINE__);
	}

	if (debug)
		BIO_printf( debug_bio, "%s:%d: [Debug Info] add sign-cert to structure\n", __FILE__, __LINE__);
	/* Signer certificate */
	msg->signer_cert = cert;
	if (debug)
		PEM_write_bio_SCEP_MSG( debug_bio, msg, pkey );

	if (debug)
		BIO_printf( debug_bio, "%s:%d: [Debug Info] add attributes\n", __FILE__, __LINE__);
	/* Set message attributes, if any */
	if ( inMsg ) {
		char *tmp = NULL;
		int len = 0;
		if (debug)
			BIO_printf( debug_bio, "%s:%d: [Debug Info] take data from request\n", __FILE__, __LINE__);

		switch ( msg->messageType ) {
		   default:
			if (debug)
				BIO_printf( debug_bio, "%s:%d: [Debug Info]   set transId\n", __FILE__, __LINE__);
			/* The transId is ever required */
			tmp = SCEP_get_string_attr_by_name( inMsg->attrs, "transId");
			if( tmp ) {
				SCEP_set_transId( msg, tmp, strlen(tmp));
				OPENSSL_free( tmp );
				if (debug)
					BIO_printf( debug_bio, "%s:%d: [Debug Info]    done\n", __FILE__, __LINE__);
			}

			if (debug)
				BIO_printf( debug_bio, "%s:%d: [Debug Info]   set recipient nonce (sendernonce from req)\n", __FILE__, __LINE__);
			/* Copy the sendernonce to the recipient nonce and
			 * generate a new sendernonce for the generated msg */
			tmp = SCEP_get_octect_attr_by_name( inMsg->attrs, 
					"senderNonce", &len);
			if( tmp ) {
				if (debug)
					BIO_printf( debug_bio, "%s:%d: [Debug Info]    %d\n", __FILE__, __LINE__, tmp);
				SCEP_set_recipientNonce( msg, tmp, len );
				OPENSSL_free( tmp );
			}
			if (debug)
				BIO_printf( debug_bio, "%s:%d: [Debug Info]   set sender nonce\n", __FILE__, __LINE__);
			SCEP_set_senderNonce_new(msg);
			if (debug)
				BIO_printf( debug_bio, "%s:%d: [Debug Info]    done\n", __FILE__, __LINE__);
		}
		if (debug)
			BIO_printf( debug_bio, "%s:%d: [Debug Info]   set pki_status\n", __FILE__, __LINE__);
		SCEP_set_pkiStatus ( msg, PKI_PENDING );
		if (debug) {
			BIO_printf( debug_bio, "%s:%d: [Debug Info]    done\n", __FILE__, __LINE__);
			BIO_printf( debug_bio, "%s:%d: [Debug Info] done\n", __FILE__, __LINE__);
		}
	} else {
		if (debug)
			BIO_printf( debug_bio, "%s:%d: [Debug Info] generate new data\n", __FILE__, __LINE__);
		SCEP_set_senderNonce_new ( msg );
		SCEP_set_recipientNonce_new ( msg );
		SCEP_set_transId_new ( msg );
		if (debug)
			BIO_printf( debug_bio, "%s:%d: [Debug Info] done\n", __FILE__, __LINE__);
	}

	if (debug)
		PEM_write_bio_SCEP_MSG( debug_bio, msg, pkey );
	return (msg);
err:
	ERR_print_errors_fp(stderr);
	return(NULL);
}
Ejemplo n.º 21
0
int dhparam_main(int argc, char **argv)
{
    BIO *in = NULL, *out = NULL;
    DH *dh = NULL;
    char *infile = NULL, *outfile = NULL, *prog, *inrand = NULL;
    ENGINE *e = NULL;
#ifndef OPENSSL_NO_DSA
    int dsaparam = 0;
#endif
    int i, text = 0, C = 0, ret = 1, num = 0, g = 0;
    int informat = FORMAT_PEM, outformat = FORMAT_PEM, check = 0, noout = 0;
    OPTION_CHOICE o;

    prog = opt_init(argc, argv, dhparam_options);
    while ((o = opt_next()) != OPT_EOF) {
        switch (o) {
        case OPT_EOF:
        case OPT_ERR:
 opthelp:
            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
            goto end;
        case OPT_HELP:
            opt_help(dhparam_options);
            ret = 0;
            goto end;
        case OPT_INFORM:
            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat))
                goto opthelp;
            break;
        case OPT_OUTFORM:
            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat))
                goto opthelp;
            break;
        case OPT_IN:
            infile = opt_arg();
            break;
        case OPT_OUT:
            outfile = opt_arg();
            break;
        case OPT_ENGINE:
            e = setup_engine(opt_arg(), 0);
            break;
        case OPT_CHECK:
            check = 1;
            break;
        case OPT_TEXT:
            text = 1;
            break;
        case OPT_DSAPARAM:
#ifndef OPENSSL_NO_DSA
            dsaparam = 1;
#endif
            break;
        case OPT_C:
            C = 1;
            break;
        case OPT_2:
            g = 2;
            break;
        case OPT_5:
            g = 5;
            break;
        case OPT_NOOUT:
            noout = 1;
            break;
        case OPT_RAND:
            inrand = opt_arg();
            break;
        }
    }
    argc = opt_num_rest();
    argv = opt_rest();

    if (argv[0] && (!opt_int(argv[0], &num) || num <= 0))
        goto end;

    if (g && !num)
        num = DEFBITS;

# ifndef OPENSSL_NO_DSA
    if (dsaparam && g) {
        BIO_printf(bio_err,
                   "generator may not be chosen for DSA parameters\n");
        goto end;
    }
# endif
    /* DH parameters */
    if (num && !g)
        g = 2;

    if (num) {

        BN_GENCB *cb;
        cb = BN_GENCB_new();
        if (cb == NULL) {
            ERR_print_errors(bio_err);
            goto end;
        }

        BN_GENCB_set(cb, dh_cb, bio_err);
        if (!app_RAND_load_file(NULL, 1) && inrand == NULL) {
            BIO_printf(bio_err,
                       "warning, not much extra random data, consider using the -rand option\n");
        }
        if (inrand != NULL)
            BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
                       app_RAND_load_files(inrand));

# ifndef OPENSSL_NO_DSA
        if (dsaparam) {
            DSA *dsa = DSA_new();

            BIO_printf(bio_err,
                       "Generating DSA parameters, %d bit long prime\n", num);
            if (dsa == NULL
                || !DSA_generate_parameters_ex(dsa, num, NULL, 0, NULL, NULL,
                                               cb)) {
                DSA_free(dsa);
                BN_GENCB_free(cb);
                ERR_print_errors(bio_err);
                goto end;
            }

            dh = DSA_dup_DH(dsa);
            DSA_free(dsa);
            if (dh == NULL) {
                BN_GENCB_free(cb);
                ERR_print_errors(bio_err);
                goto end;
            }
        } else
# endif
        {
            dh = DH_new();
            BIO_printf(bio_err,
                       "Generating DH parameters, %d bit long safe prime, generator %d\n",
                       num, g);
            BIO_printf(bio_err, "This is going to take a long time\n");
            if (dh == NULL || !DH_generate_parameters_ex(dh, num, g, cb)) {
                BN_GENCB_free(cb);
                ERR_print_errors(bio_err);
                goto end;
            }
        }

        BN_GENCB_free(cb);
        app_RAND_write_file(NULL);
    } else {

        in = bio_open_default(infile, 'r', informat);
        if (in == NULL)
            goto end;

# ifndef OPENSSL_NO_DSA
        if (dsaparam) {
            DSA *dsa;

            if (informat == FORMAT_ASN1)
                dsa = d2i_DSAparams_bio(in, NULL);
            else                /* informat == FORMAT_PEM */
                dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL);

            if (dsa == NULL) {
                BIO_printf(bio_err, "unable to load DSA parameters\n");
                ERR_print_errors(bio_err);
                goto end;
            }

            dh = DSA_dup_DH(dsa);
            DSA_free(dsa);
            if (dh == NULL) {
                ERR_print_errors(bio_err);
                goto end;
            }
        } else
# endif
        {
            if (informat == FORMAT_ASN1)
                dh = d2i_DHparams_bio(in, NULL);
            else                /* informat == FORMAT_PEM */
                dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);

            if (dh == NULL) {
                BIO_printf(bio_err, "unable to load DH parameters\n");
                ERR_print_errors(bio_err);
                goto end;
            }
        }

        /* dh != NULL */
    }

    out = bio_open_default(outfile, 'w', outformat);
    if (out == NULL)
        goto end;

    if (text) {
        DHparams_print(out, dh);
    }

    if (check) {
        if (!DH_check(dh, &i)) {
            ERR_print_errors(bio_err);
            goto end;
        }
        if (i & DH_CHECK_P_NOT_PRIME)
            BIO_printf(bio_err, "WARNING: p value is not prime\n");
        if (i & DH_CHECK_P_NOT_SAFE_PRIME)
            BIO_printf(bio_err, "WARNING: p value is not a safe prime\n");
        if (i & DH_CHECK_Q_NOT_PRIME)
            BIO_printf(bio_err, "WARNING: q value is not a prime\n");
        if (i & DH_CHECK_INVALID_Q_VALUE)
            BIO_printf(bio_err, "WARNING: q value is invalid\n");
        if (i & DH_CHECK_INVALID_J_VALUE)
            BIO_printf(bio_err, "WARNING: j value is invalid\n");
        if (i & DH_UNABLE_TO_CHECK_GENERATOR)
            BIO_printf(bio_err,
                       "WARNING: unable to check the generator value\n");
        if (i & DH_NOT_SUITABLE_GENERATOR)
            BIO_printf(bio_err, "WARNING: the g value is not a generator\n");
        if (i == 0)
            BIO_printf(bio_err, "DH parameters appear to be ok.\n");
        if (num != 0 && i != 0) {
            /*
             * We have generated parameters but DH_check() indicates they are
             * invalid! This should never happen!
             */
            BIO_printf(bio_err, "ERROR: Invalid parameters generated\n");
            goto end;
        }
    }
    if (C) {
        unsigned char *data;
        int len, bits;
        const BIGNUM *pbn, *gbn;

        len = DH_size(dh);
        bits = DH_bits(dh);
        DH_get0_pqg(dh, &pbn, NULL, &gbn);
        data = app_malloc(len, "print a BN");
        BIO_printf(out, "#ifndef HEADER_DH_H\n"
                        "# include <openssl/dh.h>\n"
                        "#endif\n"
                        "\n");
        BIO_printf(out, "DH *get_dh%d()\n{\n", bits);
        print_bignum_var(out, pbn, "dhp", bits, data);
        print_bignum_var(out, gbn, "dhg", bits, data);
        BIO_printf(out, "    DH *dh = DH_new();\n"
                        "    BIGNUM *dhp_bn, *dhg_bn;\n"
                        "\n"
                        "    if (dh == NULL)\n"
                        "        return NULL;\n");
        BIO_printf(out, "    dhp_bn = BN_bin2bn(dhp_%d, sizeof (dhp_%d), NULL);\n",
                   bits, bits);
        BIO_printf(out, "    dhg_bn = BN_bin2bn(dhg_%d, sizeof (dhg_%d), NULL);\n",
                   bits, bits);
        BIO_printf(out, "    if (dhp_bn == NULL || dhg_bn == NULL\n"
                        "            || !DH_set0_pqg(dh, dhp_bn, NULL, dhg_bn)) {\n"
                        "        DH_free(dh);\n"
                        "        BN_free(dhp_bn);\n"
                        "        BN_free(dhg_bn);\n"
                        "        return NULL;\n"
                        "    }\n");
        if (DH_get_length(dh) > 0)
            BIO_printf(out,
                        "    if (!DH_set_length(dh, %ld)) {\n"
                        "        DH_free(dh);\n"
                        "    }\n", DH_get_length(dh));
        BIO_printf(out, "    return dh;\n}\n");
        OPENSSL_free(data);
    }

    if (!noout) {
        const BIGNUM *q;
        DH_get0_pqg(dh, NULL, &q, NULL);
        if (outformat == FORMAT_ASN1)
            i = i2d_DHparams_bio(out, dh);
        else if (q != NULL)
            i = PEM_write_bio_DHxparams(out, dh);
        else
            i = PEM_write_bio_DHparams(out, dh);
        if (!i) {
            BIO_printf(bio_err, "unable to write DH parameters\n");
            ERR_print_errors(bio_err);
            goto end;
        }
    }
    ret = 0;
 end:
    BIO_free(in);
    BIO_free_all(out);
    DH_free(dh);
    release_engine(e);
    return (ret);
}
Ejemplo n.º 22
0
void *CRYPTO_remalloc(void *a, int num, const char *file, int line)
	{
	if (a != NULL) OPENSSL_free(a);
	a=(char *)OPENSSL_malloc(num);
	return(a);
	}
Ejemplo n.º 23
0
int MAIN(int argc, char **argv)
	{
	ENGINE *e = NULL;
	int operation = 0;
	int ret = 0;
	char **args;
	const char *inmode = "r", *outmode = "w";
	char *infile = NULL, *outfile = NULL, *rctfile = NULL;
	char *signerfile = NULL, *recipfile = NULL;
	STACK_OF(OPENSSL_STRING) *sksigners = NULL, *skkeys = NULL;
	char *certfile = NULL, *keyfile = NULL, *contfile=NULL;
	char *certsoutfile = NULL;
	const EVP_CIPHER *cipher = NULL;
	CMS_ContentInfo *cms = NULL, *rcms = NULL;
	X509_STORE *store = NULL;
	X509 *cert = NULL, *recip = NULL, *signer = NULL;
	EVP_PKEY *key = NULL;
	STACK_OF(X509) *encerts = NULL, *other = NULL;
	BIO *in = NULL, *out = NULL, *indata = NULL, *rctin = NULL;
	int badarg = 0;
	int flags = CMS_DETACHED, noout = 0, print = 0;
	int verify_retcode = 0;
	int rr_print = 0, rr_allorfirst = -1;
	STACK_OF(OPENSSL_STRING) *rr_to = NULL, *rr_from = NULL;
	CMS_ReceiptRequest *rr = NULL;
	char *to = NULL, *from = NULL, *subject = NULL;
	char *CAfile = NULL, *CApath = NULL;
	char *passargin = NULL, *passin = NULL;
	char *inrand = NULL;
	int need_rand = 0;
	const EVP_MD *sign_md = NULL;
	int informat = FORMAT_SMIME, outformat = FORMAT_SMIME;
        int rctformat = FORMAT_SMIME, keyform = FORMAT_PEM;
#ifndef OPENSSL_NO_ENGINE
	char *engine=NULL;
#endif
	unsigned char *secret_key = NULL, *secret_keyid = NULL;
	unsigned char *pwri_pass = NULL, *pwri_tmp = NULL;
	size_t secret_keylen = 0, secret_keyidlen = 0;

	ASN1_OBJECT *econtent_type = NULL;

	X509_VERIFY_PARAM *vpm = NULL;

	args = argv + 1;
	ret = 1;

	apps_startup();

	if (bio_err == NULL)
		{
		if ((bio_err = BIO_new(BIO_s_file())) != NULL)
			BIO_set_fp(bio_err, stderr, BIO_NOCLOSE|BIO_FP_TEXT);
		}

	if (!load_config(bio_err, NULL))
		goto end;

	while (!badarg && *args && *args[0] == '-')
		{
		if (!strcmp (*args, "-encrypt"))
			operation = SMIME_ENCRYPT;
		else if (!strcmp (*args, "-decrypt"))
			operation = SMIME_DECRYPT;
		else if (!strcmp (*args, "-sign"))
			operation = SMIME_SIGN;
		else if (!strcmp (*args, "-sign_receipt"))
			operation = SMIME_SIGN_RECEIPT;
		else if (!strcmp (*args, "-resign"))
			operation = SMIME_RESIGN;
		else if (!strcmp (*args, "-verify"))
			operation = SMIME_VERIFY;
		else if (!strcmp (*args, "-verify_retcode"))
			verify_retcode = 1;
		else if (!strcmp(*args,"-verify_receipt"))
			{
			operation = SMIME_VERIFY_RECEIPT;
			if (!args[1])
				goto argerr;
			args++;
			rctfile = *args;
			}
		else if (!strcmp (*args, "-cmsout"))
			operation = SMIME_CMSOUT;
		else if (!strcmp (*args, "-data_out"))
			operation = SMIME_DATAOUT;
		else if (!strcmp (*args, "-data_create"))
			operation = SMIME_DATA_CREATE;
		else if (!strcmp (*args, "-digest_verify"))
			operation = SMIME_DIGEST_VERIFY;
		else if (!strcmp (*args, "-digest_create"))
			operation = SMIME_DIGEST_CREATE;
		else if (!strcmp (*args, "-compress"))
			operation = SMIME_COMPRESS;
		else if (!strcmp (*args, "-uncompress"))
			operation = SMIME_UNCOMPRESS;
		else if (!strcmp (*args, "-EncryptedData_decrypt"))
			operation = SMIME_ENCRYPTED_DECRYPT;
		else if (!strcmp (*args, "-EncryptedData_encrypt"))
			operation = SMIME_ENCRYPTED_ENCRYPT;
#ifndef OPENSSL_NO_DES
		else if (!strcmp (*args, "-des3")) 
				cipher = EVP_des_ede3_cbc();
		else if (!strcmp (*args, "-des")) 
				cipher = EVP_des_cbc();
#endif
#ifndef OPENSSL_NO_SEED
		else if (!strcmp (*args, "-seed")) 
				cipher = EVP_seed_cbc();
#endif
#ifndef OPENSSL_NO_RC2
		else if (!strcmp (*args, "-rc2-40")) 
				cipher = EVP_rc2_40_cbc();
		else if (!strcmp (*args, "-rc2-128")) 
				cipher = EVP_rc2_cbc();
		else if (!strcmp (*args, "-rc2-64")) 
				cipher = EVP_rc2_64_cbc();
#endif
#ifndef OPENSSL_NO_AES
		else if (!strcmp(*args,"-aes128"))
				cipher = EVP_aes_128_cbc();
		else if (!strcmp(*args,"-aes192"))
				cipher = EVP_aes_192_cbc();
		else if (!strcmp(*args,"-aes256"))
				cipher = EVP_aes_256_cbc();
#endif
#ifndef OPENSSL_NO_CAMELLIA
		else if (!strcmp(*args,"-camellia128"))
				cipher = EVP_camellia_128_cbc();
		else if (!strcmp(*args,"-camellia192"))
				cipher = EVP_camellia_192_cbc();
		else if (!strcmp(*args,"-camellia256"))
				cipher = EVP_camellia_256_cbc();
#endif
		else if (!strcmp (*args, "-text")) 
				flags |= CMS_TEXT;
		else if (!strcmp (*args, "-nointern")) 
				flags |= CMS_NOINTERN;
		else if (!strcmp (*args, "-noverify") 
			|| !strcmp (*args, "-no_signer_cert_verify")) 
				flags |= CMS_NO_SIGNER_CERT_VERIFY;
		else if (!strcmp (*args, "-nocerts")) 
				flags |= CMS_NOCERTS;
		else if (!strcmp (*args, "-noattr")) 
				flags |= CMS_NOATTR;
		else if (!strcmp (*args, "-nodetach")) 
				flags &= ~CMS_DETACHED;
		else if (!strcmp (*args, "-nosmimecap"))
				flags |= CMS_NOSMIMECAP;
		else if (!strcmp (*args, "-binary"))
				flags |= CMS_BINARY;
		else if (!strcmp (*args, "-keyid"))
				flags |= CMS_USE_KEYID;
		else if (!strcmp (*args, "-nosigs"))
				flags |= CMS_NOSIGS;
		else if (!strcmp (*args, "-no_content_verify"))
				flags |= CMS_NO_CONTENT_VERIFY;
		else if (!strcmp (*args, "-no_attr_verify"))
				flags |= CMS_NO_ATTR_VERIFY;
		else if (!strcmp (*args, "-stream"))
				flags |= CMS_STREAM;
		else if (!strcmp (*args, "-indef"))
				flags |= CMS_STREAM;
		else if (!strcmp (*args, "-noindef"))
				flags &= ~CMS_STREAM;
		else if (!strcmp (*args, "-nooldmime"))
				flags |= CMS_NOOLDMIMETYPE;
		else if (!strcmp (*args, "-crlfeol"))
				flags |= CMS_CRLFEOL;
		else if (!strcmp (*args, "-noout"))
				noout = 1;
		else if (!strcmp (*args, "-receipt_request_print"))
				rr_print = 1;
		else if (!strcmp (*args, "-receipt_request_all"))
				rr_allorfirst = 0;
		else if (!strcmp (*args, "-receipt_request_first"))
				rr_allorfirst = 1;
		else if (!strcmp(*args,"-receipt_request_from"))
			{
			if (!args[1])
				goto argerr;
			args++;
			if (!rr_from)
				rr_from = sk_OPENSSL_STRING_new_null();
			sk_OPENSSL_STRING_push(rr_from, *args);
			}
		else if (!strcmp(*args,"-receipt_request_to"))
			{
			if (!args[1])
				goto argerr;
			args++;
			if (!rr_to)
				rr_to = sk_OPENSSL_STRING_new_null();
			sk_OPENSSL_STRING_push(rr_to, *args);
			}
		else if (!strcmp (*args, "-print"))
				{
				noout = 1;
				print = 1;
				}
		else if (!strcmp(*args,"-secretkey"))
			{
			long ltmp;
			if (!args[1])
				goto argerr;
			args++;
			secret_key = string_to_hex(*args, &ltmp);
			if (!secret_key)
				{
				BIO_printf(bio_err, "Invalid key %s\n", *args);
				goto argerr;
				}
			secret_keylen = (size_t)ltmp;
			}
		else if (!strcmp(*args,"-secretkeyid"))
			{
			long ltmp;
			if (!args[1])
				goto argerr;
			args++;
			secret_keyid = string_to_hex(*args, &ltmp);
			if (!secret_keyid)
				{
				BIO_printf(bio_err, "Invalid id %s\n", *args);
				goto argerr;
				}
			secret_keyidlen = (size_t)ltmp;
			}
		else if (!strcmp(*args,"-pwri_password"))
			{
			if (!args[1])
				goto argerr;
			args++;
			pwri_pass = (unsigned char *)*args;
			}
		else if (!strcmp(*args,"-econtent_type"))
			{
			if (!args[1])
				goto argerr;
			args++;
			econtent_type = OBJ_txt2obj(*args, 0);
			if (!econtent_type)
				{
				BIO_printf(bio_err, "Invalid OID %s\n", *args);
				goto argerr;
				}
			}
		else if (!strcmp(*args,"-rand"))
			{
			if (!args[1])
				goto argerr;
			args++;
			inrand = *args;
			need_rand = 1;
			}
#ifndef OPENSSL_NO_ENGINE
		else if (!strcmp(*args,"-engine"))
			{
			if (!args[1])
				goto argerr;
			engine = *++args;
			}
#endif
		else if (!strcmp(*args,"-passin"))
			{
			if (!args[1])
				goto argerr;
			passargin = *++args;
			}
		else if (!strcmp (*args, "-to"))
			{
			if (!args[1])
				goto argerr;
			to = *++args;
			}
		else if (!strcmp (*args, "-from"))
			{
			if (!args[1])
				goto argerr;
			from = *++args;
			}
		else if (!strcmp (*args, "-subject"))
			{
			if (!args[1])
				goto argerr;
			subject = *++args;
			}
		else if (!strcmp (*args, "-signer"))
			{
			if (!args[1])
				goto argerr;
			/* If previous -signer argument add signer to list */

			if (signerfile)
				{
				if (!sksigners)
					sksigners = sk_OPENSSL_STRING_new_null();
				sk_OPENSSL_STRING_push(sksigners, signerfile);
				if (!keyfile)
					keyfile = signerfile;
				if (!skkeys)
					skkeys = sk_OPENSSL_STRING_new_null();
				sk_OPENSSL_STRING_push(skkeys, keyfile);
				keyfile = NULL;
				}
			signerfile = *++args;
			}
		else if (!strcmp (*args, "-recip"))
			{
			if (!args[1])
				goto argerr;
			recipfile = *++args;
			}
		else if (!strcmp (*args, "-certsout"))
			{
			if (!args[1])
				goto argerr;
			certsoutfile = *++args;
			}
		else if (!strcmp (*args, "-md"))
			{
			if (!args[1])
				goto argerr;
			sign_md = EVP_get_digestbyname(*++args);
			if (sign_md == NULL)
				{
				BIO_printf(bio_err, "Unknown digest %s\n",
							*args);
				goto argerr;
				}
			}
		else if (!strcmp (*args, "-inkey"))
			{
			if (!args[1])	
				goto argerr;
			/* If previous -inkey arument add signer to list */
			if (keyfile)
				{
				if (!signerfile)
					{
					BIO_puts(bio_err, "Illegal -inkey without -signer\n");
					goto argerr;
					}
				if (!sksigners)
					sksigners = sk_OPENSSL_STRING_new_null();
				sk_OPENSSL_STRING_push(sksigners, signerfile);
				signerfile = NULL;
				if (!skkeys)
					skkeys = sk_OPENSSL_STRING_new_null();
				sk_OPENSSL_STRING_push(skkeys, keyfile);
				}
			keyfile = *++args;
			}
		else if (!strcmp (*args, "-keyform"))
			{
			if (!args[1])
				goto argerr;
			keyform = str2fmt(*++args);
			}
		else if (!strcmp (*args, "-rctform"))
			{
			if (!args[1])
				goto argerr;
			rctformat = str2fmt(*++args);
			}
		else if (!strcmp (*args, "-certfile"))
			{
			if (!args[1])
				goto argerr;
			certfile = *++args;
			}
		else if (!strcmp (*args, "-CAfile"))
			{
			if (!args[1])
				goto argerr;
			CAfile = *++args;
			}
		else if (!strcmp (*args, "-CApath"))
			{
			if (!args[1])
				goto argerr;
			CApath = *++args;
			}
		else if (!strcmp (*args, "-in"))
			{
			if (!args[1])
				goto argerr;
			infile = *++args;
			}
		else if (!strcmp (*args, "-inform"))
			{
			if (!args[1])
				goto argerr;
			informat = str2fmt(*++args);
			}
		else if (!strcmp (*args, "-outform"))
			{
			if (!args[1])
				goto argerr;
			outformat = str2fmt(*++args);
			}
		else if (!strcmp (*args, "-out"))
			{
			if (!args[1])
				goto argerr;
			outfile = *++args;
			}
		else if (!strcmp (*args, "-content"))
			{
			if (!args[1])
				goto argerr;
			contfile = *++args;
			}
		else if (args_verify(&args, NULL, &badarg, bio_err, &vpm))
			continue;
		else if ((cipher = EVP_get_cipherbyname(*args + 1)) == NULL)
			badarg = 1;
		args++;
		}

	if (((rr_allorfirst != -1) || rr_from) && !rr_to)
		{
		BIO_puts(bio_err, "No Signed Receipts Recipients\n");
		goto argerr;
		}

	if (!(operation & SMIME_SIGNERS)  && (rr_to || rr_from))
		{
		BIO_puts(bio_err, "Signed receipts only allowed with -sign\n");
		goto argerr;
		}
	if (!(operation & SMIME_SIGNERS) && (skkeys || sksigners))
		{
		BIO_puts(bio_err, "Multiple signers or keys not allowed\n");
		goto argerr;
		}

	if (operation & SMIME_SIGNERS)
		{
		if (keyfile && !signerfile)
			{
			BIO_puts(bio_err, "Illegal -inkey without -signer\n");
			goto argerr;
			}
		/* Check to see if any final signer needs to be appended */
		if (signerfile)
			{
			if (!sksigners)
				sksigners = sk_OPENSSL_STRING_new_null();
			sk_OPENSSL_STRING_push(sksigners, signerfile);
			if (!skkeys)
				skkeys = sk_OPENSSL_STRING_new_null();
			if (!keyfile)
				keyfile = signerfile;
			sk_OPENSSL_STRING_push(skkeys, keyfile);
			}
		if (!sksigners)
			{
			BIO_printf(bio_err, "No signer certificate specified\n");
			badarg = 1;
			}
		signerfile = NULL;
		keyfile = NULL;
		need_rand = 1;
		}

	else if (operation == SMIME_DECRYPT)
		{
		if (!recipfile && !keyfile && !secret_key && !pwri_pass)
			{
			BIO_printf(bio_err, "No recipient certificate or key specified\n");
			badarg = 1;
			}
		}
	else if (operation == SMIME_ENCRYPT)
		{
		if (!*args && !secret_key && !pwri_pass)
			{
			BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n");
			badarg = 1;
			}
		need_rand = 1;
		}
	else if (!operation)
		badarg = 1;

	if (badarg)
		{
		argerr:
		BIO_printf (bio_err, "Usage cms [options] cert.pem ...\n");
		BIO_printf (bio_err, "where options are\n");
		BIO_printf (bio_err, "-encrypt       encrypt message\n");
		BIO_printf (bio_err, "-decrypt       decrypt encrypted message\n");
		BIO_printf (bio_err, "-sign          sign message\n");
		BIO_printf (bio_err, "-verify        verify signed message\n");
		BIO_printf (bio_err, "-cmsout        output CMS structure\n");
#ifndef OPENSSL_NO_DES
		BIO_printf (bio_err, "-des3          encrypt with triple DES\n");
		BIO_printf (bio_err, "-des           encrypt with DES\n");
#endif
#ifndef OPENSSL_NO_SEED
		BIO_printf (bio_err, "-seed          encrypt with SEED\n");
#endif
#ifndef OPENSSL_NO_RC2
		BIO_printf (bio_err, "-rc2-40        encrypt with RC2-40 (default)\n");
		BIO_printf (bio_err, "-rc2-64        encrypt with RC2-64\n");
		BIO_printf (bio_err, "-rc2-128       encrypt with RC2-128\n");
#endif
#ifndef OPENSSL_NO_AES
		BIO_printf (bio_err, "-aes128, -aes192, -aes256\n");
		BIO_printf (bio_err, "               encrypt PEM output with cbc aes\n");
#endif
#ifndef OPENSSL_NO_CAMELLIA
		BIO_printf (bio_err, "-camellia128, -camellia192, -camellia256\n");
		BIO_printf (bio_err, "               encrypt PEM output with cbc camellia\n");
#endif
		BIO_printf (bio_err, "-nointern      don't search certificates in message for signer\n");
		BIO_printf (bio_err, "-nosigs        don't verify message signature\n");
		BIO_printf (bio_err, "-noverify      don't verify signers certificate\n");
		BIO_printf (bio_err, "-nocerts       don't include signers certificate when signing\n");
		BIO_printf (bio_err, "-nodetach      use opaque signing\n");
		BIO_printf (bio_err, "-noattr        don't include any signed attributes\n");
		BIO_printf (bio_err, "-binary        don't translate message to text\n");
		BIO_printf (bio_err, "-certfile file other certificates file\n");
		BIO_printf (bio_err, "-certsout file certificate output file\n");
		BIO_printf (bio_err, "-signer file   signer certificate file\n");
		BIO_printf (bio_err, "-recip  file   recipient certificate file for decryption\n");
		BIO_printf (bio_err, "-keyid         use subject key identifier\n");
		BIO_printf (bio_err, "-in file       input file\n");
		BIO_printf (bio_err, "-inform arg    input format SMIME (default), PEM or DER\n");
		BIO_printf (bio_err, "-inkey file    input private key (if not signer or recipient)\n");
		BIO_printf (bio_err, "-keyform arg   input private key format (PEM or ENGINE)\n");
		BIO_printf (bio_err, "-out file      output file\n");
		BIO_printf (bio_err, "-outform arg   output format SMIME (default), PEM or DER\n");
		BIO_printf (bio_err, "-content file  supply or override content for detached signature\n");
		BIO_printf (bio_err, "-to addr       to address\n");
		BIO_printf (bio_err, "-from ad       from address\n");
		BIO_printf (bio_err, "-subject s     subject\n");
		BIO_printf (bio_err, "-text          include or delete text MIME headers\n");
		BIO_printf (bio_err, "-CApath dir    trusted certificates directory\n");
		BIO_printf (bio_err, "-CAfile file   trusted certificates file\n");
		BIO_printf (bio_err, "-crl_check     check revocation status of signer's certificate using CRLs\n");
		BIO_printf (bio_err, "-crl_check_all check revocation status of signer's certificate chain using CRLs\n");
#ifndef OPENSSL_NO_ENGINE
		BIO_printf (bio_err, "-engine e      use engine e, possibly a hardware device.\n");
#endif
		BIO_printf (bio_err, "-passin arg    input file pass phrase source\n");
		BIO_printf(bio_err,  "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
		BIO_printf(bio_err,  "               load the file (or the files in the directory) into\n");
		BIO_printf(bio_err,  "               the random number generator\n");
		BIO_printf (bio_err, "cert.pem       recipient certificate(s) for encryption\n");
		goto end;
		}

#ifndef OPENSSL_NO_ENGINE
        e = setup_engine(bio_err, engine, 0);
#endif

	if (!app_passwd(bio_err, passargin, NULL, &passin, NULL))
		{
		BIO_printf(bio_err, "Error getting password\n");
		goto end;
		}

	if (need_rand)
		{
		app_RAND_load_file(NULL, bio_err, (inrand != NULL));
		if (inrand != NULL)
			BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
				app_RAND_load_files(inrand));
		}

	ret = 2;

	if (!(operation & SMIME_SIGNERS))
		flags &= ~CMS_DETACHED;

	if (operation & SMIME_OP)
		{
		if (outformat == FORMAT_ASN1)
			outmode = "wb";
		}
	else
		{
		if (flags & CMS_BINARY)
			outmode = "wb";
		}

	if (operation & SMIME_IP)
		{
		if (informat == FORMAT_ASN1)
			inmode = "rb";
		}
	else
		{
		if (flags & CMS_BINARY)
			inmode = "rb";
		}

	if (operation == SMIME_ENCRYPT)
		{
		if (!cipher)
			{
#ifndef OPENSSL_NO_DES			
			cipher = EVP_des_ede3_cbc();
#else
			BIO_printf(bio_err, "No cipher selected\n");
			goto end;
#endif
			}

		if (secret_key && !secret_keyid)
			{
			BIO_printf(bio_err, "No secret key id\n");
			goto end;
			}

		if (*args)
			encerts = sk_X509_new_null();
		while (*args)
			{
			if (!(cert = load_cert(bio_err,*args,FORMAT_PEM,
				NULL, e, "recipient certificate file")))
				goto end;
			sk_X509_push(encerts, cert);
			cert = NULL;
			args++;
			}
		}

	if (certfile)
		{
		if (!(other = load_certs(bio_err,certfile,FORMAT_PEM, NULL,
			e, "certificate file")))
			{
			ERR_print_errors(bio_err);
			goto end;
			}
		}

	if (recipfile && (operation == SMIME_DECRYPT))
		{
		if (!(recip = load_cert(bio_err,recipfile,FORMAT_PEM,NULL,
			e, "recipient certificate file")))
			{
			ERR_print_errors(bio_err);
			goto end;
			}
		}

	if (operation == SMIME_SIGN_RECEIPT)
		{
		if (!(signer = load_cert(bio_err,signerfile,FORMAT_PEM,NULL,
			e, "receipt signer certificate file")))
			{
			ERR_print_errors(bio_err);
			goto end;
			}
		}

	if (operation == SMIME_DECRYPT)
		{
		if (!keyfile)
			keyfile = recipfile;
		}
	else if ((operation == SMIME_SIGN) || (operation == SMIME_SIGN_RECEIPT))
		{
		if (!keyfile)
			keyfile = signerfile;
		}
	else keyfile = NULL;

	if (keyfile)
		{
		key = load_key(bio_err, keyfile, keyform, 0, passin, e,
			       "signing key file");
		if (!key)
			goto end;
		}

	if (infile)
		{
		if (!(in = BIO_new_file(infile, inmode)))
			{
			BIO_printf (bio_err,
				 "Can't open input file %s\n", infile);
			goto end;
			}
		}
	else
		in = BIO_new_fp(stdin, BIO_NOCLOSE);

	if (operation & SMIME_IP)
		{
		if (informat == FORMAT_SMIME) 
			cms = SMIME_read_CMS(in, &indata);
		else if (informat == FORMAT_PEM) 
			cms = PEM_read_bio_CMS(in, NULL, NULL, NULL);
		else if (informat == FORMAT_ASN1) 
			cms = d2i_CMS_bio(in, NULL);
		else
			{
			BIO_printf(bio_err, "Bad input format for CMS file\n");
			goto end;
			}

		if (!cms)
			{
			BIO_printf(bio_err, "Error reading S/MIME message\n");
			goto end;
			}
		if (contfile)
			{
			BIO_free(indata);
			if (!(indata = BIO_new_file(contfile, "rb")))
				{
				BIO_printf(bio_err, "Can't read content file %s\n", contfile);
				goto end;
				}
			}
		if (certsoutfile)
			{
			STACK_OF(X509) *allcerts;
			allcerts = CMS_get1_certs(cms);
			if (!save_certs(certsoutfile, allcerts))
				{
				BIO_printf(bio_err,
						"Error writing certs to %s\n",
								certsoutfile);
				ret = 5;
				goto end;
				}
			sk_X509_pop_free(allcerts, X509_free);
			}
		}

	if (rctfile)
		{
		char *rctmode = (rctformat == FORMAT_ASN1) ? "rb" : "r";
		if (!(rctin = BIO_new_file(rctfile, rctmode)))
			{
			BIO_printf (bio_err,
				 "Can't open receipt file %s\n", rctfile);
			goto end;
			}
		
		if (rctformat == FORMAT_SMIME) 
			rcms = SMIME_read_CMS(rctin, NULL);
		else if (rctformat == FORMAT_PEM) 
			rcms = PEM_read_bio_CMS(rctin, NULL, NULL, NULL);
		else if (rctformat == FORMAT_ASN1) 
			rcms = d2i_CMS_bio(rctin, NULL);
		else
			{
			BIO_printf(bio_err, "Bad input format for receipt\n");
			goto end;
			}

		if (!rcms)
			{
			BIO_printf(bio_err, "Error reading receipt\n");
			goto end;
			}
		}

	if (outfile)
		{
		if (!(out = BIO_new_file(outfile, outmode)))
			{
			BIO_printf (bio_err,
				 "Can't open output file %s\n", outfile);
			goto end;
			}
		}
	else
		{
		out = BIO_new_fp(stdout, BIO_NOCLOSE);
#ifdef OPENSSL_SYS_VMS
		{
		    BIO *tmpbio = BIO_new(BIO_f_linebuffer());
		    out = BIO_push(tmpbio, out);
		}
#endif
		}

	if ((operation == SMIME_VERIFY) || (operation == SMIME_VERIFY_RECEIPT))
		{
		if (!(store = setup_verify(bio_err, CAfile, CApath)))
			goto end;
		X509_STORE_set_verify_cb(store, cms_cb);
		if (vpm)
			X509_STORE_set1_param(store, vpm);
		}


	ret = 3;

	if (operation == SMIME_DATA_CREATE)
		{
		cms = CMS_data_create(in, flags);
		}
	else if (operation == SMIME_DIGEST_CREATE)
		{
		cms = CMS_digest_create(in, sign_md, flags);
		}
	else if (operation == SMIME_COMPRESS)
		{
		cms = CMS_compress(in, -1, flags);
		}
	else if (operation == SMIME_ENCRYPT)
		{
		flags |= CMS_PARTIAL;
		cms = CMS_encrypt(encerts, in, cipher, flags);
		if (!cms)
			goto end;
		if (secret_key)
			{
			if (!CMS_add0_recipient_key(cms, NID_undef, 
						secret_key, secret_keylen,
						secret_keyid, secret_keyidlen,
						NULL, NULL, NULL))
				goto end;
			/* NULL these because call absorbs them */
			secret_key = NULL;
			secret_keyid = NULL;
			}
		if (pwri_pass)
			{
			pwri_tmp = (unsigned char *)BUF_strdup((char *)pwri_pass);
			if (!pwri_tmp)
				goto end;
			if (!CMS_add0_recipient_password(cms,
						-1, NID_undef, NID_undef,
						 pwri_tmp, -1, NULL))
				goto end;
			pwri_tmp = NULL;
			}
		if (!(flags & CMS_STREAM))
			{
			if (!CMS_final(cms, in, NULL, flags))
				goto end;
			}
		}
	else if (operation == SMIME_ENCRYPTED_ENCRYPT)
		{
		cms = CMS_EncryptedData_encrypt(in, cipher,
						secret_key, secret_keylen,
						flags);

		}
	else if (operation == SMIME_SIGN_RECEIPT)
		{
		CMS_ContentInfo *srcms = NULL;
		STACK_OF(CMS_SignerInfo) *sis;
		CMS_SignerInfo *si;
		sis = CMS_get0_SignerInfos(cms);
		if (!sis)
			goto end;
		si = sk_CMS_SignerInfo_value(sis, 0);
		srcms = CMS_sign_receipt(si, signer, key, other, flags);
		if (!srcms)
			goto end;
		CMS_ContentInfo_free(cms);
		cms = srcms;
		}
	else if (operation & SMIME_SIGNERS)
		{
		int i;
		/* If detached data content we enable streaming if
		 * S/MIME output format.
		 */
		if (operation == SMIME_SIGN)
			{
				
			if (flags & CMS_DETACHED)
				{
				if (outformat == FORMAT_SMIME)
					flags |= CMS_STREAM;
				}
			flags |= CMS_PARTIAL;
			cms = CMS_sign(NULL, NULL, other, in, flags);
			if (!cms)
				goto end;
			if (econtent_type)
				CMS_set1_eContentType(cms, econtent_type);

			if (rr_to)
				{
				rr = make_receipt_request(rr_to, rr_allorfirst,
								rr_from);
				if (!rr)
					{
					BIO_puts(bio_err,
				"Signed Receipt Request Creation Error\n");
					goto end;
					}
				}
			}
		else
			flags |= CMS_REUSE_DIGEST;
		for (i = 0; i < sk_OPENSSL_STRING_num(sksigners); i++)
			{
			CMS_SignerInfo *si;
			signerfile = sk_OPENSSL_STRING_value(sksigners, i);
			keyfile = sk_OPENSSL_STRING_value(skkeys, i);
			signer = load_cert(bio_err, signerfile,FORMAT_PEM, NULL,
					e, "signer certificate");
			if (!signer)
				goto end;
			key = load_key(bio_err, keyfile, keyform, 0, passin, e,
			       "signing key file");
			if (!key)
				goto end;
			si = CMS_add1_signer(cms, signer, key, sign_md, flags);
			if (!si)
				goto end;
			if (rr && !CMS_add1_ReceiptRequest(si, rr))
				goto end;
			X509_free(signer);
			signer = NULL;
			EVP_PKEY_free(key);
			key = NULL;
			}
		/* If not streaming or resigning finalize structure */
		if ((operation == SMIME_SIGN) && !(flags & CMS_STREAM))
			{
			if (!CMS_final(cms, in, NULL, flags))
				goto end;
			}
		}

	if (!cms)
		{
		BIO_printf(bio_err, "Error creating CMS structure\n");
		goto end;
		}

	ret = 4;
	if (operation == SMIME_DECRYPT)
		{

		if (secret_key)
			{
			if (!CMS_decrypt_set1_key(cms,
						secret_key, secret_keylen,
						secret_keyid, secret_keyidlen))
				{
				BIO_puts(bio_err,
					"Error decrypting CMS using secret key\n");
				goto end;
				}
			}

		if (key)
			{
			if (!CMS_decrypt_set1_pkey(cms, key, recip))
				{
				BIO_puts(bio_err,
					"Error decrypting CMS using private key\n");
				goto end;
				}
			}

		if (pwri_pass)
			{
			if (!CMS_decrypt_set1_password(cms, pwri_pass, -1))
				{
				BIO_puts(bio_err,
					"Error decrypting CMS using password\n");
				goto end;
				}
			}

		if (!CMS_decrypt(cms, NULL, NULL, indata, out, flags))
			{
			BIO_printf(bio_err, "Error decrypting CMS structure\n");
			goto end;
			}
		}
	else if (operation == SMIME_DATAOUT)
		{
		if (!CMS_data(cms, out, flags))
			goto end;
		}
	else if (operation == SMIME_UNCOMPRESS)
		{
		if (!CMS_uncompress(cms, indata, out, flags))
			goto end;
		}
	else if (operation == SMIME_DIGEST_VERIFY)
		{
		if (CMS_digest_verify(cms, indata, out, flags) > 0)
			BIO_printf(bio_err, "Verification successful\n");
		else
			{
			BIO_printf(bio_err, "Verification failure\n");
			goto end;
			}
		}
	else if (operation == SMIME_ENCRYPTED_DECRYPT)
		{
		if (!CMS_EncryptedData_decrypt(cms, secret_key, secret_keylen,
						indata, out, flags))
			goto end;
		}
	else if (operation == SMIME_VERIFY)
		{
		if (CMS_verify(cms, other, store, indata, out, flags) > 0)
			BIO_printf(bio_err, "Verification successful\n");
		else
			{
			BIO_printf(bio_err, "Verification failure\n");
			if (verify_retcode)
				ret = verify_err + 32;
			goto end;
			}
		if (signerfile)
			{
			STACK_OF(X509) *signers;
			signers = CMS_get0_signers(cms);
			if (!save_certs(signerfile, signers))
				{
				BIO_printf(bio_err,
						"Error writing signers to %s\n",
								signerfile);
				ret = 5;
				goto end;
				}
			sk_X509_free(signers);
			}
		if (rr_print)
			receipt_request_print(bio_err, cms);
					
		}
	else if (operation == SMIME_VERIFY_RECEIPT)
		{
		if (CMS_verify_receipt(rcms, cms, other, store, flags) > 0)
			BIO_printf(bio_err, "Verification successful\n");
		else
			{
			BIO_printf(bio_err, "Verification failure\n");
			goto end;
			}
		}
	else
		{
		if (noout)
			{
			if (print)
				CMS_ContentInfo_print_ctx(out, cms, 0, NULL);
			}
		else if (outformat == FORMAT_SMIME)
			{
			if (to)
				BIO_printf(out, "To: %s\n", to);
			if (from)
				BIO_printf(out, "From: %s\n", from);
			if (subject)
				BIO_printf(out, "Subject: %s\n", subject);
			if (operation == SMIME_RESIGN)
				ret = SMIME_write_CMS(out, cms, indata, flags);
			else
				ret = SMIME_write_CMS(out, cms, in, flags);
			}
		else if (outformat == FORMAT_PEM) 
			ret = PEM_write_bio_CMS_stream(out, cms, in, flags);
		else if (outformat == FORMAT_ASN1) 
			ret = i2d_CMS_bio_stream(out,cms, in, flags);
		else
			{
			BIO_printf(bio_err, "Bad output format for CMS file\n");
			goto end;
			}
		if (ret <= 0)
			{
			ret = 6;
			goto end;
			}
		}
	ret = 0;
end:
	if (ret)
		ERR_print_errors(bio_err);
	if (need_rand)
		app_RAND_write_file(NULL, bio_err);
	sk_X509_pop_free(encerts, X509_free);
	sk_X509_pop_free(other, X509_free);
	if (vpm)
		X509_VERIFY_PARAM_free(vpm);
	if (sksigners)
		sk_OPENSSL_STRING_free(sksigners);
	if (skkeys)
		sk_OPENSSL_STRING_free(skkeys);
	if (secret_key)
		OPENSSL_free(secret_key);
	if (secret_keyid)
		OPENSSL_free(secret_keyid);
	if (pwri_tmp)
		OPENSSL_free(pwri_tmp);
	if (econtent_type)
		ASN1_OBJECT_free(econtent_type);
	if (rr)
		CMS_ReceiptRequest_free(rr);
	if (rr_to)
		sk_OPENSSL_STRING_free(rr_to);
	if (rr_from)
		sk_OPENSSL_STRING_free(rr_from);
	X509_STORE_free(store);
	X509_free(cert);
	X509_free(recip);
	X509_free(signer);
	EVP_PKEY_free(key);
	CMS_ContentInfo_free(cms);
	CMS_ContentInfo_free(rcms);
	BIO_free(rctin);
	BIO_free(in);
	BIO_free(indata);
	BIO_free_all(out);
	if (passin) OPENSSL_free(passin);
	return (ret);
}
Ejemplo n.º 24
0
static int conn_state(BIO *b, BIO_CONNECT *c)
	{
	int ret= -1,i;
	unsigned long l;
	char *p,*q;
	int (*cb)(const BIO *,int,int)=NULL;

	if (c->info_callback != NULL)
		cb=c->info_callback;

	for (;;)
		{
		switch (c->state)
			{
		case BIO_CONN_S_BEFORE:
			p=c->param_hostname;
			if (p == NULL)
				{
				BIOerr(BIO_F_CONN_STATE,BIO_R_NO_HOSTNAME_SPECIFIED);
				goto exit_loop;
				}
			for ( ; *p != '\0'; p++)
				{
				if ((*p == ':') || (*p == '/')) break;
				}

			i= *p;
			if ((i == ':') || (i == '/'))
				{

				*(p++)='\0';
				if (i == ':')
					{
					for (q=p; *q; q++)
						if (*q == '/')
							{
							*q='\0';
							break;
							}
					if (c->param_port != NULL)
						OPENSSL_free(c->param_port);
					c->param_port=BUF_strdup(p);
					}
				}

			if (c->param_port == NULL)
				{
				BIOerr(BIO_F_CONN_STATE,BIO_R_NO_PORT_SPECIFIED);
				ERR_add_error_data(2,"host=",c->param_hostname);
				goto exit_loop;
				}
			c->state=BIO_CONN_S_GET_IP;
			break;

		case BIO_CONN_S_GET_IP:
			if (BIO_get_host_ip(c->param_hostname,&(c->ip[0])) <= 0)
				goto exit_loop;
			c->state=BIO_CONN_S_GET_PORT;
			break;

		case BIO_CONN_S_GET_PORT:
			if (c->param_port == NULL)
				{
				/* abort(); */
				goto exit_loop;
				}
			else if (BIO_get_port(c->param_port,&c->port) <= 0)
				goto exit_loop;
			c->state=BIO_CONN_S_CREATE_SOCKET;
			break;

		case BIO_CONN_S_CREATE_SOCKET:
			/* now setup address */
			memset((char *)&c->them,0,sizeof(c->them));
			c->them.sin_family=AF_INET;
			c->them.sin_port=htons((unsigned short)c->port);
			l=(unsigned long)
				((unsigned long)c->ip[0]<<24L)|
				((unsigned long)c->ip[1]<<16L)|
				((unsigned long)c->ip[2]<< 8L)|
				((unsigned long)c->ip[3]);
			c->them.sin_addr.s_addr=htonl(l);
			c->state=BIO_CONN_S_CREATE_SOCKET;

			ret=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL);
			if (ret == INVALID_SOCKET)
				{
				SYSerr(SYS_F_SOCKET,get_last_socket_error());
				ERR_add_error_data(4,"host=",c->param_hostname,
					":",c->param_port);
				BIOerr(BIO_F_CONN_STATE,BIO_R_UNABLE_TO_CREATE_SOCKET);
				goto exit_loop;
				}
			b->num=ret;
			c->state=BIO_CONN_S_NBIO;
			break;

		case BIO_CONN_S_NBIO:
			if (c->nbio)
				{
				if (!BIO_socket_nbio(b->num,1))
					{
					BIOerr(BIO_F_CONN_STATE,BIO_R_ERROR_SETTING_NBIO);
					ERR_add_error_data(4,"host=",
						c->param_hostname,
						":",c->param_port);
					goto exit_loop;
					}
				}
			c->state=BIO_CONN_S_CONNECT;

#if defined(SO_KEEPALIVE) && !defined(OPENSSL_SYS_MPE)
			i=1;
			i=setsockopt(b->num,SOL_SOCKET,SO_KEEPALIVE,(char *)&i,sizeof(i));
			if (i < 0)
				{
				SYSerr(SYS_F_SOCKET,get_last_socket_error());
				ERR_add_error_data(4,"host=",c->param_hostname,
					":",c->param_port);
				BIOerr(BIO_F_CONN_STATE,BIO_R_KEEPALIVE);
				goto exit_loop;
				}
#endif
			break;

		case BIO_CONN_S_CONNECT:
			BIO_clear_retry_flags(b);
			ret=connect(b->num,
				(struct sockaddr *)&c->them,
				sizeof(c->them));
			b->retry_reason=0;
			if (ret < 0)
				{
				if (BIO_sock_should_retry(ret))
					{
					BIO_set_retry_special(b);
					c->state=BIO_CONN_S_BLOCKED_CONNECT;
					b->retry_reason=BIO_RR_CONNECT;
					}
				else
					{
					SYSerr(SYS_F_CONNECT,get_last_socket_error());
					ERR_add_error_data(4,"host=",
						c->param_hostname,
						":",c->param_port);
					BIOerr(BIO_F_CONN_STATE,BIO_R_CONNECT_ERROR);
					}
				goto exit_loop;
				}
			else
				c->state=BIO_CONN_S_OK;
			break;

		case BIO_CONN_S_BLOCKED_CONNECT:
			i=BIO_sock_error(b->num);
			if (i)
				{
				BIO_clear_retry_flags(b);
				SYSerr(SYS_F_CONNECT,i);
				ERR_add_error_data(4,"host=",
					c->param_hostname,
					":",c->param_port);
				BIOerr(BIO_F_CONN_STATE,BIO_R_NBIO_CONNECT_ERROR);
				ret=0;
				goto exit_loop;
				}
			else
				c->state=BIO_CONN_S_OK;
			break;

		case BIO_CONN_S_OK:
			ret=1;
			goto exit_loop;
		default:
			/* abort(); */
			goto exit_loop;
			}

		if (cb != NULL)
			{
			if (!(ret=cb((BIO *)b,c->state,ret)))
				goto end;
			}
		}

	/* Loop does not exit */
exit_loop:
	if (cb != NULL)
		ret=cb((BIO *)b,c->state,ret);
end:
	return(ret);
	}
Ejemplo n.º 25
0
static void BN_STACK_finish(BN_STACK *st)
{
    OPENSSL_free(st->indexes);
    st->indexes = NULL;
}
Ejemplo n.º 26
0
static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
	{
	BIO *dbio;
	int *ip;
	const char **pptr;
	long ret=1;
	BIO_CONNECT *data;

	data=(BIO_CONNECT *)b->ptr;

	switch (cmd)
		{
	case BIO_CTRL_RESET:
		ret=0;
		data->state=BIO_CONN_S_BEFORE;
		conn_close_socket(b);
		b->flags=0;
		break;
	case BIO_C_DO_STATE_MACHINE:
		/* use this one to start the connection */
		if (data->state != BIO_CONN_S_OK)
			ret=(long)conn_state(b,data);
		else
			ret=1;
		break;
	case BIO_C_GET_CONNECT:
		if (ptr != NULL)
			{
			pptr=(const char **)ptr;
			if (num == 0)
				{
				*pptr=data->param_hostname;

				}
			else if (num == 1)
				{
				*pptr=data->param_port;
				}
			else if (num == 2)
				{
				*pptr= (char *)&(data->ip[0]);
				}
			else if (num == 3)
				{
				*((int *)ptr)=data->port;
				}
			if ((!b->init) || (ptr == NULL))
				*pptr="not initialized";
			ret=1;
			}
		break;
	case BIO_C_SET_CONNECT:
		if (ptr != NULL)
			{
			b->init=1;
			if (num == 0)
				{
				if (data->param_hostname != NULL)
					OPENSSL_free(data->param_hostname);
				data->param_hostname=BUF_strdup(ptr);
				}
			else if (num == 1)
				{
				if (data->param_port != NULL)
					OPENSSL_free(data->param_port);
				data->param_port=BUF_strdup(ptr);
				}
			else if (num == 2)
				{
				char buf[16];
				unsigned char *p = ptr;

				BIO_snprintf(buf,sizeof buf,"%d.%d.%d.%d",
					     p[0],p[1],p[2],p[3]);
				if (data->param_hostname != NULL)
					OPENSSL_free(data->param_hostname);
				data->param_hostname=BUF_strdup(buf);
				memcpy(&(data->ip[0]),ptr,4);
				}
			else if (num == 3)
				{
				char buf[DECIMAL_SIZE(int)+1];

				BIO_snprintf(buf,sizeof buf,"%d",*(int *)ptr);
				if (data->param_port != NULL)
					OPENSSL_free(data->param_port);
				data->param_port=BUF_strdup(buf);
				data->port= *(int *)ptr;
				}
			}
		break;
	case BIO_C_SET_NBIO:
		data->nbio=(int)num;
		break;
	case BIO_C_GET_FD:
		if (b->init)
			{
			ip=(int *)ptr;
			if (ip != NULL)
				*ip=b->num;
			ret=b->num;
			}
		else
			ret= -1;
		break;
	case BIO_CTRL_GET_CLOSE:
		ret=b->shutdown;
		break;
	case BIO_CTRL_SET_CLOSE:
		b->shutdown=(int)num;
		break;
	case BIO_CTRL_PENDING:
	case BIO_CTRL_WPENDING:
		ret=0;
		break;
	case BIO_CTRL_FLUSH:
		break;
	case BIO_CTRL_DUP:
		{
		dbio=(BIO *)ptr;
		if (data->param_port)
			BIO_set_conn_port(dbio,data->param_port);
		if (data->param_hostname)
			BIO_set_conn_hostname(dbio,data->param_hostname);
		BIO_set_nbio(dbio,data->nbio);
		/* FIXME: the cast of the function seems unlikely to be a good idea */
                (void)BIO_set_info_callback(dbio,(bio_info_cb *)data->info_callback);
		}
		break;
	case BIO_CTRL_SET_CALLBACK:
		{
#if 0 /* FIXME: Should this be used?  -- Richard Levitte */
		BIOerr(BIO_F_CONN_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
		ret = -1;
#else
		ret=0;
#endif
		}
		break;
	case BIO_CTRL_GET_CALLBACK:
		{
		int (**fptr)(const BIO *bio,int state,int xret);

		fptr=(int (**)(const BIO *bio,int state,int xret))ptr;
		*fptr=data->info_callback;
		}
		break;
	default:
		ret=0;
		break;
		}
	return(ret);
	}
Ejemplo n.º 27
0
int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off)
{
    unsigned char *buffer = NULL;
    size_t buf_len = 0, i;
    int ret = 0, reason = ERR_R_BIO_LIB;
    BN_CTX *ctx = NULL;
    const EC_POINT *point = NULL;
    BIGNUM *p = NULL, *a = NULL, *b = NULL, *gen = NULL,
        *order = NULL, *cofactor = NULL;
    const unsigned char *seed;
    size_t seed_len = 0;

    static const char *gen_compressed = "Generator (compressed):";
    static const char *gen_uncompressed = "Generator (uncompressed):";
    static const char *gen_hybrid = "Generator (hybrid):";

    if (!x) {
        reason = ERR_R_PASSED_NULL_PARAMETER;
        goto err;
    }

    ctx = BN_CTX_new();
    if (ctx == NULL) {
        reason = ERR_R_MALLOC_FAILURE;
        goto err;
    }

    if (EC_GROUP_get_asn1_flag(x)) {
        /* the curve parameter are given by an asn1 OID */
        int nid;
        const char *nname;

        if (!BIO_indent(bp, off, 128))
            goto err;

        nid = EC_GROUP_get_curve_name(x);
        if (nid == 0)
            goto err;
        if (BIO_printf(bp, "ASN1 OID: %s", OBJ_nid2sn(nid)) <= 0)
            goto err;
        if (BIO_printf(bp, "\n") <= 0)
            goto err;
        nname = EC_curve_nid2nist(nid);
        if (nname) {
            if (!BIO_indent(bp, off, 128))
                goto err;
            if (BIO_printf(bp, "NIST CURVE: %s\n", nname) <= 0)
                goto err;
        }
    } else {
        /* explicit parameters */
        int is_char_two = 0;
        point_conversion_form_t form;
        int tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(x));

        if (tmp_nid == NID_X9_62_characteristic_two_field)
            is_char_two = 1;

        if ((p = BN_new()) == NULL || (a = BN_new()) == NULL ||
            (b = BN_new()) == NULL || (order = BN_new()) == NULL ||
            (cofactor = BN_new()) == NULL) {
            reason = ERR_R_MALLOC_FAILURE;
            goto err;
        }
#ifndef OPENSSL_NO_EC2M
        if (is_char_two) {
            if (!EC_GROUP_get_curve_GF2m(x, p, a, b, ctx)) {
                reason = ERR_R_EC_LIB;
                goto err;
            }
        } else                  /* prime field */
#endif
        {
            if (!EC_GROUP_get_curve_GFp(x, p, a, b, ctx)) {
                reason = ERR_R_EC_LIB;
                goto err;
            }
        }

        if ((point = EC_GROUP_get0_generator(x)) == NULL) {
            reason = ERR_R_EC_LIB;
            goto err;
        }
        if (!EC_GROUP_get_order(x, order, NULL) ||
            !EC_GROUP_get_cofactor(x, cofactor, NULL)) {
            reason = ERR_R_EC_LIB;
            goto err;
        }

        form = EC_GROUP_get_point_conversion_form(x);

        if ((gen = EC_POINT_point2bn(x, point, form, NULL, ctx)) == NULL) {
            reason = ERR_R_EC_LIB;
            goto err;
        }

        buf_len = (size_t)BN_num_bytes(p);
        if (buf_len < (i = (size_t)BN_num_bytes(a)))
            buf_len = i;
        if (buf_len < (i = (size_t)BN_num_bytes(b)))
            buf_len = i;
        if (buf_len < (i = (size_t)BN_num_bytes(gen)))
            buf_len = i;
        if (buf_len < (i = (size_t)BN_num_bytes(order)))
            buf_len = i;
        if (buf_len < (i = (size_t)BN_num_bytes(cofactor)))
            buf_len = i;

        if ((seed = EC_GROUP_get0_seed(x)) != NULL)
            seed_len = EC_GROUP_get_seed_len(x);

        buf_len += 10;
        if ((buffer = OPENSSL_malloc(buf_len)) == NULL) {
            reason = ERR_R_MALLOC_FAILURE;
            goto err;
        }

        if (!BIO_indent(bp, off, 128))
            goto err;

        /* print the 'short name' of the field type */
        if (BIO_printf(bp, "Field Type: %s\n", OBJ_nid2sn(tmp_nid))
            <= 0)
            goto err;

        if (is_char_two) {
            /* print the 'short name' of the base type OID */
            int basis_type = EC_GROUP_get_basis_type(x);
            if (basis_type == 0)
                goto err;

            if (!BIO_indent(bp, off, 128))
                goto err;

            if (BIO_printf(bp, "Basis Type: %s\n",
                           OBJ_nid2sn(basis_type)) <= 0)
                goto err;

            /* print the polynomial */
            if ((p != NULL) && !ASN1_bn_print(bp, "Polynomial:", p, buffer,
                                              off))
                goto err;
        } else {
            if ((p != NULL) && !ASN1_bn_print(bp, "Prime:", p, buffer, off))
                goto err;
        }
        if ((a != NULL) && !ASN1_bn_print(bp, "A:   ", a, buffer, off))
            goto err;
        if ((b != NULL) && !ASN1_bn_print(bp, "B:   ", b, buffer, off))
            goto err;
        if (form == POINT_CONVERSION_COMPRESSED) {
            if ((gen != NULL) && !ASN1_bn_print(bp, gen_compressed, gen,
                                                buffer, off))
                goto err;
        } else if (form == POINT_CONVERSION_UNCOMPRESSED) {
            if ((gen != NULL) && !ASN1_bn_print(bp, gen_uncompressed, gen,
                                                buffer, off))
                goto err;
        } else {                /* form == POINT_CONVERSION_HYBRID */

            if ((gen != NULL) && !ASN1_bn_print(bp, gen_hybrid, gen,
                                                buffer, off))
                goto err;
        }
        if ((order != NULL) && !ASN1_bn_print(bp, "Order: ", order,
                                              buffer, off))
            goto err;
        if ((cofactor != NULL) && !ASN1_bn_print(bp, "Cofactor: ", cofactor,
                                                 buffer, off))
            goto err;
        if (seed && !print_bin(bp, "Seed:", seed, seed_len, off))
            goto err;
    }
    ret = 1;
 err:
    if (!ret)
        ECerr(EC_F_ECPKPARAMETERS_PRINT, reason);
    if (p)
        BN_free(p);
    if (a)
        BN_free(a);
    if (b)
        BN_free(b);
    if (gen)
        BN_free(gen);
    if (order)
        BN_free(order);
    if (cofactor)
        BN_free(cofactor);
    if (ctx)
        BN_CTX_free(ctx);
    if (buffer != NULL)
        OPENSSL_free(buffer);
    return (ret);
}
Ejemplo n.º 28
0
void main ()
{
  int err;
  SSL_CTX* ctx;
  SSL*     ssl;
  X509*    client_cert;
  char*    str;
  char     buf [4096];
  FILE* log;
  
  log = fopen ("/dev/console", "a");                     CHK_NULL(log);
  fprintf (log, "inetdserv %ld\n", (long)getpid());
  
  SSL_load_error_strings();
  ctx = SSL_CTX_new (); CHK_NULL(ctx);
  
  err = SSL_CTX_use_RSAPrivateKey_file (ctx, KEYF,  SSL_FILETYPE_PEM);
  CHK_SSL (err);
  
  err = SSL_CTX_use_certificate_file   (ctx, CERTF, SSL_FILETYPE_PEM);
  CHK_SSL (err);

  /* inetd has already opened the TCP connection, so we can get right
     down to business. */
  
  ssl = SSL_new (ctx);  CHK_NULL(ssl);
  SSL_set_fd (ssl,  fileno(stdin));
  err = SSL_accept (ssl);                                CHK_SSL(err);
  
  /* Get the cipher - opt */
  
  fprintf (log, "SSL connection using %s\n", SSL_get_cipher (ssl));
  
  /* Get client's certificate (note: beware of dynamic allocation) - opt */

  client_cert = SSL_get_peer_certificate (ssl);
  if (client_cert != NULL) {
    fprintf (log, "Client certificate:\n");
    
    str = X509_NAME_oneline (X509_get_subject_name (client_cert));
    CHK_NULL(str);
    fprintf (log, "\t subject: %s\n", str);
    OPENSSL_free (str);
    
    str = X509_NAME_oneline (X509_get_issuer_name  (client_cert));
    CHK_NULL(str);
    fprintf (log, "\t issuer: %s\n", str);
    OPENSSL_free (str);
    
    /* We could do all sorts of certificate verification stuff here before
       deallocating the certificate. */
    
    X509_free (client_cert);
  } else
    fprintf (log, "Client doe not have certificate.\n");

  /* ------------------------------------------------- */
  /* DATA EXCHANGE: Receive message and send reply  */
  
  err = SSL_read (ssl, buf, sizeof(buf) - 1);  CHK_SSL(err);
  buf[err] = '\0';
  fprintf (log, "Got %d chars:'%s'\n", err, buf);
  
  err = SSL_write (ssl, "Loud and clear.", strlen("Loud and clear."));
  CHK_SSL(err);

  /* Clean up. */

  fclose (log);
  SSL_free (ssl);
  SSL_CTX_free (ctx);
}
Ejemplo n.º 29
0
int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
{
    // NOTE: ATM the socket is singlethread, have this in mind ...
    uint8 digest[20];
    uint32 clientSeed, id, security;
    uint32 unk2;
    uint32 BuiltNumberClient;
    LocaleConstant locale;
    std::string account;
    Sha1Hash sha1;
    BigNumber v, s, g, N, K;
    WorldPacket packet, SendAddonPacked;

    // Read the content of the packet
    recvPacket >> BuiltNumberClient;
    recvPacket >> unk2;
    recvPacket >> account;
    recvPacket >> clientSeed;
    recvPacket.read(digest, 20);

    DEBUG_LOG("WorldSocket::HandleAuthSession: client %u, unk2 %u, account %s, clientseed %u",
              BuiltNumberClient,
              unk2,
              account.c_str(),
              clientSeed);

    // Check the version of client trying to connect
    if (!IsAcceptableClientBuild(BuiltNumberClient))
    {
        packet.Initialize(SMSG_AUTH_RESPONSE, 1);
        packet << uint8(AUTH_VERSION_MISMATCH);

        SendPacket(packet);

        sLog.outError("WorldSocket::HandleAuthSession: Sent Auth Response (version mismatch).");
        return -1;
    }

    // Get the account information from the realmd database
    std::string safe_account = account; // Duplicate, else will screw the SHA hash verification below
    LoginDatabase.escape_string(safe_account);
    // No SQL injection, username escaped.

    QueryResult* result =
        LoginDatabase.PQuery("SELECT "
                             "id, "                      // 0
                             "gmlevel, "                 // 1
                             "sessionkey, "              // 2
                             "last_ip, "                 // 3
                             "locked, "                  // 4
                             "v, "                       // 5
                             "s, "                       // 6
                             "mutetime, "                // 7
                             "locale "                   // 8
                             "FROM account "
                             "WHERE username = '******'",
                             safe_account.c_str());

    // Stop if the account is not found
    if (!result)
    {
        packet.Initialize(SMSG_AUTH_RESPONSE, 1);
        packet << uint8(AUTH_UNKNOWN_ACCOUNT);

        SendPacket(packet);

        sLog.outError("WorldSocket::HandleAuthSession: Sent Auth Response (unknown account).");
        return -1;
    }

    Field* fields = result->Fetch();

    N.SetHexStr("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7");
    g.SetDword(7);

    v.SetHexStr(fields[5].GetString());
    s.SetHexStr(fields[6].GetString());

    const char* sStr = s.AsHexStr();                        // Must be freed by OPENSSL_free()
    const char* vStr = v.AsHexStr();                        // Must be freed by OPENSSL_free()

    DEBUG_LOG("WorldSocket::HandleAuthSession: (s,v) check s: %s v: %s",
              sStr,
              vStr);

    OPENSSL_free((void*) sStr);
    OPENSSL_free((void*) vStr);

    ///- Re-check ip locking (same check as in realmd).
    if (fields[4].GetUInt8() == 1)  // if ip is locked
    {
        if (strcmp(fields[3].GetString(), GetRemoteAddress().c_str()))
        {
            packet.Initialize(SMSG_AUTH_RESPONSE, 1);
            packet << uint8(AUTH_FAILED);
            SendPacket(packet);

            delete result;
            BASIC_LOG("WorldSocket::HandleAuthSession: Sent Auth Response (Account IP differs).");
            return -1;
        }
    }

    id = fields[0].GetUInt32();
    security = fields[1].GetUInt16();
    if (security > SEC_ADMINISTRATOR)                       // prevent invalid security settings in DB
        { security = SEC_ADMINISTRATOR; }

    K.SetHexStr(fields[2].GetString());

    time_t mutetime = time_t (fields[7].GetUInt64());

    locale = LocaleConstant(fields[8].GetUInt8());
    if (locale >= MAX_LOCALE)
        { locale = LOCALE_enUS; }

    delete result;

    // Re-check account ban (same check as in realmd)
    QueryResult* banresult =
        LoginDatabase.PQuery("SELECT 1 FROM account_banned WHERE id = %u AND active = 1 AND (unbandate > UNIX_TIMESTAMP() OR unbandate = bandate)"
                             "UNION "
                             "SELECT 1 FROM ip_banned WHERE (unbandate = bandate OR unbandate > UNIX_TIMESTAMP()) AND ip = '%s'",
                             id, GetRemoteAddress().c_str());

    if (banresult) // if account banned
    {
        packet.Initialize(SMSG_AUTH_RESPONSE, 1);
        packet << uint8(AUTH_BANNED);
        SendPacket(packet);

        delete banresult;

        sLog.outError("WorldSocket::HandleAuthSession: Sent Auth Response (Account banned).");
        return -1;
    }

    // Check locked state for server
    AccountTypes allowedAccountType = sWorld.GetPlayerSecurityLimit();

    if (allowedAccountType > SEC_PLAYER && AccountTypes(security) < allowedAccountType)
    {
        WorldPacket Packet(SMSG_AUTH_RESPONSE, 1);
        Packet << uint8(AUTH_UNAVAILABLE);

        SendPacket(packet);

        BASIC_LOG("WorldSocket::HandleAuthSession: User tries to login but his security level is not enough");
        return -1;
    }

    // Check that Key and account name are the same on client and server
    Sha1Hash sha;

    uint32 t = 0;
    uint32 seed = m_Seed;

    sha.UpdateData(account);
    sha.UpdateData((uint8*) & t, 4);
    sha.UpdateData((uint8*) & clientSeed, 4);
    sha.UpdateData((uint8*) & seed, 4);
    sha.UpdateBigNumbers(&K, NULL);
    sha.Finalize();

    if (memcmp(sha.GetDigest(), digest, 20))
    {
        packet.Initialize(SMSG_AUTH_RESPONSE, 1);
        packet << uint8(AUTH_FAILED);

        SendPacket(packet);

        sLog.outError("WorldSocket::HandleAuthSession: Sent Auth Response (authentification failed).");
        return -1;
    }

    std::string address = GetRemoteAddress();

    DEBUG_LOG("WorldSocket::HandleAuthSession: Client '%s' authenticated successfully from %s.",
              account.c_str(),
              address.c_str());

    // Update the last_ip in the database
    // No SQL injection, username escaped.
    static SqlStatementID updAccount;

    SqlStatement stmt = LoginDatabase.CreateStatement(updAccount, "UPDATE account SET last_ip = ? WHERE username = ?");
    stmt.PExecute(address.c_str(), account.c_str());

    // NOTE ATM the socket is single-threaded, have this in mind ...
    ACE_NEW_RETURN(m_Session, WorldSession(id, this, AccountTypes(security), mutetime, locale), -1);

    m_Crypt.SetKey(K.AsByteArray(), 40);
    m_Crypt.Init();

    m_Session->LoadTutorialsData();

    // In case needed sometime the second arg is in microseconds 1 000 000 = 1 sec
    ACE_OS::sleep(ACE_Time_Value(0, 10000));

    sWorld.AddSession(m_Session);

    // Create and send the Addon packet
    if (sAddOnHandler.BuildAddonPacket(&recvPacket, &SendAddonPacked))
        { SendPacket(SendAddonPacked); }

    return 0;
}
Ejemplo n.º 30
0
/* There have been a few bug fixes for this function from
 * Paul Keogh <*****@*****.**>, many thanks to him */
static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c)
	{
	ASN1_STRING *os=NULL;
	BUF_MEM b;
	int num;

	b.length=0;
	b.max=0;
	b.data=NULL;

	if (a == NULL)
		{
		c->error=ERR_R_PASSED_NULL_PARAMETER;
		goto err;
		}

	num=0;
	for (;;)
		{
		if (c->inf & 1)
			{
			c->eos=ASN1_const_check_infinite_end(&c->p,
				(long)(c->max-c->p));
			if (c->eos) break;
			}
		else
			{
			if (c->slen <= 0) break;
			}

		c->q=c->p;
		if (d2i_ASN1_bytes(&os,&c->p,c->max-c->p,c->tag,c->xclass)
			== NULL)
			{
			c->error=ERR_R_ASN1_LIB;
			goto err;
			}

		if (!BUF_MEM_grow_clean(&b,num+os->length))
			{
			c->error=ERR_R_BUF_LIB;
			goto err;
			}
		memcpy(&(b.data[num]),os->data,os->length);
		if (!(c->inf & 1))
			c->slen-=(c->p-c->q);
		num+=os->length;
		}

	if (!asn1_const_Finish(c)) goto err;

	a->length=num;
	if (a->data != NULL) OPENSSL_free(a->data);
	a->data=(unsigned char *)b.data;
	if (os != NULL) ASN1_STRING_free(os);
	return(1);
err:
	OPENSSL_PUT_ERROR(ASN1, c->error);
	if (os != NULL) ASN1_STRING_free(os);
	if (b.data != NULL) OPENSSL_free(b.data);
	return(0);
	}