/// <summary>
        /// Initializes a new instance of the <see cref="RsaCryptographicKey" /> class.
        /// </summary>
        /// <param name="publicKey">The public key.</param>
        /// <param name="keyIdentifier">The key identifier that may be used to query the keychain.</param>
        /// <param name="algorithm">The algorithm.</param>
        internal RsaCryptographicKey(SecKey publicKey, string keyIdentifier, AsymmetricAlgorithm algorithm)
        {
            Requires.NotNull(publicKey, "publicKey");

            this.publicKey = publicKey;
            this.keyIdentifier = keyIdentifier;
            this.algorithm = algorithm;
        }
        /// <inheritdoc/>
        public ICryptographicKey ImportPublicKey(byte[] keyBlob, CryptographicPublicKeyBlobType blobType = CryptographicPublicKeyBlobType.X509SubjectPublicKeyInfo)
        {
            Requires.NotNull(keyBlob, "keyBlob");

            RSAParameters parameters = KeyFormatter.GetFormatter(blobType).Read(keyBlob);

            // Inject the PKCS#1 public key into the KeyChain.
            string keyIdentifier = Guid.NewGuid().ToString();
            string publicKeyIdentifier = RsaCryptographicKey.GetPublicKeyIdentifierWithTag(keyIdentifier);
            var keyQueryDictionary = RsaCryptographicKey.CreateKeyQueryDictionary(publicKeyIdentifier);
            keyQueryDictionary[KSec.ValueData] = NSData.FromArray(KeyFormatter.Pkcs1PrependZeros.Write(parameters, includePrivateKey: false));
            keyQueryDictionary[KSec.AttrKeyClass] = KSec.AttrKeyClassPublic;
            keyQueryDictionary[KSec.ReturnRef] = NSNumber.FromBoolean(true);
            IntPtr resultHandle;
            int status = RsaCryptographicKey.SecItemAdd(keyQueryDictionary.Handle, out resultHandle);
            if (resultHandle != IntPtr.Zero)
            {
                var key = new SecKey(resultHandle, true);
                return new RsaCryptographicKey(key, keyIdentifier, this.Algorithm);
            }
            else
            {
                throw new InvalidOperationException("SecItemAdd return " + status);
            }
        }
        /// <summary>
        /// Obtains a reference to an iOS security key given its identifying tag.
        /// </summary>
        /// <param name="tag">The tag of the key in the keychain.</param>
        /// <returns>The security key.</returns>
        private static SecKey KeyRefWithTag(string tag)
        {
            NSMutableDictionary queryKey = CreateKeyQueryDictionary(tag);
            queryKey[KSec.ReturnRef] = NSNumber.FromBoolean(true);

            IntPtr typeRef;
            int code = SecItemCopyMatching(queryKey.Handle, out typeRef);
            var keyRef = new SecKey(typeRef, owns: true);
            return keyRef;
        }
示例#4
0
        protected INativeObject GetINativeInstance(Type t)
        {
            var ctor = t.GetConstructor(Type.EmptyTypes);

            if ((ctor != null) && !ctor.IsAbstract)
            {
                return(ctor.Invoke(null) as INativeObject);
            }

            if (!NativeObjectInterfaceType.IsAssignableFrom(t))
            {
                throw new ArgumentException("t");
            }
            switch (t.Name)
            {
            case "CFAllocator":
                return(CFAllocator.SystemDefault);

            case "CFBundle":
                var bundles = CFBundle.GetAll();
                if (bundles.Length > 0)
                {
                    return(bundles [0]);
                }
                else
                {
                    throw new InvalidOperationException(string.Format("Could not create the new instance for type {0}.", t.Name));
                }

            case "CFNotificationCenter":
                return(CFNotificationCenter.Darwin);

            case "CFReadStream":
            case "CFStream":
                CFReadStream  readStream;
                CFWriteStream writeStream;
                CFStream.CreatePairWithSocketToHost("www.google.com", 80, out readStream, out writeStream);
                return(readStream);

            case "CFWriteStream":
                CFStream.CreatePairWithSocketToHost("www.google.com", 80, out readStream, out writeStream);
                return(writeStream);

            case "CFUrl":
                return(CFUrl.FromFile("/etc"));

            case "AudioFile":
                var path = Path.GetFullPath("1.caf");
                var af   = AudioFile.Open(CFUrl.FromFile(path), AudioFilePermission.Read, AudioFileType.CAF);
                return(af);

            case "CFHTTPMessage":
                return(CFHTTPMessage.CreateEmpty(false));

            case "CGBitmapContext":
                byte[] data = new byte [400];
                using (CGColorSpace space = CGColorSpace.CreateDeviceRGB()) {
                    return(new CGBitmapContext(data, 10, 10, 8, 40, space, CGBitmapFlags.PremultipliedLast));
                }

            case "CGContextPDF":
                var filename = Environment.GetFolderPath(Environment.SpecialFolder.CommonDocuments) + "/t.pdf";
                using (var url = new NSUrl(filename))
                    return(new CGContextPDF(url));

            case "CGColorConverter":
                var cvt = new CGColorConverterTriple()
                {
                    Space     = CGColorSpace.CreateGenericRgb(),
                    Intent    = CGColorRenderingIntent.Default,
                    Transform = CGColorConverterTransformType.ApplySpace
                };
                return(new CGColorConverter(null, cvt, cvt, cvt));

            case "CGDataConsumer":
                using (NSMutableData destData = new NSMutableData()) {
                    return(new CGDataConsumer(destData));
                }

            case "CGDataProvider":
                filename = "xamarin1.png";
                return(new CGDataProvider(filename));

            case "CGFont":
                return(CGFont.CreateWithFontName("Courier New"));

            case "CGPattern":
                return(new CGPattern(
                           new RectangleF(0, 0, 16, 16),
                           CGAffineTransform.MakeIdentity(),
                           16, 16,
                           CGPatternTiling.NoDistortion,
                           true,
                           (cgc) => {}));

            case "CMBufferQueue":
                return(CMBufferQueue.CreateUnsorted(2));

            case "CTFont":
                CTFontDescriptorAttributes fda = new CTFontDescriptorAttributes()
                {
                    FamilyName = "Courier",
                    StyleName  = "Bold",
                    Size       = 16.0f
                };
                using (var fd = new CTFontDescriptor(fda))
                    return(new CTFont(fd, 10, CTFontOptions.Default));

            case "CTFontCollection":
                return(new CTFontCollection(new CTFontCollectionOptions()));

            case "CTFontDescriptor":
                fda = new CTFontDescriptorAttributes();
                return(new CTFontDescriptor(fda));

            case "CTTextTab":
                return(new CTTextTab(CTTextAlignment.Left, 2));

            case "CTTypesetter":
                return(new CTTypesetter(new NSAttributedString("Hello, world",
                                                               new CTStringAttributes()
                {
                    ForegroundColorFromContext = true,
                    Font = new CTFont("Arial", 24)
                })));

            case "CTFrame":
                var framesetter = new CTFramesetter(new NSAttributedString("Hello, world",
                                                                           new CTStringAttributes()
                {
                    ForegroundColorFromContext = true,
                    Font = new CTFont("Arial", 24)
                }));
                var bPath = UIBezierPath.FromRect(new RectangleF(0, 0, 3, 3));
                return(framesetter.GetFrame(new NSRange(0, 0), bPath.CGPath, null));

            case "CTFramesetter":
                return(new CTFramesetter(new NSAttributedString("Hello, world",
                                                                new CTStringAttributes()
                {
                    ForegroundColorFromContext = true,
                    Font = new CTFont("Arial", 24)
                })));

            case "CTGlyphInfo":
                return(new CTGlyphInfo("Zapfino", new CTFont("Arial", 24), "Foo"));

            case "CTLine":
                return(new CTLine(new NSAttributedString("Hello, world",
                                                         new CTStringAttributes()
                {
                    ForegroundColorFromContext = true,
                    Font = new CTFont("Arial", 24)
                })));

            case "CGImageDestination":
                var storage = new NSMutableData();
                return(CGImageDestination.Create(new CGDataConsumer(storage), "public.png", 1));

            case "CGImageMetadataTag":
                using (NSString name = new NSString("tagName"))
                    using (var value = new NSString("value"))
                        return(new CGImageMetadataTag(CGImageMetadataTagNamespaces.Exif, CGImageMetadataTagPrefixes.Exif, name, CGImageMetadataType.Default, value));

            case "CGImageSource":
                filename = "xamarin1.png";
                return(CGImageSource.FromUrl(NSUrl.FromFilename(filename)));

            case "SecPolicy":
                return(SecPolicy.CreateSslPolicy(false, null));

            case "SecIdentity":
                using (var options = NSDictionary.FromObjectAndKey(new NSString("farscape"), SecImportExport.Passphrase)) {
                    NSDictionary[] array;
                    var            result = SecImportExport.ImportPkcs12(farscape_pfx, options, out array);
                    if (result != SecStatusCode.Success)
                    {
                        throw new InvalidOperationException(string.Format("Could not create the new instance for type {0} due to {1}.", t.Name, result));
                    }
                    return(new SecIdentity(array [0].LowlevelObjectForKey(SecImportExport.Identity.Handle)));
                }

            case "SecTrust":
                X509Certificate x = new X509Certificate(mail_google_com);
                using (var policy = SecPolicy.CreateSslPolicy(true, "mail.google.com"))
                    return(new SecTrust(x, policy));

            case "SslContext":
                return(new SslContext(SslProtocolSide.Client, SslConnectionType.Stream));

            case "UIFontFeature":
                return(new UIFontFeature(CTFontFeatureNumberSpacing.Selector.ProportionalNumbers));

            case "NetworkReachability":
                return(new NetworkReachability(IPAddress.Loopback, null));

#if !__TVOS__
            case "VTCompressionSession":
            case "VTSession":
                return(VTCompressionSession.Create(1024, 768, CMVideoCodecType.H264, (sourceFrame, status, flags, buffer) => { }, null, (CVPixelBufferAttributes)null));

            case "VTFrameSilo":
                return(VTFrameSilo.Create());

            case "VTMultiPassStorage":
                return(VTMultiPassStorage.Create());
#endif
            case "CFString":
                return(new CFString("test"));

            case "DispatchQueue":
                return(new DispatchQueue("com.example.subsystem.taskXYZ"));

            case "DispatchGroup":
                return(DispatchGroup.Create());

            case "CGColorSpace":
                return(CGColorSpace.CreateAcesCGLinear());

            case "CGGradient":
                CGColor[] cArray = { UIColor.Black.CGColor, UIColor.Clear.CGColor, UIColor.Blue.CGColor };
                return(new CGGradient(null, cArray));

            case "CGImage":
                filename = "xamarin1.png";
                using (var dp = new CGDataProvider(filename))
                    return(CGImage.FromPNG(dp, null, false, CGColorRenderingIntent.Default));

            case "CGColor":
                return(UIColor.Black.CGColor);

            case "CMClock":
                CMClockError ce;
                CMClock      clock = CMClock.CreateAudioClock(out ce);
                if (ce == CMClockError.None)
                {
                    return(clock);
                }
                throw new InvalidOperationException(string.Format("Could not create the new instance for type {0}.", t.Name));

            case "CMTimebase":
                clock = CMClock.CreateAudioClock(out ce);
                if (ce == CMClockError.None)
                {
                    return(new CMTimebase(clock));
                }
                throw new InvalidOperationException(string.Format("Could not create the new instance for type {0}.", t.Name));

            case "CVPixelBufferPool":
                return(new CVPixelBufferPool(
                           new CVPixelBufferPoolSettings(),
                           new CVPixelBufferAttributes(CVPixelFormatType.CV24RGB, 100, 50)
                           ));

            case "SecCertificate":
                using (var cdata = NSData.FromArray(mail_google_com))
                    return(new SecCertificate(cdata));

            case "SecKey":
                SecKey private_key;
                SecKey public_key;
                using (var record = new SecRecord(SecKind.Key)) {
                    record.KeyType       = SecKeyType.RSA;
                    record.KeySizeInBits = 512;                     // it's not a performance test :)
                    SecKey.GenerateKeyPair(record.ToDictionary(), out public_key, out private_key);
                    return(private_key);
                }

            case "SecAccessControl":
                return(new SecAccessControl(SecAccessible.WhenPasscodeSetThisDeviceOnly));

            default:
                throw new InvalidOperationException(string.Format("Could not create the new instance for type {0}.", t.Name));
            }
        }
示例#5
0
        public void RoundtripRSA512PKCS1()
        {
            NSError error;
            SecKey  private_key;
            SecKey  public_key;

            using (var record = new SecRecord(SecKind.Key)) {
                record.KeyType       = SecKeyType.RSA;
                record.KeySizeInBits = 512;                 // it's not a performance test :)

                Assert.That(SecKey.GenerateKeyPair(record.ToDictionary(), out public_key, out private_key), Is.EqualTo(SecStatusCode.Success), "GenerateKeyPair");

                byte [] plain = new byte [20] {
                    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
                };
                byte [] cipher;
                if (TestRuntime.CheckXcodeVersion(8, 0))
                {
                    Assert.True(public_key.IsAlgorithmSupported(SecKeyOperationType.Encrypt, SecKeyAlgorithm.RsaEncryptionPkcs1), "public/IsAlgorithmSupported/Encrypt");
                    // I would have expect false
                    Assert.True(public_key.IsAlgorithmSupported(SecKeyOperationType.Decrypt, SecKeyAlgorithm.RsaEncryptionPkcs1), "public/IsAlgorithmSupported/Decrypt");

                    using (var pub = public_key.GetPublicKey()) {
                        // a new native instance of the key is returned (so having a new managed SecKey is fine)
                        Assert.That(pub.Handle, Is.Not.EqualTo(public_key.Handle), "public/GetPublicKey");
                    }
                    using (var attrs = public_key.GetAttributes()) {
                        Assert.That(attrs.Count, Is.GreaterThan(0), "public/GetAttributes");
                    }
                    using (var data = public_key.GetExternalRepresentation(out error)) {
                        Assert.Null(error, "public/error-1");
                        Assert.NotNull(data, "public/GetExternalRepresentation");

                        using (var key = SecKey.Create(data, SecKeyType.RSA, SecKeyClass.Public, 512, null, out error)) {
                            Assert.Null(error, "public/Create/error-1");
                        }
                    }
                }
                Assert.That(public_key.Encrypt(SecPadding.PKCS1, plain, out cipher), Is.EqualTo(SecStatusCode.Success), "Encrypt");

                byte[] result;
                if (TestRuntime.CheckXcodeVersion(8, 0))
                {
                    Assert.False(private_key.IsAlgorithmSupported(SecKeyOperationType.Encrypt, SecKeyAlgorithm.RsaEncryptionPkcs1), "private/IsAlgorithmSupported/Encrypt");
                    Assert.True(private_key.IsAlgorithmSupported(SecKeyOperationType.Decrypt, SecKeyAlgorithm.RsaEncryptionPkcs1), "private/IsAlgorithmSupported/Decrypt");

                    using (var pub2 = private_key.GetPublicKey()) {
                        // a new native instance of the key is returned (so having a new managed SecKey is fine)
                        Assert.That(pub2.Handle, Is.Not.EqualTo(public_key.Handle), "private/GetPublicKey");
                    }
                    using (var attrs = private_key.GetAttributes()) {
                        Assert.That(attrs.Count, Is.GreaterThan(0), "private/GetAttributes");
                    }
                    using (var data2 = private_key.GetExternalRepresentation(out error)) {
                        Assert.Null(error, "private/error-1");
                        Assert.NotNull(data2, "private/GetExternalRepresentation");

                        using (var key = SecKey.Create(data2, SecKeyType.RSA, SecKeyClass.Private, 512, null, out error)) {
                            Assert.Null(error, "private/Create/error-1");
                        }
                    }
                }
                public_key.Dispose();
                Assert.That(private_key.Decrypt(SecPadding.PKCS1, cipher, out result), Is.EqualTo(SecStatusCode.Success), "Decrypt");
                Assert.That(plain, Is.EqualTo(result), "match");
                private_key.Dispose();
            }
        }
示例#6
0
        public void RoundtripRSAMinPKCS1()
        {
            NSError error;
            SecKey  private_key;
            SecKey  public_key;

            using (var record = new SecRecord(SecKind.Key)) {
                record.KeyType       = SecKeyType.RSA;
                record.KeySizeInBits = MinRsaKeySize;                 // it's not a performance test :)

                Assert.That(SecKey.GenerateKeyPair(record.ToDictionary(), out public_key, out private_key), Is.EqualTo(SecStatusCode.Success), "GenerateKeyPair");

                byte [] plain = new byte [20] {
                    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
                };
                byte [] cipher;
                if (TestRuntime.CheckXcodeVersion(8, 0))
                {
                    Assert.True(public_key.IsAlgorithmSupported(SecKeyOperationType.Encrypt, SecKeyAlgorithm.RsaEncryptionPkcs1), "public/IsAlgorithmSupported/Encrypt");

#if MONOMAC
                    Assert.That(public_key.IsAlgorithmSupported(SecKeyOperationType.Decrypt, SecKeyAlgorithm.RsaEncryptionPkcs1), Is.EqualTo(TestRuntime.CheckSystemVersion(PlatformName.MacOSX, 10, 13)), "public/IsAlgorithmSupported/Decrypt");

                    using (var pub = public_key.GetPublicKey()) {
                        // macOS behaviour is not consistent - but the test main goal is to check we get a key
                        Assert.That(pub.Handle, Is.Not.EqualTo(IntPtr.Zero), "public/GetPublicKey");
                    }
#else
                    Assert.True(public_key.IsAlgorithmSupported(SecKeyOperationType.Decrypt, SecKeyAlgorithm.RsaEncryptionPkcs1), "public/IsAlgorithmSupported/Decrypt");

                    using (var pub = public_key.GetPublicKey())
                    {
                        // a new native instance of the key is returned (so having a new managed SecKey is fine)
                        Assert.False(pub.Handle == public_key.Handle, "public/GetPublicKey");
                    }
#endif

                    using (var attrs = public_key.GetAttributes()) {
                        Assert.That(attrs.Count, Is.GreaterThan(0), "public/GetAttributes");
                    }
                    using (var data = public_key.GetExternalRepresentation(out error)) {
                        Assert.Null(error, "public/error-1");
                        Assert.NotNull(data, "public/GetExternalRepresentation");

                        using (var key = SecKey.Create(data, SecKeyType.RSA, SecKeyClass.Public, MinRsaKeySize, null, out error)) {
                            Assert.Null(error, "public/Create/error-1");
                        }
                    }
                }
                Assert.That(public_key.Encrypt(SecPadding.PKCS1, plain, out cipher), Is.EqualTo(SecStatusCode.Success), "Encrypt");

                byte[] result;
                if (TestRuntime.CheckXcodeVersion(8, 0))
                {
                    Assert.False(private_key.IsAlgorithmSupported(SecKeyOperationType.Encrypt, SecKeyAlgorithm.RsaEncryptionPkcs1), "private/IsAlgorithmSupported/Encrypt");
                    Assert.True(private_key.IsAlgorithmSupported(SecKeyOperationType.Decrypt, SecKeyAlgorithm.RsaEncryptionPkcs1), "private/IsAlgorithmSupported/Decrypt");

#if MONOMAC
                    using (var pub2 = private_key.GetPublicKey()) {
                        Assert.That(pub2.Handle, Is.EqualTo(public_key.Handle), "private/GetPublicKey");
                    }
#else
                    using (var pub2 = private_key.GetPublicKey()) {
                        // a new native instance of the key is returned (so having a new managed SecKey is fine)
                        Assert.That(pub2.Handle, Is.Not.EqualTo(public_key.Handle), "private/GetPublicKey");
                    }
#endif
                    using (var attrs = private_key.GetAttributes()) {
                        Assert.That(attrs.Count, Is.GreaterThan(0), "private/GetAttributes");
                    }
                    using (var data2 = private_key.GetExternalRepresentation(out error)) {
                        Assert.Null(error, "private/error-1");
                        Assert.NotNull(data2, "private/GetExternalRepresentation");

                        using (var key = SecKey.Create(data2, SecKeyType.RSA, SecKeyClass.Private, MinRsaKeySize, null, out error)) {
                            Assert.Null(error, "private/Create/error-1");
                        }
                    }
                }
                public_key.Dispose();
                var expectedResult = SecStatusCode.Success;
#if __MACOS__
                if (!TestRuntime.CheckSystemVersion(PlatformName.MacOSX, 10, 8))
                {
                    expectedResult = SecStatusCode.InvalidData;
                }
#endif
                Assert.That(private_key.Decrypt(SecPadding.PKCS1, cipher, out result), Is.EqualTo(expectedResult), "Decrypt");
                if (expectedResult != SecStatusCode.InvalidData)
                {
                    Assert.That(plain, Is.EqualTo(result), "match");
                }
                private_key.Dispose();
            }
        }