public static void LoadBigExponentRequest_PemString(CertificateRequestLoadOptions options, bool multiPem) { string pem = TestData.BigExponentPkcs10Pem; if (multiPem) { pem = $@" -----BEGIN UNRELATED----- abcd -----END UNRELATED----- -----BEGIN CERTIFICATE REQUEST----- !!!!!INVALID!!!!! -----END CERTIFICATE REQUEST----- -----BEGIN MORE UNRELATED----- efgh -----END MORE UNRELATED----- {pem} -----BEGIN CERTIFICATE REQUEST----- !!!!!INVALID!!!!! -----END CERTIFICATE REQUEST-----"; } CertificateRequest req = CertificateRequest.LoadSigningRequestPem( pem, HashAlgorithmName.SHA512, options); Assert.Equal(HashAlgorithmName.SHA512, req.HashAlgorithm); VerifyBigExponentRequest(req, options); }
public static void LoadBigExponentRequest_Bytes(CertificateRequestLoadOptions options) { CertificateRequest req = CertificateRequest.LoadSigningRequest( TestData.BigExponentPkcs10Bytes, HashAlgorithmName.SHA384, options); Assert.Equal(HashAlgorithmName.SHA384, req.HashAlgorithm); VerifyBigExponentRequest(req, options); }
public static void LoadBigExponentRequest_Bytes_Oversized(CertificateRequestLoadOptions options) { byte[] pkcs10 = TestData.BigExponentPkcs10Bytes; Array.Resize(ref pkcs10, pkcs10.Length + 1); Assert.Throws <CryptographicException>( () => CertificateRequest.LoadSigningRequest( pkcs10, HashAlgorithmName.SHA384, options)); }
public static CertificateRequest LoadSigningRequestPem( string pkcs10Pem, HashAlgorithmName signerHashAlgorithm, CertificateRequestLoadOptions options = CertificateRequestLoadOptions.Default, RSASignaturePadding?signerSignaturePadding = null) { ArgumentNullException.ThrowIfNull(pkcs10Pem); return(LoadSigningRequestPem( pkcs10Pem.AsSpan(), signerHashAlgorithm, options, signerSignaturePadding)); }
public static CertificateRequest LoadSigningRequest( ReadOnlySpan <byte> pkcs10, HashAlgorithmName signerHashAlgorithm, out int bytesConsumed, CertificateRequestLoadOptions options = CertificateRequestLoadOptions.Default, RSASignaturePadding?signerSignaturePadding = null) { return(LoadSigningRequest( pkcs10, permitTrailingData: true, signerHashAlgorithm, out bytesConsumed, options, signerSignaturePadding)); }
public static CertificateRequest LoadSigningRequest( byte[] pkcs10, HashAlgorithmName signerHashAlgorithm, CertificateRequestLoadOptions options = CertificateRequestLoadOptions.Default, RSASignaturePadding?signerSignaturePadding = null) { ArgumentNullException.ThrowIfNull(pkcs10); return(LoadSigningRequest( pkcs10, permitTrailingData: false, signerHashAlgorithm, out _, options, signerSignaturePadding)); }
public static CertificateRequest LoadSigningRequestPem( ReadOnlySpan <char> pkcs10Pem, HashAlgorithmName signerHashAlgorithm, CertificateRequestLoadOptions options = CertificateRequestLoadOptions.Default, RSASignaturePadding?signerSignaturePadding = null) { ArgumentException.ThrowIfNullOrEmpty(signerHashAlgorithm.Name, nameof(signerHashAlgorithm)); if ((options & ~AllOptions) != 0) { throw new ArgumentOutOfRangeException(nameof(options), options, SR.Argument_InvalidFlag); } foreach ((ReadOnlySpan <char> contents, PemFields fields) in new PemEnumerator(pkcs10Pem)) { if (contents[fields.Label].SequenceEqual(PemLabels.Pkcs10CertificateRequest)) { byte[] rented = ArrayPool <byte> .Shared.Rent(fields.DecodedDataLength); if (!Convert.TryFromBase64Chars(contents[fields.Base64Data], rented, out int bytesWritten) || bytesWritten != fields.DecodedDataLength) { Debug.Fail("Base64Decode failed, but PemEncoding said it was legal"); throw new UnreachableException(); } try { return(LoadSigningRequest( rented.AsSpan(0, bytesWritten), permitTrailingData: false, signerHashAlgorithm, out _, options, signerSignaturePadding)); } finally { ArrayPool <byte> .Shared.Return(rented); } } } throw new CryptographicException( SR.Format(SR.Cryptography_NoPemOfLabel, PemLabels.Pkcs10CertificateRequest)); }
public static void LoadBigExponentRequest_Span(CertificateRequestLoadOptions options, bool oversized) { byte[] pkcs10 = TestData.BigExponentPkcs10Bytes; if (oversized) { Array.Resize(ref pkcs10, pkcs10.Length + 22); } CertificateRequest req = CertificateRequest.LoadSigningRequest( new ReadOnlySpan <byte>(pkcs10), HashAlgorithmName.SHA256, out int bytesConsumed, options); Assert.Equal(TestData.BigExponentPkcs10Bytes.Length, bytesConsumed); Assert.Equal(HashAlgorithmName.SHA256, req.HashAlgorithm); VerifyBigExponentRequest(req, options); }
public static void LoadWithUnknownOptions(int optionsValue) { CertificateRequestLoadOptions options = (CertificateRequestLoadOptions)optionsValue; HashAlgorithmName hashAlgorithm = HashAlgorithmName.SHA256; ArgumentOutOfRangeException ex; ex = Assert.Throws <ArgumentOutOfRangeException>( "options", () => CertificateRequest.LoadSigningRequest(Array.Empty <byte>(), hashAlgorithm, options)); Assert.Equal(options, ex.ActualValue); { int consumed = -1; ex = Assert.Throws <ArgumentOutOfRangeException>( "options", () => CertificateRequest.LoadSigningRequest( ReadOnlySpan <byte> .Empty, hashAlgorithm, out consumed, options)); Assert.Equal(-1, consumed); Assert.Equal(options, ex.ActualValue); } ex = Assert.Throws <ArgumentOutOfRangeException>( "options", () => CertificateRequest.LoadSigningRequestPem(string.Empty, hashAlgorithm, options)); Assert.Equal(options, ex.ActualValue); ex = Assert.Throws <ArgumentOutOfRangeException>( "options", () => CertificateRequest.LoadSigningRequestPem( ReadOnlySpan <char> .Empty, hashAlgorithm, options)); Assert.Equal(options, ex.ActualValue); }
private static unsafe CertificateRequest LoadSigningRequest( ReadOnlySpan <byte> pkcs10, bool permitTrailingData, HashAlgorithmName signerHashAlgorithm, out int bytesConsumed, CertificateRequestLoadOptions options, RSASignaturePadding?signerSignaturePadding) { ArgumentException.ThrowIfNullOrEmpty(signerHashAlgorithm.Name, nameof(signerHashAlgorithm)); if ((options & ~AllOptions) != 0) { throw new ArgumentOutOfRangeException(nameof(options), options, SR.Argument_InvalidFlag); } bool skipSignatureValidation = (options & CertificateRequestLoadOptions.SkipSignatureValidation) != 0; bool unsafeLoadCertificateExtensions = (options & CertificateRequestLoadOptions.UnsafeLoadCertificateExtensions) != 0; try { AsnValueReader outer = new AsnValueReader(pkcs10, AsnEncodingRules.DER); int encodedLength = outer.PeekEncodedValue().Length; AsnValueReader pkcs10Asn = outer.ReadSequence(); CertificateRequest req; if (!permitTrailingData) { outer.ThrowIfNotEmpty(); } fixed(byte *p10ptr = pkcs10) { using (PointerMemoryManager <byte> manager = new PointerMemoryManager <byte>(p10ptr, encodedLength)) { ReadOnlyMemory <byte> rebind = manager.Memory; ReadOnlySpan <byte> encodedRequestInfo = pkcs10Asn.PeekEncodedValue(); CertificationRequestInfoAsn requestInfo; AlgorithmIdentifierAsn algorithmIdentifier; ReadOnlySpan <byte> signature; int signatureUnusedBitCount; CertificationRequestInfoAsn.Decode(ref pkcs10Asn, rebind, out requestInfo); AlgorithmIdentifierAsn.Decode(ref pkcs10Asn, rebind, out algorithmIdentifier); if (!pkcs10Asn.TryReadPrimitiveBitString(out signatureUnusedBitCount, out signature)) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } pkcs10Asn.ThrowIfNotEmpty(); if (requestInfo.Version < 0) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } // They haven't bumped from v0 to v1 as of 2022. const int MaxSupportedVersion = 0; if (requestInfo.Version != MaxSupportedVersion) { throw new CryptographicException( SR.Format( SR.Cryptography_CertReq_Load_VersionTooNew, requestInfo.Version, MaxSupportedVersion)); } PublicKey publicKey = PublicKey.DecodeSubjectPublicKeyInfo(ref requestInfo.SubjectPublicKeyInfo); if (!skipSignatureValidation) { // None of the supported signature algorithms support signatures that are not full bytes. // So, shortcut the verification on the bit length if (signatureUnusedBitCount != 0 || !VerifyX509Signature(encodedRequestInfo, signature, publicKey, algorithmIdentifier)) { throw new CryptographicException(SR.Cryptography_CertReq_SignatureVerificationFailed); } } X500DistinguishedName subject = new X500DistinguishedName(requestInfo.Subject.Span); req = new CertificateRequest( subject, publicKey, signerHashAlgorithm, signerSignaturePadding); if (requestInfo.Attributes is not null) { bool foundCertExt = false; foreach (AttributeAsn attr in requestInfo.Attributes) { if (attr.AttrType == Oids.Pkcs9ExtensionRequest) { if (foundCertExt) { throw new CryptographicException( SR.Cryptography_CertReq_Load_DuplicateExtensionRequests); } foundCertExt = true; if (attr.AttrValues.Length != 1) { throw new CryptographicException( SR.Cryptography_CertReq_Load_DuplicateExtensionRequests); } AsnValueReader extsReader = new AsnValueReader( attr.AttrValues[0].Span, AsnEncodingRules.DER); AsnValueReader exts = extsReader.ReadSequence(); extsReader.ThrowIfNotEmpty(); // Minimum length is 1, so do..while do { X509ExtensionAsn.Decode(ref exts, rebind, out X509ExtensionAsn extAsn); if (unsafeLoadCertificateExtensions) { X509Extension ext = new X509Extension( extAsn.ExtnId, extAsn.ExtnValue.Span, extAsn.Critical); X509Extension?rich = X509Certificate2.CreateCustomExtensionIfAny(extAsn.ExtnId); if (rich is not null) { rich.CopyFrom(ext); req.CertificateExtensions.Add(rich); } else { req.CertificateExtensions.Add(ext); } } } while (exts.HasData); } else { if (attr.AttrValues.Length == 0) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } foreach (ReadOnlyMemory <byte> val in attr.AttrValues) { req.OtherRequestAttributes.Add( new AsnEncodedData(attr.AttrType, val.Span)); } } } } } } bytesConsumed = encodedLength; return(req); } catch (AsnContentException e) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); } }