示例#1
1
文件: ts.c 项目: Beatzevo/openssl
static TS_REQ *create_query(BIO *data_bio, char *digest, const EVP_MD *md,
                            const char *policy, int no_nonce, int cert)
{
    int ret = 0;
    TS_REQ *ts_req = NULL;
    int len;
    TS_MSG_IMPRINT *msg_imprint = NULL;
    X509_ALGOR *algo = NULL;
    unsigned char *data = NULL;
    ASN1_OBJECT *policy_obj = NULL;
    ASN1_INTEGER *nonce_asn1 = NULL;

    if (md == NULL && (md = EVP_get_digestbyname("sha1")) == NULL)
        goto err;
    if ((ts_req = TS_REQ_new()) == NULL)
        goto err;
    if (!TS_REQ_set_version(ts_req, 1))
        goto err;
    if ((msg_imprint = TS_MSG_IMPRINT_new()) == NULL)
        goto err;
    if ((algo = X509_ALGOR_new()) == NULL)
        goto err;
    if ((algo->algorithm = OBJ_nid2obj(EVP_MD_type(md))) == NULL)
        goto err;
    if ((algo->parameter = ASN1_TYPE_new()) == NULL)
        goto err;
    algo->parameter->type = V_ASN1_NULL;
    if (!TS_MSG_IMPRINT_set_algo(msg_imprint, algo))
        goto err;
    if ((len = create_digest(data_bio, digest, md, &data)) == 0)
        goto err;
    if (!TS_MSG_IMPRINT_set_msg(msg_imprint, data, len))
        goto err;
    if (!TS_REQ_set_msg_imprint(ts_req, msg_imprint))
        goto err;
    if (policy && (policy_obj = txt2obj(policy)) == NULL)
        goto err;
    if (policy_obj && !TS_REQ_set_policy_id(ts_req, policy_obj))
        goto err;

    /* Setting nonce if requested. */
    if (!no_nonce && (nonce_asn1 = create_nonce(NONCE_LENGTH)) == NULL)
        goto err;
    if (nonce_asn1 && !TS_REQ_set_nonce(ts_req, nonce_asn1))
        goto err;
    if (!TS_REQ_set_cert_req(ts_req, cert))
        goto err;

    ret = 1;
 err:
    if (!ret) {
        TS_REQ_free(ts_req);
        ts_req = NULL;
        BIO_printf(bio_err, "could not create query\n");
        ERR_print_errors(bio_err);
    }
    TS_MSG_IMPRINT_free(msg_imprint);
    X509_ALGOR_free(algo);
    OPENSSL_free(data);
    ASN1_OBJECT_free(policy_obj);
    ASN1_INTEGER_free(nonce_asn1);
    return ts_req;
}
示例#2
0
static LUA_FUNCTION(openssl_ts_req_gc)
{
  TS_REQ *req = CHECK_OBJECT(1, TS_REQ, "openssl.ts_req");
  lua_pushnil(L);
  lua_setmetatable(L, 1);
  TS_REQ_free(req);
  return 0;
}
示例#3
0
static int query_command(const char *data, char *digest, const EVP_MD *md,
			 const char *policy, int no_nonce, 
			 int cert, const char *in, const char *out, int text)
	{
	int ret = 0;
	TS_REQ *query = NULL;
	BIO *in_bio = NULL;
	BIO *data_bio = NULL;
	BIO *out_bio = NULL;

	/* Build query object either from file or from scratch. */
	if (in != NULL)
		{
		if ((in_bio = BIO_new_file(in, "rb")) == NULL) goto end;
		query = d2i_TS_REQ_bio(in_bio, NULL);
		}
	else
		{
		/* Open the file if no explicit digest bytes were specified. */
		if (!digest 
		    && !(data_bio = BIO_open_with_default(data, "rb", stdin)))
			goto end;
		/* Creating the query object. */
		query = create_query(data_bio, digest, md,
				     policy, no_nonce, cert);
		/* Saving the random number generator state. */
		}
	if (query == NULL) goto end;

	/* Write query either in ASN.1 or in text format. */
	if ((out_bio = BIO_open_with_default(out, "wb", stdout)) == NULL)
		goto end;
	if (text)
		{
		/* Text output. */
		if (!TS_REQ_print_bio(out_bio, query))
			goto end;
		}
	else
		{
		/* ASN.1 output. */
		if (!i2d_TS_REQ_bio(out_bio, query))
			goto end;
		}

	ret = 1;

 end:
	ERR_print_errors(bio_err);

	/* Clean up. */
	BIO_free_all(in_bio);
	BIO_free_all(data_bio);
	BIO_free_all(out_bio);
	TS_REQ_free(query);

	return ret;
	}
示例#4
0
static LUA_FUNCTION(openssl_ts_req_new)
{
  TS_REQ *ts_req = TS_REQ_new();
  long version = luaL_optinteger(L, 1, 1);

  int ret = TS_REQ_set_version(ts_req, version);
  if (ret == 1)
  {
    PUSH_OBJECT(ts_req, "openssl.ts_req");
    return 1;
  }
  TS_REQ_free(ts_req);
  return 0;
}
示例#5
0
文件: ts.c 项目: Beatzevo/openssl
/*
 * Query-related method definitions.
 */
static int query_command(const char *data, char *digest, const EVP_MD *md,
                         const char *policy, int no_nonce,
                         int cert, const char *in, const char *out, int text)
{
    int ret = 0;
    TS_REQ *query = NULL;
    BIO *in_bio = NULL;
    BIO *data_bio = NULL;
    BIO *out_bio = NULL;

    /* Build query object. */
    if (in != NULL) {
        if ((in_bio = bio_open_default(in, 'r', FORMAT_ASN1)) == NULL)
            goto end;
        query = d2i_TS_REQ_bio(in_bio, NULL);
    } else {
        if (digest == NULL
            && (data_bio = bio_open_default(data, 'r', FORMAT_ASN1)) == NULL)
            goto end;
        query = create_query(data_bio, digest, md, policy, no_nonce, cert);
    }
    if (query == NULL)
        goto end;

    if (text) {
        if ((out_bio = bio_open_default(out, 'w', FORMAT_TEXT)) == NULL)
            goto end;
        if (!TS_REQ_print_bio(out_bio, query))
            goto end;
    } else {
        if ((out_bio = bio_open_default(out, 'w', FORMAT_ASN1)) == NULL)
            goto end;
        if (!i2d_TS_REQ_bio(out_bio, query))
            goto end;
    }

    ret = 1;

 end:
    ERR_print_errors(bio_err);
    BIO_free_all(in_bio);
    BIO_free_all(data_bio);
    BIO_free_all(out_bio);
    TS_REQ_free(query);
    return ret;
}
int check_time_stamp(TS_RESP* tsResponse, X509* caCert, char* hash, UNSIGNED32 hash_size)
{
	int result = 0;
	TS_REQ* tsRequest = NULL;
	TS_VERIFY_CTX* ctx = NULL;
	TS_MSG_IMPRINT* msgImprint = NULL;
	ASN1_OCTET_STRING* hashedMessage = NULL;
	int hashedMessageLength;

	tsRequest = get_timestamp_request(hash, hash_size, tsResponse->tst_info->nonce);

	msgImprint = TS_REQ_get_msg_imprint(tsRequest);
	hashedMessage = TS_MSG_IMPRINT_get_msg(msgImprint);
	hashedMessageLength = ASN1_STRING_length((ASN1_STRING*)hashedMessage);
	if (hashedMessageLength != (int)hash_size)
	{
		goto end;
	}

	if (!(ctx = TS_REQ_to_TS_VERIFY_CTX(tsRequest, NULL)))
	{
		goto end;
	}

	ctx->flags |= TS_VFY_SIGNATURE;

	ctx->store =  X509_STORE_new();
	X509_STORE_add_cert(ctx->store, caCert);

	if (ossl_TS_RESP_verify_response(ctx, tsResponse))
	{
		result = 1;
	}
end:
	if (tsRequest != NULL)
	{
		TS_REQ_free(tsRequest);
	}

	if (ctx != NULL)
	{
		TS_VERIFY_CTX_free(ctx);
	}
	return result;
}
示例#7
0
文件: ts.c 项目: Beatzevo/openssl
static TS_VERIFY_CTX *create_verify_ctx(char *data, char *digest,
                                        char *queryfile,
                                        char *CApath, char *CAfile,
                                        char *untrusted,
                                        X509_VERIFY_PARAM *vpm)
{
    TS_VERIFY_CTX *ctx = NULL;
    BIO *input = NULL;
    TS_REQ *request = NULL;
    int ret = 0;
    int f = 0;

    if (data != NULL || digest != NULL) {
        if ((ctx = TS_VERIFY_CTX_new()) == NULL)
            goto err;
        f = TS_VFY_VERSION | TS_VFY_SIGNER;
        if (data != NULL) {
            f |= TS_VFY_DATA;
            if (TS_VERIFY_CTX_set_data(ctx, BIO_new_file(data, "rb")) == NULL)
                goto err;
        } else if (digest != NULL) {
            long imprint_len;
            unsigned char *hexstr = OPENSSL_hexstr2buf(digest, &imprint_len);
            f |= TS_VFY_IMPRINT;
            if (TS_VERIFY_CTX_set_imprint(ctx, hexstr, imprint_len) == NULL) {
                BIO_printf(bio_err, "invalid digest string\n");
                goto err;
            }
        }

    } else if (queryfile != NULL) {
        if ((input = BIO_new_file(queryfile, "rb")) == NULL)
            goto err;
        if ((request = d2i_TS_REQ_bio(input, NULL)) == NULL)
            goto err;
        if ((ctx = TS_REQ_to_TS_VERIFY_CTX(request, NULL)) == NULL)
            goto err;
    } else
        return NULL;

    /* Add the signature verification flag and arguments. */
    TS_VERIFY_CTX_add_flags(ctx, f | TS_VFY_SIGNATURE);

    /* Initialising the X509_STORE object. */
    if (TS_VERIFY_CTX_set_store(ctx, create_cert_store(CApath, CAfile, vpm))
            == NULL)
        goto err;

    /* Loading untrusted certificates. */
    if (untrusted
        && TS_VERIFY_CTS_set_certs(ctx, TS_CONF_load_certs(untrusted)) == NULL)
        goto err;
    ret = 1;

 err:
    if (!ret) {
        TS_VERIFY_CTX_free(ctx);
        ctx = NULL;
    }
    BIO_free_all(input);
    TS_REQ_free(request);
    return ctx;
}
示例#8
0
static TS_VERIFY_CTX *
create_verify_ctx(char *data, char *digest, char *queryfile, char *ca_path,
    char *ca_file, char *untrusted)
{
	TS_VERIFY_CTX *ctx = NULL;
	BIO *input = NULL;
	TS_REQ *request = NULL;
	int ret = 0;

	if (data != NULL || digest != NULL) {
		if (!(ctx = TS_VERIFY_CTX_new()))
			goto err;
		ctx->flags = TS_VFY_VERSION | TS_VFY_SIGNER;
		if (data != NULL) {
			ctx->flags |= TS_VFY_DATA;
			if (!(ctx->data = BIO_new_file(data, "rb")))
				goto err;
		} else if (digest != NULL) {
			long imprint_len;
			ctx->flags |= TS_VFY_IMPRINT;
			if (!(ctx->imprint = string_to_hex(digest,
				    &imprint_len))) {
				BIO_printf(bio_err, "invalid digest string\n");
				goto err;
			}
			ctx->imprint_len = imprint_len;
		}
	} else if (queryfile != NULL) {
		/*
		 * The request has just to be read, decoded and converted to
		 * a verify context object.
		 */
		if (!(input = BIO_new_file(queryfile, "rb")))
			goto err;
		if (!(request = d2i_TS_REQ_bio(input, NULL)))
			goto err;
		if (!(ctx = TS_REQ_to_TS_VERIFY_CTX(request, NULL)))
			goto err;
	} else
		return NULL;

	/* Add the signature verification flag and arguments. */
	ctx->flags |= TS_VFY_SIGNATURE;

	/* Initialising the X509_STORE object. */
	if (!(ctx->store = create_cert_store(ca_path, ca_file)))
		goto err;

	/* Loading untrusted certificates. */
	if (untrusted && !(ctx->certs = TS_CONF_load_certs(untrusted)))
		goto err;

	ret = 1;
err:
	if (!ret) {
		TS_VERIFY_CTX_free(ctx);
		ctx = NULL;
	}
	BIO_free_all(input);
	TS_REQ_free(request);
	return ctx;
}
TS_REQ* get_timestamp_request(char* hash, int hash_size, ASN1_INTEGER *nonce_asn1)
{
	int ret = 0;
	TS_REQ *ts_req = NULL;
	TS_MSG_IMPRINT *msg_imprint = NULL;
	X509_ALGOR *algo = NULL;
	unsigned char *data = NULL;
	ASN1_OBJECT *policy_obj = NULL;
	const EVP_MD* md = NULL;

	/* Setting default message digest. */
	if ((md = EVP_get_digestbyname("sha256")) == NULL)
	{
		goto err;
	}

	/* Creating request object. */
	if ((ts_req = TS_REQ_new()) == NULL)
	{
		goto err;
	}

	/* Setting version. */
	if (!TS_REQ_set_version(ts_req, 1)) goto err;

	/* Creating and adding MSG_IMPRINT object. */
	if ((msg_imprint = TS_MSG_IMPRINT_new()) == NULL)
	{
		goto err;
	}

	/* Adding algorithm. */
	if ((algo = X509_ALGOR_new()) == NULL)
	{
		goto err;
	}
	if ((algo->algorithm = OBJ_nid2obj(EVP_MD_type(md))) == NULL)
	{
		goto err;
	}
	if ((algo->parameter = ASN1_TYPE_new()) == NULL)
	{
		goto err;
	}
	algo->parameter->type = V_ASN1_NULL;
	if (!TS_MSG_IMPRINT_set_algo(msg_imprint, algo)) goto err;

	/* Adding message digest. */
	if (!TS_MSG_IMPRINT_set_msg(msg_imprint, (unsigned char*)hash, hash_size)) goto err;

	if (!TS_REQ_set_msg_imprint(ts_req, msg_imprint)) goto err;

	/* Setting policy if requested. */
	if ((policy_obj = OBJ_txt2obj("1.1.3", 0)) == NULL)
	{
		goto err;
	}
	if (policy_obj && !TS_REQ_set_policy_id(ts_req, policy_obj)) goto err;

	/* Setting nonce if requested. */
	if (nonce_asn1 && !TS_REQ_set_nonce(ts_req, nonce_asn1)) goto err;

	/* Setting certificate request flag if requested. */
	if (!TS_REQ_set_cert_req(ts_req, 1)) goto err;

	ret = 1;
 err:
	if (!ret)
	{
		TS_REQ_free(ts_req);
		ts_req = NULL;
	}
	TS_MSG_IMPRINT_free(msg_imprint);
	X509_ALGOR_free(algo);
	OPENSSL_free(data);
	ASN1_OBJECT_free(policy_obj);
	return ts_req;
}
UNSIGNED32 get_timestamp_response(const char* urlStr, char* hash, UNSIGNED32 hash_size, UNSIGNED32 httpTimeOut, TS_RESP** tsResponse)
{
	UNSIGNED32 result = TINTERNALERROR;
	BIO* responseBio = NULL;
	Url* url = NULL;
	TS_REQ* tsRequest = NULL;
	BIO* requestBio = NULL;
	int requestHeaderLength;
	int requestLength;
	int requestContentLength;
	char requestHeader[2048 + 256];
	char* request = NULL;
	void* contentBuffer = NULL;
	void* resultBuffer = NULL;
	int resultLength;
	TS_MSG_IMPRINT* msgImprint = NULL;
	ASN1_OCTET_STRING* hashedMessage = NULL;
	int hashedMessageLength;
	int httpResult;
	char *urlBuffer = NULL;
	int redirection = 0;

	/* Check if TS url is specified */
	if (!urlStr)
	{
		goto end;
	}

	/* Get Request for timestamp */
	tsRequest = get_timestamp_request(hash, hash_size, create_nonce(NONCE_LENGTH));
	msgImprint = TS_REQ_get_msg_imprint(tsRequest);
	hashedMessage = TS_MSG_IMPRINT_get_msg(msgImprint);
	hashedMessageLength = ASN1_STRING_length((ASN1_STRING*)hashedMessage);
	if ((int)hash_size != hashedMessageLength)
	{
		goto end;
	}

	requestBio = BIO_new(BIO_s_mem());
	if (requestBio == NULL)
	{
		goto end;
	}

	if (!i2d_TS_REQ_bio(requestBio, tsRequest))
	{
		goto end;
	}

	contentBuffer = memory_alloc(BIO_number_written(requestBio));
	if (contentBuffer == NULL)
	{
		goto end;
	}

    requestContentLength = BIO_read(requestBio, contentBuffer, BIO_number_written(requestBio));

    /* Allocate memory buffer for timestamp server url */
    urlBuffer = memory_alloc(strlen(urlStr) + 1);
    if (!urlBuffer)
    {
    	goto end;
    }
    /* Copy TS url to allocated buffer */
    strcpy(urlBuffer, urlStr);

http_redirect:

	/* Parse and check URL */
	url = parse_url(urlBuffer);
	if (url == NULL)
	{
		goto end;
	}
	if (strcmp(url->Scheme, "http") != 0)
	{
		goto end;
	}

    requestHeaderLength = sprintf(requestHeader, "POST %s HTTP/1.0\r\nHOST: %s\r\nPragma: no-cache\r\nContent-Type: application/timestamp-query\r\nAccept: application/timestamp-reply\r\nContent-Length: %d\r\n\r\n",
    		urlBuffer, url->Host, requestContentLength);

	requestLength = requestHeaderLength + requestContentLength;

	request = (char*)memory_alloc(requestLength);
	if (request == NULL)
	{
		goto end;
	}

	memcpy(request, requestHeader, requestHeaderLength);
	memcpy(request + requestHeaderLength, contentBuffer, requestContentLength);

	httpResult = http_read(url->Host, request, requestLength, url->Port, httpTimeOut, 1, &resultBuffer, &resultLength);
	if (httpResult == HTTP_REDIRECTION && (resultBuffer) && !redirection)
	{
		free_url(url);
		url = NULL;
		memory_free(request);
		request = NULL;
		/* Allocated buffer for redirected url */
	    urlBuffer = memory_realloc(urlBuffer, resultLength);
	    if (!urlBuffer)
	    {
	    	goto end;
	    }
	    memcpy(urlBuffer, resultBuffer, resultLength);
	    memory_free(resultBuffer);
	    redirection++;
		goto http_redirect;
	} else
	if ((httpResult == HTTP_NOERROR) && (resultBuffer))
	{
		responseBio = BIO_new(BIO_s_mem());
		if (responseBio == NULL)
		{
			goto end;
		}
		BIO_write(responseBio, resultBuffer, resultLength);

		*tsResponse = d2i_TS_RESP_bio(responseBio, NULL);
		if (*tsResponse == NULL)
		{
			goto end;
		}

		result = TNOERR;
	}
	else
	{
		switch (httpResult)
		{
			case HTTP_NOLIVEINTERNET_ERROR:
				result = TNONET;
				break;
			case HTTP_TIMEOUT_ERROR:
				result = TTIMEOUT;
				break;
			case HTTP_RESPONSESTATUS_ERROR:
				result = TSERVERERROR;
				break;
			default:
				result = TINTERNALERROR;
				break;
		}
	}

end:
	free_url(url);
	if (tsRequest != NULL)
	{
		TS_REQ_free(tsRequest);
	}
	if (requestBio != NULL)
	{
		BIO_free_all(requestBio);
	}
	if (responseBio != NULL)
	{
		BIO_free_all(responseBio);
	}
	if (request != NULL)
	{
		memory_free(request);
	}
	if (contentBuffer != NULL)
	{
		memory_free(contentBuffer);
	}
	if (resultBuffer != NULL)
	{
		memory_free(resultBuffer);
	}
	if (urlBuffer != NULL)
	{
		memory_free(urlBuffer);
	}

	return result;
}