- added README for PAM module
- added a few error messages - fixed certificate caching (which is still kludgy) git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@44 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
parent
1194017d5a
commit
e53cfa4595
@ -44,6 +44,8 @@
|
|||||||
#define SC_ERROR_BUFFER_TOO_SMALL -1017
|
#define SC_ERROR_BUFFER_TOO_SMALL -1017
|
||||||
#define SC_ERROR_CARD_NOT_PRESENT -1018
|
#define SC_ERROR_CARD_NOT_PRESENT -1018
|
||||||
#define SC_ERROR_RESOURCE_MANAGER -1019
|
#define SC_ERROR_RESOURCE_MANAGER -1019
|
||||||
|
#define SC_ERROR_CARD_REMOVED -1020
|
||||||
|
#define SC_ERROR_INVALID_PIN_LENGTH -1021
|
||||||
|
|
||||||
#define SC_APDU_CASE_NONE 0
|
#define SC_APDU_CASE_NONE 0
|
||||||
#define SC_APDU_CASE_1 1
|
#define SC_APDU_CASE_1 1
|
||||||
@ -117,8 +119,9 @@ struct sc_file {
|
|||||||
struct sc_card {
|
struct sc_card {
|
||||||
int class;
|
int class;
|
||||||
struct sc_context *context;
|
struct sc_context *context;
|
||||||
|
|
||||||
SCARDHANDLE pcsc_card;
|
SCARDHANDLE pcsc_card;
|
||||||
const char *reader;
|
int reader;
|
||||||
char atr[SC_MAX_ATR_SIZE];
|
char atr[SC_MAX_ATR_SIZE];
|
||||||
int atr_len;
|
int atr_len;
|
||||||
|
|
||||||
@ -170,8 +173,15 @@ int sc_destroy_context(struct sc_context *ctx);
|
|||||||
int sc_connect_card(struct sc_context *ctx,
|
int sc_connect_card(struct sc_context *ctx,
|
||||||
int reader, struct sc_card **card);
|
int reader, struct sc_card **card);
|
||||||
int sc_disconnect_card(struct sc_card *card);
|
int sc_disconnect_card(struct sc_card *card);
|
||||||
|
|
||||||
|
/* Checks if a card is present on the supplied reader
|
||||||
|
* Returns: 1 if card present, 0 if card absent and < 0 in case of an error */
|
||||||
int sc_detect_card(struct sc_context *ctx, int reader);
|
int sc_detect_card(struct sc_context *ctx, int reader);
|
||||||
/* timeout of -1 means forever, reader of -1 means all readers */
|
|
||||||
|
/* Waits for card insertion on the supplied reader
|
||||||
|
* timeout of -1 means forever, reader of -1 means all readers
|
||||||
|
* Returns: 1 if a card was found, 0 if timeout occured
|
||||||
|
* and < 0 in case of an error */
|
||||||
int sc_wait_for_card(struct sc_context *ctx, int reader, int timeout);
|
int sc_wait_for_card(struct sc_context *ctx, int reader, int timeout);
|
||||||
|
|
||||||
int sc_lock(struct sc_card *card);
|
int sc_lock(struct sc_card *card);
|
||||||
|
@ -129,27 +129,35 @@ int sc_pkcs15_read_certificate(struct sc_pkcs15_card *p15card,
|
|||||||
struct sc_file file;
|
struct sc_file file;
|
||||||
char *data = NULL;
|
char *data = NULL;
|
||||||
struct sc_pkcs15_cert *cert;
|
struct sc_pkcs15_cert *cert;
|
||||||
char fname[50];
|
char fname[150];
|
||||||
u8 buf[2048];
|
u8 buf[2048];
|
||||||
|
|
||||||
FILE *crtf = NULL;
|
FILE *crtf = NULL;
|
||||||
int cert_found = 0;
|
int cert_found = 0;
|
||||||
|
char *homedir;
|
||||||
|
|
||||||
assert(p15card != NULL && info != NULL && cert_out != NULL);
|
assert(p15card != NULL && info != NULL && cert_out != NULL);
|
||||||
|
|
||||||
|
#if 1
|
||||||
/* FIXME: Remove this kludge */
|
/* FIXME: Remove this kludge */
|
||||||
sprintf(fname, "/tmp/fineid-%02X.crt", info->id.value[0]);
|
homedir = getenv("HOME");
|
||||||
|
if (homedir == NULL)
|
||||||
|
goto no_cert;
|
||||||
|
sprintf(fname, "%s/.eid/%s_%02X.crt", homedir, p15card->label, info->id.value[0]);
|
||||||
crtf = fopen(fname, "r");
|
crtf = fopen(fname, "r");
|
||||||
if (crtf != NULL) {
|
if (crtf == NULL)
|
||||||
r = fread(buf, 1, sizeof(buf), crtf);
|
goto no_cert;
|
||||||
if (r > 0) {
|
|
||||||
data = malloc(r);
|
r = fread(buf, 1, sizeof(buf), crtf);
|
||||||
memcpy(data, buf, r);
|
if (r > 0) {
|
||||||
len = r;
|
data = malloc(r);
|
||||||
cert_found = 1;
|
memcpy(data, buf, r);
|
||||||
}
|
len = r;
|
||||||
fclose(crtf);
|
cert_found = 1;
|
||||||
}
|
}
|
||||||
|
fclose(crtf);
|
||||||
|
no_cert:
|
||||||
|
#endif
|
||||||
if (!cert_found) {
|
if (!cert_found) {
|
||||||
r = sc_select_file(p15card->card, &file, &info->path,
|
r = sc_select_file(p15card->card, &file, &info->path,
|
||||||
SC_SELECT_FILE_BY_PATH);
|
SC_SELECT_FILE_BY_PATH);
|
||||||
@ -165,11 +173,13 @@ int sc_pkcs15_read_certificate(struct sc_pkcs15_card *p15card,
|
|||||||
}
|
}
|
||||||
len = r;
|
len = r;
|
||||||
/* FIXME: kludge! */
|
/* FIXME: kludge! */
|
||||||
|
#if 1
|
||||||
crtf = fopen(fname, "w");
|
crtf = fopen(fname, "w");
|
||||||
if (crtf != NULL) {
|
if (crtf != NULL) {
|
||||||
fwrite(data, len, 1, crtf);
|
fwrite(data, len, 1, crtf);
|
||||||
fclose(crtf);
|
fclose(crtf);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
cert = malloc(sizeof(struct sc_pkcs15_cert));
|
cert = malloc(sizeof(struct sc_pkcs15_cert));
|
||||||
if (cert == NULL) {
|
if (cert == NULL) {
|
||||||
|
@ -171,7 +171,7 @@ int sc_pkcs15_verify_pin(struct sc_pkcs15_card *p15card,
|
|||||||
if (pin->magic != SC_PKCS15_PIN_MAGIC)
|
if (pin->magic != SC_PKCS15_PIN_MAGIC)
|
||||||
return SC_ERROR_OBJECT_NOT_VALID;
|
return SC_ERROR_OBJECT_NOT_VALID;
|
||||||
if (pinlen > pin->stored_length || pinlen < pin->min_length)
|
if (pinlen > pin->stored_length || pinlen < pin->min_length)
|
||||||
return SC_ERROR_INVALID_ARGUMENTS;
|
return SC_ERROR_INVALID_PIN_LENGTH;
|
||||||
card = p15card->card;
|
card = p15card->card;
|
||||||
r = sc_select_file(card, &file, &pin->path,
|
r = sc_select_file(card, &file, &pin->path,
|
||||||
SC_SELECT_FILE_BY_PATH);
|
SC_SELECT_FILE_BY_PATH);
|
||||||
|
@ -174,9 +174,19 @@ static int sc_transceive_t0(struct sc_card *card, struct sc_apdu *apdu)
|
|||||||
rv = SCardTransmit(card->pcsc_card, &sSendPci, s, dwSendLength,
|
rv = SCardTransmit(card->pcsc_card, &sSendPci, s, dwSendLength,
|
||||||
&sRecvPci, r, &dwRecvLength);
|
&sRecvPci, r, &dwRecvLength);
|
||||||
if (rv != SCARD_S_SUCCESS) {
|
if (rv != SCARD_S_SUCCESS) {
|
||||||
fprintf(stderr, "SCardTransmit failed with 0x%08x\n",
|
switch (rv) {
|
||||||
(int) rv);
|
case SCARD_W_REMOVED_CARD:
|
||||||
return SC_ERROR_TRANSMIT_FAILED;
|
return SC_ERROR_CARD_REMOVED;
|
||||||
|
case SCARD_E_NOT_TRANSACTED:
|
||||||
|
if (sc_detect_card(card->context, card->reader) != 1)
|
||||||
|
return SC_ERROR_CARD_REMOVED;
|
||||||
|
return SC_ERROR_TRANSMIT_FAILED;
|
||||||
|
default:
|
||||||
|
if (sc_debug) {
|
||||||
|
fprintf(stderr, "SCardTransmit returned 0x%08lX.\n", rv);
|
||||||
|
return SC_ERROR_TRANSMIT_FAILED;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
apdu->resplen = dwRecvLength;
|
apdu->resplen = dwRecvLength;
|
||||||
memcpy(apdu->resp, r, dwRecvLength);
|
memcpy(apdu->resp, r, dwRecvLength);
|
||||||
@ -530,7 +540,6 @@ int sc_wait_for_card(struct sc_context *ctx, int reader, int timeout)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int sc_establish_context(struct sc_context **ctx_out)
|
int sc_establish_context(struct sc_context **ctx_out)
|
||||||
{
|
{
|
||||||
struct sc_context *ctx;
|
struct sc_context *ctx;
|
||||||
@ -658,6 +667,8 @@ int sc_connect_card(struct sc_context *ctx,
|
|||||||
free(card);
|
free(card);
|
||||||
return -1; /* FIXME */
|
return -1; /* FIXME */
|
||||||
}
|
}
|
||||||
|
card->reader = reader;
|
||||||
|
card->context = ctx;
|
||||||
card->pcsc_card = card_handle;
|
card->pcsc_card = card_handle;
|
||||||
i = rgReaderStates[0].cbAtr;
|
i = rgReaderStates[0].cbAtr;
|
||||||
if (i >= SC_MAX_ATR_SIZE)
|
if (i >= SC_MAX_ATR_SIZE)
|
||||||
@ -671,7 +682,6 @@ int sc_connect_card(struct sc_context *ctx,
|
|||||||
} else {
|
} else {
|
||||||
card->class = 0; /* FIXME */
|
card->class = 0; /* FIXME */
|
||||||
}
|
}
|
||||||
card->reader = ctx->readers[reader];
|
|
||||||
*card_out = card;
|
*card_out = card;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -703,8 +713,12 @@ const char *sc_strerror(int error)
|
|||||||
"PIN code incorrect",
|
"PIN code incorrect",
|
||||||
"Security status not satisfied",
|
"Security status not satisfied",
|
||||||
"Error connecting to Resource Manager",
|
"Error connecting to Resource Manager",
|
||||||
|
"Invalid ASN.1 object",
|
||||||
"Buffer too small",
|
"Buffer too small",
|
||||||
|
"Card not present",
|
||||||
|
"Error with Resource Manager",
|
||||||
|
"Card removed",
|
||||||
|
"Invalid PIN length"
|
||||||
};
|
};
|
||||||
int nr_errors = sizeof(errors) / sizeof(errors[0]);
|
int nr_errors = sizeof(errors) / sizeof(errors[0]);
|
||||||
|
|
||||||
|
14
src/pam/README
Normal file
14
src/pam/README
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
|
||||||
|
Steps required to make the PAM module work:
|
||||||
|
|
||||||
|
1. Compile and link the pam_pkcs15.so shared library.
|
||||||
|
2. Copy pam_pkcs.so to /lib/security.
|
||||||
|
3. Edit /etc/pam.d/login file. Add the following line before the
|
||||||
|
pam_unix.so (on Debian) or pam_pwdb.so (on Red Hat) entry:
|
||||||
|
auth sufficient /lib/security/pam_pkcs15.so
|
||||||
|
4. Copy your PEM encoded certificate to a file in your home directory
|
||||||
|
called '.eid/authorized_certificates'.
|
||||||
|
NOTE: You can use the 'certtest' program to get the PEM encoded
|
||||||
|
certificate.
|
||||||
|
5. Try to login with your card in the reader.
|
||||||
|
|
@ -305,7 +305,9 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t * pamh, int flags, int argc, con
|
|||||||
DBG(printf("Verifying PIN code...\n"));
|
DBG(printf("Verifying PIN code...\n"));
|
||||||
r = sc_pkcs15_verify_pin(p15card, &p15card->pin_info[0], password, strlen(password));
|
r = sc_pkcs15_verify_pin(p15card, &p15card->pin_info[0], password, strlen(password));
|
||||||
if (r) {
|
if (r) {
|
||||||
printf("PIN code verification failed: %s\n", sc_strerror(r));
|
DBG(printf("PIN code verification failed: %s\n", sc_strerror(r)));
|
||||||
|
if (r == SC_ERROR_CARD_REMOVED)
|
||||||
|
printf("SmartCard removed.\n");
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
DBG(printf("Awright! PIN code correct!\n"));
|
DBG(printf("Awright! PIN code correct!\n"));
|
||||||
|
@ -99,5 +99,6 @@ int main(int argc, char *argv[])
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
sc_asn1_print_tags(cert->data, cert->data_len);
|
sc_asn1_print_tags(cert->data, cert->data_len);
|
||||||
}
|
}
|
||||||
|
sc_test_cleanup();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user