// generate EC signature // // Sign UserID input // will read files: UserID.der, input // will create file: input.sig // #include #include #include #include #include #include #include void error( const char *msg) { fprintf( stderr, "sign: %s\n", msg); exit(1); } int main( int argc, char *argv[]) { if( argc != 3) error( "Usage: sign UserID input"); BIO *bio_err; if( (bio_err=BIO_new(BIO_s_file())) != NULL) BIO_set_fp( bio_err, stderr, BIO_NOCLOSE|BIO_FP_TEXT); // read private key // char fname[BUFSIZ]; strcat( strcpy( fname, argv[1]), ".der"); BIO *priv = BIO_new(BIO_s_file()); if( BIO_read_filename( priv, fname) <= 0) { perror( fname); error( "BIO_read_filename() failed"); } EC_KEY *eckey = d2i_ECPrivateKey_bio( priv, NULL); BIO_free( priv); if (eckey == NULL) { ERR_print_errors( bio_err); error( "unable to load private key"); } // create a digest context and initialize it // EVP_MD_CTX *ctx = EVP_MD_CTX_create(); if( EVP_DigestInit_ex( ctx, EVP_sha256(), NULL) != 1) error( "EVP_DigestInit_ex() failed"); // stick bytes into the digest // unsigned char buf[BUFSIZ]; int nbytes; FILE *fp = fopen( argv[2], "r"); if( fp == NULL) { perror( argv[2]); error( "can't open input data file"); } while( (nbytes = fread( buf, 1, BUFSIZ, fp)) > 0) EVP_DigestUpdate( ctx, buf, nbytes); fclose( fp); // finish digest and clean up // unsigned char md[EVP_MAX_MD_SIZE]; unsigned int mdlen; EVP_DigestFinal_ex( ctx, md, &mdlen); EVP_MD_CTX_destroy( ctx); // display digest // // printf( "sha256: "); // for( int i = 0; i < mdlen; ++i) // printf("%02x", md[i]); // printf("\n"); printf( "Signing %s using %s\n", argv[2], fname); // sign // // Also see ECDSA_sign_setup() and ECDSA_sign_ex() for efficiency, // and PKCS7_sign() for compatibility // unsigned int siglen = ECDSA_size( eckey); unsigned char *sig = OPENSSL_malloc( siglen); if( !ECDSA_sign( 0, md, mdlen, sig, &siglen, eckey)) { ERR_print_errors( bio_err); error( "ECDSA_sign failed"); } strcat( strcpy( fname, argv[2]), ".sig"); fp = fopen( fname, "w"); if( fp == NULL) { perror( fname); error( "can't open signature output file"); } fwrite( sig, siglen, 1, fp); fclose( fp); return 0; }