Skip to content

Commit

Permalink
Fix ABI problem when marshalling X509VerifyStatusCode on s390x
Browse files Browse the repository at this point in the history
The X509VerifyStatusCode type is defined as an enum in C code, but as
a struct (with a single member) in C# code.  This means that marshalling
this type only works correctly on platforms where the ABI treats these
two types as equivalent.  This fails e.g. on Linux on s390x.

Fixed by changing all native functions that take X509VerifyStatusCode
as argument or return type to use a plain "int" instead.
  • Loading branch information
uweigand committed May 18, 2021
1 parent dbc9142 commit 4fd2aa9
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ ref MemoryMarshal.GetReference(buf),
internal static extern void OcspResponseDestroy(IntPtr ocspReq);

[DllImport(Libraries.CryptoNative)]
private static extern X509VerifyStatusCode CryptoNative_X509ChainGetCachedOcspStatus(
private static extern int CryptoNative_X509ChainGetCachedOcspStatus(
SafeX509StoreCtxHandle ctx,
string cachePath,
int chainDepth);

internal static X509VerifyStatusCode X509ChainGetCachedOcspStatus(SafeX509StoreCtxHandle ctx, string cachePath, int chainDepth)
{
X509VerifyStatusCode response = CryptoNative_X509ChainGetCachedOcspStatus(ctx, cachePath, chainDepth);
X509VerifyStatusCode response = (X509VerifyStatusCode)CryptoNative_X509ChainGetCachedOcspStatus(ctx, cachePath, chainDepth);

if (response.Code < 0)
{
Expand All @@ -54,7 +54,7 @@ internal static X509VerifyStatusCode X509ChainGetCachedOcspStatus(SafeX509StoreC
}

[DllImport(Libraries.CryptoNative)]
private static extern X509VerifyStatusCode CryptoNative_X509ChainVerifyOcsp(
private static extern int CryptoNative_X509ChainVerifyOcsp(
SafeX509StoreCtxHandle ctx,
SafeOcspRequestHandle req,
SafeOcspResponseHandle resp,
Expand All @@ -68,7 +68,7 @@ internal static X509VerifyStatusCode X509ChainVerifyOcsp(
string cachePath,
int chainDepth)
{
X509VerifyStatusCode response = CryptoNative_X509ChainVerifyOcsp(ctx, req, resp, cachePath, chainDepth);
X509VerifyStatusCode response = (X509VerifyStatusCode)CryptoNative_X509ChainVerifyOcsp(ctx, req, resp, cachePath, chainDepth);

if (response.Code < 0)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,13 @@ internal static bool X509VerifyCert(SafeX509StoreCtxHandle ctx)
return result != 0;
}

[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_X509StoreCtxGetError")]
internal static extern X509VerifyStatusCode X509StoreCtxGetError(SafeX509StoreCtxHandle ctx);
[DllImport(Libraries.CryptoNative)]
internal static extern int CryptoNative_X509StoreCtxGetError(SafeX509StoreCtxHandle ctx);

internal static X509VerifyStatusCode X509StoreCtxGetError(SafeX509StoreCtxHandle ctx)
{
return (X509VerifyStatusCode)CryptoNative_X509StoreCtxGetError(ctx);
}

[DllImport(Libraries.CryptoNative)]
private static extern int CryptoNative_X509StoreCtxReset(SafeX509StoreCtxHandle ctx);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -302,9 +302,9 @@ X509* CryptoNative_X509StoreCtxGetTargetCert(X509_STORE_CTX* ctx)
return NULL;
}

X509VerifyStatusCode CryptoNative_X509StoreCtxGetError(X509_STORE_CTX* ctx)
int32_t CryptoNative_X509StoreCtxGetError(X509_STORE_CTX* ctx)
{
return (unsigned int)X509_STORE_CTX_get_error(ctx);
return (int32_t)X509_STORE_CTX_get_error(ctx);
}

int32_t CryptoNative_X509StoreCtxReset(X509_STORE_CTX* ctx)
Expand Down Expand Up @@ -337,7 +337,7 @@ int32_t CryptoNative_X509StoreCtxGetErrorDepth(X509_STORE_CTX* ctx)
return X509_STORE_CTX_get_error_depth(ctx);
}

const char* CryptoNative_X509VerifyCertErrorString(X509VerifyStatusCode n)
const char* CryptoNative_X509VerifyCertErrorString(int32_t n)
{
return X509_verify_cert_error_string((long)n);
}
Expand Down Expand Up @@ -949,27 +949,27 @@ static time_t GetIssuanceWindowStart()
return t;
}

X509VerifyStatusCode CryptoNative_X509ChainGetCachedOcspStatus(X509_STORE_CTX* storeCtx, char* cachePath, int chainDepth)
int32_t CryptoNative_X509ChainGetCachedOcspStatus(X509_STORE_CTX* storeCtx, char* cachePath, int chainDepth)
{
if (storeCtx == NULL || cachePath == NULL)
{
return (X509VerifyStatusCode)-1;
return -1;
}

X509* subject;
X509* issuer;

if (!Get0CertAndIssuer(storeCtx, chainDepth, &subject, &issuer))
{
return (X509VerifyStatusCode)-2;
return -2;
}

X509VerifyStatusCode ret = PAL_X509_V_ERR_UNABLE_TO_GET_CRL;
char* fullPath = BuildOcspCacheFilename(cachePath, subject);

if (fullPath == NULL)
{
return ret;
return (int32_t)ret;
}

BIO* bio = BIO_new_file(fullPath, "rb");
Expand Down Expand Up @@ -1031,7 +1031,7 @@ X509VerifyStatusCode CryptoNative_X509ChainGetCachedOcspStatus(X509_STORE_CTX* s
OCSP_RESPONSE_free(resp);
}

return ret;
return (int32_t)ret;
}

OCSP_REQUEST* CryptoNative_X509ChainBuildOcspRequest(X509_STORE_CTX* storeCtx, int chainDepth)
Expand Down Expand Up @@ -1079,28 +1079,28 @@ OCSP_REQUEST* CryptoNative_X509ChainBuildOcspRequest(X509_STORE_CTX* storeCtx, i
return req;
}

X509VerifyStatusCode
int32_t
CryptoNative_X509ChainVerifyOcsp(X509_STORE_CTX* storeCtx, OCSP_REQUEST* req, OCSP_RESPONSE* resp, char* cachePath, int chainDepth)
{
if (storeCtx == NULL || req == NULL || resp == NULL)
{
return (X509VerifyStatusCode)-1;
return -1;
}

X509* subject;
X509* issuer;

if (!Get0CertAndIssuer(storeCtx, chainDepth, &subject, &issuer))
{
return (X509VerifyStatusCode)-2;
return -2;
}

X509VerifyStatusCode ret = PAL_X509_V_ERR_UNABLE_TO_GET_CRL;
OCSP_CERTID* certId = MakeCertId(subject, issuer);

if (certId == NULL)
{
return (X509VerifyStatusCode)-3;
return -3;
}

ASN1_GENERALIZEDTIME* thisUpdate = NULL;
Expand Down Expand Up @@ -1167,5 +1167,5 @@ CryptoNative_X509ChainVerifyOcsp(X509_STORE_CTX* storeCtx, OCSP_REQUEST* req, OC
ASN1_GENERALIZEDTIME_free(thisUpdate);
}

return ret;
return (int32_t)ret;
}
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ PALEXPORT X509* CryptoNative_X509StoreCtxGetTargetCert(X509_STORE_CTX* ctx);
/*
Shims the X509_STORE_CTX_get_error method.
*/
PALEXPORT X509VerifyStatusCode CryptoNative_X509StoreCtxGetError(X509_STORE_CTX* ctx);
PALEXPORT int32_t CryptoNative_X509StoreCtxGetError(X509_STORE_CTX* ctx);

/*
Resets ctx to before the chain was built, preserving the target cert, trust store, extra cert context,
Expand Down Expand Up @@ -301,7 +301,7 @@ PALEXPORT void CryptoNative_X509StoreCtxSetVerifyCallback(X509_STORE_CTX* ctx, X
/*
Shims the X509_verify_cert_error_string method.
*/
PALEXPORT const char* CryptoNative_X509VerifyCertErrorString(X509VerifyStatusCode n);
PALEXPORT const char* CryptoNative_X509VerifyCertErrorString(int32_t n);

/*
Shims the X509_CRL_free method.
Expand Down Expand Up @@ -378,7 +378,7 @@ PALEXPORT int32_t CryptoNative_X509StoreCtxResetForSignatureError(X509_STORE_CTX
Look for a cached OCSP response appropriate to the end-entity certificate using the issuer as
determined by the chain in storeCtx.
*/
PALEXPORT X509VerifyStatusCode CryptoNative_X509ChainGetCachedOcspStatus(X509_STORE_CTX* storeCtx, char* cachePath, int chainDepth);
PALEXPORT int32_t CryptoNative_X509ChainGetCachedOcspStatus(X509_STORE_CTX* storeCtx, char* cachePath, int chainDepth);

/*
Build an OCSP request appropriate for the end-entity certificate using the issuer (and trust) as
Expand All @@ -390,8 +390,8 @@ PALEXPORT OCSP_REQUEST* CryptoNative_X509ChainBuildOcspRequest(X509_STORE_CTX* s
Determine if the OCSP response is acceptable, and if acceptable report the status and
cache the result (if appropriate)
*/
PALEXPORT X509VerifyStatusCode CryptoNative_X509ChainVerifyOcsp(X509_STORE_CTX* storeCtx,
OCSP_REQUEST* req,
OCSP_RESPONSE* resp,
char* cachePath,
int chainDepth);
PALEXPORT int32_t CryptoNative_X509ChainVerifyOcsp(X509_STORE_CTX* storeCtx,
OCSP_REQUEST* req,
OCSP_RESPONSE* resp,
char* cachePath,
int chainDepth);

0 comments on commit 4fd2aa9

Please sign in to comment.