void _cdk_free_signature(cdk_pkt_signature_t sig) { cdk_desig_revoker_t r; size_t nsig; if (!sig) return; nsig = cdk_pk_get_nsig(sig->pubkey_algo); _cdk_free_mpibuf(nsig, sig->mpi); cdk_subpkt_free(sig->hashed); sig->hashed = NULL; cdk_subpkt_free(sig->unhashed); sig->unhashed = NULL; while (sig->revkeys) { r = sig->revkeys->next; cdk_free(sig->revkeys); sig->revkeys = r; } cdk_free(sig); }
static cdk_error_t write_signature (cdk_stream_t out, cdk_pkt_signature_t sig, int old_ctb) { byte *buf; size_t nbytes, size, nsig; cdk_error_t rc; assert (out); assert (sig); if (!KEY_CAN_SIGN (sig->pubkey_algo)) return CDK_Inv_Algo; if (sig->version < 2 || sig->version > 4) return CDK_Inv_Packet; if (DEBUG_PKT) _cdk_log_debug ("write_signature:\n"); nsig = cdk_pk_get_nsig (sig->pubkey_algo); if (!nsig) return CDK_Inv_Algo; if (sig->version < 4) return write_v3_sig (out, sig, nsig); size = 10 + calc_subpktsize (sig->hashed) + calc_subpktsize (sig->unhashed) + calc_mpisize (sig->mpi, nsig); rc = pkt_write_head (out, 0, size, CDK_PKT_SIGNATURE); if (!rc) rc = stream_putc (out, 4); if (!rc) rc = stream_putc (out, sig->sig_class); if (!rc) rc = stream_putc (out, _cdk_pub_algo_to_pgp (sig->pubkey_algo)); if (!rc) rc = stream_putc (out, _gnutls_hash_algo_to_pgp (sig->digest_algo)); if (!rc) rc = write_16 (out, sig->hashed_size); if (!rc) { buf = _cdk_subpkt_get_array (sig->hashed, 0, &nbytes); if (!buf) return CDK_Out_Of_Core; rc = stream_write (out, buf, nbytes); cdk_free (buf); } if (!rc) rc = write_16 (out, sig->unhashed_size); if (!rc) { buf = _cdk_subpkt_get_array (sig->unhashed, 0, &nbytes); if (!buf) return CDK_Out_Of_Core; rc = stream_write (out, buf, nbytes); cdk_free (buf); } if (!rc) rc = stream_putc (out, sig->digest_start[0]); if (!rc) rc = stream_putc (out, sig->digest_start[1]); if (!rc) rc = write_mpibuf (out, sig->mpi, nsig); return rc; }
static cdk_error_t read_signature (cdk_stream_t inp, size_t pktlen, cdk_pkt_signature_t sig) { size_t nbytes; size_t i, size, nsig; cdk_error_t rc; if (!inp || !sig) return CDK_Inv_Value; if (DEBUG_PKT) _cdk_log_debug ("read_signature: %d octets\n", pktlen); if (pktlen < 16) return CDK_Inv_Packet; sig->version = cdk_stream_getc (inp); if (sig->version < 2 || sig->version > 4) return CDK_Inv_Packet_Ver; sig->flags.exportable = 1; sig->flags.revocable = 1; if (sig->version < 4) { if (cdk_stream_getc (inp) != 5) return CDK_Inv_Packet; sig->sig_class = cdk_stream_getc (inp); sig->timestamp = read_32 (inp); sig->keyid[0] = read_32 (inp); sig->keyid[1] = read_32 (inp); sig->pubkey_algo = _pgp_pub_algo_to_cdk (cdk_stream_getc (inp)); sig->digest_algo = _pgp_hash_algo_to_gnutls (cdk_stream_getc (inp)); sig->digest_start[0] = cdk_stream_getc (inp); sig->digest_start[1] = cdk_stream_getc (inp); nsig = cdk_pk_get_nsig (sig->pubkey_algo); if (!nsig) return CDK_Inv_Algo; for (i = 0; i < nsig; i++) { rc = read_mpi (inp, &sig->mpi[i], 0); if (rc) return rc; } } else { sig->sig_class = cdk_stream_getc (inp); sig->pubkey_algo = _pgp_pub_algo_to_cdk (cdk_stream_getc (inp)); sig->digest_algo = _pgp_hash_algo_to_gnutls (cdk_stream_getc (inp)); sig->hashed_size = read_16 (inp); size = sig->hashed_size; sig->hashed = NULL; while (size > 0) { rc = read_subpkt (inp, &sig->hashed, &nbytes); if (rc) return rc; size -= nbytes; } sig->unhashed_size = read_16 (inp); size = sig->unhashed_size; sig->unhashed = NULL; while (size > 0) { rc = read_subpkt (inp, &sig->unhashed, &nbytes); if (rc) return rc; size -= nbytes; } rc = parse_sig_subpackets (sig); if (rc) return rc; sig->digest_start[0] = cdk_stream_getc (inp); sig->digest_start[1] = cdk_stream_getc (inp); nsig = cdk_pk_get_nsig (sig->pubkey_algo); if (!nsig) return CDK_Inv_Algo; for (i = 0; i < nsig; i++) { rc = read_mpi (inp, &sig->mpi[i], 0); if (rc) return rc; } } return 0; }