/* Same as make_canon_sexp but pad the buffer to multiple of 64 bits. If SECURE is set, secure memory will be allocated. */ gpg_error_t make_canon_sexp_pad (gcry_sexp_t sexp, int secure, unsigned char **r_buffer, size_t *r_buflen) { size_t len; unsigned char *buf; *r_buffer = NULL; if (r_buflen) *r_buflen = 0;; len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_CANON, NULL, 0); if (!len) return gpg_error (GPG_ERR_BUG); len += (8 - len % 8) % 8; buf = secure? xtrycalloc_secure (1, len) : xtrycalloc (1, len); if (!buf) return gpg_error_from_syserror (); if (!gcry_sexp_sprint (sexp, GCRYSEXP_FMT_CANON, buf, len)) return gpg_error (GPG_ERR_BUG); *r_buffer = buf; if (r_buflen) *r_buflen = len; return 0; }
/* Helper function to create a canonical encoded S-expression from a Libgcrypt S-expression object. The function returns 0 on success and the malloced canonical S-expression is stored at R_BUFFER and the allocated length at R_BUFLEN. On error an error code is returned and (NULL, 0) stored at R_BUFFER and R_BUFLEN. If the allocated buffer length is not required, NULL by be used for R_BUFLEN. */ gpg_error_t make_canon_sexp (gcry_sexp_t sexp, unsigned char **r_buffer, size_t *r_buflen) { size_t len; unsigned char *buf; *r_buffer = NULL; if (r_buflen) *r_buflen = 0;; len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_CANON, NULL, 0); if (!len) return gpg_error (GPG_ERR_BUG); buf = xtrymalloc (len); if (!buf) return gpg_error_from_syserror (); len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_CANON, buf, len); if (!len) return gpg_error (GPG_ERR_BUG); *r_buffer = buf; if (r_buflen) *r_buflen = len; return 0; }
/* Compare SE to the canonical formatted expression in * (CANON,CANONLEN). This is done by a converting SE to canonical * format and doing a byte compare. Returns 0 if they match. */ static int compare_to_canon (gcry_sexp_t se, const unsigned char *canon, size_t canonlen) { size_t n, n1; char *p1; n1 = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, NULL, 0); if (!n1) { fail ("get required length in compare_to_canon failed\n"); return -1; } p1 = gcry_xmalloc (n1); n = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, p1, n1); if (n1 != n+1) { fail ("length mismatch in compare_to_canon detected\n"); xfree (p1); return -1; } if (n1 != canonlen || memcmp (p1, canon, canonlen)) { xfree (p1); return -1; } xfree (p1); return 0; }
size_t outputSexp (gcry_sexp_t s_exp, char **txtexp){ size_t length; length = gcry_sexp_sprint(s_exp, GCRYSEXP_FMT_CANON, NULL, MAX_BUFF_SIZE); *txtexp = malloc(length); if( gcry_sexp_sprint( s_exp, GCRYSEXP_FMT_CANON, *txtexp, length ) == 0 ) die( " during s-exp export" ); return length; }
char* sexp_string(gcry_sexp_t sexp) { size_t buf_len = gcry_sexp_sprint(sexp, GCRYSEXP_FMT_ADVANCED, NULL, 0); char *buffer = (char*)gcry_malloc(buf_len); if (buffer == NULL) { printf("gcry_malloc(%ld) returned NULL in sexp_string()!\n", buf_len); exit(1); } if (0 == gcry_sexp_sprint(sexp, GCRYSEXP_FMT_ADVANCED, buffer, buf_len)) { printf("gcry_sexp_sprint() lies!\n"); exit(1); } return buffer; // This should be freed with gcry_free(buffer); }
static void print_sexp (const char *prefix, gcry_sexp_t a) { char *buf; size_t size; if (prefix) fputs (prefix, stderr); size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0); buf = gcry_xmalloc (size); gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size); fprintf (stderr, "%.*s", (int)size, buf); gcry_free (buf); }
static void show_sexp (const char *prefix, gcry_sexp_t a) { char *buf; size_t size; fputs (prefix, stderr); size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0); buf = malloc (size); if (!buf) die ("out of core\n"); gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size); fprintf (stderr, "%.*s", (int)size, buf); }
/* * Write the sexp A to OUT. */ static int sexp_write (iobuf_t out, gcry_sexp_t a) { int max_len = 2000; char buffer[max_len]; size_t nbytes; int rc; int len; len = gcry_sexp_sprint (a, 1, buffer, max_len); printf("after sexp sprint %d \n", len); if( len!=0 ) { nbytes = 0; while(buffer[nbytes]!=0) { printf("%c",buffer[nbytes]); nbytes++; } rc = iobuf_write( out, buffer, len ); printf("\n finished writing buf\n"); } else if (gpg_err_code(rc) == GPG_ERR_TOO_SHORT ) { log_info ("mpi too large (%u bits)\n", gcry_mpi_get_nbits (a)); /* The buffer was too small. We better tell the user about the MPI. */ rc = gpg_error (GPG_ERR_TOO_LARGE); } return rc; }
static gcry_error_t sexp_write(FILE *privf, gcry_sexp_t sexp) { size_t buflen; char *buf; buflen = gcry_sexp_sprint(sexp, GCRYSEXP_FMT_ADVANCED, NULL, 0); buf = malloc(buflen); if (buf == NULL && buflen > 0) { return gcry_error(GPG_ERR_ENOMEM); } gcry_sexp_sprint(sexp, GCRYSEXP_FMT_ADVANCED, buf, buflen); fprintf(privf, "%s", buf); free(buf); return gcry_error(GPG_ERR_NO_ERROR); }
static void show_sexp (const char *prefix, gcry_sexp_t a) { char *buf; size_t size; fprintf (stderr, "%s: ", "keygen"); if (prefix) fputs (prefix, stderr); size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0); buf = malloc (size); assert (buf); memset (buf, 0, size); gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size); fprintf (stderr, "%.*s", (int)size, buf); free (buf); }
/* Print the S-Expression in BUF to extended STREAM, which has a valid length of BUFLEN, as a human readable string in one line to FP. */ static void pretty_es_print_sexp (estream_t fp, const unsigned char *buf, size_t buflen) { size_t len; gcry_sexp_t sexp; char *result, *p; if ( gcry_sexp_sscan (&sexp, NULL, (const char*)buf, buflen) ) { es_fputs (_("[Error - invalid encoding]"), fp); return; } len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, NULL, 0); assert (len); result = xtrymalloc (len); if (!result) { es_fputs (_("[Error - out of core]"), fp); gcry_sexp_release (sexp); return; } len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, result, len); assert (len); for (p = result; len; len--, p++) { if (*p == '\n') { if (len > 1) /* Avoid printing the trailing LF. */ es_fputs ("\\n", fp); } else if (*p == '\r') es_fputs ("\\r", fp); else if (*p == '\v') es_fputs ("\\v", fp); else if (*p == '\t') es_fputs ("\\t", fp); else es_putc (*p, fp); } xfree (result); gcry_sexp_release (sexp); }
/** * Encode the public key in a format suitable for * storing it into a file. * * @param key the private key * @param[out] buffer set to a buffer with the encoded key * @return size of memory allocated in @a buffer */ size_t GNUNET_CRYPTO_rsa_public_key_encode (const struct GNUNET_CRYPTO_rsa_PublicKey *key, char **buffer) { size_t n; char *b; n = gcry_sexp_sprint (key->sexp, GCRYSEXP_FMT_ADVANCED, NULL, 0); b = GNUNET_malloc (n); GNUNET_assert ((n -1) == /* since the last byte is \0 */ gcry_sexp_sprint (key->sexp, GCRYSEXP_FMT_ADVANCED, b, n)); *buffer = b; return n; }
/** * Encode the given signature in a format suitable for storing it into a file. * * @param sig the signature * @param[out] buffer set to a buffer with the encoded key * @return size of memory allocated in @a buffer */ size_t GNUNET_CRYPTO_rsa_signature_encode (const struct GNUNET_CRYPTO_rsa_Signature *sig, char **buffer) { size_t n; char *b; n = gcry_sexp_sprint (sig->sexp, GCRYSEXP_FMT_ADVANCED, NULL, 0); b = GNUNET_malloc (n); GNUNET_assert ((n - 1) == /* since the last byte is \0 */ gcry_sexp_sprint (sig->sexp, GCRYSEXP_FMT_ADVANCED, b, n)); *buffer = b; return n; }
/** * cdk_seckey_to_sexp: * @sk: the secret key * @sexp: where to store the S-expression * @len: the length of sexp * * Convert a public key to an S-expression. sexp is allocated by this * function, but you have to cdk_free() it yourself. The S-expression * is stored in canonical format as used by libgcrypt * (GCRYSEXP_FMT_CANON). **/ cdk_error_t cdk_seckey_to_sexp (cdk_pkt_seckey_t sk, char **sexp, size_t * len) { char *buf; size_t sexp_len; gcry_sexp_t sk_sexp; cdk_error_t rc; if (!sk || !sexp) return CDK_Inv_Value; rc = seckey_to_sexp (&sk_sexp, sk); if (rc) return rc; sexp_len = gcry_sexp_sprint (sk_sexp, GCRYSEXP_FMT_CANON, NULL, 0); if (!sexp_len) return CDK_Wrong_Format; buf = (char *) cdk_malloc (sexp_len); if (!buf) { gcry_sexp_release (sk_sexp); return CDK_Out_Of_Core; } sexp_len = gcry_sexp_sprint (sk_sexp, GCRYSEXP_FMT_CANON, buf, sexp_len); gcry_sexp_release (sk_sexp); if (!sexp_len) { cdk_free (buf); return CDK_Wrong_Format; } if (len) *len = sexp_len; *sexp = buf; return CDK_Success; }
void test_sexp ( int argc, char **argv ) { int rc, nbits; gcry_sexp_t sexp; gcry_mpi_t key[3]; size_t n; char *buf; if ( gcry_mpi_scan( &key[0], GCRYMPI_FMT_HEX, elg_testkey1.p, NULL ) ) BUG(); if ( gcry_mpi_scan( &key[1], GCRYMPI_FMT_HEX, elg_testkey1.g, NULL ) ) BUG(); if ( gcry_mpi_scan( &key[2], GCRYMPI_FMT_HEX, elg_testkey1.y, NULL ) ) BUG(); /* get nbits from a key */ rc = gcry_sexp_build ( &sexp, NULL, "(public-key(elg(p%m)(g%m)(y%m)))", key[0], key[1], key[2] ); fputs ( "DUMP of PK:\n", stderr ); gcry_sexp_dump ( sexp ); { gcry_sexp_t x; x = gcry_sexp_cdr ( sexp ); fputs ( "DUMP of CDR:\n", stderr ); gcry_sexp_dump ( x ); gcry_sexp_release ( x ); } nbits = gcry_pk_get_nbits( sexp ); printf ( "elg_testkey1 - nbits=%d\n", nbits ); n = gcry_sexp_sprint ( sexp, 0, NULL, 0 ); buf = gcry_xmalloc ( n ); n = gcry_sexp_sprint ( sexp, 0, buf, n ); printf ( "sprint length=%u\n", (unsigned int)n ); gcry_free ( buf ); gcry_sexp_release( sexp ); }
static void back_and_forth_one (int testno, const char *buffer, size_t length) { gcry_error_t rc; gcry_sexp_t se, se1; size_t n, n1; char *p1; rc = gcry_sexp_new (&se, buffer, length, 1); if (rc) { fail ("baf %d: gcry_sexp_new failed: %s\n", testno, gpg_strerror (rc)); return; } n1 = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, NULL, 0); if (!n1) { fail ("baf %d: get required length for canon failed\n", testno); return; } p1 = gcry_xmalloc (n1); n = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, p1, n1); if (n1 != n+1) /* sprints adds an extra 0 but dies not return it */ { fail ("baf %d: length mismatch for canon\n", testno); return; } rc = gcry_sexp_create (&se1, p1, n, 0, gcry_free); if (rc) { fail ("baf %d: gcry_sexp_create failed: %s\n", testno, gpg_strerror (rc)); return; } gcry_sexp_release (se1); /* Again but with memory checking. */ p1 = gcry_xmalloc (n1+2); *p1 = '\x55'; p1[n1+1] = '\xaa'; n = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, p1+1, n1); if (n1 != n+1) /* sprints adds an extra 0 but does not return it */ { fail ("baf %d: length mismatch for canon\n", testno); return; } if (*p1 != '\x55' || p1[n1+1] != '\xaa') fail ("baf %d: memory corrupted (1)\n", testno); rc = gcry_sexp_create (&se1, p1+1, n, 0, NULL); if (rc) { fail ("baf %d: gcry_sexp_create failed: %s\n", testno, gpg_strerror (rc)); return; } if (*p1 != '\x55' || p1[n1+1] != '\xaa') fail ("baf %d: memory corrupted (2)\n", testno); gcry_sexp_release (se1); if (*p1 != '\x55' || p1[n1+1] != '\xaa') fail ("baf %d: memory corrupted (3)\n", testno); gcry_free (p1); /* FIXME: we need a lot more tests */ gcry_sexp_release (se); }
static void back_and_forth_one (int testno, const char *buffer, size_t length) { gcry_error_t rc; gcry_sexp_t se, se1; unsigned char *canon; size_t canonlen; /* Including the hidden nul suffix. */ size_t n, n1; char *p1; rc = gcry_sexp_new (&se, buffer, length, 1); if (rc) { fail ("baf %d: gcry_sexp_new failed: %s\n", testno, gpg_strerror (rc)); return; } n1 = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, NULL, 0); if (!n1) { fail ("baf %d: get required length for canon failed\n", testno); return; } p1 = gcry_xmalloc (n1); n = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, p1, n1); if (n1 != n+1) /* sprints adds an extra 0 but does not return it. */ { fail ("baf %d: length mismatch for canon\n", testno); return; } canonlen = n1; canon = gcry_malloc (canonlen); memcpy (canon, p1, canonlen); rc = gcry_sexp_create (&se1, p1, n, 0, gcry_free); if (rc) { fail ("baf %d: gcry_sexp_create failed: %s\n", testno, gpg_strerror (rc)); return; } gcry_sexp_release (se1); /* Again but with memory checking. */ p1 = gcry_xmalloc (n1+2); *p1 = '\x55'; p1[n1+1] = '\xaa'; n = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, p1+1, n1); if (n1 != n+1) /* sprints adds an extra 0 but does not return it */ { fail ("baf %d: length mismatch for canon\n", testno); return; } if (*p1 != '\x55' || p1[n1+1] != '\xaa') fail ("baf %d: memory corrupted (1)\n", testno); rc = gcry_sexp_create (&se1, p1+1, n, 0, NULL); if (rc) { fail ("baf %d: gcry_sexp_create failed: %s\n", testno, gpg_strerror (rc)); return; } if (*p1 != '\x55' || p1[n1+1] != '\xaa') fail ("baf %d: memory corrupted (2)\n", testno); gcry_sexp_release (se1); if (*p1 != '\x55' || p1[n1+1] != '\xaa') fail ("baf %d: memory corrupted (3)\n", testno); gcry_free (p1); /* Check converting to advanced format. */ n1 = gcry_sexp_sprint (se, GCRYSEXP_FMT_ADVANCED, NULL, 0); if (!n1) { fail ("baf %d: get required length for advanced failed\n", testno); return; } p1 = gcry_xmalloc (n1); n = gcry_sexp_sprint (se, GCRYSEXP_FMT_ADVANCED, p1, n1); if (n1 != n+1) /* sprints adds an extra 0 but does not return it */ { fail ("baf %d: length mismatch for advanced\n", testno); return; } rc = gcry_sexp_create (&se1, p1, n, 0, gcry_free); if (rc) { fail ("baf %d: gcry_sexp_create failed: %s\n", testno, gpg_strerror (rc)); return; } if (compare_to_canon (se1, canon, canonlen)) { fail ("baf %d: converting to advanced failed: %s\n", testno, gpg_strerror (rc)); return; } gcry_sexp_release (se1); /* FIXME: we need a lot more tests */ gcry_sexp_release (se); xfree (canon); }
/** Read key given cert id in line. */ gpg_error_t cmd_readkey (assuan_context_t ctx, char *line) { gpg_err_code_t error = GPG_ERR_GENERAL; pkcs11h_certificate_id_t cert_id = NULL; gcry_sexp_t sexp = NULL; unsigned char *blob = NULL; size_t blob_size; if ( (error = _get_certificate_by_name ( ctx, line, 0, &cert_id, NULL )) != GPG_ERR_NO_ERROR || (error = get_cert_sexp (ctx, cert_id, &sexp)) != GPG_ERR_NO_ERROR ) { goto cleanup; } if ((blob_size = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_CANON, NULL, 0)) == 0) { error = GPG_ERR_BAD_KEY; goto cleanup; } if ((blob = (unsigned char *)malloc (blob_size)) == NULL) { error = GPG_ERR_ENOMEM; goto cleanup; } if (gcry_sexp_sprint (sexp, GCRYSEXP_FMT_CANON, blob, blob_size) == 0) { error = GPG_ERR_BAD_KEY; goto cleanup; } if ( (error = assuan_send_data( ctx, blob, gcry_sexp_canon_len (blob, 0, NULL, NULL) )) != GPG_ERR_NO_ERROR ) { goto cleanup; } error = GPG_ERR_NO_ERROR; cleanup: if (sexp != NULL) { gcry_sexp_release(sexp); sexp = NULL; } if (cert_id != NULL) { pkcs11h_certificate_freeCertificateId (cert_id); cert_id = NULL; } if (blob != NULL) { free (blob); blob = NULL; } return gpg_error (error); }