void keynote_sigver(int argc, char *argv[]) { char *buf, **assertlist; int fd, i, n, j; struct stat sb; if (argc != 2) { sigverusage(); exit(0); } /* Open and read assertion file */ fd = open(argv[1], O_RDONLY, 0); if (fd < 0) { perror(argv[1]); exit(1); } if (fstat(fd, &sb) < 0) { perror("fstat()"); exit(1); } if (sb.st_size == 0) /* Paranoid */ { fprintf(stderr, "Illegal assertion-file size 0\n"); exit(1); } buf = (char *) calloc(sb.st_size + 1, sizeof(char)); if (buf == (char *) NULL) { perror("calloc()"); exit(1); } if (read(fd, buf, sb.st_size) < 0) { perror("read()"); exit(1); } close(fd); assertlist = kn_read_asserts(buf, sb.st_size, &n); if (assertlist == NULL) { fprintf(stderr, "Out of memory while allocating memory for " "assertions.\n"); exit(1); } if (n == 0) { fprintf(stderr, "No assertions found in %s.\n", argv[1]); free(assertlist); exit(1); } free(buf); for (j = 0; j < n; j++) { i = kn_verify_assertion(assertlist[j], strlen(assertlist[j])); if (i == -1) { switch (keynote_errno) { case ERROR_MEMORY: fprintf(stderr, "Out of memory while parsing assertion %d.\n", j); break; case ERROR_SYNTAX: fprintf(stderr, "Syntax error while parsing assertion %d.\n", j); break; default: fprintf(stderr, "Unknown error while parsing assertion %d.\n", j); } } else { if (i == SIGRESULT_TRUE) fprintf(stdout, "Signature on assertion %d verified.\n", j); else { if (keynote_errno != 0) fprintf(stdout, "Signature on assertion %d could not be verified " "(keynote_errno = %d).\n", j, keynote_errno); else fprintf(stdout, "Signature on assertion %d did not verify!\n", j); } } free(assertlist[j]); } free(assertlist); exit(0); }
int initialize_keynote(char *str_nonce, char *str_date) { char *policy_assertions; // policy file char *root_key; // root of trust char policy_template[] = "" "KeyNote-Version: 2\n" "Authorizer: \"POLICY\"\n" "licensees:\n%s" "conditions: app_domain == \"%s\" && nonce == \"%s\" " "&& date >= \"%s\"-> \"true\";\n"; int sessionid, num, i, j; char **decomposed; int rlen; /* * create temporary KeyNote session. */ sessionid = kn_init(); if (sessionid == -1) { fprintf(stderr, "Failed to create a new session.\n"); return(-1); } /* create policy. We read in the root of trust key from * a file and create a policy file for the temporary session * that is a close match to this request */ if (read_file("auth_public_key", &root_key, &rlen) < 0) { fprintf(stderr, "failed to read file 'auth_public_key'.\n"); return(-1); } else { char *str_app_domain = APP_DOMAIN; // char *str_nonce = nonce; // we get this from our offer // char *str_date = "20140216"; // we get this from our offer printf(policy_template, root_key, str_app_domain, str_nonce, str_date); rlen = strlen(policy_template) + strlen(root_key) + strlen(str_app_domain) + strlen(str_nonce) + strlen(str_date); if ((policy_assertions = calloc(rlen, 1)) == NULL) { fprintf(stderr, "policy calloc failed to get %d bytes\n", rlen); return(-1); } snprintf(policy_assertions, rlen, policy_template, root_key, str_app_domain, str_nonce, str_date); printf("policy file = <<<%s>>>\n", policy_assertions); } /* Let's find how many policies we just "read". */ decomposed = kn_read_asserts(policy_assertions, strlen(policy_assertions), &num); if (decomposed == NULL) { fprintf(stderr, "Failed to allocate memory for policy assertions.\n"); return(-1); } /* * If there were no assertions in the first argument to kn_read_asserts, * we'll get a valid pointer back, which we need to free. Note that this * is an error; we always MUST have at least one policy assertion. */ if (num == 0) { free(decomposed); fprintf(stderr, "No policy assertions provided.\n"); return(-1); } /* * We no longer need a copy of policy_assertions, so we could * free it here. */ free(policy_assertions); /* * decomposed now contains num pointers to strings, each containing a * single assertion. We now add them all to the session. */ for (i = 0; i < num; i++) { // printf("kn_add_assertion(%s)\n", decomposed[i]); j = kn_add_assertion(sessionid, decomposed[i], strlen(decomposed[i]), ASSERT_FLAG_LOCAL); if (j == -1) { switch (keynote_errno) { case ERROR_MEMORY: fprintf(stderr, "Out of memory, trying to add policy " "assertion %d.\n", j); break; case ERROR_SYNTAX: fprintf(stderr, "Syntax error parsing policy " "assertion %d.\n", j); break; case ERROR_NOTFOUND: fprintf(stderr, "Session %d not found while adding " "policy assertion %d.\n", sessionid, j); default: fprintf(stderr, "Unspecified error %d (shouldn't happen) " "while adding policy assertion %d.\n", keynote_errno, j); break; } /* We don't need the assertion any more. */ free(decomposed[i]); } } /* Now free decomposed itself. */ free(decomposed); return(sessionid); }
int load_credential(int sessionid, char *credential_assertions) { int num; int i; int j; char **decomposed; /* Let's find how many credentials we just "received". */ decomposed = kn_read_asserts(credential_assertions, strlen(credential_assertions), &num); if (decomposed == NULL) { fprintf(stderr, "Failed to allocate memory for credential " "assertions.\n"); return(-1); } /* * If there were no assertions in the first argument to kn_read_asserts, * we'll get a valid pointer back, which we need to free. Note that * it is legal to have zero credentials. */ if (num == 0) { free(decomposed); fprintf(stderr, "No credential assertions provided.\n"); } /* * decomposed now contains num pointers to strings, each containing a * single assertion. We now add them all to the session. */ for (i = 0; i < num; i++) { // printf("kn_add_assertion<<<%s>>>\n", decomposed[i]); j = kn_add_assertion(sessionid, decomposed[i], strlen(decomposed[i]), 0); if (j == -1) { switch (keynote_errno) { case ERROR_MEMORY: fprintf(stderr, "Out of memory, trying to add credential " "assertion %d.\n", j); break; case ERROR_SYNTAX: fprintf(stderr, "Syntax error parsing credential " "assertion %d.\n", j); break; case ERROR_NOTFOUND: fprintf(stderr, "Session %d not found while adding " "credential assertion %d.\n", sessionid, j); default: fprintf(stderr, "Unspecified error %d (shouldn't happen) " "while adding credential assertion %d.\n", keynote_errno, j); break; } /* We don't need the assertion any more. */ free(decomposed[i]); } } free(decomposed); }
/* * process_request_msg -- process the request that should nominally be * received from the client over the socket. * The request is a pseudo-credential, which is close enough * to the real thing that keynote can parse it and verify it. * The request has as the authoriser the key of the client * (and is signed by that key). * There is no licensees per se, we use the word 'REQUEST' as * a placeholder and so that the server can confirm that this * is a request, not a credential. * * The conditions are *assignments*. This is were it stops * looking like a real credential. We read these in as state * variables for the keynote session (actions). * * Processing takes these steps: * a) verify the request (i.e. that it signed by the authorizer) * b) extract the authorizer key and feed it into keynote as * the action authorizer (the key that makes the request) * c) extract the state variables from the request and feed * them into keynote. * * If all goes OK, we return 0, otherwise a negative number. */ int process_request_msg(int sessionid, char *rbuf, int rlen) { int n; int rval; char **assertlist; struct assertion *assertp; char *vps; char *vpe; char c; if ((assertlist = kn_read_asserts(rbuf, rlen, &n)) == NULL) { fprintf(stderr, "Out of memory while allocating memory for " "request.\n"); return(-1); } if (n != 1) { fprintf(stderr, "Request must haev only one assetion\n"); return(-1); } if (kn_verify_assertion(assertlist[0], strlen(assertlist[0])) < 0) { switch (keynote_errno) { case ERROR_MEMORY: fprintf(stderr, "Out of memory while parsing request.\n"); break; case ERROR_SYNTAX: fprintf(stderr, "Syntax error while parsing request.\n"); break; default: fprintf(stderr, "Unknown error while parsing request.\n"); } return(-1); } /* * verified, so now we use an internal keynote routine to * parse the request pseudo-credential and extract the * authoriser key and the variables. */ if ((assertp = keynote_parse_assertion(rbuf, rlen, 0)) == NULL) { fprintf(stderr, "keynote_parse_assertion failed\n"); return(-1); } /* * we now extract the authoriser key from the request and add it to the * keynote database. This is to ensure that the key which signed the * request is the authorizer key for this session. */ if ((rval = add_authorizer(sessionid, assertp->as_authorizer_string_s, assertp->as_authorizer_string_e)) < 0) { fprintf(stderr, "add_authorizer failed\n"); return(-1); } /* * we now extract the variables from the request and insert them into * the Keynote database * * Why do we trust the variables given to us by the client? * we have added variables to the root policy (e.g. app_domain, * nonce, date, etc) from our offer, in order to ensure that * the request refers to *our* offer. */ vps = assertp->as_conditions_s; vpe = assertp->as_conditions_e; c = *vpe; *vpe = '\0'; if ((rval = add_variables(sessionid, vps)) < 0) { fprintf(stderr, "add_variable, returned %d\n", rval); return(-1); } *vpe = c; return(0); }