+
+OSStatus
+SSLGetSessionConfigurationIdentifier(SSLContext *ctx, SSLBuffer *buffer)
+{
+ if (buffer == NULL) {
+ return errSecParam;
+ }
+
+ // Don't recompute the buffer if we've done it before and cached the result.
+ // Just copy out the result.
+ if (ctx->contextConfigurationBuffer.data != NULL) {
+ buffer->length = ctx->contextConfigurationBuffer.length;
+ buffer->data = (uint8_t *) malloc(buffer->length);
+ if (buffer->data == NULL) {
+ return errSecAllocate;
+ }
+ memcpy(buffer->data, ctx->contextConfigurationBuffer.data, buffer->length);
+ return errSecSuccess;
+ }
+
+ // Allocate the buffer, freeing up any data that was previously stored
+ // 10 here is the number of attributes we're adding below. Change it as needed.
+ buffer->length = 10 * sizeof(Boolean);
+ if (buffer->data) {
+ free(buffer->data);
+ }
+ buffer->data = malloc(buffer->length);
+ if (buffer->data == NULL) {
+ return errSecAllocate;
+ }
+
+ // Copy in the session configuration options
+ int offset = 0;
+ memcpy(buffer->data + offset, &ctx->breakOnServerAuth, sizeof(ctx->breakOnServerAuth));
+ offset += sizeof(ctx->breakOnServerAuth);
+
+ memcpy(buffer->data + offset, &ctx->breakOnCertRequest, sizeof(ctx->breakOnCertRequest));
+ offset += sizeof(ctx->breakOnCertRequest);
+
+ memcpy(buffer->data + offset, &ctx->breakOnClientAuth, sizeof(ctx->breakOnClientAuth));
+ offset += sizeof(ctx->breakOnClientAuth);
+
+ memcpy(buffer->data + offset, &ctx->signalServerAuth, sizeof(ctx->signalServerAuth));
+ offset += sizeof(ctx->signalServerAuth);
+
+ memcpy(buffer->data + offset, &ctx->signalCertRequest, sizeof(ctx->signalCertRequest));
+ offset += sizeof(ctx->signalCertRequest);
+
+ memcpy(buffer->data + offset, &ctx->signalClientAuth, sizeof(ctx->signalClientAuth));
+ offset += sizeof(ctx->signalClientAuth);
+
+ memcpy(buffer->data + offset, &ctx->breakOnClientHello, sizeof(ctx->breakOnClientHello));
+ offset += sizeof(ctx->breakOnClientHello);
+
+ memcpy(buffer->data + offset, &ctx->allowServerIdentityChange, sizeof(ctx->allowServerIdentityChange));
+ offset += sizeof(ctx->allowServerIdentityChange);
+
+ memcpy(buffer->data + offset, &ctx->allowRenegotiation, sizeof(ctx->allowRenegotiation));
+ offset += sizeof(ctx->allowRenegotiation);
+
+ memcpy(buffer->data + offset, &ctx->enableSessionTickets, sizeof(ctx->enableSessionTickets));
+ offset += sizeof(ctx->enableSessionTickets);
+
+ // Sanity check on the length
+ if (offset != buffer->length) {
+ free(buffer->data);
+ return errSecInternal;
+ }
+
+ // Save the configuration buffer for later use
+ ctx->contextConfigurationBuffer.length = buffer->length;
+ ctx->contextConfigurationBuffer.data = (uint8_t *) malloc(buffer->length);
+ memcpy(ctx->contextConfigurationBuffer.data, buffer->data, buffer->length);
+
+ return errSecSuccess;
+}