Annotation of embedaddon/axTLS/bindings/csharp/axTLS.cs, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (c) 2007, Cameron Rich
        !             3:  * 
        !             4:  * All rights reserved.
        !             5:  * 
        !             6:  * Redistribution and use in source and binary forms, with or without 
        !             7:  * modification, are permitted provided that the following conditions are met:
        !             8:  *
        !             9:  * * Redistributions of source code must retain the above copyright notice, 
        !            10:  *   this list of conditions and the following disclaimer.
        !            11:  * * Redistributions in binary form must reproduce the above copyright notice, 
        !            12:  *   this list of conditions and the following disclaimer in the documentation 
        !            13:  *   and/or other materials provided with the distribution.
        !            14:  * * Neither the name of the axTLS project nor the names of its contributors 
        !            15:  *   may be used to endorse or promote products derived from this software 
        !            16:  *   without specific prior written permission.
        !            17:  *
        !            18:  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
        !            19:  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
        !            20:  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
        !            21:  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
        !            22:  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
        !            23:  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
        !            24:  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
        !            25:  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
        !            26:  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
        !            27:  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
        !            28:  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            29:  */
        !            30: 
        !            31: /**
        !            32:  * A wrapper around the unmanaged interface to give a semi-decent C# API
        !            33:  */
        !            34: 
        !            35: using System;
        !            36: using System.Runtime.InteropServices;
        !            37: using System.Net.Sockets;
        !            38: 
        !            39: /**
        !            40:  * @defgroup csharp_api C# API.
        !            41:  *
        !            42:  * Ensure that the appropriate Dispose() methods are called when finished with
        !            43:  * various objects - otherwise memory leaks will result.
        !            44:  * @{
        !            45:  */
        !            46: namespace axTLS
        !            47: {
        !            48:     /**
        !            49:      * @class SSL
        !            50:      * @ingroup csharp_api 
        !            51:      * @brief A representation of an SSL connection.
        !            52:      */
        !            53:     public class SSL
        !            54:     {
        !            55:         public IntPtr m_ssl;    /**< A pointer to the real SSL type */
        !            56: 
        !            57:         /**
        !            58:          * @brief Store the reference to an SSL context.
        !            59:          * @param ip [in] A reference to an SSL object.
        !            60:          */
        !            61:         public SSL(IntPtr ip)
        !            62:         {
        !            63:             m_ssl = ip;
        !            64:         }
        !            65: 
        !            66:         /**
        !            67:          * @brief Free any used resources on this connection. 
        !            68:          * 
        !            69:          * A "Close Notify" message is sent on this connection (if possible). 
        !            70:          * It is up to the application to close the socket.
        !            71:          */
        !            72:         public void Dispose()
        !            73:         {
        !            74:             axtls.ssl_free(m_ssl);
        !            75:         }
        !            76: 
        !            77:         /**
        !            78:          * @brief Return the result of a handshake.
        !            79:          * @return SSL_OK if the handshake is complete and ok.
        !            80:          * @see ssl.h for the error code list.
        !            81:          */
        !            82:         public int HandshakeStatus()
        !            83:         {
        !            84:             return axtls.ssl_handshake_status(m_ssl);
        !            85:         }
        !            86: 
        !            87:         /**
        !            88:          * @brief Return the SSL cipher id.
        !            89:          * @return The cipher id which is one of:
        !            90:          * - SSL_AES128_SHA (0x2f)
        !            91:          * - SSL_AES256_SHA (0x35)
        !            92:          * - SSL_RC4_128_SHA (0x05)
        !            93:          * - SSL_RC4_128_MD5 (0x04)
        !            94:          */
        !            95:         public byte GetCipherId()
        !            96:         {
        !            97:             return axtls.ssl_get_cipher_id(m_ssl);
        !            98:         }
        !            99: 
        !           100:         /**
        !           101:          * @brief Get the session id for a handshake. 
        !           102:          * 
        !           103:          * This will be a 32 byte sequence and is available after the first
        !           104:          * handshaking messages are sent.
        !           105:          * @return The session id as a 32 byte sequence.
        !           106:          * @note A SSLv23 handshake may have only 16 valid bytes.
        !           107:          */
        !           108:         public byte[] GetSessionId()
        !           109:         {
        !           110:             IntPtr ptr = axtls.ssl_get_session_id(m_ssl);
        !           111:             byte sess_id_size = axtls.ssl_get_session_id_size(m_ssl);
        !           112:             byte[] result = new byte[sess_id_size];
        !           113:             Marshal.Copy(ptr, result, 0, sess_id_size);
        !           114:             return result;
        !           115:         }
        !           116: 
        !           117:         /**
        !           118:          * @brief Retrieve an X.509 distinguished name component.
        !           119:          * 
        !           120:          * When a handshake is complete and a certificate has been exchanged, 
        !           121:          * then the details of the remote certificate can be retrieved.
        !           122:          *
        !           123:          * This will usually be used by a client to check that the server's 
        !           124:          * common name matches the URL.
        !           125:          *
        !           126:          * A full handshake needs to occur for this call to work.
        !           127:          *
        !           128:          * @param component [in] one of:
        !           129:          * - SSL_X509_CERT_COMMON_NAME
        !           130:          * - SSL_X509_CERT_ORGANIZATION
        !           131:          * - SSL_X509_CERT_ORGANIZATIONAL_NAME
        !           132:          * - SSL_X509_CA_CERT_COMMON_NAME
        !           133:          * - SSL_X509_CA_CERT_ORGANIZATION
        !           134:          * - SSL_X509_CA_CERT_ORGANIZATIONAL_NAME
        !           135:          * @return The appropriate string (or null if not defined)
        !           136:          */
        !           137:         public string GetCertificateDN(int component)
        !           138:         {
        !           139:             return axtls.ssl_get_cert_dn(m_ssl, component);
        !           140:         }
        !           141:     }
        !           142: 
        !           143:     /**
        !           144:      * @class SSLUtil
        !           145:      * @ingroup csharp_api 
        !           146:      * @brief Some global helper functions.
        !           147:      */
        !           148:     public class SSLUtil
        !           149:     {
        !           150: 
        !           151:         /**
        !           152:          * @brief Return the build mode of the axTLS project.
        !           153:          * @return The build mode is one of:
        !           154:          * - SSL_BUILD_SERVER_ONLY
        !           155:          * - SSL_BUILD_ENABLE_VERIFICATION
        !           156:          * - SSL_BUILD_ENABLE_CLIENT
        !           157:          * - SSL_BUILD_FULL_MODE
        !           158:          */
        !           159:         public static int BuildMode()
        !           160:         {
        !           161:             return axtls.ssl_get_config(axtls.SSL_BUILD_MODE);
        !           162:         }
        !           163: 
        !           164:         /**
        !           165:          * @brief Return the number of chained certificates that the 
        !           166:          * client/server supports.
        !           167:          * @return The number of supported server certificates.
        !           168:          */
        !           169:         public static int MaxCerts()
        !           170:         {
        !           171:             return axtls.ssl_get_config(axtls.SSL_MAX_CERT_CFG_OFFSET);
        !           172:         }
        !           173: 
        !           174:         /**
        !           175:          * @brief Return the number of CA certificates that the client/server
        !           176:          * supports.
        !           177:          * @return The number of supported CA certificates.
        !           178:          */
        !           179:         public static int MaxCACerts()
        !           180:         {
        !           181:             return axtls.ssl_get_config(axtls.SSL_MAX_CA_CERT_CFG_OFFSET);
        !           182:         }
        !           183: 
        !           184:         /**
        !           185:          * @brief Indicate if PEM is supported.
        !           186:          * @return true if PEM supported.
        !           187:          */
        !           188:         public static bool HasPEM()
        !           189:         {
        !           190:             return axtls.ssl_get_config(axtls.SSL_HAS_PEM) > 0 ? true : false;
        !           191:         }
        !           192: 
        !           193:         /**
        !           194:          * @brief Display the text string of the error.
        !           195:          * @param error_code [in] The integer error code.
        !           196:          */
        !           197:         public static void DisplayError(int error_code)
        !           198:         {
        !           199:             axtls.ssl_display_error(error_code);
        !           200:         }
        !           201: 
        !           202:         /**
        !           203:          * @brief Return the version of the axTLS project.
        !           204:          */
        !           205:         public static string Version()
        !           206:         {
        !           207:             return axtls.ssl_version();
        !           208:         }
        !           209:     }
        !           210: 
        !           211:     /**
        !           212:      * @class SSLCTX
        !           213:      * @ingroup csharp_api 
        !           214:      * @brief A base object for SSLServer/SSLClient.
        !           215:      */
        !           216:     public class SSLCTX
        !           217:     {
        !           218:         /**
        !           219:          * @brief A reference to the real client/server context.
        !           220:          */
        !           221:         protected IntPtr m_ctx;
        !           222: 
        !           223:         /**
        !           224:          * @brief Establish a new client/server context.
        !           225:          *
        !           226:          * This function is called before any client/server SSL connections are 
        !           227:          * made.  If multiple threads are used, then each thread will have its 
        !           228:          * own SSLCTX context. Any number of connections may be made with a 
        !           229:          * single context. 
        !           230:          *
        !           231:          * Each new connection will use the this context's private key and 
        !           232:          * certificate chain. If a different certificate chain is required, 
        !           233:          * then a different context needs to be be used.
        !           234:          *
        !           235:          * @param options [in]  Any particular options. At present the options
        !           236:          * supported are:
        !           237:          * - SSL_SERVER_VERIFY_LATER (client only): Don't stop a handshake if 
        !           238:          * the server authentication fails. The certificate can be 
        !           239:          * authenticated later with a call to VerifyCert().
        !           240:          * - SSL_CLIENT_AUTHENTICATION (server only): Enforce client 
        !           241:          * authentication i.e. each handshake will include a "certificate 
        !           242:          * request" message from the server.
        !           243:          * - SSL_DISPLAY_BYTES (full mode build only): Display the byte 
        !           244:          * sequences during the handshake.
        !           245:          * - SSL_DISPLAY_STATES (full mode build only): Display the state 
        !           246:          * changes during the handshake.
        !           247:          * - SSL_DISPLAY_CERTS (full mode build only): Display the 
        !           248:          * certificates that are passed during a handshake.
        !           249:          * - SSL_DISPLAY_RSA (full mode build only): Display the RSA key 
        !           250:          * details that are passed during a handshake.
        !           251:          * @param num_sessions [in] The number of sessions to be used for 
        !           252:          * session caching. If this value is 0, then there is no session 
        !           253:          * caching.
        !           254:          * @return A client/server context.
        !           255:          */
        !           256:         protected SSLCTX(uint options, int num_sessions)
        !           257:         {
        !           258:             m_ctx = axtls.ssl_ctx_new(options, num_sessions);
        !           259:         }
        !           260: 
        !           261:         /**
        !           262:          * @brief Remove a client/server context.
        !           263:          *
        !           264:          * Frees any used resources used by this context. Each connection will 
        !           265:          * be sent a "Close Notify" alert (if possible).
        !           266:          */
        !           267:         public void Dispose()
        !           268:         {
        !           269:             axtls.ssl_ctx_free(m_ctx);
        !           270:         }
        !           271: 
        !           272:         /**
        !           273:          * @brief Read the SSL data stream.
        !           274:          * @param ssl [in] An SSL object reference.
        !           275:          * @param in_data [out] After a successful read, the decrypted data 
        !           276:          * will be here. It will be null otherwise.
        !           277:          * @return The number of decrypted bytes:
        !           278:          * - if > 0, then the handshaking is complete and we are returning the 
        !           279:          * number of decrypted bytes. 
        !           280:          * - SSL_OK if the handshaking stage is successful (but not yet 
        !           281:          * complete).  
        !           282:          * - < 0 if an error.
        !           283:          * @see ssl.h for the error code list.
        !           284:          * @note Use in_data before doing any successive ssl calls.
        !           285:          */
        !           286:         public int Read(SSL ssl, out byte[] in_data)
        !           287:         {
        !           288:             IntPtr ptr = IntPtr.Zero;
        !           289:             int ret = axtls.ssl_read(ssl.m_ssl, ref ptr);
        !           290: 
        !           291:             if (ret > axtls.SSL_OK)
        !           292:             {
        !           293:                 in_data = new byte[ret];
        !           294:                 Marshal.Copy(ptr, in_data, 0, ret);
        !           295:             }
        !           296:             else
        !           297:             {
        !           298:                 in_data = null;
        !           299:             }
        !           300: 
        !           301:             return ret;
        !           302:         }
        !           303: 
        !           304:         /**
        !           305:          * @brief Write to the SSL data stream.
        !           306:          * @param ssl [in] An SSL obect reference.
        !           307:          * @param out_data [in] The data to be written
        !           308:          * @return The number of bytes sent, or if < 0 if an error.
        !           309:          * @see ssl.h for the error code list.
        !           310:          */
        !           311:         public int Write(SSL ssl, byte[] out_data)
        !           312:         {
        !           313:             return axtls.ssl_write(ssl.m_ssl, out_data, out_data.Length);
        !           314:         }
        !           315: 
        !           316:         /**
        !           317:          * @brief Write to the SSL data stream.
        !           318:          * @param ssl [in] An SSL obect reference.
        !           319:          * @param out_data [in] The data to be written
        !           320:          * @param out_len [in] The number of bytes to be written
        !           321:          * @return The number of bytes sent, or if < 0 if an error.
        !           322:          * @see ssl.h for the error code list.
        !           323:          */
        !           324:         public int Write(SSL ssl, byte[] out_data, int out_len)
        !           325:         {
        !           326:             return axtls.ssl_write(ssl.m_ssl, out_data, out_len);
        !           327:         }
        !           328: 
        !           329:         /**
        !           330:          * @brief Find an ssl object based on a Socket reference.
        !           331:          *
        !           332:          * Goes through the list of SSL objects maintained in a client/server 
        !           333:          * context to look for a socket match.
        !           334:          * @param s [in] A reference to a <A HREF="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemnetsocketssocketclasstopic.asp">Socket</A> object.
        !           335:          * @return A reference to the SSL object. Returns null if the object 
        !           336:          * could not be found.
        !           337:          */
        !           338:         public SSL Find(Socket s)
        !           339:         {
        !           340:             int client_fd = s.Handle.ToInt32();
        !           341:             return new SSL(axtls.  ssl_find(m_ctx, client_fd));
        !           342:         }
        !           343: 
        !           344:         /**
        !           345:          * @brief Authenticate a received certificate.
        !           346:          * 
        !           347:          * This call is usually made by a client after a handshake is complete 
        !           348:          * and the context is in SSL_SERVER_VERIFY_LATER mode.
        !           349:          * @param ssl [in] An SSL object reference.
        !           350:          * @return SSL_OK if the certificate is verified.
        !           351:          */
        !           352:         public int VerifyCert(SSL ssl)
        !           353:         {
        !           354:             return axtls.ssl_verify_cert(ssl.m_ssl);
        !           355:         }
        !           356: 
        !           357:         /**
        !           358:          * @brief Force the client to perform its handshake again.
        !           359:          *
        !           360:          * For a client this involves sending another "client hello" message.
        !           361:          * For the server is means sending a "hello request" message.
        !           362:          *
        !           363:          * This is a blocking call on the client (until the handshake 
        !           364:          * completes).
        !           365:          * @param ssl [in] An SSL object reference.
        !           366:          * @return SSL_OK if renegotiation instantiation was ok
        !           367:          */
        !           368:         public int Renegotiate(SSL ssl)
        !           369:         {
        !           370:             return axtls.ssl_renegotiate(ssl.m_ssl);
        !           371:         }
        !           372: 
        !           373:         /**
        !           374:          * @brief Load a file into memory that is in binary DER or ASCII PEM 
        !           375:          * format.
        !           376:          *
        !           377:          * These are temporary objects that are used to load private keys,
        !           378:          * certificates etc into memory.
        !           379:          * @param obj_type [in] The format of the file. Can be one of:
        !           380:          * - SSL_OBJ_X509_CERT (no password required)
        !           381:          * - SSL_OBJ_X509_CACERT (no password required)
        !           382:          * - SSL_OBJ_RSA_KEY (AES128/AES256 PEM encryption supported)
        !           383:          * - SSL_OBJ_P8 (RC4-128 encrypted data supported)
        !           384:          * - SSL_OBJ_P12 (RC4-128 encrypted data supported)
        !           385:          *
        !           386:          * PEM files are automatically detected (if supported).
        !           387:          * @param filename [in] The location of a file in DER/PEM format.
        !           388:          * @param password [in] The password used. Can be null if not required.
        !           389:          * @return SSL_OK if all ok
        !           390:          */
        !           391:         public int ObjLoad(int obj_type, string filename, string password)
        !           392:         {
        !           393:             return axtls.ssl_obj_load(m_ctx, obj_type, filename, password);
        !           394:         }
        !           395: 
        !           396:         /**
        !           397:          * @brief Transfer binary data into the object loader.
        !           398:          *
        !           399:          * These are temporary objects that are used to load private keys,
        !           400:          * certificates etc into memory.
        !           401:          * @param obj_type [in] The format of the memory data.
        !           402:          * @param data [in] The binary data to be loaded.
        !           403:          * @param len [in] The amount of data to be loaded.
        !           404:          * @param password [in] The password used. Can be null if not required.
        !           405:          * @return SSL_OK if all ok
        !           406:          */
        !           407:         public int ObjLoad(int obj_type, byte[] data, int len, string password)
        !           408:         {
        !           409:             return axtls.ssl_obj_memory_load(m_ctx, obj_type, 
        !           410:                                             data, len, password);
        !           411:         }
        !           412:     }
        !           413: 
        !           414:     /**
        !           415:      * @class SSLServer
        !           416:      * @ingroup csharp_api 
        !           417:      * @brief The server context.
        !           418:      *
        !           419:      * All server connections are started within a server context.
        !           420:      */
        !           421:     public class SSLServer : SSLCTX
        !           422:     {
        !           423:         /**
        !           424:          * @brief Start a new server context.
        !           425:          * 
        !           426:          * @see SSLCTX for details.
        !           427:          */
        !           428:         public SSLServer(uint options, int num_sessions) :
        !           429:                             base(options, num_sessions) {}
        !           430: 
        !           431:         /**
        !           432:          * @brief Establish a new SSL connection to an SSL client.
        !           433:          *
        !           434:          * It is up to the application to establish the initial socket 
        !           435:          * connection.
        !           436:          *
        !           437:          * Call Dispose() when the connection is to be removed.
        !           438:          * @param s [in] A reference to a <A HREF="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemnetsocketssocketclasstopic.asp">Socket</A> object.
        !           439:          * @return An SSL object reference.
        !           440:          */
        !           441:         public SSL Connect(Socket s)
        !           442:         {
        !           443:             int client_fd = s.Handle.ToInt32();
        !           444:             return new SSL(axtls.ssl_server_new(m_ctx, client_fd));
        !           445:         }
        !           446:     }
        !           447: 
        !           448:     /**
        !           449:      * @class SSLClient
        !           450:      * @ingroup csharp_api
        !           451:      * @brief The client context.
        !           452:      *
        !           453:      * All client connections are started within a client context.
        !           454:      */
        !           455:     public class SSLClient : SSLCTX
        !           456:     {
        !           457:         /**
        !           458:          * @brief Start a new client context.
        !           459:          * 
        !           460:          * @see SSLCTX for details.
        !           461:          */
        !           462:         public SSLClient(uint options, int num_sessions) :
        !           463:                         base(options, num_sessions) {}
        !           464: 
        !           465:         /**
        !           466:          * @brief Establish a new SSL connection to an SSL server.
        !           467:          *
        !           468:          * It is up to the application to establish the initial socket 
        !           469:          * connection.
        !           470:          *
        !           471:          * This is a blocking call - it will finish when the handshake is 
        !           472:          * complete (or has failed).
        !           473:          *
        !           474:          * Call Dispose() when the connection is to be removed.
        !           475:          * @param s [in] A reference to a <A HREF="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemnetsocketssocketclasstopic.asp">Socket</A> object.
        !           476:          * @param session_id [in] A 32 byte session id for session resumption. 
        !           477:          * This can be null if no session resumption is not required.
        !           478:          * @return An SSL object reference. Use SSL.handshakeStatus() to check 
        !           479:          * if a handshake succeeded.
        !           480:          */
        !           481:         public SSL Connect(Socket s, byte[] session_id)
        !           482:         {
        !           483:             int client_fd = s.Handle.ToInt32();
        !           484:             byte sess_id_size = (byte)(session_id != null ? 
        !           485:                                 session_id.Length : 0);
        !           486:             return new SSL(axtls.ssl_client_new(m_ctx, client_fd, session_id,
        !           487:                         sess_id_size));
        !           488:         }
        !           489:     }
        !           490: }
        !           491: /** @} */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>