Kyle's Place2023-09-23T19:22:03+00:00http://kyle.gorak.us/Kyle GorakAccess CAC enabled websites on iOS2023-07-09T00:00:00+00:00http://kyle.gorak.us//2023/07/09/ios-cac-enabled<h3 id="update-22-sep-2023">Update 22 Sep 2023:</h3>
<p>Confirmed the iPhone 15 Pro with a
<a href="https://www.amazon.com/Identiv-SCR3310v2-0-Smart-Card-Reader/dp/B07VVSY96H/">USB-C Smart Card reader</a>
connected directly works without any special connector (you can still use a
USB Type A to USB Type C adapter, if your smart card reader requires it).</p>
<h2 id="native-smart-card-support-in-iosipados">Native Smart Card Support in iOS/iPadOS</h2>
<p>Starting with iOS 16 and iPadOS 16.1, Apple
<a href="https://support.apple.com/guide/deployment/use-a-smart-card-on-iphone-and-ipad-dep8b8c8927a/web">natively</a>
supports smart card readers and authentication, signing, and encryption using your Common Access Card (CAC) through the
<a href="https://developer.apple.com/documentation/cryptotokenkit">CryptoTokenKit</a> framework.
You no longer need to utilize expensive software or hardware devices previously required from third party
sites to use CAC-enabled websites on your Apple mobile devices. Now all you need is an On The Go (OTG) adapter
(<a href="https://www.apple.com/shop/product/MD821AM/A/lightning-to-usb-camera-adapter">1</a>,
<a href="https://www.apple.com/shop/product/MK0W2AM/A/lightning-to-usb-3-camera-adapter">2</a>,
<a href="https://www.amazon.com/apple-lightning-usb-camera-adapter/s?k=apple+lightning+to+usb+otg+adapter">3</a>)
to access websites such as <a href="https://webmail.apps.mil/mail/">webmail</a>, <a href="https://www.hrc.army.mil/">HRC</a>,
<a href="https://www.defensetravel.osd.mil/">DTS</a>, <a href="https://my.ippsa.army.mil/psp/hcpdc/?cmd=login">IPPS-A</a>, etc.</p>
<h2 id="setup">Setup</h2>
<p>First, you will need to download the DoD’s PKI Certificate Authority
<a href="https://public.cyber.mil/announcement/new-dod-pki-cas-released/">certificates</a> onto your Apple device.
(<em>note: some websites may require additional certificates, which can be downloaded from
<a href="https://crl.gds.disa.mil">DISA</a></em>). Once downloaded, open the <code class="language-plaintext highlighter-rouge">dod_pke_chain.pem</code> file within the zip file from your
downloads folder. You will install them on your iPhone by clicking it, then navigating to your
<code class="language-plaintext highlighter-rouge">Settings->Profile Downloaded->Install</code>. Recommend you always verify the certificates are authentic by following the
instructions in the README included in the zip file.</p>
<p>Once installed, plugin your adapter, smart card reader, and CAC and navigate to the webpage of your choice. You
will be prompted to select your certificate and enter your pin.</p>
<p><img src="http://kyle.gorak.us//assets/images/cac-enabled-sites.png" alt="Cac Enabled Sites on an iPhone!" class="center-image" /></p>
<h2 id="certificate-management">Certificate Management</h2>
<p>All certificates are accessible in <code class="language-plaintext highlighter-rouge">Settings->General->VPN & Device Management->Configuration Profiles</code>
while the root certificates are managed in <code class="language-plaintext highlighter-rouge">Settings->General->About->Certificate Trust Settings</code>.</p>
<p><img src="http://kyle.gorak.us//assets/images/cert_management.png" alt="Certificates" class="center-image" /></p>
<p>I tested this with an iPhone 12 with the
<a href="https://www.apple.com/shop/product/MK0W2AM/A/lightning-to-usb-3-camera-adapter">USB-3 camera adapter</a>
and a generic OTG lightning to USB3.0 adapter from
<a href="https://www.amazon.com/Certified-Lightning-Portable-iPhone13-Keyboard/dp/B09NND4R8N/">Amazon</a>.
However, this should work with any OTG adapter or
<a href="https://www.amazon.com/Identiv-SCR3310v2-0-Smart-Card-Reader/dp/B07VVSY96H/">USB-C smart card reader</a>
directly to a USB-C iPad.</p>
<h2 id="troubleshooting">Troubleshooting:</h2>
<h3 id="this-connection-is-not-private">This Connection is Not Private</h3>
<p>Click <code class="language-plaintext highlighter-rouge">Show Details->view the certificate</code> and download the respective certificate from
<a href="https://crl.gds.disa.mil">DISA</a>.</p>
<p><img src="http://kyle.gorak.us//assets/images/connection_not_private.png" alt="Connection is Not Private" class="center-image" /></p>
<p>For example, IPPS-A uses the <code class="language-plaintext highlighter-rouge">DOD SW CA-60</code> certificate. You can either download the <code class="language-plaintext highlighter-rouge">DOD SW CA-60</code> in DISA’s
<a href="https://crl.gds.disa.mil">DoD PKI Management</a> and install it or simply click <code class="language-plaintext highlighter-rouge">visit this website</code>.</p>
<p>You may also have to <code class="language-plaintext highlighter-rouge">reduce protections</code> if you have any additional privacy & security settings enabled for
Safari such as <code class="language-plaintext highlighter-rouge">Advanced Tracking and Fingerprinting Protection</code> or <code class="language-plaintext highlighter-rouge">Show IP Address</code> if you have iCloud
Private Relay turned on. If you are still having issues after installing the certificate, you can try restarting
your device, clearing the history and website data, or use private browsing.</p>
<h3 id="cannot-use-accessory">Cannot Use Accessory</h3>
<p>I did run into some issues with Apple’s Lightning to USB 3 Camera Adapter where the power provided by the adapter was
insufficient, but this was solved by plugging in a charger to the lightning port on the adapter.</p>
<p><img src="http://kyle.gorak.us//assets/images/usb-3-camera-cac.png" alt="Smart Card Reader Power" class="center-image" /></p>
Army MWR Rosetta Stone for Free2017-05-02T00:00:00+00:00http://kyle.gorak.us//2017/05/02/Rosetta-Stone-DoD<p>Like many, I was disappointed to discover <a href="http://support.rosettastone.com/articles/en_US/Text/Rosetta-Stone-for-United-States-Armed-Forces-members">Rosetta Stone’s military contract expired in 2011</a>. However, don’t fall for the 10% military discount they offer in consolation, you can still get Rosetta Stone for free by visiting your local MWR Library!</p>
<h3 id="army-mwr-library">Army MWR Library</h3>
<p>The Army-Rosetta Stone contract may have expired, but MWR picked up the contract! To get full access to Rosetta Stone go to your local MWR library and get an account. Once you have your web login and PIN login to your account at <a href="https://mwrlibrary.armybiznet.com">mwrlibrary.armybiznet.com</a>. Go to <a href="https://mwrlibrary.armybiznet.com/screens~S01/resources2.html">Online Resources</a> to view all the free resources MWR has available, such as <a href="https://secure.rosettastone.com/lp/ebsco/index.html?custid=s3962601">Rosetta Stone</a>, <a href="https://army.overdrive.com">Overdrive</a> (download ebooks, audiobooks, and stream movies), access to <a href="http://0-www.consumerreports.org.mwrlibrary.armybiznet.com/cro/index.htm">Consumer Reports</a>, access to various periodicals, journals, and more. You will be able to use the Rosetta Stone <a href="https://itunes.apple.com/us/app/learn-languages-with-rosetta-stone/id435588892?mt=8">iOS</a> and <a href="https://play.google.com/store/apps/details?id=air.com.rosettastone.mobile.CoursePlayer&hl=en">Google Play</a> apps, but you must launch the application through the <a href="https://mwrlibrary.armybiznet.com/screens/RosettaStoneBrochure.pdf">MWR website address</a>.</p>
<h3 id="learning-a-foreign-language-on-your-phone">Learning a Foreign Language on your Phone</h3>
<p>I am using <a href="https://www.duolingo.com">Duolingo</a>, <a href="https://www.babbel.com">Babbel</a>, and <a href="https://secure.rosettastone.com/lp/ebsco/index.html?custid=s3962601">Rosetta Stone</a> to learn Italian on my iPhone.</p>
Installing PyQt5 on Mac OS X2016-03-26T00:00:00+00:00http://kyle.gorak.us//2016/03/26/PyQt5-install-mac<p>I am learning how to use <a href="https://riverbankcomputing.com/software/pyqt/intro">PyQt</a> to create a Python GUI. These are the steps in installing PyQt5 on Mac OS X. I am running El Capitan 10.11.4 with <a href="http://brew.sh">Homebrew</a>.</p>
<h4 id="downloading-pre-requisites">Downloading pre-requisites</h4>
<ul>
<li>Create a <a href="/2016/01/08/using-virtualenvs/">virtual environment</a>
<ul>
<li><code class="language-plaintext highlighter-rouge">$ mkvirtualenv my_app -ppython3.5</code></li>
<li><code class="language-plaintext highlighter-rouge">$ workon my_app</code></li>
<li><code class="language-plaintext highlighter-rouge">$ mkdir my_app</code></li>
</ul>
</li>
<li>Download <a href="https://www.riverbankcomputing.com/software/sip/download">SIP</a></li>
<li>Download <a href="https://www.riverbankcomputing.com/software/pyqt/download5">PyQt</a></li>
<li>Move unarchived SIP and PyQt folders to your project folder
<ul>
<li><code class="language-plaintext highlighter-rouge">$ tar -xzf [tar file]</code> or use Archive Utility</li>
</ul>
</li>
</ul>
<h4 id="installing-pyqt">Installing PyQt</h4>
<p>You must install SIP prior to installing PyQt.</p>
<ul>
<li>Installing SIP
<ul>
<li><code class="language-plaintext highlighter-rouge">$ cd sip-4.17/</code></li>
<li><code class="language-plaintext highlighter-rouge">$ python configure.py</code></li>
<li><code class="language-plaintext highlighter-rouge">$ make</code></li>
<li><code class="language-plaintext highlighter-rouge">$ make install</code></li>
<li>Test the installation
<ul>
<li><code class="language-plaintext highlighter-rouge">$ python</code></li>
<li><code class="language-plaintext highlighter-rouge">>>> import sip</code></li>
<li><code class="language-plaintext highlighter-rouge">>>> sip.SIP_VERSION_STR</code> should equal ‘4.17’</li>
</ul>
</li>
<li>Delete the SIP directory</li>
</ul>
</li>
<li>Installing PyQt
<ul>
<li><code class="language-plaintext highlighter-rouge">$ brew install qt5</code></li>
<li><code class="language-plaintext highlighter-rouge">$ brew linkapps qt5</code></li>
<li><code class="language-plaintext highlighter-rouge">$ cd PyQt-gpl-5.5.1/</code></li>
<li><code class="language-plaintext highlighter-rouge">$ python configure.py --qmake /usr/local/opt/qt5/bin/qmake</code></li>
<li><code class="language-plaintext highlighter-rouge">$ make</code></li>
<li><code class="language-plaintext highlighter-rouge">$ make install</code></li>
<li>Test the installation
<ul>
<li><code class="language-plaintext highlighter-rouge">$ python</code></li>
<li><code class="language-plaintext highlighter-rouge">>>> from PyQt5 import QtCore</code></li>
<li><code class="language-plaintext highlighter-rouge">>>> QtCore.QT_VERSION_STR</code> should equal ‘5.6.0’</li>
<li><code class="language-plaintext highlighter-rouge">>>> from PyQt5 import Qt</code></li>
<li><code class="language-plaintext highlighter-rouge">>>> Qt.PYQT_VERSION_STR</code> should equal ‘5.5.1’</li>
</ul>
</li>
<li>Delete the PyQt directory</li>
</ul>
</li>
</ul>
<h4 id="creating-your-first-project">Creating your first project</h4>
<p>PyQt5 <a href="http://pyqt.sourceforge.net/Docs/PyQt5/class_reference.html">Documentation</a> and a simple hello world application to get you started:</p>
<script src="https://gist.github.com/mizki9577/6856389.js?file=helloqt.py"> </script>
<p><img src="http://kyle.gorak.us//assets/images/pyqt-hello.png" alt="Hello World!" class="center-image" /></p>
Python Virtual Environments Cheat Sheet2016-01-08T00:00:00+00:00http://kyle.gorak.us//2016/01/08/using-virtualenvs<p>Virtual environments make using Python a bit more manageable, especially when it comes to deploying Python programs and creating the requirements (able to use <code class="language-plaintext highlighter-rouge">pip freeze > requirements.txt</code> and only use packages necessary to that individual project). However, I commonly find myself forgetting some of the more basic commands. For Python 2 use <code class="language-plaintext highlighter-rouge">pip</code>, for Python 3 use <code class="language-plaintext highlighter-rouge">pip3</code>.</p>
<h4 id="downloading-virtualenv">Downloading virtualenv</h4>
<ol>
<li>Download virtualenv using <a href="https://virtualenv.readthedocs.org/en/latest/installation.html">pip</a> <code class="language-plaintext highlighter-rouge">pip install virtualenv</code></li>
<li>Download virtualenvwrapper using <a href="https://virtualenvwrapper.readthedocs.org/en/latest/install.html">pip</a> <code class="language-plaintext highlighter-rouge">pip install virtualenvwrapper</code>. Virtual environment wrapper will make using virtual environments a little easier.</li>
<li>On a Mac:
<ul>
<li>Create a directory to store your virtual environments, i.e <code class="language-plaintext highlighter-rouge">mkdir ~/Documents/Development/virtualenvs</code></li>
<li><code class="language-plaintext highlighter-rouge">vi ~/.bash_profile</code></li>
<li>Add to file:
<script src="https://gist.github.com/gorhack/28f5e556a9eaf495f25f.js?file=.bash_profile"> </script></li>
<li>Save and quit (esc + :wq)</li>
<li><code class="language-plaintext highlighter-rouge">source ~/.bash_profile</code></li>
<li>Quit and reopen terminal to reload bash profile</li>
</ul>
</li>
</ol>
<h4 id="basic-commands-to-use-virtual-environments">Basic commands to use virtual environments</h4>
<ul>
<li><code class="language-plaintext highlighter-rouge">lsvirtualenv</code>: List your virtual environments</li>
<li><code class="language-plaintext highlighter-rouge">mkvirtualenv [name]</code>: Create a new virtual environment. Use the flag <code class="language-plaintext highlighter-rouge">-ppython3.5</code> after name to create a Python 3.5 virtual environment.</li>
<li><code class="language-plaintext highlighter-rouge">rmvirtualenv [name]</code>: Remove a virtual environment</li>
<li><code class="language-plaintext highlighter-rouge">workon [name]</code>: Enter a virtual environment</li>
<li><code class="language-plaintext highlighter-rouge">deactivate</code>: Stop working on a virtual environment</li>
<li><code class="language-plaintext highlighter-rouge">pip freeze > requirements.txt</code>: View modules installed in current environment</li>
<li><code class="language-plaintext highlighter-rouge">pip install -r requirements.txt</code>: Install all modules in requirements.txt</li>
</ul>
<h4 id="setting-up-virtual-environments">Setting up virtual environments</h4>
<ul>
<li>To make <code class="language-plaintext highlighter-rouge">workon [name]</code> go directly to the directory of the project directory, edit the /virtualenvs/postactivate and add: <script src="https://gist.github.com/gorhack/d554e7065e061f5b7284.js?file=postactivate.bash"> </script></li>
<li>To make <code class="language-plaintext highlighter-rouge">deactivate</code> exit the project directory, edit the /virtualenvs/postdeactivate and add: <script src="https://gist.github.com/gorhack/d554e7065e061f5b7284.js?file=postdeactivate.bash"> </script>
<ul>
<li>by <a href="http://hmarr.com/2010/jan/19/making-virtualenv-play-nice-with-git/">Harry Marr</a></li>
</ul>
</li>
</ul>
BytesIO to POST file with requests2015-12-28T00:00:00+00:00http://kyle.gorak.us//2015/12/28/bytes-image-upload<p>I have been working on a project that prohibits me from saving files to disk. In my case, I needed to download an image from a website and upload that image elsewhere.</p>
<h4 id="get-the-file-as-a-byte-stream">GET the file as a Byte Stream</h4>
<p>This can be done using only <a href="http://docs.python-requests.org/en/latest/">requests</a> and <a href="https://docs.python.org/3.5/library/io.html#io.BytesIO">BytesIO</a>; no need for <a href="https://pillow.readthedocs.org/en/3.0.x/">Pillow</a> or any other file manipulation modules! After getting the file through a GET request (<code class="language-plaintext highlighter-rouge">r = requests.get(url)</code>), read the response <a href="http://docs.python-requests.org/en/latest/user/quickstart/#binary-response-content">as bytes</a> using <code class="language-plaintext highlighter-rouge">r.content</code>. These bytes can be used to create a BytesIO object <code class="language-plaintext highlighter-rouge">file = BytesIO(r.content)</code>.</p>
<h4 id="post-the-file-for-upload">POST the file for upload</h4>
<p>Now that you have a BytesIO object, requests can send that object as a <a href="http://docs.python-requests.org/en/latest/user/quickstart/#post-a-multipart-encoded-file">file parameter</a>. Use the <code class="language-plaintext highlighter-rouge">getvalue()</code> method to read the entire buffer of the BytesIO object. Create the files parameter for the requests encoded-file upload: <code class="language-plaintext highlighter-rouge">files = { 'file':file.getvalue() }</code>. Now that the parameters are ready, the file is ready for upload <code class="language-plaintext highlighter-rouge">r = requests.post(url, files=files)</code>.</p>
<p>Putting it all together:
<script src="https://gist.github.com/gorhack/2b09b603a8b2d6e8cbb9.js"> </script></p>
<p>There you have it, upload a file without ever saving it to disk.</p>
Getting Started: Swift 2 and Facebook SDK 4.8.02015-12-26T00:00:00+00:00http://kyle.gorak.us//2015/12/26/swift-facebook<p>I was starting a new Swift 2 project and saw the Facebook developer portal did not cover Swift. I figured I would take it upon myself to fill in some of the missing pieces of the tutorial found on <a href="https://developers.facebook.com/quickstarts/?platform=ios">developer.facebook.com</a>. Full sample project on <a href="https://github.com/gorhack/fblogin_swift2">Github</a>.</p>
<h4 id="importing-the-facebook-sdk-frameworks-into-the-project">Importing the Facebook SDK frameworks into the project:</h4>
<p>Download the <a href="https://origincache.facebook.com/developers/resources/?id=facebook-ios-sdk-current.zip">Facebook SDK</a> add the necessary framework files to your project. You will need to select “Copy items if needed” when adding the files to your project (click Options if now showing).
<img src="http://kyle.gorak.us//assets/images/add_files.png" alt="Add files to project" class="center-image" /></p>
<h4 id="configure-your-plist">Configure your .plist</h4>
<p>Add the following to <code class="language-plaintext highlighter-rouge">info.plist</code> (right click, Open As > Source Code) inside the <code class="language-plaintext highlighter-rouge"><dict>...</dict></code> tag:
<script src="https://gist.github.com/gorhack/7d8ff0c39903dd6f750e.js?file=info.plist"> </script></p>
<h4 id="add-the-facebook-framework-to-your-app-delegate">Add the Facebook framework to your App Delegate</h4>
<p>In your <code class="language-plaintext highlighter-rouge">AppDelegate.swift</code> import <code class="language-plaintext highlighter-rouge">FBSDKShareKit</code> and add a new application function.
<script src="https://gist.github.com/gorhack/7d8ff0c39903dd6f750e.js?file=AppDelegate.swift"> </script></p>
<h4 id="add-login-button-to-your-view-controller">Add login button to your View Controller</h4>
<p>In one of your <code class="language-plaintext highlighter-rouge">ViewController.swift</code> files import <code class="language-plaintext highlighter-rouge">FBSDKLoginKit</code> and add the login button to the <code class="language-plaintext highlighter-rouge">viewDidLoad()</code> function.
<script src="https://gist.github.com/gorhack/7d8ff0c39903dd6f750e.js?file=ViewController.swift"> </script></p>
<h4 id="test-your-program">Test your program</h4>
<p>Run your application on the emulator or on a device and you should see a Facebook login button that will direct you to login. Logging in will store your application in your Facebook account’s Apps section as an authorized application. Inside the Swift application you now have a logout button instead of a login button.
<img src="http://kyle.gorak.us//assets/images/facebook-test.png" alt="Add files to project" class="center-image" /></p>