コード例 #1
0
ファイル: PKey.cpp プロジェクト: CheneyWong/fibjs
result_t PKey::sign(Buffer_base *data, obj_ptr<Buffer_base> &retVal,
                    exlib::AsyncEvent *ac)
{
    if (switchToAsync(ac))
        return CHECK_ERROR(CALL_E_NOSYNC);

    result_t hr;
    bool priv;

    hr = isPrivate(priv);
    if (hr < 0)
        return hr;

    if (!priv)
        return CHECK_ERROR(CALL_E_INVALID_CALL);

    int ret;
    std::string str;
    std::string output;
    size_t olen;

    data->toString(str);
    output.resize(POLARSSL_PREMASTER_SIZE);

    ret = pk_sign(&m_key, POLARSSL_MD_NONE,
                  (const unsigned char *)str.c_str(), str.length(),
                  (unsigned char *)&output[0], &olen,
                  ctr_drbg_random, &g_ssl.ctr_drbg);
    if (ret != 0)
        return CHECK_ERROR(_ssl::setError(ret));

    output.resize(olen);
    retVal = new Buffer(output);

    return 0;
}
コード例 #2
0
ファイル: pkblocker.c プロジェクト: smorin/libpagekite
int pkb_update_dns(struct pk_manager* pkm)
{
  int j, len, bogus, rlen;
  struct pk_tunnel* fe_list[1024]; /* Magic, bounded by address_list[] below */
  struct pk_tunnel** fes;
  struct pk_tunnel* fe;
  struct pk_pagekite* kite;
  char printip[128], get_result[10240], *result, *lastup;
  char address_list[1024], payload[2048], signature[2048], url[2048], *alp;

  PK_TRACE_FUNCTION;

  if (time(0) < pkm->last_dns_update + PK_DDNS_UPDATE_INTERVAL_MIN)
    return 0;

  address_list[0] = '\0';
  alp = address_list;

  fes = fe_list;
  *fes = NULL;

  bogus = 0;
  for (j = 0, fe = pkm->tunnels; j < pkm->tunnel_max; j++, fe++) {
    if (fe->ai.ai_addr && fe->fe_hostname && (fe->conn.sockfd >= 0)) {
      if (fe->conn.status & FE_STATUS_WANTED) {
        if (NULL != in_ipaddr_to_str(fe->ai.ai_addr, printip, 128)) {
          len = strlen(printip);
          if (len < 1000-(alp-address_list)) {
            if (alp != address_list) *alp++ = ',';
            strcpy(alp, printip);
            alp += len;
            *fes++ = fe;
            *fes = NULL;
          }
        }
        if (!(fe->conn.status & FE_STATUS_IN_DNS) || pk_state.force_update)
          bogus++;
      }
      else /* Stuff in DNS that shouldn't be also triggers updates */
        if (fe->conn.status & FE_STATUS_IN_DNS) bogus++;
    }
  }
  PK_CHECK_MEMORY_CANARIES;
  if (!bogus) return 0;
  if (!address_list[0]) return 0;

  bogus = 0;
  lastup = "";
  for (j = 0, kite = pkm->kites; j < pkm->kite_max; kite++, j++) {
    if ((kite->protocol[0] != '\0') &&
        (0 != strcasecmp(lastup, kite->public_domain))) {
      PKS_STATE(pkm->status = PK_STATUS_UPDATING_DNS);
      sprintf(payload, "%s:%s", kite->public_domain, address_list);
      pk_sign(NULL, kite->auth_secret, payload, 100, signature);

      sprintf(url, pkm->dynamic_dns_url,
              kite->public_domain, address_list, signature);
      rlen = http_get(url, get_result, 10240);

      if (rlen < 1) {
        pk_log(PK_LOG_MANAGER_ERROR, "DDNS: No response from %s", url);
        bogus++;
      }
      else {
        lastup = kite->public_domain;
        result = skip_http_header(rlen, get_result);
        if ((strncasecmp(result, "nochg", 5) == 0) ||
            (strncasecmp(result, "good", 4) == 0)) {
          pk_log(PK_LOG_MANAGER_INFO, "DDNS: Update OK, %s=%s",
                                      kite->public_domain, address_list);
          for (fes = fe_list; *fes; fes++) {
            (*fes)->last_ddnsup = time(0);
            (*fes)->conn.status |= FE_STATUS_IN_DNS;
          }
        }
        else {
          result[7] = '\0';
          pk_log(PK_LOG_MANAGER_ERROR, "DDNS: Update failed for %s (%s -> %s)",
                                       kite->public_domain, url, result);
          bogus++;
        }
      }
    }
  }

  pkm->last_dns_update = time(0);
  PK_CHECK_MEMORY_CANARIES;
  return bogus;
}
コード例 #3
0
ファイル: pk_sign.c プロジェクト: randombit/hacrypto
int main( int argc, char *argv[] )
{
    FILE *f;
    int ret = 1;
    pk_context pk;
    entropy_context entropy;
    ctr_drbg_context ctr_drbg;
    unsigned char hash[20];
    unsigned char buf[POLARSSL_MPI_MAX_SIZE];
    char filename[512];
    const char *pers = "pk_sign";
    size_t olen = 0;

    entropy_init( &entropy );
    pk_init( &pk );

    if( argc != 3 )
    {
        polarssl_printf( "usage: pk_sign <key_file> <filename>\n" );

#if defined(_WIN32)
        polarssl_printf( "\n" );
#endif

        goto exit;
    }

    polarssl_printf( "\n  . Seeding the random number generator..." );
    fflush( stdout );

    if( ( ret = ctr_drbg_init( &ctr_drbg, entropy_func, &entropy,
                               (const unsigned char *) pers,
                               strlen( pers ) ) ) != 0 )
    {
        polarssl_printf( " failed\n  ! ctr_drbg_init returned -0x%04x\n", -ret );
        goto exit;
    }

    polarssl_printf( "\n  . Reading private key from '%s'", argv[1] );
    fflush( stdout );

    if( ( ret = pk_parse_keyfile( &pk, argv[1], "" ) ) != 0 )
    {
        ret = 1;
        polarssl_printf( " failed\n  ! Could not open '%s'\n", argv[1] );
        goto exit;
    }

    /*
     * Compute the SHA-1 hash of the input file,
     * then calculate the signature of the hash.
     */
    polarssl_printf( "\n  . Generating the SHA-1 signature" );
    fflush( stdout );

    if( ( ret = sha1_file( argv[2], hash ) ) != 0 )
    {
        polarssl_printf( " failed\n  ! Could not open or read %s\n\n", argv[2] );
        goto exit;
    }

    if( ( ret = pk_sign( &pk, POLARSSL_MD_SHA1, hash, 0, buf, &olen,
                         ctr_drbg_random, &ctr_drbg ) ) != 0 )
    {
        polarssl_printf( " failed\n  ! pk_sign returned -0x%04x\n", -ret );
        goto exit;
    }

    /*
     * Write the signature into <filename>-sig.txt
     */
    snprintf( filename, sizeof(filename), "%s.sig", argv[2] );

    if( ( f = fopen( filename, "wb+" ) ) == NULL )
    {
        ret = 1;
        polarssl_printf( " failed\n  ! Could not create %s\n\n", filename );
        goto exit;
    }

    if( fwrite( buf, 1, olen, f ) != olen )
    {
        polarssl_printf( "failed\n  ! fwrite failed\n\n" );
        goto exit;
    }

    fclose( f );

    polarssl_printf( "\n  . Done (created \"%s\")\n\n", filename );

exit:
    pk_free( &pk );
    ctr_drbg_free( &ctr_drbg );
    entropy_free( &entropy );

#if defined(POLARSSL_ERROR_C)
    polarssl_strerror( ret, (char *) buf, sizeof(buf) );
    polarssl_printf( "  !  Last error was: %s\n", buf );
#endif

#if defined(_WIN32)
    polarssl_printf( "  + Press Enter to exit this program.\n" );
    fflush( stdout );
    getchar();
#endif

    return( ret );
}
コード例 #4
0
ファイル: x509write_csr.c プロジェクト: RuralHunter/showtime
int x509write_csr_der( x509write_csr *ctx, unsigned char *buf, size_t size,
                       int (*f_rng)(void *, unsigned char *, size_t),
                       void *p_rng )
{
    int ret;
    const char *sig_oid;
    size_t sig_oid_len = 0;
    unsigned char *c, *c2;
    unsigned char hash[64];
    unsigned char sig[POLARSSL_MPI_MAX_SIZE];
    unsigned char tmp_buf[2048];
    size_t pub_len = 0, sig_and_oid_len = 0, sig_len;
    size_t len = 0;
    pk_type_t pk_alg;

    /*
     * Prepare data to be signed in tmp_buf
     */
    c = tmp_buf + sizeof( tmp_buf );

    ASN1_CHK_ADD( len, x509_write_extensions( &c, tmp_buf, ctx->extensions ) );

    if( len )
    {
        ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
        ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED |
                                                        ASN1_SEQUENCE ) );

        ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
        ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED |
                                                        ASN1_SET ) );

        ASN1_CHK_ADD( len, asn1_write_oid( &c, tmp_buf, OID_PKCS9_CSR_EXT_REQ,
                                          OID_SIZE( OID_PKCS9_CSR_EXT_REQ ) ) );

        ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
        ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED |
                                                        ASN1_SEQUENCE ) );
    }

    ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
    ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED |
                                                    ASN1_CONTEXT_SPECIFIC ) );

    ASN1_CHK_ADD( pub_len, pk_write_pubkey_der( ctx->key,
                                                tmp_buf, c - tmp_buf ) );
    c -= pub_len;
    len += pub_len;

    /*
     *  Subject  ::=  Name
     */
    ASN1_CHK_ADD( len, x509_write_names( &c, tmp_buf, ctx->subject ) );

    /*
     *  Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
     */
    ASN1_CHK_ADD( len, asn1_write_int( &c, tmp_buf, 0 ) );

    ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
    ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED |
                                                    ASN1_SEQUENCE ) );

    /*
     * Prepare signature
     */
    md( md_info_from_type( ctx->md_alg ), c, len, hash );

    if( ( ret = pk_sign( ctx->key, ctx->md_alg, hash, 0, sig, &sig_len,
                         f_rng, p_rng ) ) != 0 )
    {
        return( ret );
    }

    if( pk_can_do( ctx->key, POLARSSL_PK_RSA ) )
        pk_alg = POLARSSL_PK_RSA;
    else if( pk_can_do( ctx->key, POLARSSL_PK_ECDSA ) )
        pk_alg = POLARSSL_PK_ECDSA;
    else
        return( POLARSSL_ERR_X509_INVALID_ALG );

    if( ( ret = oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg,
                                        &sig_oid, &sig_oid_len ) ) != 0 )
    {
        return( ret );
    }

    /*
     * Write data to output buffer
     */
    c2 = buf + size;
    ASN1_CHK_ADD( sig_and_oid_len, x509_write_sig( &c2, buf,
                                        sig_oid, sig_oid_len, sig, sig_len ) );

    if( len > (size_t)( c2 - buf ) )
        return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );

    c2 -= len;
    memcpy( c2, c, len );

    len += sig_and_oid_len;
    ASN1_CHK_ADD( len, asn1_write_len( &c2, buf, len ) );
    ASN1_CHK_ADD( len, asn1_write_tag( &c2, buf, ASN1_CONSTRUCTED |
                                                 ASN1_SEQUENCE ) );

    return( (int) len );
}
コード例 #5
0
void attacker_send_asym_signature(havege_state *havege_state, void* socket)
  //@ requires attacker_invariant(?pub, ?pred, ?kc, havege_state, socket, ?attacker);
  //@ ensures  attacker_invariant(pub, pred, kc, havege_state, socket, attacker);
{
  int temp;
  int size1;
  int size2;
  unsigned int osize;
  char buffer1[MAX_MESSAGE_SIZE];
  char buffer2[MAX_MESSAGE_SIZE];
  char buffer3[MAX_MESSAGE_SIZE];
  pk_context context;

  //@ open attacker_invariant(pub, pred, kc, havege_state, socket, attacker);

  size1 = net_recv(socket, buffer1, MAX_MESSAGE_SIZE);
  size2 = net_recv(socket, buffer2, MAX_MESSAGE_SIZE);
  if (size1 <= 0 || size2 < MINIMAL_STRING_SIZE)
  {
    //@ close attacker_invariant(pub, pred, kc, havege_state, socket, attacker);
    return;
  }

  //@ close pk_context(&context);
  pk_init(&context);
  //@ interpret_private_key(buffer1, size1);
  //@ assert cryptogram(buffer1, size1, ?ccs1, ?cg_key);
  //@ assert cg_key == cg_private_key(?p, ?c);
  if (pk_parse_key(&context, buffer1, (unsigned int) size1, NULL, 0) == 0)
  {
    if (size2 * 8 < size1)
    {
      //@ close random_state_predicate(havege_state_initialized);
      /*@ produce_function_pointer_chunk random_function(
                  attacker_key_item_havege_random_stub)
                  (havege_state_initialized)(state, out, len) { call(); } @*/
      //@ chars_to_crypto_chars(buffer2, size2);
      if (pk_sign(&context, POLARSSL_MD_NONE, buffer2, (unsigned int) size2,
                  buffer3, &osize, attacker_key_item_havege_random_stub,
                  havege_state) == 0)
      {
        /*@
          {
            assert u_integer(&osize, ?osize_val);
            assert cryptogram(buffer3, osize_val, ?ccs_enc, ?cg_sig);
            assert cg_sig == cg_asym_signature(p, c, ?cs2, _);
            assert is_public_asym_signature_is_public(?proof, pub, pred);
            crypto_chars_to_chars(buffer2, size2);
            public_chars(buffer2, size2);
            proof(cg_sig);
            public_cryptogram(buffer3, cg_sig);
            chars_to_crypto_chars(buffer2, size2);
          }
        @*/
        net_send(socket, buffer3, osize);
      }
      //@ crypto_chars_to_chars(buffer2, size2);
    }
    //@ pk_release_context_with_key(&context);
  }
  pk_free(&context);
  //@ open pk_context(&context);
  //@ close attacker_invariant(pub, pred, kc, havege_state, socket, attacker);
  //@ public_cryptogram(buffer1, cg_key);
}
コード例 #6
0
ファイル: x509write_crt.c プロジェクト: Chiri23/dolphin
int x509write_crt_der( x509write_cert *ctx, unsigned char *buf, size_t size,
                       int (*f_rng)(void *, unsigned char *, size_t),
                       void *p_rng )
{
    int ret;
    const char *sig_oid;
    size_t sig_oid_len = 0;
    unsigned char *c, *c2;
    unsigned char hash[64];
    unsigned char sig[POLARSSL_MPI_MAX_SIZE];
    unsigned char tmp_buf[2048];
    size_t sub_len = 0, pub_len = 0, sig_and_oid_len = 0, sig_len;
    size_t len = 0;
    pk_type_t pk_alg;

    /*
     * Prepare data to be signed in tmp_buf
     */
    c = tmp_buf + sizeof( tmp_buf );

    /* Signature algorithm needed in TBS, and later for actual signature */
    pk_alg = pk_get_type( ctx->issuer_key );
    if( pk_alg == POLARSSL_PK_ECKEY )
        pk_alg = POLARSSL_PK_ECDSA;

    if( ( ret = oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg,
                                        &sig_oid, &sig_oid_len ) ) != 0 )
    {
        return( ret );
    }

    /*
     *  Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension
     */
    ASN1_CHK_ADD( len, x509_write_extensions( &c, tmp_buf, ctx->extensions ) );
    ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
    ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
    ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
    ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 3 ) );

    /*
     *  SubjectPublicKeyInfo
     */
    ASN1_CHK_ADD( pub_len, pk_write_pubkey_der( ctx->subject_key,
                                                tmp_buf, c - tmp_buf ) );
    c -= pub_len;
    len += pub_len;

    /*
     *  Subject  ::=  Name
     */
    ASN1_CHK_ADD( len, x509_write_names( &c, tmp_buf, ctx->subject ) );

    /*
     *  Validity ::= SEQUENCE {
     *       notBefore      Time,
     *       notAfter       Time }
     */
    sub_len = 0;

    ASN1_CHK_ADD( sub_len, x509_write_time( &c, tmp_buf, ctx->not_after,
                                            X509_RFC5280_UTC_TIME_LEN ) );

    ASN1_CHK_ADD( sub_len, x509_write_time( &c, tmp_buf, ctx->not_before,
                                            X509_RFC5280_UTC_TIME_LEN ) );

    len += sub_len;
    ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, sub_len ) );
    ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );

    /*
     *  Issuer  ::=  Name
     */
    ASN1_CHK_ADD( len, x509_write_names( &c, tmp_buf, ctx->issuer ) );

    /*
     *  Signature   ::=  AlgorithmIdentifier
     */
    ASN1_CHK_ADD( len, asn1_write_algorithm_identifier( &c, tmp_buf,
                       sig_oid, strlen( sig_oid ), 0 ) );

    /*
     *  Serial   ::=  INTEGER
     */
    ASN1_CHK_ADD( len, asn1_write_mpi( &c, tmp_buf, &ctx->serial ) );

    /*
     *  Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
     */
    sub_len = 0;
    ASN1_CHK_ADD( sub_len, asn1_write_int( &c, tmp_buf, ctx->version ) );
    len += sub_len;
    ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, sub_len ) );
    ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) );

    ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
    ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );

    /*
     * Make signature
     */
    md( md_info_from_type( ctx->md_alg ), c, len, hash );

    if( ( ret = pk_sign( ctx->issuer_key, ctx->md_alg, hash, 0, sig, &sig_len,
                         f_rng, p_rng ) ) != 0 )
    {
        return( ret );
    }

    /*
     * Write data to output buffer
     */
    c2 = buf + size;
    ASN1_CHK_ADD( sig_and_oid_len, x509_write_sig( &c2, buf,
                                        sig_oid, sig_oid_len, sig, sig_len ) );

    c2 -= len;
    memcpy( c2, c, len );

    len += sig_and_oid_len;
    ASN1_CHK_ADD( len, asn1_write_len( &c2, buf, len ) );
    ASN1_CHK_ADD( len, asn1_write_tag( &c2, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );

    return( (int) len );
}
コード例 #7
0
struct item *asymmetric_signature(struct item *key, struct item *payload)
  /*@ requires [?f]world(?pub, ?key_clsfy) &*&
               principal(?principal1, ?count1) &*&
               item(payload, ?pay, pub) &*& item(key, ?k, pub) &*&
               k == private_key_item(?principal2, ?count2); @*/
  /*@ ensures  [f]world(pub, key_clsfy) &*&
               principal(principal1, count1 + 1) &*&
               item(payload, pay, pub) &*& item(key, k, pub) &*&
               item(result, ?sig, pub) &*&
               col ? true :
                 sig == asymmetric_signature_item(principal2, count2,
                                                  some(pay), ?ent); @*/
{
  debug_print("ASYM SIGNING:\n");
  print_item(payload);

  struct item* result;
  result = malloc(sizeof(struct item));
  if (result == 0) abort_crypto_lib("Malloc failed");

  debug_print("signing item\n");
  print_item(payload);
  print_item(key);

  {
    pk_context context;
    unsigned int olen;
    char* output;

    // Key
    //@ close pk_context(&context);
    //@ open [f]world(pub, key_clsfy);
    pk_init(&context);
    //@ close [f]world(pub, key_clsfy);
    set_private_key(&context, key);
    //@ open [f]world(pub, key_clsfy);
    /*@ assert pk_context_with_key(&context, pk_private,
                                   ?principal, ?count, RSA_BIT_KEY_SIZE); @*/
    //@ assert col || principal == principal2;
    //@ assert col || count == count2;

    // Payload
    //@ open item(payload, pay, pub);
    //@ open [_]item_constraints(pay, ?pay_cs, pub);
    //@ assert payload->content |-> ?p_cont &*& payload->size |-> ?p_size;
    if (payload->size > RSA_KEY_SIZE)
      abort_crypto_lib("Assymetric signing failed: incorrect size");
    output = malloc(RSA_KEY_SIZE);
    if (output == 0) abort_crypto_lib("Malloc failed");

    void *random_state = nonces_expose_state();
    //@ close random_state_predicate(havege_state_initialized);
    /*@ produce_function_pointer_chunk random_function(
                      asym_sig_havege_random_stub)
                     (havege_state_initialized)(state, out, len) { call(); } @*/
    //@ open principal(principal1, count1);
    if(pk_sign(&context, POLARSSL_MD_NONE,
               payload->content, (unsigned int) payload->size,
               output, &olen,
               asym_sig_havege_random_stub, random_state) != 0)
      abort_crypto_lib("Signing failed");
    //@ open principal(principal1, count1 + 1);
    //@ open cryptogram(output, ?sig_length, ?sig_cs, ?sig_cg);
    //@ assert sig_cg == cg_asym_signature(principal, count, pay_cs, ?ent);
    //@ assert u_integer(&olen, sig_length);
    //@ assert sig_length > 0 &*& sig_length <= RSA_KEY_SIZE;
    nonces_hide_state(random_state);
    //@ pk_release_context_with_key(&context);
    pk_free(&context);
    //@ open pk_context(&context);
    //@ close [f]world(pub, key_clsfy);
    debug_print("signed item\n");
    print_buffer(output, (int) olen);

    // Create item
    if (olen < MINIMAL_STRING_SIZE)
      abort_crypto_lib("Assymetric signing failed: output to small");
    result->size = TAG_LENGTH + (int) olen;
    result->content = malloc(result->size);
    if (result->content == 0) {abort_crypto_lib("Malloc failed");}
    write_tag(result->content, TAG_ASYMMETRIC_SIG);
    //@ assert result->content |-> ?cont &*& result->size |-> ?size;
    //@ assert chars(cont, TAG_LENGTH, ?tag_cs);
    //@ assert tag_cs == full_tag(TAG_ASYMMETRIC_SIG);
    //@ public_chars(cont, TAG_LENGTH);
    //@ chars_to_secret_crypto_chars(cont, TAG_LENGTH);
    memcpy(result->content + TAG_LENGTH, output, olen);

    //@ crypto_chars_join(cont);
    //@ list<char> cs = append(tag_cs, sig_cs);
    //@ assert crypto_chars(secret, cont, size, cs);

    //@ item e = asymmetric_signature_item(principal, count, some(pay), ent);
    //@ close ic_cg(e)(sig_cs, sig_cg);
    /*@ if (col)
        {
          public_chars(cont, size);
          public_generated_split(polarssl_pub(pub), cs, TAG_LENGTH);
        }
    @*/
    //@ close item(payload, pay, pub);
    zeroize(output, (int) olen);
    //@ chars_join(output);
    free(output);
    //@ WELL_FORMED(tag_cs, sig_cs, TAG_ASYMMETRIC_SIG)
    //@ close ic_parts(e)(tag_cs, sig_cs);
    //@ close well_formed_item_chars(e)(pay_cs);
    //@ leak well_formed_item_chars(e)(pay_cs);
    //@ close item_constraints(e, cs, pub);
    //@ leak item_constraints(e, cs, pub);
    //@ close item(result, e, pub);
  }
  debug_print("SINGING RESULT:\n");
  print_item(result);

  return result;
}