static int print_pem_object(const char *kind, const u8*data, size_t data_len) { FILE *outf; unsigned char *buf = NULL; size_t buf_len = 1024; int r; /* With base64, every 3 bytes yield 4 characters, and with * 64 chars per line we know almost exactly how large a buffer we * will need. */ buf_len = (data_len + 2) / 3 * 4; buf_len += 2 * (buf_len / 64 + 2); /* certain platforms use CRLF */ buf_len += 64; /* slack for checksum etc */ if (!(buf = malloc(buf_len))) { perror("print_pem_object"); return 1; } r = sc_base64_encode(data, data_len, buf, buf_len, 64); if (r < 0) { fprintf(stderr, "Base64 encoding failed: %s\n", sc_strerror(r)); free(buf); return 1; } if (opt_outfile != NULL) { outf = fopen(opt_outfile, "w"); if (outf == NULL) { fprintf(stderr, "Error opening file '%s': %s\n", opt_outfile, strerror(errno)); free(buf); return 2; } } else outf = stdout; fprintf(outf, "-----BEGIN %s-----\n" "%s" "-----END %s-----\n", kind, buf, kind); if (outf != stdout) fclose(outf); free(buf); return 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); }
NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char* argn[], char* argv[], NPSavedData* saved) { PluginInstance* This = NULL; NPError rv; int r, i, datalen, b64datalen; u8 *data = NULL, *b64data = NULL; char *postUrl = NULL, *dataToSign = NULL, *fieldName = NULL; printf("NPP_New()\n"); if (instance == NULL) return NPERR_INVALID_INSTANCE_ERROR; instance->pdata = NPN_MemAlloc(sizeof(PluginInstance)); This = (PluginInstance*) instance->pdata; if (This == NULL) return NPERR_OUT_OF_MEMORY_ERROR; This->ctx = NULL; This->card = NULL; This->p15card = NULL; for (i = 0; i < argc; i++) { if (strcmp(argn[i], "wsxaction") == 0) { postUrl = strdup(argv[i]); } else if (strcmp(argn[i], "wsxdatatosign") == 0) { dataToSign = strdup(argv[i]); } else if (strcmp(argn[i], "wsxname") == 0) { fieldName = strdup(argv[i]); } else printf("'%s' = '%s'\n", argn[i], argv[i]); } if (postUrl == NULL || dataToSign == NULL) { r = NPERR_GENERIC_ERROR; goto err; } if (fieldName == NULL) fieldName = strdup("SignedData"); This->signdata = dataToSign; This->signdata_len = strlen(dataToSign); r = create_envelope(This, &data, &datalen); if (r) { r = NPERR_GENERIC_ERROR; goto err; } b64datalen = datalen * 4 / 3 + 4; b64data = (u8 *) malloc(b64datalen); r = sc_base64_encode(data, datalen, b64data, b64datalen, 0); if (r) { r = NPERR_GENERIC_ERROR; goto err; } printf("Posting to '%s'\n", postUrl); printf("Data to sign: %s\n", dataToSign); printf("Signed: %s\n", b64data); rv = post_data(instance, postUrl, "_self", strlen((char *) b64data), (char *) b64data, fieldName); printf("post_data returned %d\n", rv); r = NPERR_NO_ERROR; err: if (fieldName) free(fieldName); if (dataToSign) free(dataToSign); if (postUrl) free(postUrl); if (data) free(data); if (b64data) free(b64data); return r; }