File: src\libraries\Common\src\Interop\Unix\System.Security.Cryptography.Native\Interop.OCSP.cs
Web Access
Project: src\src\libraries\System.Security.Cryptography\src\System.Security.Cryptography.csproj (System.Security.Cryptography)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Security.Cryptography.X509Certificates;
using Microsoft.Win32.SafeHandles;
 
internal static partial class Interop
{
    internal static partial class Crypto
    {
        [LibraryImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_OcspRequestDestroy")]
        internal static partial void OcspRequestDestroy(IntPtr ocspReq);
 
        [LibraryImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_GetOcspRequestDerSize")]
        internal static partial int GetOcspRequestDerSize(SafeOcspRequestHandle req);
 
        [LibraryImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EncodeOcspRequest")]
        internal static partial int EncodeOcspRequest(SafeOcspRequestHandle req, byte[] buf);
 
        [LibraryImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_X509BuildOcspRequest")]
        internal static partial SafeOcspRequestHandle X509BuildOcspRequest(IntPtr subject, IntPtr issuer);
 
        [LibraryImport(Libraries.CryptoNative)]
        private static unsafe partial int CryptoNative_X509DecodeOcspToExpiration(
            byte* buf,
            int len,
            SafeOcspRequestHandle req,
            IntPtr subject,
            IntPtr* issuers,
            int issuersLen,
            ref long expiration);
 
        internal static unsafe bool X509DecodeOcspToExpiration(
            ReadOnlySpan<byte> buf,
            SafeOcspRequestHandle request,
            IntPtr x509Subject,
            ReadOnlySpan<IntPtr> x509Issuers,
            out DateTimeOffset expiration)
        {
            long timeT = 0;
            int ret;
 
            fixed (byte* pBuf = buf)
            fixed (IntPtr* pIssuers = x509Issuers)
            {
                ret = CryptoNative_X509DecodeOcspToExpiration(
                    pBuf,
                    buf.Length,
                    request,
                    x509Subject,
                    pIssuers,
                    x509Issuers.Length,
                    ref timeT);
            }
 
            if (ret == 1)
            {
                if (timeT != 0)
                {
                    expiration = DateTimeOffset.FromUnixTimeSeconds(timeT);
                }
                else
                {
                    // Something went wrong during the determination of when the response
                    // should not be used any longer.
                    // Half an hour sounds fair?
                    expiration = DateTimeOffset.UtcNow.AddMinutes(30);
                }
 
                return true;
            }
 
            Debug.Assert(ret == 0, $"Unexpected response from X509DecodeOcspToExpiration: {ret}");
            expiration = DateTimeOffset.MinValue;
            return false;
        }
 
        [LibraryImport(Libraries.CryptoNative)]
        private static partial SafeOcspResponseHandle CryptoNative_DecodeOcspResponse(ref byte buf, int len);
 
        internal static SafeOcspResponseHandle DecodeOcspResponse(ReadOnlySpan<byte> buf)
        {
            return CryptoNative_DecodeOcspResponse(
                ref MemoryMarshal.GetReference(buf),
                buf.Length);
        }
 
        [LibraryImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_OcspResponseDestroy")]
        internal static partial void OcspResponseDestroy(IntPtr ocspReq);
    }
}
 
namespace System.Security.Cryptography.X509Certificates
{
    internal sealed class SafeOcspRequestHandle : SafeHandleZeroOrMinusOneIsInvalid
    {
        public SafeOcspRequestHandle()
            : base(true)
        {
        }
 
        protected override bool ReleaseHandle()
        {
            Interop.Crypto.OcspRequestDestroy(handle);
            handle = IntPtr.Zero;
            return true;
        }
    }
 
    internal sealed class SafeOcspResponseHandle : SafeHandleZeroOrMinusOneIsInvalid
    {
        public SafeOcspResponseHandle()
            : base(true)
        {
        }
 
        protected override bool ReleaseHandle()
        {
            Interop.Crypto.OcspResponseDestroy(handle);
            handle = IntPtr.Zero;
            return true;
        }
    }
}