summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2014-11-28 17:54:39 +0900
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2014-11-28 17:56:27 +0900
commit8669ab8a98ac36db6c228bcc1bb4688c25d1dccc (patch)
tree72945d25d9cc69b094750107d0b1f3332619eea5
parent151eeacec8c21f203e9d17718ac132d7f56e5155 (diff)
eet - add new api to verify eet file against stored cert
this api makes it far more obvious as to how to verify an eet file via the eet identify mechanisms that use x509 certificates to sign files. this is consistent with the api used to generate the key for sigining thus you can use the same certificate file to compare against for identify. @feature
-rw-r--r--src/lib/eet/Eet.h20
-rw-r--r--src/lib/eet/eet_lib.c148
-rw-r--r--src/tests/eet/eet_suite.c3
3 files changed, 171 insertions, 0 deletions
diff --git a/src/lib/eet/Eet.h b/src/lib/eet/Eet.h
index b3451fa4..de56b18 100644
--- a/src/lib/eet/Eet.h
+++ b/src/lib/eet/Eet.h
@@ -2063,6 +2063,26 @@ eet_identity_print(Eet_Key *key,
2063 FILE *out); 2063 FILE *out);
2064 2064
2065/** 2065/**
2066 * Compare the identify certificate of an eet file against a stored one
2067 *
2068 * @param ef The file handle to check the identify of
2069 * @param certificate_file The path to the certificate file
2070 * @return EINA_TRUE if the certificates match, otherwise EINA_FALSE;
2071 *
2072 * The @p ef file handle mus be valid, and a signed file, otherwise
2073 * checking will fail. The path to the certificate file must be a valid
2074 * file path to a 'pem' format file (the same used for siging with
2075 * eet_identity_open() as a certificate file).
2076 *
2077 * @warning You need to compile signature support in EET.
2078 * @since 1.13
2079 * @ingroup Eet_Cipher_Group
2080 */
2081EAPI Eina_Bool
2082eet_identity_verify(Eet_File *ef,
2083 const char *certificate_file);
2084
2085/**
2066 * Get the x509 der certificate associated with an Eet_File. Will return NULL 2086 * Get the x509 der certificate associated with an Eet_File. Will return NULL
2067 * if the file is not signed. 2087 * if the file is not signed.
2068 * 2088 *
diff --git a/src/lib/eet/eet_lib.c b/src/lib/eet/eet_lib.c
index daa6d3b..ed610f6 100644
--- a/src/lib/eet/eet_lib.c
+++ b/src/lib/eet/eet_lib.c
@@ -1676,6 +1676,154 @@ eet_mode_get(Eet_File *ef)
1676 return ef->mode; 1676 return ef->mode;
1677} 1677}
1678 1678
1679static const char *_b64_table =
1680 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1681
1682static Eina_Bool
1683_b64_is(char c)
1684{
1685 const char *p;
1686
1687 if (!c) return EINA_FALSE;
1688 p = strchr(_b64_table, c);
1689 if (p >= _b64_table) return EINA_TRUE;
1690 return EINA_FALSE;
1691}
1692
1693static unsigned char
1694_b64_val(char c)
1695{
1696 const char *p = strchr(_b64_table, c);
1697 if (p) return p - _b64_table;
1698 return 0;
1699}
1700
1701static int
1702_b64_dec(unsigned char *dst, const char *src, int len)
1703{
1704 unsigned char *p = dst;
1705 *dst = 0;
1706
1707 if (!*src) return 0;
1708 do
1709 {
1710 unsigned char a = _b64_val(src[0]);
1711 unsigned char b = _b64_val(src[1]);
1712 unsigned char c = _b64_val(src[2]);
1713 unsigned char d = _b64_val(src[3]);
1714
1715 *p++ = (a << 2) | (b >> 4);
1716 *p++ = (b << 4) | (c >> 2);
1717 *p++ = (c << 6) | d;
1718
1719 if (!_b64_is(src[1]))
1720 {
1721 p -= 2;
1722 break;
1723 }
1724 else if (!_b64_is(src[2]))
1725 {
1726 p -= 2;
1727 break;
1728 }
1729 else if (!_b64_is(src[3]))
1730 {
1731 p--;
1732 break;
1733 }
1734 src += 4;
1735 while (*src && ((*src == 13) || (*src == 10))) src++;
1736 }
1737 while ((len -= 4));
1738 *p = 0;
1739 return (int)(p - dst);
1740}
1741
1742static unsigned char *
1743_base64_dec(const char *file, int *size_ret)
1744{
1745 char buf[4096], *p, *end;
1746 unsigned char *data = NULL;
1747 Eina_Binbuf *binbuf;
1748 FILE *f;
1749
1750 f = fopen(file, "rb");
1751 if (!f) return NULL;
1752 binbuf = eina_binbuf_new();
1753 if (!binbuf)
1754 {
1755 fclose(f);
1756 return NULL;
1757 }
1758 while (fgets(buf, sizeof(buf) - 1, f))
1759 {
1760 buf[sizeof(buf) - 1] = 0;
1761 // check where first invalid char in a line is
1762 for (p = buf; *p; p++)
1763 {
1764 // this is the first invalid char
1765 if ((*p != '=') && (!_b64_is(*p))) break;
1766 }
1767 end = p;
1768 // go from line start to (but not including) first invalid char
1769 if (((end - buf) > 0) && (((end - buf) % 4) == 0))
1770 {
1771 unsigned char *tmp = malloc((end - buf + 4) * 2);
1772
1773 if (tmp)
1774 {
1775 int len = _b64_dec(tmp, buf, end - buf);
1776 char *str = malloc(end - buf + 1);
1777 strncpy(str, buf, end - buf);
1778 str[end - buf] = 0;
1779 free(str);
1780 eina_binbuf_append_length(binbuf, tmp, len);
1781 free(tmp);
1782 }
1783 }
1784 }
1785 fclose(f);
1786 // as long as data is less than a mb - we have a cert that is possibly ok
1787 if (eina_binbuf_length_get(binbuf) < (1 * 1024 * 1024))
1788 {
1789 *size_ret = eina_binbuf_length_get(binbuf);
1790 data = eina_binbuf_string_steal(binbuf);
1791 }
1792 eina_binbuf_free(binbuf);
1793 return data;
1794}
1795
1796EAPI Eina_Bool
1797eet_identity_verify(Eet_File *ef,
1798 const char *certificate_file)
1799{
1800 unsigned char *cert;
1801 int cert_len;
1802
1803 if (eet_check_pointer(ef))
1804 return EINA_FALSE;
1805
1806 if (!ef->x509_der)
1807 return EINA_FALSE;
1808
1809 cert = _base64_dec(certificate_file, &cert_len);
1810 if (!cert)
1811 return EINA_FALSE;
1812
1813 if (cert_len != ef->x509_length)
1814 {
1815 free(cert);
1816 return EINA_FALSE;
1817 }
1818 if (memcmp(ef->x509_der, cert, cert_len))
1819 {
1820 free(cert);
1821 return EINA_FALSE;
1822 }
1823 free(cert);
1824 return EINA_TRUE;
1825}
1826
1679EAPI const void * 1827EAPI const void *
1680eet_identity_x509(Eet_File *ef, 1828eet_identity_x509(Eet_File *ef,
1681 int *der_length) 1829 int *der_length)
diff --git a/src/tests/eet/eet_suite.c b/src/tests/eet/eet_suite.c
index 7baabe6..a028d64 100644
--- a/src/tests/eet/eet_suite.c
+++ b/src/tests/eet/eet_suite.c
@@ -1752,6 +1752,9 @@ START_TEST(eet_identity_simple)
1752 ef = eet_open(file, EET_FILE_MODE_READ); 1752 ef = eet_open(file, EET_FILE_MODE_READ);
1753 fail_if(!ef); 1753 fail_if(!ef);
1754 1754
1755 /* check that the certificates match */
1756 fail_if(!eet_identity_verify(ef, _cert_pem));
1757
1755 test = eet_read(ef, "keys/tests", &size); 1758 test = eet_read(ef, "keys/tests", &size);
1756 fail_if(!test); 1759 fail_if(!test);
1757 fail_if(size != (int)strlen(buffer) + 1); 1760 fail_if(size != (int)strlen(buffer) + 1);