On Wed, Dec 31, 2003, Griff Miller wrote:

> I sent this on the 23rd, but I haven't seen it show up yet in the archives.
> Perhaps I have to actually be a member of the list to post (though the
> information at http://www.openssl.org/support/ suggests otherwise) .
> I just subscribed, and am posting again. So please forgive me if this
> crops up twice.
> 
> ...
> 
> I am trying to implement a simple software license key scheme. The idea is
> to prevent the program in question from running unless an authentic license
> file is present.
> 
> To ensure that the license file is authentic, I want to digitally sign it
> with a private key. Then, of course, the application that reads the license
> file must verify it with the public key.
> 
> Instead of using the openssl command via system(), popen(), or within a
> wrapper script around my application (because that would be too easily
> hacked) I want to put the signature verification code right into my
> program's source. So I intend to insert the necessary calls to functions
> in libcrypto.a into my source. Of course, this is still hackable by anyone
> with a disassembler, but less so.
> 
> Reading the docs, it looks like I need to call RSA_verify .  That seems
> easy enough, but it's getting set up to call RSA_verify that's slowing me
> down. I don't know how to assemble the inputs to the function (indeed,
> the RSA_verify manpage doesn't make it clear which args are input and
> which are outputs).
> 
> I tried loading openssl into a debugger, and stepping through the code to
> see what it does. One of the things it does that seems essential is to call
> load_pubkey - but this seems to be a private interface. Hmm.
> 
> So, instead of me floundering around trying to figure out how to do this,
> I was hoping that some kind soul could provide an example that I could work
> off of. Can anyone help? It's step 5 of the procedure below that I am
> trying to incorporate into my executable:
> 
> 1) Set umask:
> 
>    umask 077
> 
> 2) Create private key:
> 
>    openssl genrsa -des3 -out privkey.pem 2048
> 
> 3) Extract the public key:
> 
>    openssl rsa -in privkey.pem -pubout -out pubkey.pem
> 
> 4) Sign a file:
> 
>    openssl rsautl -sign -in /etc/hosts -inkey privkey.pem -out hosts.sig
> 
> 5) Verify a file:
> 
>    openssl rsautl -verify -in hosts.sig -pubin -inkey pubkey.pem
> 

As you've no doubt realised such license schemes are not very secure. A few
well placed NOPs will circumvent many of them. Equally replacing the public
key with a known one would also work. The code can be obfuscated and called at
various times but it is at best security by obscurity.

If you really want to do things that way then you should sign a digest using
the documented EVP_Sign*() functions. The "dgst" command can use them for
signing.

As for step 5 well this is just loading a public key into a EVP_PKEY
structure. This has been asked and answered several times. In outline:

1. Convert public key to DER.
2. Convert binary DER file to a C structure using xxd.
3. Convert public key to EVP_PKEY structure using d2i_PUBKEY().

Steve.
--
Dr Stephen N. Henson. Email, S/MIME and PGP keys: see homepage
OpenSSL project core developer and freelance consultant.
Funding needed! Details on homepage.
Homepage: http://www.drh-consultancy.demon.co.uk
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [EMAIL PROTECTED]
Automated List Manager                           [EMAIL PROTECTED]

Reply via email to