Example #1
0
SilcBool silc_pkcs1_sign_no_oid(void *private_key,
				unsigned char *src,
				SilcUInt32 src_len,
				unsigned char *signature,
				SilcUInt32 signature_size,
				SilcUInt32 *ret_signature_len,
				SilcBool compute_hash,
				SilcHash hash)
{
  RsaPrivateKey *key = private_key;
  SilcMPInt mp_tmp;
  SilcMPInt mp_dst;
  unsigned char padded[2048 + 1], hashr[SILC_HASH_MAXLEN];
  SilcUInt32 len = (key->bits + 7) / 8;

  SILC_LOG_DEBUG(("Sign"));

  if (sizeof(padded) < len)
    return FALSE;
  if (signature_size < len)
    return FALSE;

  /* Compute hash if requested */
  if (compute_hash) {
    silc_hash_make(hash, src, src_len, hashr);
    src = hashr;
    src_len = silc_hash_len(hash);
  }

  /* Pad data */
  if (!silc_pkcs1_encode(SILC_PKCS1_BT_PRV1, src, src_len,
			 padded, len, NULL))
    return FALSE;

  silc_mp_init(&mp_tmp);
  silc_mp_init(&mp_dst);

  /* Data to MP */
  silc_mp_bin2mp(padded, len, &mp_tmp);

  /* Sign */
  silc_rsa_private_operation(key, &mp_tmp, &mp_dst);

  /* MP to data */
  silc_mp_mp2bin_noalloc(&mp_dst, signature, len);
  *ret_signature_len = len;

  memset(padded, 0, sizeof(padded));
  silc_mp_uninit(&mp_tmp);
  silc_mp_uninit(&mp_dst);
  if (compute_hash)
    memset(hashr, 0, sizeof(hashr));

  return TRUE;
}
Example #2
0
unsigned char *silc_mp_mp2bin(SilcMPInt *val, SilcUInt32 len,
			      SilcUInt32 *ret_len)
{
  SilcUInt32 size;
  unsigned char *ret;

  size = (len ? len : ((silc_mp_sizeinbase(val, 2) + 7) / 8));
  ret = silc_calloc(size, sizeof(*ret));
  if (!ret)
    return NULL;

  silc_mp_mp2bin_noalloc(val, ret, size);

  if (ret_len)
    *ret_len = size;

  return ret;
}
Example #3
0
SilcBool silc_pkcs1_encrypt(void *public_key,
			    unsigned char *src,
			    SilcUInt32 src_len,
			    unsigned char *dst,
			    SilcUInt32 dst_size,
			    SilcUInt32 *ret_dst_len,
			    SilcRng rng)
{
  RsaPublicKey *key = public_key;
  SilcMPInt mp_tmp;
  SilcMPInt mp_dst;
  unsigned char padded[2048 + 1];
  SilcUInt32 len = (key->bits + 7) / 8;

  if (sizeof(padded) < len)
    return FALSE;
  if (dst_size < len)
    return FALSE;

  /* Pad data */
  if (!silc_pkcs1_encode(SILC_PKCS1_BT_PUB, src, src_len,
			 padded, len, rng))
    return FALSE;

  silc_mp_init(&mp_tmp);
  silc_mp_init(&mp_dst);

  /* Data to MP */
  silc_mp_bin2mp(padded, len, &mp_tmp);

  /* Encrypt */
  silc_rsa_public_operation(key, &mp_tmp, &mp_dst);

  /* MP to data */
  silc_mp_mp2bin_noalloc(&mp_dst, dst, len);
  *ret_dst_len = len;

  memset(padded, 0, sizeof(padded));
  silc_mp_uninit(&mp_tmp);
  silc_mp_uninit(&mp_dst);

  return TRUE;
}
Example #4
0
static void silc_pkcs_ssh_sign_cb(SilcBool success,
				  const unsigned char *signature,
				  SilcUInt32 signature_len,
				  void *context)
{
  SilcSshSign sign = context;
  SilcStack stack = sign->stack;
  unsigned char rbuf[20], sbuf[20];
  SilcBufferStruct sig;
  SilcAsn1 asn1;
  SilcMPInt r, s;

  memset(&sig, 0, sizeof(sig));

  /* Format the signature.  RSA is easy because PKCS#1 is already in
     correct format.  For DSA the returned signature is in PKIX compliant
     format and we have to reformat it for SSH2. */
  if (!strcmp(sign->privkey->pkcs->name, "dsa")) {
    asn1 = silc_asn1_alloc(stack);
    if (!asn1) {
      sign->sign_cb(FALSE, NULL, 0, sign->context);
      silc_sfree(stack, sign);
      silc_stack_free(stack);
      return;
    }

    /* Decode the signature */
    silc_buffer_set(&sig, (unsigned char *)signature, signature_len);
    if (!silc_asn1_decode(asn1, &sig,
			  SILC_ASN1_SEQUENCE,
			    SILC_ASN1_INT(&r),
			    SILC_ASN1_INT(&s),
			  SILC_ASN1_END, SILC_ASN1_END)) {
      sign->sign_cb(FALSE, NULL, 0, sign->context);
      silc_asn1_free(asn1);
      silc_sfree(stack, sign);
      silc_stack_free(stack);
      return;
    }

    /* Encode the integers */
    memset(rbuf, 0, sizeof(rbuf));
    memset(sbuf, 0, sizeof(sbuf));
    silc_mp_mp2bin_noalloc(&r, rbuf, sizeof(rbuf));
    silc_mp_mp2bin_noalloc(&s, sbuf, sizeof(sbuf));

    silc_asn1_free(asn1);

    /* Encode SSH2 DSS signature */
    if (silc_buffer_sformat(stack, &sig,
			    SILC_STR_UI_INT(7),
			    SILC_STR_UI32_STRING("ssh-dss"),
			    SILC_STR_UI_INT(sizeof(rbuf) + sizeof(sbuf)),
			    SILC_STR_DATA(rbuf, sizeof(rbuf)),
			    SILC_STR_DATA(sbuf, sizeof(sbuf)),
			    SILC_STR_END) < 0) {
      sign->sign_cb(FALSE, NULL, 0, sign->context);
      silc_sfree(stack, sign);
      silc_stack_free(stack);
      return;
    }
  } else {
    /* Encode SSH2 RSA signature */
    if (silc_buffer_sformat(stack, &sig,
			    SILC_STR_UI_INT(7),
			    SILC_STR_UI32_STRING("ssh-rsa"),
			    SILC_STR_UI_INT(signature_len),
			    SILC_STR_DATA(signature, signature_len),
			    SILC_STR_END) < 0) {
      sign->sign_cb(FALSE, NULL, 0, sign->context);
      silc_sfree(stack, sign);
      silc_stack_free(stack);
      return;
    }
  }

  /* Deliver result */
  sign->sign_cb(TRUE, silc_buffer_data(&sig), silc_buffer_len(&sig),
		sign->context);

  silc_buffer_spurge(stack, &sig);
  silc_sfree(stack, sign);
  silc_stack_free(stack);
}
Example #5
0
SilcBool silc_pkcs1_sign(void *private_key,
			 unsigned char *src,
			 SilcUInt32 src_len,
			 unsigned char *signature,
			 SilcUInt32 signature_size,
			 SilcUInt32 *ret_signature_len,
			 SilcBool compute_hash,
			 SilcHash hash)
{
  RsaPrivateKey *key = private_key;
  unsigned char padded[2048 + 1], hashr[SILC_HASH_MAXLEN];
  SilcMPInt mp_tmp;
  SilcMPInt mp_dst;
  SilcBufferStruct di;
  SilcUInt32 len = (key->bits + 7) / 8;
  const char *oid;
  SilcAsn1 asn1;

  SILC_LOG_DEBUG(("Sign"));

  if (sizeof(padded) < len)
    return FALSE;
  if (signature_size < len)
    return FALSE;

  oid = silc_hash_get_oid(hash);
  if (!oid)
    return FALSE;

  asn1 = silc_asn1_alloc();
  if (!asn1)
    return FALSE;

  /* Compute hash */
  if (compute_hash) {
    silc_hash_make(hash, src, src_len, hashr);
    src = hashr;
    src_len = silc_hash_len(hash);
  }

  /* Encode digest info */
  memset(&di, 0, sizeof(di));
  if (!silc_asn1_encode(asn1, &di,
			SILC_ASN1_SEQUENCE,
			  SILC_ASN1_SEQUENCE,
			    SILC_ASN1_OID(oid),
			    SILC_ASN1_NULL,
			  SILC_ASN1_END,
			  SILC_ASN1_OCTET_STRING(src, src_len),
			SILC_ASN1_END, SILC_ASN1_END)) {
    silc_asn1_free(asn1);
    return FALSE;
  }
  SILC_LOG_HEXDUMP(("DigestInfo"), silc_buffer_data(&di),
		   silc_buffer_len(&di));

  /* Pad data */
  if (!silc_pkcs1_encode(SILC_PKCS1_BT_PRV1, silc_buffer_data(&di),
			 silc_buffer_len(&di), padded, len, NULL)) {
    silc_asn1_free(asn1);
    return FALSE;
  }

  silc_mp_init(&mp_tmp);
  silc_mp_init(&mp_dst);

  /* Data to MP */
  silc_mp_bin2mp(padded, len, &mp_tmp);

  /* Sign */
  silc_rsa_private_operation(key, &mp_tmp, &mp_dst);

  /* MP to data */
  silc_mp_mp2bin_noalloc(&mp_dst, signature, len);
  *ret_signature_len = len;

  memset(padded, 0, sizeof(padded));
  silc_mp_uninit(&mp_tmp);
  silc_mp_uninit(&mp_dst);
  if (compute_hash)
    memset(hashr, 0, sizeof(hashr));
  silc_asn1_free(asn1);

  return TRUE;
}