Beispiel #1
0
            //
            // This returns an allocated native memory block. Its lifetime (and that of any allocated subblocks it may point to) is that of "hb".
            //
            private static unsafe CERT_ID EncodeRecipientId(CmsRecipient recipient, SafeCertContextHandle hCertContext, CERT_CONTEXT *pCertContext, CERT_INFO *pCertInfo, HeapBlockRetainer hb)
            {
                CERT_ID recipientId        = default(CERT_ID);
                SubjectIdentifierType type = recipient.RecipientIdentifierType;

                switch (type)
                {
                case SubjectIdentifierType.IssuerAndSerialNumber:
                {
                    recipientId.dwIdChoice = CertIdChoice.CERT_ID_ISSUER_SERIAL_NUMBER;
                    recipientId.u.IssuerSerialNumber.Issuer       = pCertInfo->Issuer;
                    recipientId.u.IssuerSerialNumber.SerialNumber = pCertInfo->SerialNumber;
                    break;
                }

                case SubjectIdentifierType.SubjectKeyIdentifier:
                {
                    byte[] ski  = hCertContext.GetSubjectKeyIdentifer();
                    IntPtr pSki = hb.AllocBytes(ski);

                    recipientId.dwIdChoice     = CertIdChoice.CERT_ID_KEY_IDENTIFIER;
                    recipientId.u.KeyId.cbData = (uint)(ski.Length);
                    recipientId.u.KeyId.pbData = pSki;
                    break;
                }

                default:
                    // The public contract for CmsRecipient guarantees that SubjectKeyIdentifier and IssuerAndSerialNumber are the only two possibilities.
                    Debug.Fail($"Unexpected SubjectIdentifierType: {type}");
                    throw new NotSupportedException(SR.Format(SR.Cryptography_Cms_Invalid_Subject_Identifier_Type, type));
                }

                return(recipientId);
            }
Beispiel #2
0
        public static SubjectIdentifier ToSubjectIdentifier(this CERT_ID certId)
        {
            switch (certId.dwIdChoice)
            {
            case CertIdChoice.CERT_ID_ISSUER_SERIAL_NUMBER:
            {
                const CertNameStrTypeAndFlags dwStrType = CertNameStrTypeAndFlags.CERT_X500_NAME_STR | CertNameStrTypeAndFlags.CERT_NAME_STR_REVERSE_FLAG;
                string issuer = Interop.Crypt32.CertNameToStr(ref certId.u.IssuerSerialNumber.Issuer, dwStrType);

                byte[]        serial       = certId.u.IssuerSerialNumber.SerialNumber.ToByteArray();
                StringBuilder serialString = new StringBuilder(serial.Length * 2);
                for (int i = serial.Length; i > 0; i--)
                {
                    serialString.Append(serial[i - 1].ToString("X2"));
                }
                return(new SubjectIdentifier(SubjectIdentifierType.IssuerAndSerialNumber, new X509IssuerSerial(issuer, serialString.ToString())));
            }

            case CertIdChoice.CERT_ID_KEY_IDENTIFIER:
            {
                byte[]        ski = certId.u.KeyId.ToByteArray();
                StringBuilder sb  = new StringBuilder(ski.Length * 2);
                foreach (byte b in ski)
                {
                    sb.Append(b.ToString("X2"));
                }
                return(new SubjectIdentifier(SubjectIdentifierType.SubjectKeyIdentifier, sb.ToString()));
            }

            default:
                throw new CryptographicException(SR.Format(SR.Cryptography_Cms_Invalid_Subject_Identifier_Type, certId.dwIdChoice));
            }
        }
Beispiel #3
0
        public static SubjectIdentifier ToSubjectIdentifier(this CERT_ID certId)
        {
            switch (certId.dwIdChoice)
            {
            case CertIdChoice.CERT_ID_ISSUER_SERIAL_NUMBER:
            {
                const int dwStrType = (int)(CertNameStrTypeAndFlags.CERT_X500_NAME_STR | CertNameStrTypeAndFlags.CERT_NAME_STR_REVERSE_FLAG);

                string issuer;
                unsafe
                {
                    DATA_BLOB *dataBlobPtr = &certId.u.IssuerSerialNumber.Issuer;

                    int nc = Interop.Crypt32.CertNameToStr((int)MsgEncodingType.All, dataBlobPtr, dwStrType, null, 0);
                    if (nc <= 1)         // The API actually return 1 when it fails; which is not what the documentation says.
                    {
                        throw Interop.CPError.GetLastWin32Error().ToCryptographicException();
                    }

                    Span <char> name = nc <= 128 ? stackalloc char[128] : new char[nc];
                    fixed(char *namePtr = name)
                    {
                        nc = Interop.Crypt32.CertNameToStr((int)MsgEncodingType.All, dataBlobPtr, dwStrType, namePtr, nc);
                        if (nc <= 1)         // The API actually return 1 when it fails; which is not what the documentation says.
                        {
                            throw Interop.CPError.GetLastWin32Error().ToCryptographicException();
                        }

                        issuer = new string(namePtr);
                    }
                }

                byte[]           serial       = certId.u.IssuerSerialNumber.SerialNumber.ToByteArray();
                X509IssuerSerial issuerSerial = new X509IssuerSerial(issuer, serial.ToSerialString());
                return(new SubjectIdentifier(SubjectIdentifierType.IssuerAndSerialNumber, issuerSerial));
            }

            case CertIdChoice.CERT_ID_KEY_IDENTIFIER:
            {
                byte[] ski = certId.u.KeyId.ToByteArray();
                return(new SubjectIdentifier(SubjectIdentifierType.SubjectKeyIdentifier, ski.ToSkiString()));
            }

            default:
                throw new CryptographicException(SR.Format(SR.Cryptography_Cms_Invalid_Subject_Identifier_Type, certId.dwIdChoice));
            }
        }
Beispiel #4
0
        public static SubjectIdentifierOrKey ToSubjectIdentifierOrKey(this CERT_ID certId)
        {
            //
            // SubjectIdentifierOrKey is just a SubjectIdentifier with an (irrelevant here) "key" option thumbtacked onto it so
            // the easiest way is to subcontract the job to SubjectIdentifier.
            //
            SubjectIdentifier     subjectIdentifier     = certId.ToSubjectIdentifier();
            SubjectIdentifierType subjectIdentifierType = subjectIdentifier.Type;

            switch (subjectIdentifierType)
            {
            case SubjectIdentifierType.IssuerAndSerialNumber:
                return(new SubjectIdentifierOrKey(SubjectIdentifierOrKeyType.IssuerAndSerialNumber, subjectIdentifier.Value));

            case SubjectIdentifierType.SubjectKeyIdentifier:
                return(new SubjectIdentifierOrKey(SubjectIdentifierOrKeyType.SubjectKeyIdentifier, subjectIdentifier.Value));

            default:
                Debug.Fail("Only the framework can construct SubjectIdentifier's so if we got a bad value here, that's our fault.");
                throw new CryptographicException(SR.Format(SR.Cryptography_Cms_Invalid_Subject_Identifier_Type, subjectIdentifierType));
            }
        }
Beispiel #5
0
        public static SubjectIdentifier ToSubjectIdentifier(this CERT_ID certId)
        {
            switch (certId.dwIdChoice)
            {
            case CertIdChoice.CERT_ID_ISSUER_SERIAL_NUMBER:
            {
                const CertNameStrTypeAndFlags dwStrType = CertNameStrTypeAndFlags.CERT_X500_NAME_STR | CertNameStrTypeAndFlags.CERT_NAME_STR_REVERSE_FLAG;
                string           issuer       = Interop.Crypt32.CertNameToStr(ref certId.u.IssuerSerialNumber.Issuer, dwStrType);
                byte[]           serial       = certId.u.IssuerSerialNumber.SerialNumber.ToByteArray();
                X509IssuerSerial issuerSerial = new X509IssuerSerial(issuer, serial.ToSerialString());
                return(new SubjectIdentifier(SubjectIdentifierType.IssuerAndSerialNumber, issuerSerial));
            }

            case CertIdChoice.CERT_ID_KEY_IDENTIFIER:
            {
                byte[] ski = certId.u.KeyId.ToByteArray();
                return(new SubjectIdentifier(SubjectIdentifierType.SubjectKeyIdentifier, ski.ToSkiString()));
            }

            default:
                throw new CryptographicException(SR.Format(SR.Cryptography_Cms_Invalid_Subject_Identifier_Type, certId.dwIdChoice));
            }
        }
Beispiel #6
0
 internal CMSG_SIGNER_ENCODE_INFO(int size) {
     cbSize = (uint) size;
     pCertInfo = IntPtr.Zero;
     hCryptProv = IntPtr.Zero;
     dwKeySpec = 0;
     HashAlgorithm = new CRYPT_ALGORITHM_IDENTIFIER();
     pvHashAuxInfo = IntPtr.Zero;
     cAuthAttr = 0;
     rgAuthAttr = IntPtr.Zero;
     cUnauthAttr = 0;
     rgUnauthAttr = IntPtr.Zero;
     SignerId = new CERT_ID();
     HashEncryptionAlgorithm = new CRYPT_ALGORITHM_IDENTIFIER();
     pvHashEncryptionAuxInfo = IntPtr.Zero;
 }