I have the following program:

#include <err.h>
#include <stdio.h>

#include <openssl/bio.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/evp.h>
#include <openssl/x509.h>

static void
info (const char *str)
{
  fprintf (stderr, "info: %s\n", str);
}

static void
die_core (const char *func1, const char *func2)
{
  unsigned long code;

  for (;;) {
    code = ERR_get_error ();
    if (!code) break;
    warnx ("%s: %s: %s", func1, func2, ERR_error_string (code, NULL));
  }
  exit (112);
}

#define die(s) die_core(__func__, s)

static X509 *
load_cert (const char *file)
{
  BIO *bio;
  X509 *cert;

  bio = BIO_new (BIO_s_file ());
  if (!bio) die ("BIO_new");
  if (BIO_read_filename (bio, file) <= 0) die ("BIO_read_filename");

  cert = PEM_read_bio_X509 (bio, NULL, NULL, NULL);
  if (!cert) die ("PEM_read_bio_X509");

  BIO_free (bio);
  return cert;
}

static EVP_PKEY *
load_key (const char *file)
{
  BIO *bio;
  EVP_PKEY *key;

  bio = BIO_new (BIO_s_file ());
  if (!bio) die ("BIO_new");
  if (BIO_read_filename (bio, file) <= 0) die ("BIO_read_filename");

  key = PEM_read_bio_PrivateKey (bio, NULL, NULL, NULL);
  if (!key) die ("PEM_read_bio_PrivateKey");

  BIO_free (bio);
  return key;
}

int
main (void)
{
  const EVP_CIPHER *cipher = NULL;
  const char *signer = "moi.cert";
  const char *inkey = "moi.key";
  X509 *cert;
  EVP_PKEY *key;
  BIO *in;
  BIO *out;
  PKCS7 *message;

  /* get meaningful error messages */
  ERR_load_crypto_strings();

  info ("setting up streams");

  in = BIO_new_fp (stdin, BIO_NOCLOSE);
  if (!in) die ("BIO_new_fp");
  out = BIO_new_fp (stdout, BIO_NOCLOSE);
  if (!out) die ("BIO_new_fp");

  info ("loading cipher");

  cipher = EVP_des_ede3_cbc();
  if (!cipher) die ("EVP_des_ede3_cbc");

  info ("loading private key");
  key  = load_key (inkey);

  info ("loading certificate");
  cert = load_cert (signer);

  info ("signing message");
  message = PKCS7_sign (cert, key, NULL, in, PKCS7_BINARY);

  info ("writing signed message");
  PEM_write_bio_PKCS7 (out, message);

  return 0;
}

For some reason, data is never read from stdin (*in):

$ echo 'something' | ./sign
info: setting up streams
info: loading cipher
info: loading private key
info: loading certificate
info: signing message
info: writing signed message
-----BEGIN PKCS7-----
-----END PKCS7-----

Tracing the process with ktrace confirms no data is ever read from the
first fd:

$ echo 'something' | ktrace ./sign >/dev/null 2>&1
$ kdump | grep something

What have I done wrong here? I can't see what smime.c in the standard
distribution does any differently (that's what my code is based on).

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [email protected]
Automated List Manager                           [email protected]

Reply via email to