static gpgme_error_t parse_enc_to (char *args, gpgme_recipient_t *recp, gpgme_protocol_t protocol) { gpgme_recipient_t rec; char *tail; int i; rec = malloc (sizeof (*rec)); if (!rec) return gpg_error_from_syserror (); rec->next = NULL; rec->keyid = rec->_keyid; rec->status = 0; for (i = 0; i < sizeof (rec->_keyid) - 1; i++) { if (args[i] == '\0' || args[i] == ' ') break; rec->_keyid[i] = args[i]; } rec->_keyid[i] = '\0'; args = &args[i]; if (*args != '\0' && *args != ' ') { free (rec); return trace_gpg_error (GPG_ERR_INV_ENGINE); } while (*args == ' ') args++; if (*args) { gpg_err_set_errno (0); rec->pubkey_algo = _gpgme_map_pk_algo (strtol (args, &tail, 0), protocol); if (errno || args == tail || *tail != ' ') { /* The crypto backend does not behave. */ free (rec); return trace_gpg_error (GPG_ERR_INV_ENGINE); } } /* FIXME: The key length is always 0 right now, so no need to parse it. */ *recp = rec; return 0; }
static gpgme_error_t parse_valid_sig (gpgme_signature_t sig, char *args, gpgme_protocol_t protocol) { char *end = strchr (args, ' '); if (end) { *end = '\0'; end++; } if (!*args) /* We require at least the fingerprint. */ return gpg_error (GPG_ERR_GENERAL); if (sig->fpr) free (sig->fpr); sig->fpr = strdup (args); if (!sig->fpr) return gpg_error_from_syserror (); /* Skip the creation date. */ end = strchr (end, ' '); if (end) { char *tail; sig->timestamp = _gpgme_parse_timestamp (end, &tail); if (sig->timestamp == -1 || end == tail || (*tail && *tail != ' ')) return trace_gpg_error (GPG_ERR_INV_ENGINE); end = tail; sig->exp_timestamp = _gpgme_parse_timestamp (end, &tail); if (sig->exp_timestamp == -1 || end == tail || (*tail && *tail != ' ')) return trace_gpg_error (GPG_ERR_INV_ENGINE); end = tail; while (*end == ' ') end++; /* Skip the signature version. */ end = strchr (end, ' '); if (end) { while (*end == ' ') end++; /* Skip the reserved field. */ end = strchr (end, ' '); if (end) { /* Parse the pubkey algo. */ gpg_err_set_errno (0); sig->pubkey_algo = _gpgme_map_pk_algo (strtol (end, &tail, 0), protocol); if (errno || end == tail || *tail != ' ') return trace_gpg_error (GPG_ERR_INV_ENGINE); end = tail; while (*end == ' ') end++; if (*end) { /* Parse the hash algo. */ gpg_err_set_errno (0); sig->hash_algo = strtol (end, &tail, 0); if (errno || end == tail || *tail != ' ') return trace_gpg_error (GPG_ERR_INV_ENGINE); end = tail; } } } } return 0; }
static gpgme_error_t parse_new_sig (op_data_t opd, gpgme_status_code_t code, char *args, gpgme_protocol_t protocol) { gpgme_signature_t sig; char *end = strchr (args, ' '); char *tail; if (end) { *end = '\0'; end++; } if (!opd->did_prepare_new_sig) { gpg_error_t err; err = prepare_new_sig (opd); if (err) return err; } assert (opd->did_prepare_new_sig); opd->did_prepare_new_sig = 0; assert (opd->current_sig); sig = opd->current_sig; /* FIXME: We should set the source of the state. */ switch (code) { case GPGME_STATUS_GOODSIG: sig->status = gpg_error (GPG_ERR_NO_ERROR); break; case GPGME_STATUS_EXPSIG: sig->status = gpg_error (GPG_ERR_SIG_EXPIRED); break; case GPGME_STATUS_EXPKEYSIG: sig->status = gpg_error (GPG_ERR_KEY_EXPIRED); break; case GPGME_STATUS_BADSIG: sig->status = gpg_error (GPG_ERR_BAD_SIGNATURE); break; case GPGME_STATUS_REVKEYSIG: sig->status = gpg_error (GPG_ERR_CERT_REVOKED); break; case GPGME_STATUS_ERRSIG: /* Parse the pubkey algo. */ if (!end) goto parse_err_sig_fail; gpg_err_set_errno (0); sig->pubkey_algo = _gpgme_map_pk_algo (strtol (end, &tail, 0), protocol); if (errno || end == tail || *tail != ' ') goto parse_err_sig_fail; end = tail; while (*end == ' ') end++; /* Parse the hash algo. */ if (!*end) goto parse_err_sig_fail; gpg_err_set_errno (0); sig->hash_algo = strtol (end, &tail, 0); if (errno || end == tail || *tail != ' ') goto parse_err_sig_fail; end = tail; while (*end == ' ') end++; /* Skip the sig class. */ end = strchr (end, ' '); if (!end) goto parse_err_sig_fail; while (*end == ' ') end++; /* Parse the timestamp. */ sig->timestamp = _gpgme_parse_timestamp (end, &tail); if (sig->timestamp == -1 || end == tail || (*tail && *tail != ' ')) return trace_gpg_error (GPG_ERR_INV_ENGINE); end = tail; while (*end == ' ') end++; /* Parse the return code. */ if (end[0] && (!end[1] || end[1] == ' ')) { switch (end[0]) { case '4': sig->status = gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); break; case '9': sig->status = gpg_error (GPG_ERR_NO_PUBKEY); break; default: sig->status = gpg_error (GPG_ERR_GENERAL); } } else goto parse_err_sig_fail; goto parse_err_sig_ok; parse_err_sig_fail: sig->status = gpg_error (GPG_ERR_GENERAL); parse_err_sig_ok: break; default: return gpg_error (GPG_ERR_GENERAL); } if (*args) { sig->fpr = strdup (args); if (!sig->fpr) return gpg_error_from_syserror (); } return 0; }