static int read_certificate(void) { int r, i, count; struct sc_pkcs15_id id; struct sc_pkcs15_object *objs[32]; id.len = SC_PKCS15_MAX_ID_SIZE; sc_pkcs15_hex_string_to_id(opt_cert, &id); r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_CERT_X509, objs, 32); if (r < 0) { fprintf(stderr, "Certificate enumeration failed: %s\n", sc_strerror(r)); return 1; } count = r; for (i = 0; i < count; i++) { struct sc_pkcs15_cert_info *cinfo = (struct sc_pkcs15_cert_info *) objs[i]->data; struct sc_pkcs15_cert *cert; if (sc_pkcs15_compare_id(&id, &cinfo->id) != 1) continue; if (verbose) printf("Reading certificate with ID '%s'\n", opt_cert); r = sc_pkcs15_read_certificate(p15card, cinfo, &cert); if (r) { fprintf(stderr, "Certificate read failed: %s\n", sc_strerror(r)); return 1; } r = print_pem_object("CERTIFICATE", cert->data, cert->data_len); sc_pkcs15_free_certificate(cert); return r; } fprintf(stderr, "Certificate with ID '%s' not found.\n", opt_cert); return 2; }
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); }
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; }
static int get_key(unsigned int usage, sc_pkcs15_object_t **result) { sc_pkcs15_object_t *key, *pin; const char *usage_name; sc_pkcs15_id_t id; int r; usage_name = (usage & SC_PKCS15_PRKEY_USAGE_SIGN)? "signature" : "decryption"; if (opt_key_id != NULL) { sc_pkcs15_hex_string_to_id(opt_key_id, &id); r = sc_pkcs15_find_prkey_by_id_usage(p15card, &id, usage, &key); if (r < 0) { fprintf(stderr, "Unable to find private %s key '%s': %s\n", usage_name, opt_key_id, sc_strerror(r)); return 2; } } else { r = sc_pkcs15_find_prkey_by_id_usage(p15card, NULL, usage, &key); if (r < 0) { fprintf(stderr, "Unable to find any private %s key: %s\n", usage_name, sc_strerror(r)); return 2; } } *result = key; if (key->auth_id.len) { static sc_pkcs15_object_t *prev_pin = NULL; char *pincode; r = sc_pkcs15_find_pin_by_auth_id(p15card, &key->auth_id, &pin); if (r) { fprintf(stderr, "Unable to find PIN code for private key: %s\n", sc_strerror(r)); return 1; } /* Pin already verified previously */ if (pin == prev_pin) return 0; pincode = get_pin(pin); if (((pincode == NULL || *pincode == '\0')) && !(p15card->card->reader->capabilities & SC_READER_CAP_PIN_PAD)) return 5; r = sc_pkcs15_verify_pin(p15card, pin, (const u8 *)pincode, pincode ? strlen(pincode) : 0); if (r) { fprintf(stderr, "PIN code verification failed: %s\n", sc_strerror(r)); return 5; } free(pincode); if (verbose) fprintf(stderr, "PIN code correct.\n"); prev_pin = pin; } return 0; }