static int get_certificate(PluginInstance *inst,
                           X509 **cert_out, struct sc_pkcs15_id *certid_out)
{
        struct sc_pkcs15_cert *cert;
        struct sc_pkcs15_cert_info *cinfo;
	struct sc_pkcs15_object *objs[32], *cert_obj;
        int r, i, count;
        X509 *x509;
        struct sc_pkcs15_id cert_id;
        const u8 *p;

        r = sc_pkcs15_get_objects(inst->p15card, SC_PKCS15_TYPE_PRKEY_RSA, objs, 32);
        if (r < 0)
                return r;
        if (r == 0)
                return SC_ERROR_OBJECT_NOT_FOUND;
        cert_id.len = 0;
        count = r;
        for (i = 0; i < count; i++) {
                struct sc_pkcs15_prkey_info *key = (struct sc_pkcs15_prkey_info *) objs[i]->data;

#if 0
                if (key->usage & SC_PKCS15_PRKEY_USAGE_NONREPUDIATION) {
#endif
                        /* Use the first available non-repudiation key */
                        cert_id = key->id;
                        break;
#if 0
                }
#endif
        }
        if (cert_id.len == 0)
                return SC_ERROR_OBJECT_NOT_FOUND;
        r = sc_pkcs15_find_cert_by_id(inst->p15card, &cert_id, &cert_obj);
        if (r)
                return r;
	cinfo = (struct sc_pkcs15_cert_info *) cert_obj->data;
        r = sc_pkcs15_read_certificate(inst->p15card, cinfo, &cert);
        if (r)
                return r;
        x509 = X509_new();
        p = cert->data;
        if (!d2i_X509(&x509, &p, cert->data_len)) {
                return -1; /* FIXME */
        }
        *certid_out = cinfo->id;
        sc_pkcs15_free_certificate(cert);
        *cert_out = x509;
        return 0;
}
Exemplo n.º 2
0
static int read_ssh_key(void)
{
	int r;
	struct sc_pkcs15_id id;
	struct sc_pkcs15_object *obj;
	sc_pkcs15_pubkey_t *pubkey = NULL;
	sc_pkcs15_cert_t *cert = NULL;
        FILE            *outf;

        if (opt_outfile != NULL) {
                outf = fopen(opt_outfile, "w");
                if (outf == NULL) {
                        fprintf(stderr, "Error opening file '%s': %s\n",
                                opt_outfile, strerror(errno));
                        goto fail2;
                }
        } else
                outf = stdout;

	id.len = SC_PKCS15_MAX_ID_SIZE;
	sc_pkcs15_hex_string_to_id(opt_pubkey, &id);

	r = sc_pkcs15_find_pubkey_by_id(p15card, &id, &obj);
	if (r >= 0) {
		if (verbose)
			fprintf(stderr,"Reading ssh key with ID '%s'\n", opt_pubkey);
		r = authenticate(obj);
		if (r >= 0)
			r = sc_pkcs15_read_pubkey(p15card, obj, &pubkey);
	} else if (r == SC_ERROR_OBJECT_NOT_FOUND) {
		/* No pubkey - try if there's a certificate */
		r = sc_pkcs15_find_cert_by_id(p15card, &id, &obj);
		if (r >= 0) {
			if (verbose)
				fprintf(stderr,"Reading certificate with ID '%s'\n", opt_pubkey);
			r = sc_pkcs15_read_certificate(p15card,
				(sc_pkcs15_cert_info_t *) obj->data,
				&cert);
		}
		if (r >= 0)
			pubkey = cert->key;
	}

	if (r == SC_ERROR_OBJECT_NOT_FOUND) {
		fprintf(stderr, "Public key with ID '%s' not found.\n", opt_pubkey);
		return 2;
	}
	if (r < 0) {
		fprintf(stderr, "Public key enumeration failed: %s\n", sc_strerror(r));
		return 1;
	}

	/* rsa1 keys */
	if (pubkey->algorithm == SC_ALGORITHM_RSA) {
		int bits;
		BIGNUM *bn;
		char *exp,*mod;

		bn = BN_new();
		BN_bin2bn((unsigned char*)pubkey->u.rsa.modulus.data,
				pubkey->u.rsa.modulus.len, bn);
		bits = BN_num_bits(bn);
		exp =  BN_bn2dec(bn);
		BN_free(bn);

		bn = BN_new();
		BN_bin2bn((unsigned char*)pubkey->u.rsa.exponent.data,
				pubkey->u.rsa.exponent.len, bn);
		mod = BN_bn2dec(bn);
		BN_free(bn);

		if (bits && exp && mod) {
			fprintf(outf, "%u %s %s\n", bits,mod,exp);
		} else {
			fprintf(stderr, "decoding rsa key failed!\n");
		}
		OPENSSL_free(exp);
		OPENSSL_free(mod);
	}
	
	/* rsa and des keys - ssh2 */
	/* key_to_blob */

	if (pubkey->algorithm == SC_ALGORITHM_RSA) {
		unsigned char buf[2048];
		unsigned char *uu;
		uint32_t len;
		uint32_t n;

		buf[0]=0;
		buf[1]=0;
		buf[2]=0;
		buf[3]=7;

		len = sprintf((char *) buf+4,"ssh-rsa");
		len+=4;

		if (sizeof(buf)-len < 4+pubkey->u.rsa.exponent.len) 
			goto fail;
		n = pubkey->u.rsa.exponent.len;
		if (pubkey->u.rsa.exponent.data[0] & 0x80) n++;
		buf[len++]=(n >>24) & 0xff;
		buf[len++]=(n >>16) & 0xff;
		buf[len++]=(n >>8) & 0xff;
		buf[len++]=(n) & 0xff;
		if (pubkey->u.rsa.exponent.data[0] & 0x80) 
			buf[len++]= 0;

		memcpy(buf+len,pubkey->u.rsa.exponent.data,
			pubkey->u.rsa.exponent.len);
		len += pubkey->u.rsa.exponent.len;

		if (sizeof(buf)-len < 5+pubkey->u.rsa.modulus.len) 
			goto fail;
		n = pubkey->u.rsa.modulus.len;
		if (pubkey->u.rsa.modulus.data[0] & 0x80) n++;
		buf[len++]=(n >>24) & 0xff;
		buf[len++]=(n >>16) & 0xff;
		buf[len++]=(n >>8) & 0xff;
		buf[len++]=(n) & 0xff;
		if (pubkey->u.rsa.modulus.data[0] & 0x80) 
			buf[len++]= 0;

		memcpy(buf+len,pubkey->u.rsa.modulus.data,
			pubkey->u.rsa.modulus.len);
		len += pubkey->u.rsa.modulus.len;

		uu = malloc(len*2);
		r = sc_base64_encode(buf, len, uu, 2*len, 2*len);

		fprintf(outf,"ssh-rsa %s", uu);
		free(uu);

	}
Exemplo n.º 3
0
static int read_public_key(void)
{
	int r;
	struct sc_pkcs15_id id;
	struct sc_pkcs15_object *obj;
	sc_pkcs15_pubkey_t *pubkey = NULL;
	sc_pkcs15_cert_t *cert = NULL;
	sc_pkcs15_der_t pem_key;

	id.len = SC_PKCS15_MAX_ID_SIZE;
	sc_pkcs15_hex_string_to_id(opt_pubkey, &id);

	r = sc_pkcs15_find_pubkey_by_id(p15card, &id, &obj);
	if (r >= 0) {
		if (verbose)
			printf("Reading public key with ID '%s'\n", opt_pubkey);
		r = authenticate(obj);
		if (r >= 0)
			r = sc_pkcs15_read_pubkey(p15card, obj, &pubkey);
	} else if (r == SC_ERROR_OBJECT_NOT_FOUND) {
		/* No pubkey - try if there's a certificate */
		r = sc_pkcs15_find_cert_by_id(p15card, &id, &obj);
		if (r >= 0) {
			if (verbose)
				printf("Reading certificate with ID '%s'\n", opt_pubkey);
			r = sc_pkcs15_read_certificate(p15card,
				(sc_pkcs15_cert_info_t *) obj->data,
				&cert);
		}
		if (r >= 0)
			pubkey = cert->key;
	}

	if (r == SC_ERROR_OBJECT_NOT_FOUND) {
		fprintf(stderr, "Public key with ID '%s' not found.\n", opt_pubkey);
		return 2;
	}
	if (r < 0) {
		fprintf(stderr, "Public key enumeration failed: %s\n", sc_strerror(r));
		return 1;
	}
	if (!pubkey) {
		fprintf(stderr, "Public key not available\n");
		return 1;
	}

	r = pubkey_pem_encode(pubkey, &pubkey->data, &pem_key);
	if (r < 0) {
		fprintf(stderr, "Error encoding PEM key: %s\n", sc_strerror(r));
		r = 1;
	} else {
		r = print_pem_object("PUBLIC KEY", pem_key.value, pem_key.len);
		free(pem_key.value);
	}

	if (cert)
		sc_pkcs15_free_certificate(cert);
	else if (pubkey)
		sc_pkcs15_free_pubkey(pubkey);

	return r;
}