Exemplo n.º 1
0
int
pgp_put_uint16(struct nettle_buffer *buffer, unsigned i)
{
  uint8_t *p = nettle_buffer_space(buffer, 2);
  if (!p)
    return 0;
  
  WRITE_UINT16(p, i);
  return 1;
}
Exemplo n.º 2
0
int
pgp_put_uint32(struct nettle_buffer *buffer, uint32_t i)
{
  uint8_t *p = nettle_buffer_space(buffer, 4);
  if (!p)
    return 0;
  
  WRITE_UINT32(p, i);
  return 1;
}
Exemplo n.º 3
0
int
pgp_put_mpi(struct nettle_buffer *buffer, const mpz_t x)
{
  unsigned bits = mpz_sizeinbase(x, 2);
  unsigned octets = (bits + 7) / 8;

  uint8_t *p;

  /* FIXME: What's the correct representation of zero? */
  if (!pgp_put_uint16(buffer, bits))
    return 0;
  
  p = nettle_buffer_space(buffer, octets);

  if (!p)
    return 0;
  
  nettle_mpz_get_str_256(octets, p, x);

  return 1;
}
unsigned
sexp_transport_vformat(struct nettle_buffer *buffer,
		       const char *format, va_list args)
{
  unsigned start = 0;
  unsigned length;
  unsigned base64_length;

  if (buffer)
    {
      if (!NETTLE_BUFFER_PUTC(buffer, '{'))
	return 0;

      start = buffer->size;
    }
  
  length = sexp_vformat(buffer, format, args);

  if (!length)
    return 0;

  base64_length = BASE64_ENCODE_RAW_LENGTH(length);

  if (buffer)
    {
      if (!nettle_buffer_space(buffer, base64_length - length))
	return 0;

      base64_encode_raw(buffer->contents + start,
			length, buffer->contents + start);
      
      if (!NETTLE_BUFFER_PUTC(buffer, '}'))
	return 0;
    }
  
  return base64_length + 2;
}
Exemplo n.º 5
0
int
pgp_armor(struct nettle_buffer *buffer,
	  const char *tag,
	  unsigned length,
	  const uint8_t *data)
{
  struct base64_encode_ctx ctx;
  
  unsigned crc = pgp_crc24(length, data);

  base64_encode_init(&ctx);
  
  if (! (write_string(buffer, "BEGIN PGP ")
	 && write_string(buffer, tag)
	 && write_string(buffer, "\nComment: Nettle\n\n")))
    return 0;

  for (;
       length >= BINARY_PER_LINE;
       length -= BINARY_PER_LINE, data += BINARY_PER_LINE)
    {
      unsigned done;
      uint8_t *p
	= nettle_buffer_space(buffer, TEXT_PER_LINE);
      
      if (!p)
	return 0;

      done = base64_encode_update(&ctx, p, BINARY_PER_LINE, data);
      assert(done <= TEXT_PER_LINE);

      /* FIXME: Create some official way to do this */
      buffer->size -= (TEXT_PER_LINE - done);
      
      if (!NETTLE_BUFFER_PUTC(buffer, '\n'))
	return 0;
    }

  if (length)
    {
      unsigned text_size = BASE64_ENCODE_LENGTH(length)
	+ BASE64_ENCODE_FINAL_LENGTH;
      unsigned done;
      
      uint8_t *p
	= nettle_buffer_space(buffer, text_size);
      if (!p)
	return 0;

      done = base64_encode_update(&ctx, p, length, data);
      done += base64_encode_final(&ctx, p + done);

      /* FIXME: Create some official way to do this */
      buffer->size -= (text_size - done);
      
      if (!NETTLE_BUFFER_PUTC(buffer, '\n'))
	return 0;
    }
  /* Checksum */
  if (!NETTLE_BUFFER_PUTC(buffer, '='))
    return 0;

  {
    uint8_t *p = nettle_buffer_space(buffer, 4);
    if (!p)
      return 0;
    base64_encode_group(p, crc);
  }
  
  return (write_string(buffer, "\nBEGIN PGP ")
	  && write_string(buffer, tag)
	  && NETTLE_BUFFER_PUTC(buffer, '\n'));
}
Exemplo n.º 6
0
int
pgp_put_rsa_sha1_signature(struct nettle_buffer *buffer,
			   const struct rsa_private_key *key,
			   const uint8_t *keyid,
			   unsigned type,
			   struct sha1_ctx *hash)
{
  unsigned signature_start = buffer->size;
  unsigned hash_end;
  unsigned sub_packet_start;
  uint8_t trailer[6];
  mpz_t s;
  
  /* Signature packet. The packet could reasonably be both smaller and
   * larger than 192, so for simplicity we use the 4 octet header
   * form. */

  if (! (pgp_put_header(buffer, PGP_TAG_SIGNATURE, PGP_LENGTH_FOUR_OCTETS)
	 && NETTLE_BUFFER_PUTC(buffer, 4)  /* Version */
	 && NETTLE_BUFFER_PUTC(buffer, type)
	 /* Could also be PGP_RSA_SIGN */
	 && NETTLE_BUFFER_PUTC(buffer, PGP_RSA)
	 && NETTLE_BUFFER_PUTC(buffer, PGP_SHA1)
	 && pgp_put_uint16(buffer, 0)))  /* Hashed subpacket length */
    return 0;

  hash_end = buffer->size;

  sha1_update(hash,
	      hash_end - signature_start,
	      buffer->contents + signature_start);

  trailer[0] = 4; trailer[1] = 0xff;
  WRITE_UINT32(trailer + 2, buffer->size - signature_start);

  sha1_update(hash, sizeof(trailer), trailer);

  {
    struct sha1_ctx hcopy = *hash;
    uint8_t *p = nettle_buffer_space(buffer, 2);
    if (!p)
      return 0;
    
    sha1_digest(&hcopy, 2, p);
  }

  /* One "sub-packet" field with the issuer keyid */
  sub_packet_start = pgp_sub_packet_start(buffer);
  if (!sub_packet_start)
    return 0;

  if (pgp_put_sub_packet(buffer, PGP_SUBPACKET_ISSUER_KEY_ID, 8, keyid))
    {
      pgp_sub_packet_end(buffer, sub_packet_start);
      return 0;
    }
    
  mpz_init(s);
  if (!(rsa_sha1_sign(key, hash, s)
	&& pgp_put_mpi(buffer, s)))
    {
      mpz_clear(s);
      return 0;
    }

  mpz_clear(s);
  pgp_put_header_length(buffer, signature_start, 4);

  return 1;
}
Exemplo n.º 7
0
unsigned
pgp_sub_packet_start(struct nettle_buffer *buffer)
{
  return nettle_buffer_space(buffer, 2) ? buffer->size : 0;
}