/** * cdk_stream_tmp_from_mem: * @buf: the buffer which shall be written to the temp stream. * @buflen: how large the buffer is * @r_out: the new stream with the given contents. * * Creates a new tempory stream with the given contests. */ cdk_error_t cdk_stream_tmp_from_mem (const void *buf, size_t buflen, cdk_stream_t * r_out) { cdk_stream_t s; cdk_error_t rc; int nwritten; *r_out = NULL; rc = cdk_stream_tmp_new (&s); if (rc) { gnutls_assert (); return rc; } nwritten = cdk_stream_write (s, buf, buflen); if (nwritten == EOF) { cdk_stream_close (s); gnutls_assert (); return s->error; } cdk_stream_seek (s, 0); *r_out = s; return 0; }
/** * cdk_kbnode_write_to_mem_alloc: * @node: the key node * @r_buf: buffer to hold the raw data * @r_buflen: buffer length of the allocated raw data. * * The function acts similar to cdk_kbnode_write_to_mem but * it allocates the buffer to avoid the lengthy second run. */ cdk_error_t cdk_kbnode_write_to_mem_alloc (cdk_kbnode_t node, byte ** r_buf, size_t * r_buflen) { cdk_kbnode_t n; cdk_stream_t s; cdk_error_t rc; size_t len; if (!node || !r_buf || !r_buflen) { gnutls_assert (); return CDK_Inv_Value; } *r_buf = NULL; *r_buflen = 0; rc = cdk_stream_tmp_new (&s); if (rc) { gnutls_assert (); return rc; } for (n = node; n; n = n->next) { /* Skip all packets which cannot occur in a key composition. */ if (n->pkt->pkttype != CDK_PKT_PUBLIC_KEY && n->pkt->pkttype != CDK_PKT_PUBLIC_SUBKEY && n->pkt->pkttype != CDK_PKT_SECRET_KEY && n->pkt->pkttype != CDK_PKT_SECRET_SUBKEY && n->pkt->pkttype != CDK_PKT_SIGNATURE && n->pkt->pkttype != CDK_PKT_USER_ID && n->pkt->pkttype != CDK_PKT_ATTRIBUTE) continue; rc = cdk_pkt_write (s, n->pkt); if (rc) { cdk_stream_close (s); gnutls_assert (); return rc; } } cdk_stream_seek (s, 0); len = cdk_stream_get_length (s); *r_buf = cdk_calloc (1, len); *r_buflen = cdk_stream_read (s, *r_buf, len); cdk_stream_close (s); return 0; }
static cdk_error_t file_verify_clearsign (cdk_ctx_t hd, const char *file, const char *output) { cdk_stream_t inp = NULL, out = NULL, tmp = NULL; digest_hd_st md; char buf[512], chk[512]; const char *s; int i, is_signed = 0, nbytes; int digest_algo = 0; int err; cdk_error_t rc; memset(&md, 0, sizeof(md)); if (output) { rc = cdk_stream_create (output, &out); if (rc) return rc; } rc = cdk_stream_open (file, &inp); if (rc) { if (output) cdk_stream_close (out); return rc; } s = "-----BEGIN PGP SIGNED MESSAGE-----"; while (!cdk_stream_eof (inp)) { nbytes = _cdk_stream_gets (inp, buf, DIM (buf) - 1); if (!nbytes || nbytes == -1) break; if (!strncmp (buf, s, strlen (s))) { is_signed = 1; break; } } if (cdk_stream_eof (inp) && !is_signed) { rc = CDK_Armor_Error; goto leave; } while (!cdk_stream_eof (inp)) { nbytes = _cdk_stream_gets (inp, buf, DIM (buf) - 1); if (!nbytes || nbytes == -1) break; if (nbytes == 1) /* Empty line */ break; else if (!strncmp (buf, "Hash: ", 6)) { for (i = 0; digest_table[i].name; i++) { if (!strcmp (buf + 6, digest_table[i].name)) { digest_algo = digest_table[i].algo; break; } } } } if (digest_algo && _gnutls_hash_get_algo_len (digest_algo) <= 0) { rc = CDK_Inv_Algo; goto leave; } if (!digest_algo) digest_algo = GNUTLS_DIG_MD5; err = _gnutls_hash_init (&md, digest_algo); if (err < 0) { rc = map_gnutls_error (err); goto leave; } s = "-----BEGIN PGP SIGNATURE-----"; while (!cdk_stream_eof (inp)) { nbytes = _cdk_stream_gets (inp, buf, DIM (buf) - 1); if (!nbytes || nbytes == -1) break; if (!strncmp (buf, s, strlen (s))) break; else { cdk_stream_peek (inp, (byte *) chk, DIM (chk) - 1); i = strncmp (chk, s, strlen (s)); if (strlen (buf) == 0 && i == 0) continue; /* skip last '\n' */ _cdk_trim_string (buf, i == 0 ? 0 : 1); _gnutls_hash (&md, buf, strlen (buf)); } if (!strncmp (buf, "- ", 2)) /* FIXME: handle it recursive. */ memmove (buf, buf + 2, nbytes - 2); if (out) { if (strstr (buf, "\r\n")) buf[strlen (buf) - 2] = '\0'; cdk_stream_write (out, buf, strlen (buf)); _cdk_stream_puts (out, _cdk_armor_get_lineend ()); } } /* We create a temporary stream object to store the signature data in there. */ rc = cdk_stream_tmp_new (&tmp); if (rc) goto leave; s = "-----BEGIN PGP SIGNATURE-----\n"; _cdk_stream_puts (tmp, s); while (!cdk_stream_eof (inp)) { nbytes = _cdk_stream_gets (inp, buf, DIM (buf) - 1); if (!nbytes || nbytes == -1) break; if (nbytes < (int) (DIM (buf) - 3)) { buf[nbytes - 1] = '\n'; buf[nbytes] = '\0'; } cdk_stream_write (tmp, buf, nbytes); } /* FIXME: This code is not very elegant. */ cdk_stream_tmp_set_mode (tmp, STREAMCTL_READ); cdk_stream_seek (tmp, 0); cdk_stream_set_armor_flag (tmp, 0); cdk_stream_read (tmp, NULL, 0); /* the digest handle will be closed there. */ rc = _cdk_proc_packets (hd, tmp, NULL, NULL, NULL, &md); leave: _gnutls_hash_deinit (&md, NULL); cdk_stream_close (out); cdk_stream_close (tmp); cdk_stream_close (inp); return rc; }
/** * cdk_kbnode_write_to_mem: * @node: the key node * @buf: the buffer to store the node data * @r_nbytes: the new length of the buffer. * * Tries to write the contents of the key node to the buffer @buf and * return the length of it in @r_nbytes. If buf is zero, only the * length of the node is calculated and returned in @r_nbytes. * Whenever it is possible, the cdk_kbnode_write_to_mem_alloc should be used. **/ cdk_error_t cdk_kbnode_write_to_mem (cdk_kbnode_t node, byte * buf, size_t * r_nbytes) { cdk_kbnode_t n; cdk_stream_t s; cdk_error_t rc; size_t len; if (!node || !r_nbytes) { gnutls_assert (); return CDK_Inv_Value; } rc = cdk_stream_tmp_new (&s); if (rc) { gnutls_assert (); return rc; } for (n = node; n; n = n->next) { /* Skip all packets which cannot occur in a key composition. */ if (n->pkt->pkttype != CDK_PKT_PUBLIC_KEY && n->pkt->pkttype != CDK_PKT_PUBLIC_SUBKEY && n->pkt->pkttype != CDK_PKT_SECRET_KEY && n->pkt->pkttype != CDK_PKT_SECRET_SUBKEY && n->pkt->pkttype != CDK_PKT_SIGNATURE && n->pkt->pkttype != CDK_PKT_USER_ID && n->pkt->pkttype != CDK_PKT_ATTRIBUTE) continue; rc = cdk_pkt_write (s, n->pkt); if (rc) { cdk_stream_close (s); gnutls_assert (); return rc; } } cdk_stream_seek (s, 0); len = cdk_stream_get_length (s); if (!buf) { *r_nbytes = len; /* Only return the length of the buffer */ cdk_stream_close (s); return 0; } if (*r_nbytes < len) { *r_nbytes = len; rc = CDK_Too_Short; } if (!rc) *r_nbytes = cdk_stream_read (s, buf, len); else gnutls_assert (); cdk_stream_close (s); return rc; }