static int sign(struct sc_pkcs15_object *obj) { u8 buf[1024], out[1024]; struct sc_pkcs15_prkey_info *key = (struct sc_pkcs15_prkey_info *) obj->data; int r, c, len; if (opt_input == NULL) { fprintf(stderr, "No input file specified.\n"); return 2; } c = read_input(buf, sizeof(buf)); if (c < 0) return 2; len = sizeof(out); if (obj->type == SC_PKCS15_TYPE_PRKEY_RSA && !(opt_crypt_flags & SC_ALGORITHM_RSA_PAD_PKCS1) && (size_t)c != key->modulus_length/8) { fprintf(stderr, "Input has to be exactly %lu bytes, when using no padding.\n", (unsigned long) key->modulus_length/8); return 2; } if (!key->native) { fprintf(stderr, "Deprecated non-native key detected! Upgrade your smart cards.\n"); return SC_ERROR_NOT_SUPPORTED; } r = sc_pkcs15_compute_signature(p15card, obj, opt_crypt_flags, buf, c, out, len); if (r < 0) { fprintf(stderr, "Compute signature failed: %s\n", sc_strerror(r)); return 1; } len = r; if (obj->type == SC_PKCS15_TYPE_PRKEY_EC) { if (opt_sig_format && (!strcmp(opt_sig_format, "openssl") || !strcmp(opt_sig_format, "sequence"))) { unsigned char *seq; size_t seqlen; if (sc_asn1_sig_value_rs_to_sequence(ctx, out, len, &seq, &seqlen)) { fprintf(stderr, "Failed to convert signature to ASN1 sequence format.\n"); return 2; } memcpy(out, seq, seqlen); len = seqlen; free(seq); } } r = write_output(out, len); return r; }
static int sign(struct sc_pkcs15_object *obj) { u8 buf[1024], out[1024]; struct sc_pkcs15_prkey_info *key = (struct sc_pkcs15_prkey_info *) obj->data; int r, c, len; if (opt_input == NULL) { fprintf(stderr, "No input file specified.\n"); return 2; } c = read_input(buf, sizeof(buf)); if (c < 0) return 2; len = sizeof(out); if (obj->type == SC_PKCS15_TYPE_PRKEY_RSA && !(opt_crypt_flags & SC_ALGORITHM_RSA_PAD_PKCS1) && (size_t)c != key->modulus_length/8) { fprintf(stderr, "Input has to be exactly %lu bytes, when using no padding.\n", (unsigned long) key->modulus_length/8); return 2; } if (!key->native) { fprintf(stderr, "Deprecated non-native key detected! Upgrade your smart cards.\n"); return SC_ERROR_NOT_SUPPORTED; } r = sc_pkcs15_compute_signature(p15card, obj, opt_crypt_flags, buf, c, out, len); if (r < 0) { fprintf(stderr, "Compute signature failed: %s\n", sc_strerror(r)); return 1; } r = write_output(out, r); return 0; }
static int sc_sign(int type, u_char *m, unsigned int m_len, unsigned char *sigret, unsigned int *siglen, RSA *rsa) { struct sc_pkcs15_object *key_obj; int r; unsigned long flags = 0; /* XXX: sc_prkey_op_init will search for a pkcs15 private * key object with the sign or signrecover usage flag set. * If the signing key has only the non-repudiation flag set * the key will be rejected as using a non-repudiation key * for authentication is not recommended. Note: This does not * prevent the use of a non-repudiation key for authentication * if the sign or signrecover flag is set as well. */ r = sc_prkey_op_init(rsa, &key_obj, SC_USAGE_SIGN); if (r) return -1; /* FIXME: length of sigret correct? */ /* FIXME: check 'type' and modify flags accordingly */ flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_SHA1; r = sc_pkcs15_compute_signature(p15card, key_obj, flags, m, m_len, sigret, RSA_size(rsa)); sc_unlock(card); if (r < 0) { error("sc_pkcs15_compute_signature() failed: %s", sc_strerror(r)); goto err; } *siglen = r; return 1; err: sc_close(); return 0; }
void OpenSCKeyHandle::generateSignature(const Context &context, CSSM_ALGORITHMS signOnly, const CssmData &input, CssmData &signature) { // for sc_pkcs15_compute_signature() unsigned int flags = 0; sc_debug(mToken.mScCtx, "In OpenSCKeyHandle::generateSignature()\n"); if (context.type() == CSSM_ALGCLASS_SIGNATURE) { sc_debug(mToken.mScCtx, " type == CSSM_ALGCLASS_SIGNATURE\n"); } else { sc_debug(mToken.mScCtx, " Unknown type: 0x%0x, exiting\n", context.type()); CssmError::throwMe(CSSMERR_CSP_INVALID_CONTEXT); } if (context.algorithm() == CSSM_ALGID_RSA) { sc_debug(mToken.mScCtx, " algorithm == CSSM_ALGID_RSA\n"); } else { sc_debug(mToken.mScCtx, " Unknown algorithm: 0x%0x, exiting\n", context.algorithm()); CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM); } if (signOnly == CSSM_ALGID_SHA1) { if (input.Length != 20) CssmError::throwMe(CSSMERR_CSP_BLOCK_SIZE_MISMATCH); flags |= SC_ALGORITHM_RSA_HASH_SHA1; sc_debug(mToken.mScCtx, " Using SHA1, length is 20\n"); } else if (signOnly == CSSM_ALGID_MD5) { if (input.Length != 16) CssmError::throwMe(CSSMERR_CSP_BLOCK_SIZE_MISMATCH); flags |= SC_ALGORITHM_RSA_HASH_MD5; sc_debug(mToken.mScCtx, " Using MD5, length is 16\n"); } else if (signOnly == CSSM_ALGID_NONE) { sc_debug(mToken.mScCtx, " NO digest (perhaps for SSL authentication)\n"); flags |= SC_ALGORITHM_RSA_HASH_NONE; } else { sc_debug(mToken.mScCtx, " Unknown signOnly value: 0x%0x, exiting\n", signOnly); CssmError::throwMe(CSSMERR_CSP_INVALID_DIGEST_ALGORITHM); } // Get padding, but default to pkcs1 style padding uint32 padding = CSSM_PADDING_PKCS1; context.getInt(CSSM_ATTRIBUTE_PADDING, padding); if (padding == CSSM_PADDING_PKCS1) { sc_debug(mToken.mScCtx, " PKCS#1 padding\n"); flags |= SC_ALGORITHM_RSA_PAD_PKCS1; } else if (padding == CSSM_PADDING_NONE) { sc_debug(mToken.mScCtx, " NO padding\n"); } else { sc_debug(mToken.mScCtx, " Unknown padding 0x%0x, exiting\n", padding); CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_PADDING); } size_t keyLength = (mKey.sizeInBits() + 7) / 8; // @@@ Switch to using tokend allocators unsigned char *outputData = reinterpret_cast<unsigned char *>(malloc(keyLength)); if (outputData == NULL) CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR); sc_debug(mToken.mScCtx, " Signing buffers: inlen=%d, outlen=%d\n",input.Length, keyLength); // Call OpenSC to do the actual signing int rv = sc_pkcs15_compute_signature(mToken.mScP15Card, mKey.signKey(), flags, input.Data, input.Length, outputData, keyLength); sc_debug(mToken.mScCtx, " sc_pkcs15_compute_signature(): rv = %d\n", rv); if (rv < 0) { free(outputData); CssmError::throwMe(CSSMERR_CSP_FUNCTION_FAILED); } signature.Data = outputData; signature.Length = rv; }