Beispiel #1
0
unsigned char *silc_pkcs1_export_public_key(void *public_key,
					    SilcUInt32 *ret_len)
{
  RsaPublicKey *key = public_key;
  SilcAsn1 asn1 = NULL;
  SilcBufferStruct alg_key;
  unsigned char *ret;

  asn1 = silc_asn1_alloc();
  if (!asn1)
    goto err;

  /* Encode to PKCS #1 public key */
  memset(&alg_key, 0, sizeof(alg_key));
  if (!silc_asn1_encode(asn1, &alg_key,
			SILC_ASN1_OPTS(SILC_ASN1_ALLOC),
			SILC_ASN1_SEQUENCE,
			  SILC_ASN1_INT(&key->n),
			  SILC_ASN1_INT(&key->e),
			SILC_ASN1_END, SILC_ASN1_END))
    goto err;

  ret = silc_buffer_steal(&alg_key, ret_len);
  silc_asn1_free(asn1);

  return ret;

 err:
  if (asn1)
    silc_asn1_free(asn1);
  return NULL;
}
Beispiel #2
0
int silc_pkcs1_import_private_key(unsigned char *key,
				  SilcUInt32 key_len,
				  void **ret_private_key)
{
  SilcAsn1 asn1;
  SilcBufferStruct alg_key;
  RsaPrivateKey *privkey;
  SilcUInt32 ver;

  if (!ret_private_key)
    return 0;

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

  /* Allocate RSA private key */
  *ret_private_key = privkey = silc_calloc(1, sizeof(*privkey));
  if (!privkey)
    goto err;

  /* Parse the PKCS #1 private key */
  silc_buffer_set(&alg_key, key, key_len);
  if (!silc_asn1_decode(asn1, &alg_key,
			SILC_ASN1_OPTS(SILC_ASN1_ALLOC),
			SILC_ASN1_SEQUENCE,
			  SILC_ASN1_SHORT_INT(&ver),
			  SILC_ASN1_INT(&privkey->n),
			  SILC_ASN1_INT(&privkey->e),
			  SILC_ASN1_INT(&privkey->d),
			  SILC_ASN1_INT(&privkey->p),
			  SILC_ASN1_INT(&privkey->q),
			  SILC_ASN1_INT(&privkey->dP),
			  SILC_ASN1_INT(&privkey->dQ),
			  SILC_ASN1_INT(&privkey->qP),
			SILC_ASN1_END, SILC_ASN1_END))
    goto err;

  if (ver != 0)
    goto err;

  /* Set key length */
  privkey->bits = ((silc_mp_sizeinbase(&privkey->n, 2) + 7) / 8) * 8;

  silc_asn1_free(asn1);

  return key_len;

 err:
  silc_free(privkey);
  silc_asn1_free(asn1);
  return 0;
}
Beispiel #3
0
int silc_pkcs1_import_public_key(unsigned char *key,
				 SilcUInt32 key_len,
				 void **ret_public_key)
{
  SilcAsn1 asn1 = NULL;
  SilcBufferStruct alg_key;
  RsaPublicKey *pubkey;

  if (!ret_public_key)
    return 0;

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

  /* Allocate RSA public key */
  *ret_public_key = pubkey = silc_calloc(1, sizeof(*pubkey));
  if (!pubkey)
    goto err;

  /* Parse the PKCS #1 public key */
  silc_buffer_set(&alg_key, key, key_len);
  if (!silc_asn1_decode(asn1, &alg_key,
			SILC_ASN1_OPTS(SILC_ASN1_ALLOC),
			SILC_ASN1_SEQUENCE,
			  SILC_ASN1_INT(&pubkey->n),
			  SILC_ASN1_INT(&pubkey->e),
			SILC_ASN1_END, SILC_ASN1_END))
    goto err;

  /* Set key length */
  pubkey->bits = ((silc_mp_sizeinbase(&pubkey->n, 2) + 7) / 8) * 8;

  silc_asn1_free(asn1);

  return key_len;

 err:
  silc_free(pubkey);
  silc_asn1_free(asn1);
  return 0;
}
Beispiel #4
0
unsigned char *silc_pkcs1_export_private_key(void *private_key,
					     SilcUInt32 *ret_len)
{
  RsaPrivateKey *key = private_key;
  SilcAsn1 asn1;
  SilcBufferStruct alg_key;
  unsigned char *ret;

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

  /* Encode to PKCS #1 private key */
  memset(&alg_key, 0, sizeof(alg_key));
  if (!silc_asn1_encode(asn1, &alg_key,
			SILC_ASN1_OPTS(SILC_ASN1_ALLOC),
			SILC_ASN1_SEQUENCE,
			  SILC_ASN1_SHORT_INT(0),
			  SILC_ASN1_INT(&key->n),
			  SILC_ASN1_INT(&key->e),
			  SILC_ASN1_INT(&key->d),
			  SILC_ASN1_INT(&key->p),
			  SILC_ASN1_INT(&key->q),
			  SILC_ASN1_INT(&key->dP),
			  SILC_ASN1_INT(&key->dQ),
			  SILC_ASN1_INT(&key->qP),
			SILC_ASN1_END, SILC_ASN1_END))
    goto err;

  ret = silc_buffer_steal(&alg_key, ret_len);
  silc_asn1_free(asn1);

  return ret;

 err:
  silc_asn1_free(asn1);
  return NULL;
}
Beispiel #5
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);
}