How to prove that certain data is calculated(or generated) inside Enclave(Intel SGX)? - sgx

How to prove that certain data is calculated(or generated) inside Enclave(Intel SGX)?
I tried to generate asymmetric key pair inside enclave(private key might be invisible to outside), and
then expose public key with evidence(i guess quote or remote attestation related things).
I got how remote attestation goes but, i cannot come up with applying remote attestation to verifying enclave-generated data.
Is this possible scenario with Intel SGX?

You can prove the origin of the public key by placing it in the report_data field of a Quote generated during report attestation.
_quote_t.report_data can be used to attest arbitrary data:
The 64 byte data buffer is free form data and you can supply any information in that buffer that you would like to have identified as being in the possession and protection envelope of the enclave when the report/quote was generated. You can thus use this buffer to convey whatever information you would like to a verifying party. (Source)
The report_data field can be found by tracking the following structures:
sgx_key_exchange.h
typedef struct _ra_msg3_t {
sgx_mac_t mac
sgx_ec256_public_t g_a;
sgx_ps_sec_prop_desc_t ps_sec_prop;
uint8_t quote[]; // <- Here!
} sgx_ra_msg3_t;
sgx_quote.h
typedef struct _quote_t
{
uint16_t version;
uint16_t sign_type;
sgx_epid_group_id_t epid_group_id;
sgx_isv_svn_t qe_svn;
sgx_isv_svn_t pce_svn;
uint32_t xeid;
sgx_basename_t basename;
sgx_report_body_t report_body; // <- Here!
uint32_t signature_len;
uint8_t signature[];
} sgx_quote_t;
The Quote is part of the Msg3 (client-to-server) of remote attestation protocol. You can review the details of Msg3 creation in this official Code Sample and in the intel/sgx-ra-sample RA example.
In the latter, you can find out how the report is generated using sgx_create_report:
sgx_status_t get_report(sgx_report_t *report, sgx_target_info_t *target_info)
{
#ifdef SGX_HW_SIM
return sgx_create_report(NULL, NULL, report);
#else
return sgx_create_report(target_info, NULL, report);
#endif
}
In both cases, second argument sgx_report_data_t *report_data is NULL and can be replaced by pointer to arbitrary input. This is where you want to put your public key or any other data.

Related

How to pass arbitrary data between the C module callbacks in FreeRADIUS

What is the proper/recommended method to pass data between the callbacks in a C module in FreeRADIUS?
For example, I want to create a unique request_id for the request and use it for all log entries during that request. If I create this value inside mod_authorize, how do I pass it over to mod_authenticate on the same request thread, and how do I retrieve it?
static rlm_rcode_t CC_HINT(nonnull) mod_authorize(void *instance, REQUEST *request)
{
// Generate uuid
uuid_t uuid;
uuid_generate_random(uuid);
// Convert to a string representation
char *request_id = talloc_array(mem_ctx, char, UUID_STR_LEN);
uuid_unparse(uuid, request_id);
// Do stuff and log authorize messages
radlog(L_INFO, "request_id inside mod_authorize: %s", request_id);
// How do I pass request_id to mod_authenticate callback
// ?????????????
return RLM_MODULE_OK;
}
static rlm_rcode_t CC_HINT(nonnull) mod_authenticate(void *instance, REQUEST *request)
{
char *request_id = NULL;
// How do I retrieve the request_id value
// ???????????????????
// Do stuff and log authenticate messages
radlog(L_INFO, "request_id inside mod_authenticate: %s", request_id);
return RLM_MODULE_OK;
}
Attaching the value to the request object seems like a logical thing, but I don't see a way of doing it, other than adding a value pair to the request->reply (and I don't want to return this value to NAS).
Thank you.
Apparently, there is a range of "Temporary attributes, for local storage" (defined in the dictionary.freeradius.internal file) that can be used with one of the requests object's collections (request->config, request->reply->vps and request->packet->vps). You can find the start of this range by searching dictionary.freeradius.internal file in the FreeRADIUS repository for
ATTRIBUTE Tmp-String-0
In this case I found request->packet->vps to be appropriate, and used Tmp-String-3 to add my request_id to it while inside MOD_AUTHORIZE callback:
pair_make_request("Tmp-String-3", request_ctx->request_id, T_OP_EQ);
where pair_make_request is a macro defined as
fr_pair_make(request->packet, &request->packet->vps, _a, _b, _c)
I then retrieved it, while inside MOD_AUTHENTICATE callback:
VALUE_PAIR *vp = fr_pair_find_by_num(request->packet->vps, PW_TMP_STRING_3, 0, TAG_ANY);
The numerical values of these attributes change between the versions, you must use macro definitions instead
The macros for these attributes, such as PW_TMP_STRING_3 in the esample above, are located in the file "attributes.h" which is auto-generated during the build. Here is a quote from Arran Cudbard-Bell, that I found here:
If you really want to know where each one is used, download,
configure, build the source. Then see src/include/attributes.h for the
macro versions, and grep -r through the code. That'll at least tell
you the modules, and if you're familiar with C you should be able to
figure out how/when they're added or checked for. – Arran Cudbard-Bell
Apr 12 '15 at 20:51
In my case, the resulting file is located at /usr/include/freeradius/attributes.h
I must say that it took me unreasonable amount of effort to track this information down. There is no other trace, none whatsoever, of these attribute macros. Not in the code, not in the FreeRADIUS documentation, not in Google search results.

Testing for GVfs metadata support in C

I am trying to add support for per-directory viewing settings to the Thunar file browser of the Xfce desktop. So for example if a user chooses to view the contents of a directory as a list rather than as a grid of icons, this setting is remembered for that directory and will be used whenever that directory is viewed.
Now Thunar is built on GLib, and the mechanism we have chosen to use to implement this is to store metadata using GFile attributes, using methods like g_file_set_attributes_async to store
keys with names such as "metadata::thunar-view-type". The per-directory feature can be turned on or off by the user via a checkbox in a preferences dialog. My knowledge of GIO and GLib is pretty limited, but I have now managed to get this all working as desired (you can see my merge request here if you are interested).
Now as I understand it, the functionality that I am using here relies on something called "GVfs metadata", and as I understand it this might not be available on all systems. On systems where GVfs metadata is not available, I want to turn this functionality off and in particular make the checkbox in the preferences dialog insensitive (i.e. greyed out). Thus I need to write a function to detect if gvfs metadata support is available, by which I mean whether I can use functions like g_file_set_attributes_async to successfully save metadata so that it will be available in future.
Thunar is written in C, so this function needs to be written in C using the C API for GLib, GIO, etc.
The function I have come up with (from much reading of API documentation, modifying code scraps I have found, and experimentation) is as follows.
gboolean
thunar_g_vfs_metadata_is_supported (void)
{
GDBusMessage *send, *reply;
GDBusConnection *conn;
GVariant *v1, *v2;
GError *error = NULL;
const gchar **service_names;
gboolean metadata_found;
/* connect to the session bus */
conn = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
/* check that the connection was opened sucessfully */
if (error != NULL)
{
g_error_free (error);
return FALSE;
}
/* create the message to send to list the available services */
send = g_dbus_message_new_method_call ("org.freedesktop.DBus",
"/org/freedesktop/DBus",
"org.freedesktop.DBus",
"ListNames");
/* send the message and wait for the reply */
reply = g_dbus_connection_send_message_with_reply_sync (conn, send, G_DBUS_SEND_MESSAGE_FLAGS_NONE,
-1, NULL, NULL, &error);
/* release the connection and the sent message */
g_object_unref (send);
g_object_unref (conn);
/* check if we got a sucessful reply */
if (error != NULL)
{
g_error_free (error);
return FALSE;
}
/* extract the GVariant with the array of strings describing the available services */
v1 = g_dbus_message_get_body (reply); /* v1 belongs to reply and must not be freed */
if (v1 == NULL || !g_variant_is_container (v1) || g_variant_n_children (v1) < 1)
{
g_object_unref (reply);
return FALSE;
}
v2 = g_variant_get_child_value (v1, 0);
g_object_unref (reply);
/* check that the GVariant we have been given does contain an array of strings */
if (!g_variant_is_of_type (v2, G_VARIANT_TYPE_STRING_ARRAY))
{
g_variant_unref (v2);
return FALSE;
}
/* search through the list of service names to see if gvfs metadata is present */
metadata_found = FALSE;
service_names = g_variant_get_strv (v2, NULL);
for (int i=0; service_names[i] != NULL; i++)
if (g_strcmp0 (service_names[i], "org.gtk.vfs.Metadata") == 0)
metadata_found = TRUE;
g_free (service_names);
g_variant_unref (v2);
return metadata_found;
}
As you can see, this function uses DBus to query service names to see if the necessary service is available. Now, as far as I have been able to test it, this function works as I want it to. However, during a code review it has been questioned whether this can be done without relying on DBus (which might itself not be available even though GVfs metadata is).
Thus (at last!) my question: what is the best (i.e. most robust and accurate) way to test for GVfs metadata support via the C API for GLib, GIO, etc?. As I said above, by "GVfs metadata support" I mean "can I use functions like g_file_set_attributes_async to successfully save metadata so that it will be available in future?".
One method I have considered is looking at the list of running processes for the name "gvfsd-metadata", but that seems a bit kludgy to me.
Also, as mentioned above I am very much a novice with these technologies, so I is absolutely possible that I have misunderstood stuff here, so if you spot any errors in the assertions I have made above, please let me know.
Thanks!
(And yes, usual story, I'm a long time reader of SO & co, but a first time asker, so please feel free to edit or let me know if I've done something wrong/bad)
Call g_file_query_settable_attributes() and g_file_query_writable_namespaces() on the GFile, as described in the GFileInfo documentation:
However, not all attributes can be changed in the file. For instance, the actual size of a file cannot be changed via g_file_info_set_size(). You may call g_file_query_settable_attributes() and g_file_query_writable_namespaces() to discover the settable attributes of a particular file at runtime.

Where are the parameters for Indy's TIdCompressorZLib.CompressStream Method documented?

The TIdComproessorZLib component is used for compression and decompression in the Delphi/C++ Builder Indy library. The CompressStream Method has the following definition:
public: virtual __fastcall CompressStream(TStream AInStream, TStream AOutStream, const TIdCompressionLevel ALevel, const int AWindowBits, const int AMemLevel, const int AStrategy);
The complete description of those parameters in the help file is:
CompressStream is a public overridden procedure. that implements the
abstract the virtual method declared in the ancestor class.
AInStream is the stream containing the uncompressed contents used in
the compression operation.
AOutStream is the stream used to store the compressed contents from
the compression operation. AOutStream is cleared prior to outputting
the compressed contents from the operation. When AOutStream is
omitted, the stream in AInStream is cleared and reused for the output
from the compression operation.
Use ALevel to indicate the desired compression level for the
operation.
Use AWindowsBits and AMemLevel to control the memory footprint
required to perform in-memory compression using the ZLib library.
Use AStrategy to control the RLE-encoding strategy used in the
compression operation.
ALevel's values defined on the help page for TIdCompressionLevel, but I cannot find any indication of what values should be used for AWindowBits, AMemLevel, or AStrategy, which are just integers.
I looked in the source code, but CompressStream just delegates to IndyCompressStream, which is listed in the help file as:
IndyCompressStream(TStream InStream, TStream OutStream, const int level = Z_DEFAULT_COMPRESSION, const int WinBits = MAX_WBITS, const int MemLevel = MAX_MEM_LEVEL, const int Stratagy = Z_DEFAULT_STRATEGY);
The help for IndyCompressStream doesn't even list the minimal description of the parameters that CompressStream does.
I tracked down the file where (I think) those default constants mentioned in IndyCompressStream live, source\Indy10\Protocols\IdZLibHeaders.pas, and they are
Z_DEFAULT_STRATEGY = 0;
Z_DEFAULT_COMPRESSION = -1;
MAX_WBITS = 15; { 32K LZ77 window }
MAX_MEM_LEVEL = 9;
However, the value given for Z_DEFAULT_COMPRESSION is not even a legal value for that parameter according to the documentation for TIdCompressionLevel
Is there some documentation somewhere about what AWindowBits, AMemLevel, and AStrategy mean to this component, and what values are reasonable to use for them? Are the values listed above the actual recommended defaults? Also, the source files include "indy", "Indy10", and "indyimpl" directories. Which of those should we be using to find the source for the current Indy components?
Thanks!
You will need to look to the zlib documentation in zlib.h. In particular, the parameters to deflateInit2().
In nearly all cases, the only ones you should mess with are the compression level and the window bits. For window bits, you would normally leave the window size at 32K (15), but either add 16 for the gzip format (31), or negate (-15) to get the raw deflate format with no header or trailer. For some special kinds of data, you may get an improvement with a different compression strategy, e.g. image or other numerical arrays of data.
Thank you for the comments and answers, especially Remy and Mark. I had not realized that the Indy units were wrappers around zlib, and that the parameters were defined in the zlib library.
I was trying to create a gzip format stream for uploading to a server that was expecting gzip.
Here is the working code for gzip compression and decompression:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TStringStream* streamIn = new TStringStream(String("This is some data to compress"));
TMemoryStream* streamCompressed = new TMemoryStream;
TStringStream* streamOut = new TStringStream;
/* this also works to compress to gzip format, but you must #include <IdZlib.hpp>
CompressStreamEx(streamIn, streamCompressed, Idzlib::clDefault, zsGZip); */
// NOTE: according to docs, you can leave outstream null, and instream
// will be replaced and reused, but I could not get that to work
IdCompressorZLib1->CompressStream(
streamIn, // System::Classes::TStream* AInStream,
streamCompressed, // System::Classes::TStream* AOutStream,
1, // const Idzlibcompressorbase::TIdCompressionLevel ALevel,
15 + 16, // const int AWindowBits, -- add 16 to get gzip format
8, // const int AMemLevel, -- see note below
0); // const int AStrategy);
streamCompressed->Position = 0;
IdCompressorZLib1->DecompressGZipStream(streamCompressed, streamOut);
String out = streamOut->DataString;
ShowMessage(out);
}
In particular, note that passing -1 for ALevel produces ZLib Error -2, Z_STREAM_ERROR which means invalid parameter, in spite of the defaults I had found. Also, AWindowBits normally ranges from 8 to 15, but adding 16 gives you a gzip format, and negative numbers give you a raw format, as described in the zlib documentation referenced by Mark Adler, one of the authors of the zlib library. I changed AMemLevel from Indy's default per Mark Adler's comment.
Also, as noted the CompressStreamEx function will produce gzip compression using the parameters included in the comments above.
The above was tested in RAD Studio XE3. Thanks again for your help!

Load RSA PKCS#1 private key from memory?

I have to write a program to establish a secure communication with a USB device. I have to use the private key generated from it which is stored in PKCS#1 format. As I have used Crypto++ in order part of my program, I would like to utilize it for this purpose as well.
However, I cannot find a way to import RSA private key from memory. It accepts private key in PKCS#8 format only. Could some pro show me a sample code on how to do it? Many thanks!
PKCS#1 format is ASN.1 encoded. For RSAPublicKey and RSAPrivateKey, its as easy as:
RSA::PublicKey publicKey(...);
ByteQueue queue;
publicKey.Save(queue);
// The public key is now in the ByteQueue in PKCS #1 format
// ------------
// Load a PKCS #1 private key
byte key[] = {...}
ArraySource arr(key, sizeof(key));
RSA::PrivateKey privateKey;
privateKey.Load(arr);
// The private key is now ready to use
Saving and loading keys is discussed in more detail at the Crypto++ wiki under Keys and Formats.

System.IO.Stream in favor of HttpPostedFileBase

I have a site where I allow members to upload photos. In the MVC Controller I take the FormCollection as the parameter to the Action. I then read the first file as type HttpPostedFileBase. I use this to generate thumbnails. This all works fine.
In addition to allowing members to upload their own photos, I would like to use the System.Net.WebClient to import photos myself.
I am trying to generalize the method that processes the uploaded photo (file) so that it can take a general Stream object instead of the specific HttpPostedFileBase.
I am trying to base everything off of Stream since the HttpPostedFileBase has an InputStream property that contains the stream of the file and the WebClient has an OpenRead method that returns Stream.
However, by going with Stream over HttpPostedFileBase, it looks like I am loosing ContentType and ContentLength properties which I use for validating the file.
Not having worked with binary stream before, is there a way to get the ContentType and ContentLength from a Stream? Or is there a way to create a HttpPostedFileBase object using the Stream?
You're right to look at it from a raw stream perspective because then you can create one method that handles streams and therefore many scenarios from which they come.
In the file upload scenario, the stream you're acquiring is on a separate property from the content-type. Sometimes magic numbers (also a great source here) can be used to detect the data type by the stream header bytes but this might be overkill since the data is already available to you through other means (i.e. the Content-Type header, or the .ext file extension, etc).
You can measure the byte length of the stream just by virtue of reading it so you don't really need the Content-Length header: the browser just finds it useful to know what size of file to expect in advance.
If your WebClient is accessing a resource URI on the Internet, it will know the file extension like http://www.example.com/image.gif and that can be a good file type identifier.
Since the file info is already available to you, why not open up one more argument on your custom processing method to accept a content type string identifier like:
public static class Custom {
// Works with a stream from any source and a content type string indentifier.
static public void SavePicture(Stream inStream, string contentIdentifer) {
// Parse and recognize contentIdentifer to know the kind of file.
// Read the bytes of the file in the stream (while counting them).
// Write the bytes to wherever the destination is (e.g. disk)
// Example:
long totalBytesSeen = 0L;
byte[] bytes = new byte[1024]; //1K buffer to store bytes.
// Read one chunk of bytes at a time.
do
{
int num = inStream.Read(bytes, 0, 1024); // read up to 1024 bytes
// No bytes read means end of file.
if (num == 0)
break; // good bye
totalBytesSeen += num; //Actual length is accumulating.
/* Can check for "magic number" here, while reading this stream
* in the case the file extension or content-type cannot be trusted.
*/
/* Write logic here to write the byte buffer to
* disk or do what you want with them.
*/
} while (true);
}
}
Some useful filename parsing features are in the IO namespace:
using System.IO;
Use your custom method in the scenarios you mentioned like so:
From an HttpPostedFileBase instance named myPostedFile
Custom.SavePicture(myPostedFile.InputStream, myPostedFile.ContentType);
When using a WebClient instance named webClient1:
var imageFilename = "pic.gif";
var stream = webClient1.DownloadFile("http://www.example.com/images/", imageFilename)
//...
Custom.SavePicture(stream, Path.GetExtension(imageFilename));
Or even when processing a file from disk:
Custom.SavePicture(File.Open(pathToFile), Path.GetExtension(pathToFile));
Call the same custom method for any stream with a content identifer that you can parse and recognize.

Resources