I have the following program that runs without error but for
some reason appears to write a truncated or invalid signed message:

--

#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 (int argc, char *argv[])
{
  const char *signer;
  const char *inkey;
  X509 *cert;
  EVP_PKEY *key;
  BIO *in;
  BIO *mem_buf;
  PKCS7 *message;

  if (argc < 3) return 112;

  signer = argv[1];
  inkey = argv[2];

  /* 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");
  mem_buf = BIO_new (BIO_s_mem());
  if (!mem_buf) die ("BIO_new");

  OpenSSL_add_all_algorithms ();

  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);
  if (!message) die ("PKCS7_sign");

  info ("writing signed message");
  if (!i2d_PKCS7_bio (mem_buf, message)) die ("i2d_PKCS7_bio");

  {
    char *data;
    int size = BIO_get_mem_data (mem_buf, &data);
    printf ("%s", data);
    size = 0; /* unused var warning */
  }
  return 0;
}

--

The following script essentially just parses the message, without
attempting to verify:

#!/bin/sh
# verify.sh
exec openssl smime -verify -inform der -noverify

When combined with my program:

$ echo hello | ./sign2 test.cert test.key | ./verify.sh
info: setting up streams
info: loading private key
info: loading certificate
info: signing message
info: writing signed message
Error reading S/MIME message
78815:error:0D06B08E:asn1 encoding routines:ASN1_d2i_bio:not enough 
data:/usr/src/secure/lib/libcrypto/../../../crypto/openssl/crypto/asn1/a_d2i_fp.c:240:

What am I doing wrong here?

Any help would be appreciated.
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           majord...@openssl.org

Reply via email to