Intial commit
This commit is contained in:
		
							
								
								
									
										37
									
								
								otpnet/LICENSE.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								otpnet/LICENSE.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
				
			|||||||
 | 
					OTPNet is licensed under the terms of Apache 2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Copyright [2012] [Nathan Adams]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					   you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					   You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					       http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					   distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					   See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					   limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This project was based off of OTPHP (https://github.com/lelag/otphp) by Le Lag 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Copyright (c) 2011 Le Lag 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
				
			||||||
 | 
					of this software and associated documentation files (the "Software"), to deal
 | 
				
			||||||
 | 
					in the Software without restriction, including without limitation the rights
 | 
				
			||||||
 | 
					to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
				
			||||||
 | 
					copies of the Software, and to permit persons to whom the Software is
 | 
				
			||||||
 | 
					furnished to do so, subject to the following conditions:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The above copyright notice and this permission notice shall be included in
 | 
				
			||||||
 | 
					all copies or substantial portions of the Software.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
				
			||||||
 | 
					IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
				
			||||||
 | 
					FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
				
			||||||
 | 
					AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
				
			||||||
 | 
					LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
				
			||||||
 | 
					OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
				
			||||||
 | 
					THE SOFTWARE.
 | 
				
			||||||
							
								
								
									
										132
									
								
								otpnet/Libraries/Base32Encoding.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								otpnet/Libraries/Base32Encoding.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,132 @@
 | 
				
			|||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace OTPNet
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // http://stackoverflow.com/a/7135008/195722
 | 
				
			||||||
 | 
					    public class Base32Encoding
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public static byte[] ToBytes(string input)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (string.IsNullOrEmpty(input))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                throw new ArgumentNullException("input");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            input = input.TrimEnd('='); //remove padding characters
 | 
				
			||||||
 | 
					            int byteCount = input.Length * 5 / 8; //this must be TRUNCATED
 | 
				
			||||||
 | 
					            byte[] returnArray = new byte[byteCount];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            byte curByte = 0, bitsRemaining = 8;
 | 
				
			||||||
 | 
					            int mask = 0, arrayIndex = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            foreach (char c in input)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                int cValue = CharToValue(c);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (bitsRemaining > 5)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    mask = cValue << (bitsRemaining - 5);
 | 
				
			||||||
 | 
					                    curByte = (byte)(curByte | mask);
 | 
				
			||||||
 | 
					                    bitsRemaining -= 5;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    mask = cValue >> (5 - bitsRemaining);
 | 
				
			||||||
 | 
					                    curByte = (byte)(curByte | mask);
 | 
				
			||||||
 | 
					                    returnArray[arrayIndex++] = curByte;
 | 
				
			||||||
 | 
					                    curByte = (byte)(cValue << (3 + bitsRemaining));
 | 
				
			||||||
 | 
					                    bitsRemaining += 3;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            //if we didn't end with a full byte
 | 
				
			||||||
 | 
					            if (arrayIndex != byteCount)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                returnArray[arrayIndex] = curByte;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return returnArray;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static string ToString(byte[] input)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (input == null || input.Length == 0)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                throw new ArgumentNullException("input");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            int charCount = (int)Math.Ceiling(input.Length / 5d) * 8;
 | 
				
			||||||
 | 
					            char[] returnArray = new char[charCount];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            byte nextChar = 0, bitsRemaining = 5;
 | 
				
			||||||
 | 
					            int arrayIndex = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            foreach (byte b in input)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                nextChar = (byte)(nextChar | (b >> (8 - bitsRemaining)));
 | 
				
			||||||
 | 
					                returnArray[arrayIndex++] = ValueToChar(nextChar);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (bitsRemaining < 4)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    nextChar = (byte)((b >> (3 - bitsRemaining)) & 31);
 | 
				
			||||||
 | 
					                    returnArray[arrayIndex++] = ValueToChar(nextChar);
 | 
				
			||||||
 | 
					                    bitsRemaining += 5;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                bitsRemaining -= 3;
 | 
				
			||||||
 | 
					                nextChar = (byte)((b << bitsRemaining) & 31);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            //if we didn't end with a full char
 | 
				
			||||||
 | 
					            if (arrayIndex != charCount)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                returnArray[arrayIndex++] = ValueToChar(nextChar);
 | 
				
			||||||
 | 
					                while (arrayIndex != charCount) returnArray[arrayIndex++] = '='; //padding
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return new string(returnArray);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private static int CharToValue(char c)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            int value = (int)c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            //65-90 == uppercase letters
 | 
				
			||||||
 | 
					            if (value < 91 && value > 64)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return value - 65;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            //50-55 == numbers 2-7
 | 
				
			||||||
 | 
					            if (value < 56 && value > 49)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return value - 24;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            //97-122 == lowercase letters
 | 
				
			||||||
 | 
					            if (value < 123 && value > 96)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return value - 97;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            throw new ArgumentException("Character is not a Base32 character.", "c");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private static char ValueToChar(byte b)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (b < 26)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return (char)(b + 65);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (b < 32)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return (char)(b + 24);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            throw new ArgumentException("Byte is not a value Base32 value.", "b");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										45
									
								
								otpnet/Libraries/StringExtensions.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								otpnet/Libraries/StringExtensions.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
				
			|||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace OTPNet
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public static class StringExtensions
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /// <summary>Returns a string array that contains the substrings in this string that are seperated a given fixed length.</summary>
 | 
				
			||||||
 | 
					        /// <param name="s">This string object.</param>
 | 
				
			||||||
 | 
					        /// <param name="length">Size of each substring.
 | 
				
			||||||
 | 
					        ///     <para>CASE: length > 0 , RESULT: String is split from left to right.</para>
 | 
				
			||||||
 | 
					        ///     <para>CASE: length == 0 , RESULT: String is returned as the only entry in the array.</para>
 | 
				
			||||||
 | 
					        ///     <para>CASE: length < 0 , RESULT: String is split from right to left.</para>
 | 
				
			||||||
 | 
					        /// </param>
 | 
				
			||||||
 | 
					        /// <returns>String array that has been split into substrings of equal length.</returns>
 | 
				
			||||||
 | 
					        /// <example>
 | 
				
			||||||
 | 
					        ///     <code>
 | 
				
			||||||
 | 
					        ///         string s = "1234567890";
 | 
				
			||||||
 | 
					        ///         string[] a = s.Split(4); // a == { "1234", "5678", "90" }
 | 
				
			||||||
 | 
					        ///     </code>
 | 
				
			||||||
 | 
					        /// </example>            
 | 
				
			||||||
 | 
					        public static string[] Split(this string s, int length)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            System.Globalization.StringInfo str = new System.Globalization.StringInfo(s);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            int lengthAbs = Math.Abs(length);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (str == null || str.LengthInTextElements == 0 || lengthAbs == 0 || str.LengthInTextElements <= lengthAbs)
 | 
				
			||||||
 | 
					                return new string[] { str.ToString() };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            string[] array = new string[(str.LengthInTextElements % lengthAbs == 0 ? str.LengthInTextElements / lengthAbs : (str.LengthInTextElements / lengthAbs) + 1)];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (length > 0)
 | 
				
			||||||
 | 
					                for (int iStr = 0, iArray = 0; iStr < str.LengthInTextElements && iArray < array.Length; iStr += lengthAbs, iArray++)
 | 
				
			||||||
 | 
					                    array[iArray] = str.SubstringByTextElements(iStr, (str.LengthInTextElements - iStr < lengthAbs ? str.LengthInTextElements - iStr : lengthAbs));
 | 
				
			||||||
 | 
					            else // if (length < 0)
 | 
				
			||||||
 | 
					                for (int iStr = str.LengthInTextElements - 1, iArray = array.Length - 1; iStr >= 0 && iArray >= 0; iStr -= lengthAbs, iArray--)
 | 
				
			||||||
 | 
					                    array[iArray] = str.SubstringByTextElements((iStr - lengthAbs < 0 ? 0 : iStr - lengthAbs + 1), (iStr - lengthAbs < 0 ? iStr + 1 : lengthAbs));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return array;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										35
									
								
								otpnet/Libraries/Unixtime.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								otpnet/Libraries/Unixtime.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
				
			|||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace OTPNet
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    class Unixtime
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        private DateTime date;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public Unixtime()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            this.date = DateTime.Now;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public Unixtime(int timestamp)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            DateTime converted = new DateTime(1970, 1, 1, 0, 0, 0, 0);
 | 
				
			||||||
 | 
					            DateTime newDateTime = converted.AddSeconds(timestamp);
 | 
				
			||||||
 | 
					            this.date = newDateTime.ToLocalTime();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public DateTime toDateTime()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return this.date;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public long toTimeStamp()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            TimeSpan span = (this.date - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).ToLocalTime());
 | 
				
			||||||
 | 
					            return Convert.ToInt64(span.TotalSeconds);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										58
									
								
								otpnet/OTP/HOTP.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								otpnet/OTP/HOTP.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
				
			|||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace OTPNet
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					         * HOTP - One time password generator 
 | 
				
			||||||
 | 
					         * 
 | 
				
			||||||
 | 
					         * The HOTP class allow for the generation 
 | 
				
			||||||
 | 
					         * and verification of one-time password using 
 | 
				
			||||||
 | 
					         * the HOTP specified algorithm.
 | 
				
			||||||
 | 
					         *
 | 
				
			||||||
 | 
					         * This class is meant to be compatible with 
 | 
				
			||||||
 | 
					         * Google Authenticator
 | 
				
			||||||
 | 
					         *
 | 
				
			||||||
 | 
					         * This class was originally ported from the rotp
 | 
				
			||||||
 | 
					         * ruby library available at https://github.com/mdp/rotp
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					    public class HOTP : OTP
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public HOTP(string secret)
 | 
				
			||||||
 | 
					            : base(secret, 6, HashAlgorithm.SHA1)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /**
 | 
				
			||||||
 | 
					         *  Get the password for a specific counter value
 | 
				
			||||||
 | 
					         *  @param integer $count the counter which is used to
 | 
				
			||||||
 | 
					         *  seed the hmac hash function.
 | 
				
			||||||
 | 
					         *  @return integer the One Time Password
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        public int at(int count)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return this.generateOTP(count);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /**
 | 
				
			||||||
 | 
					         * Verify if a password is valid for a specific counter value
 | 
				
			||||||
 | 
					         *
 | 
				
			||||||
 | 
					         * @param integer $otp the one-time password 
 | 
				
			||||||
 | 
					         * @param integer $counter the counter value
 | 
				
			||||||
 | 
					         * @return  bool true if the counter is valid, false otherwise
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        public bool verify(int otp, int counter)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return (otp == this.at(counter));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public string provisioning_uri(string name, int initial_count)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return "otpauth://hotp/" + name + "?secret=" + this.secret + " &counter=" + initial_count.ToString();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										147
									
								
								otpnet/OTP/OTP.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								otpnet/OTP/OTP.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,147 @@
 | 
				
			|||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					using System.Security.Cryptography;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace OTPNet
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Please see LICENSE.txt for information on what license this is released under
 | 
				
			||||||
 | 
					    public enum HashAlgorithm
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        SHA1
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // This class was ported from this PHP library https://github.com/lelag/otphp which was ported from a Ruby library
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * One Time Password Generator 
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * The OTP class allow the generation of one-time
 | 
				
			||||||
 | 
					     * password that is described in rfc 4xxx.
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * This is class is meant to be compatible with 
 | 
				
			||||||
 | 
					     * Google Authenticator.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * This class was originally ported from the rotp
 | 
				
			||||||
 | 
					     * ruby library available at https://github.com/mdp/rotp
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public class OTP
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /**
 | 
				
			||||||
 | 
					         * The base32 encoded secret key
 | 
				
			||||||
 | 
					         * @var string
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        public string secret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /**
 | 
				
			||||||
 | 
					         * The algorithm used for the hmac hash function
 | 
				
			||||||
 | 
					         * @var string
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        public HashAlgorithm digest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /**
 | 
				
			||||||
 | 
					         * The number of digits in the one-time password
 | 
				
			||||||
 | 
					         * @var integer
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        public int digits;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /**
 | 
				
			||||||
 | 
					         * Constructor for the OTP class
 | 
				
			||||||
 | 
					         * @param string $secret the secret key
 | 
				
			||||||
 | 
					         * @param array $opt options array can contain the
 | 
				
			||||||
 | 
					         * following keys :
 | 
				
			||||||
 | 
					         *   @param integer digits : the number of digits in the one time password
 | 
				
			||||||
 | 
					         *   Currently Google Authenticator only support 6. Defaults to 6.
 | 
				
			||||||
 | 
					         *   @param string digest : the algorithm used for the hmac hash function
 | 
				
			||||||
 | 
					         *   Google Authenticator only support sha1. Defaults to sha1
 | 
				
			||||||
 | 
					         *
 | 
				
			||||||
 | 
					         * @return new OTP class.
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        public OTP(string secret)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            this.secret = secret;
 | 
				
			||||||
 | 
					            this.digits = 6;
 | 
				
			||||||
 | 
					            this.digest = HashAlgorithm.SHA1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public OTP(string secret, int digits)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            this.digits = digits;
 | 
				
			||||||
 | 
					            this.digest = HashAlgorithm.SHA1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public OTP(string secret, int digits, HashAlgorithm digest)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            this.secret = secret;
 | 
				
			||||||
 | 
					            this.digits = digits;
 | 
				
			||||||
 | 
					            this.digest = digest;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /**
 | 
				
			||||||
 | 
					         * Generate a one-time password
 | 
				
			||||||
 | 
					         *
 | 
				
			||||||
 | 
					         * @param integer $input : number used to seed the hmac hash function.
 | 
				
			||||||
 | 
					         * This number is usually a counter (HOTP) or calculated based on the current
 | 
				
			||||||
 | 
					         * timestamp (see TOTP class).
 | 
				
			||||||
 | 
					         * @return integer the one-time password 
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        public int generateOTP(Int64 input)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            HMAC hashgenerator = null;
 | 
				
			||||||
 | 
					            switch (digest)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                case HashAlgorithm.SHA1:
 | 
				
			||||||
 | 
					                    hashgenerator = new HMACSHA1(Base32Encoding.ToBytes(secret));
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            hashgenerator.ComputeHash(intToByteString(input));
 | 
				
			||||||
 | 
					            string hash = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            foreach(byte b in hashgenerator.Hash)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                hash += b.ToString("x2");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            List<int> hmac = new List<int>();
 | 
				
			||||||
 | 
					            foreach (string s in hash.Split(2))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                hmac.Add(Int32.Parse(s, System.Globalization.NumberStyles.HexNumber));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            int offset = hmac[19] & 0xf;
 | 
				
			||||||
 | 
					            int code = (hmac[offset + 0] & 0x7F) << 24 |
 | 
				
			||||||
 | 
					                    (hmac[offset + 1] & 0xFF) << 16 |
 | 
				
			||||||
 | 
					                    (hmac[offset + 2] & 0xFF) << 8 |
 | 
				
			||||||
 | 
					                    (hmac[offset + 3] & 0xFF);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return code % (int)Math.Pow((double)10, (double)this.digits);
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public byte[] intToByteString(Int64 i)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            List<byte> res = new List<byte>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            while (i != 0)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                res.Add((byte)(i & 0xFF));
 | 
				
			||||||
 | 
					                i >>= 8;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            int rcount = res.Count;
 | 
				
			||||||
 | 
					            for (int z = 0; z < 8 - rcount; z++)
 | 
				
			||||||
 | 
					                res.Add((byte)0);
 | 
				
			||||||
 | 
					            res.Reverse();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return res.ToArray();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										120
									
								
								otpnet/OTP/TOTP.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								otpnet/OTP/TOTP.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,120 @@
 | 
				
			|||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace OTPNet
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					        * TOTP - One time password generator 
 | 
				
			||||||
 | 
					        * 
 | 
				
			||||||
 | 
					        * The TOTP class allow for the generation 
 | 
				
			||||||
 | 
					        * and verification of one-time password using 
 | 
				
			||||||
 | 
					        * the TOTP specified algorithm.
 | 
				
			||||||
 | 
					        *
 | 
				
			||||||
 | 
					        * This class is meant to be compatible with 
 | 
				
			||||||
 | 
					        * Google Authenticator
 | 
				
			||||||
 | 
					        *
 | 
				
			||||||
 | 
					        * This class was originally ported from the rotp
 | 
				
			||||||
 | 
					        * ruby library available at https://github.com/mdp/rotp
 | 
				
			||||||
 | 
					        */
 | 
				
			||||||
 | 
					    public class TOTP : OTP
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /**
 | 
				
			||||||
 | 
					         * The interval in seconds for a one-time password timeframe
 | 
				
			||||||
 | 
					         * Defaults to 30
 | 
				
			||||||
 | 
					         * @var integer
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        public double interval;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public TOTP(string secret)
 | 
				
			||||||
 | 
					            : base(secret, 6, HashAlgorithm.SHA1)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            this.interval = 30;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public TOTP(string secret, double interval)
 | 
				
			||||||
 | 
					            : base(secret, 6, HashAlgorithm.SHA1)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            this.interval = interval;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public TOTP(string secret, double interval, int digits)
 | 
				
			||||||
 | 
					            : base(secret, digits, HashAlgorithm.SHA1)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            this.interval = interval;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public TOTP(string secret, double interval, int digits, HashAlgorithm algo)
 | 
				
			||||||
 | 
					            : base(secret, digits, algo)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            this.interval = interval;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /**
 | 
				
			||||||
 | 
					         *  Get the password for a specific timestamp value 
 | 
				
			||||||
 | 
					         *
 | 
				
			||||||
 | 
					         *  @param integer $timestamp the timestamp which is timecoded and 
 | 
				
			||||||
 | 
					         *  used to seed the hmac hash function.
 | 
				
			||||||
 | 
					         *  @return integer the One Time Password
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        public int at(double timestamp)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return this.generateOTP(this.timecode(timestamp));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /**
 | 
				
			||||||
 | 
					         *  Get the password for the current timestamp value 
 | 
				
			||||||
 | 
					         *
 | 
				
			||||||
 | 
					         *  @return integer the current One Time Password
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        public int now()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return this.at(new Unixtime().toTimeStamp());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /**
 | 
				
			||||||
 | 
					         * Verify if a password is valid for a specific counter value
 | 
				
			||||||
 | 
					         *
 | 
				
			||||||
 | 
					         * @param integer $otp the one-time password 
 | 
				
			||||||
 | 
					         * @param integer $timestamp the timestamp for the a given time, defaults to current time.
 | 
				
			||||||
 | 
					         * @return  bool true if the counter is valid, false otherwise
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        public bool verify(int otp, double timestamp)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return (otp == this.at(timestamp));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public bool verify(int otp)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            //calls verify(int, int)
 | 
				
			||||||
 | 
					            return this.verify(otp, new Unixtime().toTimeStamp());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /**
 | 
				
			||||||
 | 
					         * Returns the uri for a specific secret for totp method.
 | 
				
			||||||
 | 
					         * Can be encoded as a image for simple configuration in 
 | 
				
			||||||
 | 
					         * Google Authenticator.
 | 
				
			||||||
 | 
					         *
 | 
				
			||||||
 | 
					         * @param string $name the name of the account / profile
 | 
				
			||||||
 | 
					         * @return string the uri for the hmac secret
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        public string provisitioning_uri(string name)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return "otpauth://totp/" + name + "?secret=" + this.secret;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /**
 | 
				
			||||||
 | 
					         * Transform a timestamp in a counter based on specified internal
 | 
				
			||||||
 | 
					         *
 | 
				
			||||||
 | 
					         * @param integer $timestamp
 | 
				
			||||||
 | 
					         * @return integer the timecode
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        public Int64 timecode(double timestamp)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return (Int64)(((((timestamp * 1000)) / (this.interval * 1000))));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										59
									
								
								otpnet/OTPNet.csproj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								otpnet/OTPNet.csproj
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,59 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="utf-8"?>
 | 
				
			||||||
 | 
					<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 | 
				
			||||||
 | 
					  <PropertyGroup>
 | 
				
			||||||
 | 
					    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
 | 
				
			||||||
 | 
					    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
 | 
				
			||||||
 | 
					    <ProductVersion>8.0.30703</ProductVersion>
 | 
				
			||||||
 | 
					    <SchemaVersion>2.0</SchemaVersion>
 | 
				
			||||||
 | 
					    <ProjectGuid>{F1FD321D-6F2A-4431-8307-6BF959419DBE}</ProjectGuid>
 | 
				
			||||||
 | 
					    <OutputType>Library</OutputType>
 | 
				
			||||||
 | 
					    <AppDesignerFolder>Properties</AppDesignerFolder>
 | 
				
			||||||
 | 
					    <RootNamespace>OTPNet</RootNamespace>
 | 
				
			||||||
 | 
					    <AssemblyName>OTPNet</AssemblyName>
 | 
				
			||||||
 | 
					    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
 | 
				
			||||||
 | 
					    <FileAlignment>512</FileAlignment>
 | 
				
			||||||
 | 
					  </PropertyGroup>
 | 
				
			||||||
 | 
					  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
 | 
				
			||||||
 | 
					    <DebugSymbols>true</DebugSymbols>
 | 
				
			||||||
 | 
					    <DebugType>full</DebugType>
 | 
				
			||||||
 | 
					    <Optimize>false</Optimize>
 | 
				
			||||||
 | 
					    <OutputPath>bin\Debug\</OutputPath>
 | 
				
			||||||
 | 
					    <DefineConstants>DEBUG;TRACE</DefineConstants>
 | 
				
			||||||
 | 
					    <ErrorReport>prompt</ErrorReport>
 | 
				
			||||||
 | 
					    <WarningLevel>4</WarningLevel>
 | 
				
			||||||
 | 
					  </PropertyGroup>
 | 
				
			||||||
 | 
					  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
 | 
				
			||||||
 | 
					    <DebugType>pdbonly</DebugType>
 | 
				
			||||||
 | 
					    <Optimize>true</Optimize>
 | 
				
			||||||
 | 
					    <OutputPath>bin\Release\</OutputPath>
 | 
				
			||||||
 | 
					    <DefineConstants>TRACE</DefineConstants>
 | 
				
			||||||
 | 
					    <ErrorReport>prompt</ErrorReport>
 | 
				
			||||||
 | 
					    <WarningLevel>4</WarningLevel>
 | 
				
			||||||
 | 
					  </PropertyGroup>
 | 
				
			||||||
 | 
					  <ItemGroup>
 | 
				
			||||||
 | 
					    <Reference Include="System" />
 | 
				
			||||||
 | 
					    <Reference Include="System.Core" />
 | 
				
			||||||
 | 
					    <Reference Include="System.Xml.Linq" />
 | 
				
			||||||
 | 
					    <Reference Include="System.Data.DataSetExtensions" />
 | 
				
			||||||
 | 
					    <Reference Include="Microsoft.CSharp" />
 | 
				
			||||||
 | 
					    <Reference Include="System.Data" />
 | 
				
			||||||
 | 
					    <Reference Include="System.Xml" />
 | 
				
			||||||
 | 
					  </ItemGroup>
 | 
				
			||||||
 | 
					  <ItemGroup>
 | 
				
			||||||
 | 
					    <Compile Include="Libraries\Base32Encoding.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="OTP\HOTP.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="OTP\OTP.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Properties\AssemblyInfo.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Libraries\StringExtensions.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="OTP\TOTP.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Libraries\Unixtime.cs" />
 | 
				
			||||||
 | 
					  </ItemGroup>
 | 
				
			||||||
 | 
					  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
 | 
				
			||||||
 | 
					  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
 | 
				
			||||||
 | 
					       Other similar extension points exist, see Microsoft.Common.targets.
 | 
				
			||||||
 | 
					  <Target Name="BeforeBuild">
 | 
				
			||||||
 | 
					  </Target>
 | 
				
			||||||
 | 
					  <Target Name="AfterBuild">
 | 
				
			||||||
 | 
					  </Target>
 | 
				
			||||||
 | 
					  -->
 | 
				
			||||||
 | 
					</Project>
 | 
				
			||||||
							
								
								
									
										20
									
								
								otpnet/OTPNet.sln
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								otpnet/OTPNet.sln
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					Microsoft Visual Studio Solution File, Format Version 11.00
 | 
				
			||||||
 | 
					# Visual Studio 2010
 | 
				
			||||||
 | 
					Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OTPNet", "OTPNet.csproj", "{F1FD321D-6F2A-4431-8307-6BF959419DBE}"
 | 
				
			||||||
 | 
					EndProject
 | 
				
			||||||
 | 
					Global
 | 
				
			||||||
 | 
						GlobalSection(SolutionConfigurationPlatforms) = preSolution
 | 
				
			||||||
 | 
							Debug|Any CPU = Debug|Any CPU
 | 
				
			||||||
 | 
							Release|Any CPU = Release|Any CPU
 | 
				
			||||||
 | 
						EndGlobalSection
 | 
				
			||||||
 | 
						GlobalSection(ProjectConfigurationPlatforms) = postSolution
 | 
				
			||||||
 | 
							{F1FD321D-6F2A-4431-8307-6BF959419DBE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 | 
				
			||||||
 | 
							{F1FD321D-6F2A-4431-8307-6BF959419DBE}.Debug|Any CPU.Build.0 = Debug|Any CPU
 | 
				
			||||||
 | 
							{F1FD321D-6F2A-4431-8307-6BF959419DBE}.Release|Any CPU.ActiveCfg = Release|Any CPU
 | 
				
			||||||
 | 
							{F1FD321D-6F2A-4431-8307-6BF959419DBE}.Release|Any CPU.Build.0 = Release|Any CPU
 | 
				
			||||||
 | 
						EndGlobalSection
 | 
				
			||||||
 | 
						GlobalSection(SolutionProperties) = preSolution
 | 
				
			||||||
 | 
							HideSolutionNode = FALSE
 | 
				
			||||||
 | 
						EndGlobalSection
 | 
				
			||||||
 | 
					EndGlobal
 | 
				
			||||||
							
								
								
									
										36
									
								
								otpnet/Properties/AssemblyInfo.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								otpnet/Properties/AssemblyInfo.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					using System.Reflection;
 | 
				
			||||||
 | 
					using System.Runtime.CompilerServices;
 | 
				
			||||||
 | 
					using System.Runtime.InteropServices;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// General Information about an assembly is controlled through the following 
 | 
				
			||||||
 | 
					// set of attributes. Change these attribute values to modify the information
 | 
				
			||||||
 | 
					// associated with an assembly.
 | 
				
			||||||
 | 
					[assembly: AssemblyTitle("OTPNet")]
 | 
				
			||||||
 | 
					[assembly: AssemblyDescription("")]
 | 
				
			||||||
 | 
					[assembly: AssemblyConfiguration("")]
 | 
				
			||||||
 | 
					[assembly: AssemblyCompany("")]
 | 
				
			||||||
 | 
					[assembly: AssemblyProduct("OTPNet")]
 | 
				
			||||||
 | 
					[assembly: AssemblyCopyright("Copyright ©  2013")]
 | 
				
			||||||
 | 
					[assembly: AssemblyTrademark("")]
 | 
				
			||||||
 | 
					[assembly: AssemblyCulture("")]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Setting ComVisible to false makes the types in this assembly not visible 
 | 
				
			||||||
 | 
					// to COM components.  If you need to access a type in this assembly from 
 | 
				
			||||||
 | 
					// COM, set the ComVisible attribute to true on that type.
 | 
				
			||||||
 | 
					[assembly: ComVisible(false)]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// The following GUID is for the ID of the typelib if this project is exposed to COM
 | 
				
			||||||
 | 
					[assembly: Guid("ff624b9a-844a-4ede-9cdd-87025ddd4201")]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Version information for an assembly consists of the following four values:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//      Major Version
 | 
				
			||||||
 | 
					//      Minor Version 
 | 
				
			||||||
 | 
					//      Build Number
 | 
				
			||||||
 | 
					//      Revision
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// You can specify all the values or you can default the Build and Revision Numbers 
 | 
				
			||||||
 | 
					// by using the '*' as shown below:
 | 
				
			||||||
 | 
					// [assembly: AssemblyVersion("1.0.*")]
 | 
				
			||||||
 | 
					[assembly: AssemblyVersion("1.0.0.0")]
 | 
				
			||||||
 | 
					[assembly: AssemblyFileVersion("1.0.0.0")]
 | 
				
			||||||
		Reference in New Issue
	
	Block a user