Authenticode timestamp processing: error while parsing timestamp request
Hi everyone, I'm trying to write a CGI program to generate timestamps for the Authenticode(TM) digital signature system. I'm having trouble extracting the original ContentInfo from the timestamp request (the ContentInfo is required to generate a valid reply). Since the requests are Base64-encoded, I have set up a BIO that reads the request from standard input and decodes it via the OpenSSL builtin Base64 filter; however, it seems that the request is not parsed correctly. Since I have adapted the ASN1 definitions from the osslsigncode project, is it possible that the absence of the attributes member in the ASN1 definitions is causing the request not to be decoded correctly? I attach a test program and a sample timestamp request for clarification. Thanks for your help, Alessandro Menti - Test program - #include stdio.h #include stdlib.h #include openssl/asn1.h #include openssl/asn1t.h #include openssl/bio.h #include openssl/objects.h #include openssl/pem.h #include openssl/pkcs7.h /* The ASN.1 format of the timestamp request, according to MSDN (see http://this), is: TimeStampRequest ::= SEQUENCE { countersignatureType OBJECT IDENTIFIER, attributes Attributes OPTIONAL, content ContentInfo } The countersignatureType is the OID 1.3.6.1.4.1.311.3.2.1; the attributes are not interpreted and the content is a ContentInfo as defined by PKCS#7. The definitions below have been adapted from the osslsigncode project (http://sf.net/projects/osslsigncode/). */ typedef struct { ASN1_OBJECT *type; ASN1_OCTET_STRING *data; } TimeStampContentInfo; typedef struct { ASN1_OBJECT *countersignatureType; TimeStampContentInfo *content; } TimeStampRequest; ASN1_SEQUENCE(TimeStampContentInfo) = { ASN1_SIMPLE(TimeStampContentInfo, type, ASN1_OBJECT), ASN1_EXP_OPT(TimeStampContentInfo, data, ASN1_OCTET_STRING, 0) } ASN1_SEQUENCE_END(TimeStampContentInfo) DECLARE_ASN1_FUNCTIONS(TimeStampRequest) ASN1_SEQUENCE(TimeStampRequest) = { ASN1_SIMPLE(TimeStampRequest, countersignatureType, ASN1_OBJECT), ASN1_SIMPLE(TimeStampRequest, content, TimeStampContentInfo) } ASN1_SEQUENCE_END(TimeStampRequest) IMPLEMENT_ASN1_FUNCTIONS(TimeStampRequest) /* Function prototypes */ TimeStampRequest *d2i_TimeStampRequest_bio(BIO *bp, TimeStampRequest **tsr); int main() { PKCS7_SIGNER_INFO *respSigner; BIO *dataFeedIn, *dataFilter; TimeStampRequest *request; OpenSSL_add_all_algorithms(); dataFilter=BIO_new(BIO_f_base64()); dataFeedIn=BIO_new_fp(stdin, BIO_NOCLOSE); dataFeedIn=BIO_push(dataFilter, dataFeedIn); request=d2i_TimeStampRequest_bio(dataFeedIn, NULL); /* If decoding was successful, request should be a pointer to a valid TimeStampRequest structure; otherwise, it should be NULL */ if (request==NULL) printf(Error\n); else printf(Success\n); return 0; } TimeStampRequest *d2i_TimeStampRequest_bio(BIO *bp, TimeStampRequest **tsr) { return ASN1_item_d2i_bio(ASN1_ITEM_rptr(TimeStampRequest), bp, tsr); } - Sample timestamp request - MIICIwYKKwYBBAGCNwMCATCCAhMGCSqGSIb3DQEHAaCCAgQEggIANlq5EqVVVLmMCQ9na+KbNTYHaFZ/s/XGttBL+ZCBjA3LCH/fqRyTrlfiUj758X6usGzMU0xaCKNVezuj3OCrI19GeBHn4xpT9CQY+ZgWqNdXO04A0Vtu253tvXHnkfu2lmrnLKsQt9YcvyB1eEWiqW/eZECTlsl9cchKzC7z8fj1I2r8Zs3RgXfgFbV6d9iSCxcoGgHfoDKmiOaYIkDP6apc83yDNdfj486EQ2GrRIUPrlLnnctlMZ0OGCqAsIzt0E2Ye3TAy9Q0HsZNdDbYYcpCLiH1H2HJFq8U1oDJaS5+O60eaA3qsZ+phyBNTUT80Lpbs/kV3JvEl64+/9YHpRHvYlMc14dXo0qStmLko4iSxY2i5XB3ud9zlZPNy595+IglJ4fXs9i8Vqla0sdiAKmoZBQqBJOEeuP0M2A/OWpLuw/7EUliHeE0HLLYxG79CvPP1/4hhUlx7F3WlCjIwPG0Yfj3m75wdgWxPnehcrCKv+UzHiYlWcJnFy0wu7fLzXTQnUCdnO7wu56PRgCKPDwuDamtE5yTEeV68C6Q8GOmUOBrDdy3LTYB2LOzy1q4tfS2I0wUsYr0yX9tnSoUIEdoGHGWnULv10sFHWx5gefDJBjMZ552JuvuCZcG/JrHURaaaKc0ftvt8K6thXjNhOhUrARR2Bm6rqdCW/NoOyA= __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: Authenticode timestamp processing: error while parsing timestamp request
Your ASN.1 looks a lot like what I am sending in my own signing tools (developed independently from the sf project you mention). I ran your example request through Peter Gutman's dumpasn1 with my old config file, and here is the output, which looks like the same requests I generate (no attributes, explicit [0] tag before the OCTET string): 0 547: SEQUENCE { 4 10: OBJECT IDENTIFIER : timestampRequest (1 3 6 1 4 1 311 3 2 1) 16 531: SEQUENCE { 209: OBJECT IDENTIFIER : data (1 2 840 113549 1 7 1) 31 516: [0] { 35 512: OCTET STRING : 36 5A B9 12 A5 55 54 B9 8C 09 0F 67 6B E2 9B 35 : 36 07 68 56 7F B3 F5 C6 B6 D0 4B F9 90 81 8C 0D : CB 08 7F DF A9 1C 93 AE 57 E2 52 3E F9 F1 7E AE : B0 6C CC 53 4C 5A 08 A3 55 7B 3B A3 DC E0 AB 23 : 5F 46 78 11 E7 E3 1A 53 F4 24 18 F9 98 16 A8 D7 : 57 3B 4E 00 D1 5B 6E DB 9D ED BD 71 E7 91 FB B6 : 96 6A E7 2C AB 10 B7 D6 1C BF 20 75 78 45 A2 A9 : 6F DE 64 40 93 96 C9 7D 71 C8 4A CC 2E F3 F1 F8 : [ Another 384 bytes skipped ] : } : } : } I suspect that your OpenSSL declarations are missing the explicit [0] tag. On 18-08-2010 11:23, Alessandro Menti wrote: Hi everyone, I'm trying to write a CGI program to generate timestamps for the Authenticode(TM) digital signature system. I'm having trouble extracting the original ContentInfo from the timestamp request (the ContentInfo is required to generate a valid reply). Since the requests are Base64-encoded, I have set up a BIO that reads the request from standard input and decodes it via the OpenSSL builtin Base64 filter; however, it seems that the request is not parsed correctly. Since I have adapted the ASN1 definitions from the osslsigncode project, is it possible that the absence of the attributes member in the ASN1 definitions is causing the request not to be decoded correctly? I attach a test program and a sample timestamp request for clarification. Thanks for your help, Alessandro Menti - Test program - #includestdio.h #includestdlib.h #includeopenssl/asn1.h #includeopenssl/asn1t.h #includeopenssl/bio.h #includeopenssl/objects.h #includeopenssl/pem.h #includeopenssl/pkcs7.h /* The ASN.1 format of the timestamp request, according to MSDN (see http://this), is: TimeStampRequest ::= SEQUENCE { countersignatureType OBJECT IDENTIFIER, attributes Attributes OPTIONAL, contentContentInfo } The countersignatureType is the OID 1.3.6.1.4.1.311.3.2.1; the attributes are not interpreted and the content is a ContentInfo as defined by PKCS#7. The definitions below have been adapted from the osslsigncode project (http://sf.net/projects/osslsigncode/). */ typedef struct { ASN1_OBJECT *type; ASN1_OCTET_STRING *data; } TimeStampContentInfo; typedef struct { ASN1_OBJECT *countersignatureType; TimeStampContentInfo *content; } TimeStampRequest; ASN1_SEQUENCE(TimeStampContentInfo) = { ASN1_SIMPLE(TimeStampContentInfo, type, ASN1_OBJECT), ASN1_EXP_OPT(TimeStampContentInfo, data, ASN1_OCTET_STRING, 0) } ASN1_SEQUENCE_END(TimeStampContentInfo) DECLARE_ASN1_FUNCTIONS(TimeStampRequest) ASN1_SEQUENCE(TimeStampRequest) = { ASN1_SIMPLE(TimeStampRequest, countersignatureType, ASN1_OBJECT), ASN1_SIMPLE(TimeStampRequest, content, TimeStampContentInfo) } ASN1_SEQUENCE_END(TimeStampRequest) IMPLEMENT_ASN1_FUNCTIONS(TimeStampRequest) /* Function prototypes */ TimeStampRequest *d2i_TimeStampRequest_bio(BIO *bp, TimeStampRequest **tsr); int main() { PKCS7_SIGNER_INFO *respSigner; BIO *dataFeedIn, *dataFilter; TimeStampRequest *request; OpenSSL_add_all_algorithms(); dataFilter=BIO_new(BIO_f_base64()); dataFeedIn=BIO_new_fp(stdin, BIO_NOCLOSE); dataFeedIn=BIO_push(dataFilter, dataFeedIn); request=d2i_TimeStampRequest_bio(dataFeedIn, NULL); /* If decoding was successful, request should be a pointer to a valid TimeStampRequest structure; otherwise, it should be NULL */ if (request==NULL) printf(Error\n); else printf(Success\n); return 0; } TimeStampRequest *d2i_TimeStampRequest_bio(BIO *bp, TimeStampRequest **tsr) { return ASN1_item_d2i_bio(ASN1_ITEM_rptr(TimeStampRequest), bp, tsr); } - Sample timestamp request -
Re: Man in the middle proxy - Not working
Hi Thanks for your valuable suggestion. I didn't understand some points which you described in the previous posting, may because of my lack of exposure to the socket technology. I have tried one more method to read the data from the socket, which was partially successful it is defined as follows do { dwReadDataLen = SSL_read(Serverssl,pBuff,iBufferSize); // Gets the data from the server side SSL_write(SourceSsl,pBuff,dwReadDataLen); // Writes the data back to the SSL } while(dwReadDataLen 0 ); By using this method I am able to read the content data from the server and put it back to my browser. But this method is not consistent though, Sometimes browse request will not get completed and also it takes lot of time complete one browse request - Replies and quires to the previous posting For a socket used with openssl directly, I believe OVERLAPPED will be ignored and is of no use. I think you would have to do your own 'physical' level either as your own BIO type or as a BIO_pair looping back to your code (the more usual way). Frankly I don't think you're anywhere near ready for that. I didn't understand about this, Can you describe this in more detail, Sorry for that I am new to this technology You should check for error (=0) and report/handle it. Error on _write especially initial is not common, but if it ever happens, proceeding with other operations will likely cause much greater confusion. I have checked all the error codes of SSL functions in my application, I have posted only some code snippet to avoid junk data SSL_accept(Serverssl); This is useless. SSL_accept _creates_ a server-side endpoint; it is not applicable to a client-side endpoint. I have removed this from my application Also, the data read by SSL_read (like POSIX read or C fread) does not get a null terminator byte added, so outputting pBuff as a C-style string is likely to append garbage, especially on the second or more time through the loop. I have outputted the buffer only for indicative purpose. I have removed the code for outputting the buffer That's your problem. SSL_pending only indicates data _already received and buffered_ by OpenSSL but not yet read by the app. For responses more than one SSL record (max 32kbytes if I recall correctly, and server may choose less) AND (probably) more than the TCP window (varies but typically 2 MTU = about 3kbytes to start) there will be some time delay between receiving the first chunk of the data and the next, and the next and so on. } while(SSL_pending(Serverssl)); Instead of using the above condition I have opted for while(dwReadDataLen 0 ); By using this I was able to read the content data. For a waited/blocking socket, which is the default as you have here, you need to keep reading from the server (and in your case writing back to the client) until you've done all the data in the response. If you require, or the server chooses, HTTP/1.0 style conn-per-txn (also known as connection: close or not-keepalive or not-pipelined, and also not-chunked) you can just loop until you receive EOF (0) from SSL_read, caused by the server closing the connection. EOF (0) I am not sure about EOF(0), is that some thing similar to End Of File in C++; If you allow and the server uses HTTP/1.1 keep-alive (or pipelining) and/or chunked data, the situation can get quite a bit more complicated. See RFC 2616. If you use a nonblocking socket (which is supported on Windows as far as I know but is apparently not the same as OVERLAPPED) you can also do your own timeout -- that is, read until EOF or optionally calculated end of the response body, *or* timeout. Since HTTP servers will normally send a complete response within a short time (like at most a few seconds), and if one doesn't a person at a browser usually doesn't want to wait anyway, this can be a good simple compromise. Could you send me some code snippet using 'bio' in SSL, I have seen using 'bio' is some sample applications instead of Sockets Thanks, Raj Rajmohan SK - Original Message - From: Dave Thompson dthomp...@prinpay.com To: openssl-users@openssl.org Sent: Saturday, August 07, 2010 9:06 AM Subject: RE: Man in the middle proxy - Not working From: owner-openssl-us...@openssl.org On Behalf Of Raj Sent: Friday, 06 August, 2010 10:14 I was able to read the content data from the server using SSL_read and put back to the browser by using SSL_write. I don't know whether is a right approach or not. If you are doing an SSL connection to the server then SSL_write to and SSL_read from the server are correct. (And you should since the client is requesting SSL.) SSL_read from and SSL_write back to the client are correct if the client is SSL, and you said it is. For [an .ico] I got the response as follows and I was able to see the icon in my browser snip But for [a .png], which is 42,565 bytes long, I am receiving
Re: Basics concepts about openssl+rsa
Hello again. I'm reading these documents and I've seen that the IO struct for these is the BIO struct. My idea is do something like following (I've generated rsa_public.key with genrsa): $ openssl rsautl -encrypt -in legible_file -pubin -inkey rsa_public.key -out encrypted_file But in my program legible_file and encrypted_file are char[] strings. I'm looking at the EVP_PKEY_encrypt, but the EVP_PKEY_CTX type seems don't exist (I'm using openssl 0.9.8). I'm seeing some tutorials about openssl, but they are quite old (ten years is much time :-)). Are there more updated tutorials in the Internet? I've really liked openssl, but I don't know where to start. Is there a irc channel where users can talk? Regards 2010/8/17 Leandro Santiago leandrosansi...@gmail.com: Thx. I'll read these documents. In my system the keys aren't generated in instalation-time, but I have both the keys, private and public pre-generated. Actually in my system the password based encrypt system works fine, and it's part of a larger subsystem. So the rsa idea has sounded good for me :-) Regards 2010/8/17 Wim Lewis w...@omnigroup.com: On Aug 17, 2010, at 3:19 PM, Wim Lewis wrote: But for any real-world application, you'll want to do the standard business of generating a session key, encrypting the message using conventional symmetric encryption, and encrypting the session key with the public key. Since that's a lot of hassle and it's very easy to write something that works but isn't secure, it's probably a good idea to just adopt one of the higher level cryptographic containers such as CMS: http://www.openssl.org/docs/crypto/CMS_encrypt.html even though this does mean you start having to deal with all the X.509 crud. Ah, I forgot about http://www.openssl.org/docs/crypto/EVP_SealInit.html and friends, maybe that would be an easier approach. __ OpenSSL Project http://www.openssl.org User Support Mailing List openssl-us...@openssl.org Automated List Manager majord...@openssl.org __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Error: relocations based on the ABS44 coding model can not be used in building a shared object
Hi Tim, Thank you very much. I moved forward using your suggestion. But again Iam stuck at one point. (1) Iam facing problem in creating my specific .so. Iam having error: ld: fatal: relocation error: R_SPARC_H44: file ssl/s2_meth.o: symbolunknown: relocations based on the ABS44 coding model can not be used in building a shared object Iam using makefile: INCSO += -lsocket -lnsl -ldl -lkstat -lsunmath -lm CFLAGS = -xO4 -xarch=v9 -xcode=abs64 -G export CFLAGS LIB_SO = myown.so LIB_OBJS= ssl/s2_meth.o CC -xO4 -xarch=v9 -xcode=abs64 -KPIC -G -o $(LIB_SO) -DS_SUN -Qoption ld '-t' $(LIB_OBJS) $(INCSO) -lc Please show me the right direction to solve the issue. (2) Also please list me the .o file that need to be included in $(LIB_OBJS) to create .so that includes all the .o files included in libssl.so libcrypto.so. Actually I have to create my own specific .so that includes all the libraries included in libssl.so libcrypto.so. Thanks for your support. Waiting for response. Thanks Regards, Seemant Bisht. Alcatel Ph. No. +91-124-4133453 Mobile: +919810063317 Alcatel-Lucent India Building No.1, Fourth Floor, Seat No.59 Plot No.406, Udyog Vihar, Phase III Gurgaon 122016 P Think of the environmental impact before printing From: Tim Hudson [mailto:t...@cryptsoft.com] Sent: 18 August 2010 02:37 To: openssl-users@openssl.org Cc: BISHT, SEEMANT (SEEMANT) Subject: Re: wrong ELF class: ELFCLASS32 On 17/08/2010 7:03 PM, BISHT, SEEMANT (SEEMANT) wrote: Can you please tell me how to compile openssl library in 64-bit type? As when compiling the openssl, and checking If it was a linux intel based setup if would be: ./Configure linux-x86_64 or ./Configure linux-generic64 However given you seem to be on a sparc box: ./Configure solaris64-sparcv9-gcc or ./Configure solaris64-sparcv9-cc (depending on if you are using GCC or the Sun compiler) Look at the various targets available in the Configure script for more information. Then the usual make clean all Tim.
RE: Authenticode timestamp processing: error while parsing timestamp request
Thanks for your help, Jacob. Where can I find your signing tools? A quick Google search revealed no useful links. Alternatively, can you suggest me how to complete the original ASN.1 structures so as to add the explicit [0] tag? I have already searched the official OpenSSL documentation for some clues, but I have found nothing of interest (moreover, this is the first time I use the OpenSSL library in one of my projects). Thanks in advance, Alessandro Menti - Original structures - typedef struct { ASN1_OBJECT *type; ASN1_OCTET_STRING *data; } TimeStampContentInfo; typedef struct { ASN1_OBJECT *countersignatureType; TimeStampContentInfo *content; } TimeStampRequest; ASN1_SEQUENCE(TimeStampContentInfo) = { ASN1_SIMPLE(TimeStampContentInfo, type, ASN1_OBJECT), ASN1_EXP_OPT(TimeStampContentInfo, data, ASN1_OCTET_STRING, 0) } ASN1_SEQUENCE_END(TimeStampContentInfo) DECLARE_ASN1_FUNCTIONS(TimeStampRequest) ASN1_SEQUENCE(TimeStampRequest) = { ASN1_SIMPLE(TimeStampRequest, countersignatureType, ASN1_OBJECT), ASN1_SIMPLE(TimeStampRequest, content, TimeStampContentInfo) } ASN1_SEQUENCE_END(TimeStampRequest) IMPLEMENT_ASN1_FUNCTIONS(TimeStampRequest) __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: dynamic locks don't get cleaned up
any takers from the openssl team? true, false? known issue, user error? anything? On 10-08-17 04:23 PM, Jeff Saremi wrote: I apologize if this shows up more than once. I've been having problems sending emails out, all day. First I encountered this with valgrind but then I decided to have openssl print the leaks and it was also confirmed. I have reduced my code to the following two lines. Prior to this if course initilization of openssl and then the cleanup. Either there's a call that I'm missing or the the dynamic locks don't get cleaned up upon exit. Looking at the code in cryptlib.c, i don't see anywhere freeing up the memory allocated to the following stacks: static STACK_OF(OPENSSL_STRING) *app_locks=NULL; static STACK_OF(CRYPTO_dynlock) *dyn_locks=NULL; And here's my sample code: int l = CRYPTO_get_new_dynlockid(); CRYPTO_destroy_dynlockid(l); Before this I have a bunch of lines like: CRYPTO_malloc_debug_init(); CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); SSL_library_init(); OpenSSL_add_all_digests(); CRYPTO_set_id_callback(..); CRYPTO_set_locking_callback(...); CRYPTO_set_dynlock_create_callback(...); CRYPTO_set_dynlock_lock_callback(...); CRYPTO_set_dynlock_destroy_callback(...); And at the end of the code I have something like: CRYPTO_set_id_callback(NULL); CRYPTO_set_locking_callback(NULL); CRYPTO_set_dynlock_create_callback(NULL); CRYPTO_set_dynlock_lock_callback(NULL); CRYPTO_set_dynlock_destroy_callback(NULL); ENGINE_cleanup(); EVP_cleanup(); CRYPTO_cleanup_all_ex_data(); ERR_free_strings(); OBJ_NAME_cleanup(-1); ERR_remove_thread_state(NULL); SSL_free_comp_methods(); CRYPTO_mem_leaks_fp(stderr); As you can see I have included every cleanup call I could find. Running the code produces the following output: [19:49:10] 188 file=stack.c, line=125, thread=19596, number=20, address=08DF0E50 [19:49:10] 189 file=stack.c, line=127, thread=19596, number=16, address=08DF0F78 36 bytes leaked in 2 chunks __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
RE: Man in the middle proxy - Not working
Raj wrote: I have tried one more method to read the data from the socket, which was partially successful it is defined as follows do { dwReadDataLen = SSL_read(Serverssl,pBuff,iBufferSize); // Gets the data from the server side SSL_write(SourceSsl,pBuff,dwReadDataLen); // Writes the data back to the SSL } while(dwReadDataLen 0 ); This is the basic idea of how you proxy, but it can't work for a general HTTP proxy. For one thing, it assumes the end of a reply is marked by the close of a connection. This is true for some HTTP requests, but it's not true in general. You can write a proxy two different ways: 1) You can understand the protocol you are parsing and know when it changes directions. Based on this understanding, you can switch from proxying in one direction to proxying in the other. 2) You can avoid having to understand the protocol you are parsing. But in this case, you will not know which side is supposed to send data next, so you must always be ready to proxy in either direction. It seems you do neither of these two things. You try to proxy in only one direction at a time but you don't track the protocol. How do you even know when you've sent the entire request and can even enter this loop? How do you know when you've read the entire reply and can begin reading the next request? Your test condition, 'dwReadDataLen0' will be true so long as the connection is healthy. It will typically remain healthy even when the reply has been fully sent. DS __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org