Overview
Comment: | Added support for loading CA certificates from virtual file systems. Source: https://core.tcl-lang.org/tcltls/tktview/030c713ca2 |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | tls-1.8 |
Files: | files | file ages | folders |
SHA3-256: |
b70fbfd8cf57f77264599ebd1ba6cabf |
User & Date: | bohagan on 2024-10-26 17:34:13 |
Other Links: | branch diff | manifest | tags |
Context
2024-10-26
| ||
22:32 | Updated windows makefile to preserve manifest.uuid file if it already exists. Added checks for git repo. check-in: 50fb4f4fc1 user: bohagan tags: tls-1.8 | |
17:34 | Added support for loading CA certificates from virtual file systems. Source: https://core.tcl-lang.org/tcltls/tktview/030c713ca2 check-in: b70fbfd8cf user: bohagan tags: tls-1.8 | |
17:04 | Updated README.txt file. check-in: 22727e2eee user: bohagan tags: tls-1.8 | |
Changes
Modified generic/tls.c from [99b0260693] to [25505d8d36].
︙ | ︙ | |||
1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 | Tcl_DStringFree(&upperChannelBlocking); return res; } /* *------------------------------------------------------------------- * * CTX_Init -- construct a SSL_CTX instance * * Results: * A valid SSL_CTX instance or NULL. * * Side effects: * constructs SSL context (CTX) | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 | Tcl_DStringFree(&upperChannelBlocking); return res; } /* *------------------------------------------------------------------- * * TlsLoadClientCAFileFromMemory -- Load certificates from a client * CA file from VFS into memory. * * Results: * Number of certificates loaded or 0 for none. * * Side effects: * Loads CA certificates * *------------------------------------------------------------------- */ static int TlsLoadClientCAFileFromMemory(Tcl_Interp *interp, SSL_CTX *ctx, Tcl_Obj *file) { BIO *bio = NULL; X509 *cert = NULL; X509_STORE *store = NULL; Tcl_Obj *buf = NULL; const void *data = NULL; X509_NAME *name = NULL; STACK_OF(X509_NAME) *certNames = NULL; int ret = 0; Tcl_Size len = 0; /* Read file into memory */ Tcl_Channel in = Tcl_FSOpenFileChannel(interp, file, "r", 0); if (in == NULL) { goto cleanup; } Tcl_SetChannelOption(interp, in, "-encoding", "binary"); buf = Tcl_NewObj(); Tcl_IncrRefCount(buf); if (Tcl_ReadChars(in, buf, -1, 0) < 0) { Tcl_Close(interp, in); goto cleanup; } Tcl_Close(interp, in); data = (const void *) Tcl_GetByteArrayFromObj(buf, &len); bio = BIO_new_mem_buf(data, len); if (bio == NULL) { goto cleanup; } /* Where the certs go */ store = SSL_CTX_get_cert_store(ctx); if (store == NULL) { store = X509_STORE_new(); if (store == NULL) { goto cleanup; } } /* Where the CA names go */ certNames = sk_X509_NAME_new_null(); if (!certNames) { goto cleanup; } /* Attempt to load all certs from the PEM file */ while ((cert = PEM_read_bio_X509(bio, NULL, 0, NULL)) != NULL) { if (X509_STORE_add_cert(store, cert) == 0) { X509_free(cert); ret = 0; goto cleanup; } /* Copy name to stack before certificate gets freed */ name = X509_get_subject_name(cert); if (name) { X509_NAME *name_copy = X509_NAME_dup(name); if (!name_copy || !sk_X509_NAME_push(certNames, name_copy)) { X509_free(cert); ret = 0; goto cleanup; } } X509_free(cert); ret ++; } /* At least one cert was added so retain the store and CA list */ if (ret) { if (SSL_CTX_get_cert_store(ctx) == NULL) { SSL_CTX_set_cert_store(ctx, store); } SSL_CTX_set_client_CA_list(ctx, certNames); } cleanup: if (! ret) { /* New store is not required */ if (store != SSL_CTX_get_cert_store(ctx)) { X509_STORE_free(store); } /* Cert names will not be used */ if (certNames) { sk_X509_NAME_pop_free(certNames, X509_NAME_free); } } BIO_free(bio); if (buf) Tcl_DecrRefCount(buf); return ret; } /* *------------------------------------------------------------------- * * CTX_Init -- construct a SSL_CTX instance * * Results: * A valid SSL_CTX instance or NULL. * * Side effects: * constructs SSL context (CTX) |
︙ | ︙ | |||
2115 2116 2117 2118 2119 2120 2121 | abort++; } Tcl_DStringFree(&ds); } /* Set file of CA certificates in PEM format. */ if (CAfile != NULL) { | > > > > > > > > > > > | | | | | | | | | | > > > > > > > > > > > > > | 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 | abort++; } Tcl_DStringFree(&ds); } /* Set file of CA certificates in PEM format. */ if (CAfile != NULL) { Tcl_Obj *cafileobj = Tcl_NewStringObj(CAfile, -1); Tcl_IncrRefCount(cafileobj); Tcl_Obj *fsinfo = Tcl_FSFileSystemInfo(cafileobj); if (fsinfo) { Tcl_IncrRefCount(fsinfo); Tcl_Obj *fstype = NULL; Tcl_ListObjIndex(interp, fsinfo, 0, &fstype); if (Tcl_StringMatch("native", Tcl_GetString(fstype))) { if (!SSL_CTX_load_verify_file(ctx, F2N(CAfile, &ds))) { abort++; } Tcl_DStringFree(&ds); /* Set list of CAs to send to client when requesting a client certificate */ STACK_OF(X509_NAME) *certNames = SSL_load_client_CA_file(F2N(CAfile, &ds)); if (certNames != NULL) { SSL_CTX_set_client_CA_list(ctx, certNames); } Tcl_DStringFree(&ds); } else { /* Load certificate into memory */ if (!TlsLoadClientCAFileFromMemory(interp, ctx, cafileobj)) { abort++; } } Tcl_DecrRefCount(fsinfo); } else { abort++; /* Path is not recognized */ } Tcl_DecrRefCount(cafileobj); } #endif } if (abort > 0) { /* return error */ } |
︙ | ︙ |