Example #1
0
    HRESULT GetTokenFromPublicKey(SBuffer &publicKeyBLOB,
                                  SBuffer &publicKeyTokenBLOB)
    {
        HRESULT hr = S_OK;
        BINDER_LOG_ENTER(W("GetTokenFromPublicKey"));

        const BYTE *pByteKey = publicKeyBLOB;
        DWORD dwKeyLen = publicKeyBLOB.GetSize();
        BYTE *pByteToken = NULL;
        DWORD dwTokenLen = 0;

        if (!StrongNameTokenFromPublicKey(const_cast<BYTE *>(pByteKey),
                                          dwKeyLen,
                                          &pByteToken,
                                          &dwTokenLen))
        {
            BINDER_LOG(W("StrongNameTokenFromPublicKey failed!"));
            IF_FAIL_GO(StrongNameErrorInfo());
        }
        else
        {
            _ASSERTE(pByteToken != NULL);
            publicKeyTokenBLOB.Set(pByteToken, dwTokenLen);
            StrongNameFreeBuffer(pByteToken);
        }

    Exit:
        BINDER_LOG_LEAVE_HR(W("GetTokenFromPublicKey"), hr);
        return hr;
    }
Example #2
0
FCIMPLEND


FCIMPL1(Object*, AssemblyNameNative::GetPublicKeyToken, Object* refThisUNSAFE)
{
    FCALL_CONTRACT;

    OBJECTREF orOutputArray = NULL;
    OBJECTREF refThis       = (OBJECTREF) refThisUNSAFE;
    HELPER_METHOD_FRAME_BEGIN_RET_1(refThis);

    if (refThis == NULL)
        COMPlusThrow(kNullReferenceException, W("NullReference_This"));

    ASSEMBLYNAMEREF orThis = (ASSEMBLYNAMEREF)refThis;
    U1ARRAYREF orPublicKey = orThis->GetPublicKey();

    if (orPublicKey != NULL) {
        DWORD cb = orPublicKey->GetNumComponents();
        StrongNameBufferHolder<BYTE> pbToken;

        if (cb) {    
            CQuickBytes qb;
            BYTE *pbKey = (BYTE*) qb.AllocThrows(cb);
            memcpy(pbKey, orPublicKey->GetDataPtr(), cb);

            {
                GCX_PREEMP();
                if (!StrongNameTokenFromPublicKey(pbKey, cb, &pbToken, &cb))
                    COMPlusThrowHR(StrongNameErrorInfo());
            }
        }

        Security::CopyEncodingToByteArray(pbToken, cb, &orOutputArray);
    }

    HELPER_METHOD_FRAME_END();
    return OBJECTREFToObject(orOutputArray);
}
Example #3
0
HRESULT AssemblySpec::LoadAssembly(Assembly** ppAssembly,
                                   OBJECTREF* pThrowable, /*= NULL*/
                                   OBJECTREF* pExtraEvidence, /*= NULL*/
                                   BOOL fPolicyLoad) /*= FALSE*/
{
    IAssembly* pIAssembly = NULL;

    HRESULT hr;
    Assembly *pAssembly = GetAppDomain()->FindCachedAssembly(this);
    if(pAssembly) {
        if ((pExtraEvidence != NULL) && (*pExtraEvidence != NULL))
            IfFailGo(SECURITY_E_INCOMPATIBLE_EVIDENCE);

        *ppAssembly = pAssembly;
        return S_FALSE;
    }

    PEFile *pFile;
    IfFailGo(GetAppDomain()->BindAssemblySpec(this, 
                                              &pFile, 
                                              &pIAssembly, 
                                              &pAssembly, 
                                              pExtraEvidence,
                                              pThrowable));

    // Loaded by AssemblyResolve event handler
    if (hr == S_FALSE) {

        //If loaded by the AssemblyResolve event, check that
        // the public keys are the same as in the AR.
        // However, if the found assembly is a dynamically
        // created one, security has decided to allow it.
        if (m_cbPublicKeyOrToken &&
            pAssembly->m_pManifestFile) {
                
            if (!pAssembly->m_cbPublicKey)
                IfFailGo(FUSION_E_PRIVATE_ASM_DISALLOWED);

            // Ref has the full key
            if (m_dwFlags & afPublicKey) {
                if ((m_cbPublicKeyOrToken != pAssembly->m_cbPublicKey) ||
                    memcmp(m_pbPublicKeyOrToken, pAssembly->m_pbPublicKey, m_cbPublicKeyOrToken))
                    IfFailGo(FUSION_E_REF_DEF_MISMATCH);
            }
            
            // Ref has a token
            else if (pAssembly->m_cbRefedPublicKeyToken) {
                if ((m_cbPublicKeyOrToken != pAssembly->m_cbRefedPublicKeyToken) ||
                    memcmp(m_pbPublicKeyOrToken,
                           pAssembly->m_pbRefedPublicKeyToken,
                           m_cbPublicKeyOrToken))
                    IfFailGo(FUSION_E_REF_DEF_MISMATCH);
            }
            else {
                if (!StrongNameTokenFromPublicKey(pAssembly->m_pbPublicKey,
                                                  pAssembly->m_cbPublicKey,
                                                  &pAssembly->m_pbRefedPublicKeyToken,
                                                  &pAssembly->m_cbRefedPublicKeyToken))
                    IfFailGo(StrongNameErrorInfo());
                
                if ((m_cbPublicKeyOrToken != pAssembly->m_cbRefedPublicKeyToken) ||
                    memcmp(m_pbPublicKeyOrToken,
                           pAssembly->m_pbRefedPublicKeyToken,
                           m_cbPublicKeyOrToken))
                    IfFailGo(FUSION_E_REF_DEF_MISMATCH);
            }
        }
        
        *ppAssembly = pAssembly;
        return S_OK;
    }


    // Until we can create multiple Assembly objects for a single HMODULE
    // we can only store one IAssembly* per Assembly. It is very important
    // to maintain the IAssembly* for an image that is in the load-context.
    // An Assembly in the load-from-context can bind to an assembly in the
    // load-context but not visa-versa. Therefore, if we every get an IAssembly
    // from the load-from-context we must make sure that it will never be 
    // found using a load. If it did then we could end up with Assembly dependencies
    // that are wrong. For example, if I do a LoadFrom() on an assembly in the GAC
    // and it requires another Assembly that I have preloaded in the load-from-context
    // then that dependency gets burnt into the Jitted code. Later on a Load() is
    // done on the assembly in the GAC and we single instance it back to the one
    // we have gotten from the load-from-context because the HMODULES are the same.
    // Now the dependency is wrong because it would not have the preloaded assembly
    // if the order was reversed.
    
    if (pIAssembly) {
        IFusionLoadContext *pLoadContext;
        hr = pIAssembly->GetFusionLoadContext(&pLoadContext);
        _ASSERTE(SUCCEEDED(hr));
        if (SUCCEEDED(hr)) {
            if (pLoadContext->GetContextType() == LOADCTX_TYPE_LOADFROM) {

                mdAssembly mda;
                if (FAILED(pFile->GetMDImport()->GetAssemblyFromScope(&mda))) {
                    hr = COR_E_ASSEMBLYEXPECTED;
                    goto exit;
                }

                LPCUTF8 psName;
                PBYTE pbPublicKey;
                DWORD cbPublicKey;
                AssemblyMetaDataInternal context;
                DWORD dwFlags;
                pFile->GetMDImport()->GetAssemblyProps(mda,
                                                       (const void**) &pbPublicKey,
                                                       &cbPublicKey,
                                                       NULL, // hash alg
                                                       &psName,
                                                       &context,
                                                       &dwFlags);
                
                AssemblySpec spec;
                if (FAILED(hr = spec.Init(psName, 
                                          &context, 
                                          pbPublicKey,
                                          cbPublicKey, 
                                          dwFlags)))
                    goto exit;
                    
                IAssemblyName* pFoundAssemblyName;
                if (FAILED(hr = spec.CreateFusionName(&pFoundAssemblyName, FALSE)))
                    goto exit;
                
                AssemblySink* pFoundSink = GetAppDomain()->GetAssemblySink();
                if(!pFoundSink) {
                    pFoundAssemblyName->Release();
                    hr = E_OUTOFMEMORY;
                    goto exit;
                }
                    
                IAssembly *pFoundIAssembly;
                BEGIN_ENSURE_PREEMPTIVE_GC();
                hr = FusionBind::GetAssemblyFromFusion(GetAppDomain()->GetFusionContext(),
                                                       pFoundSink,
                                                       pFoundAssemblyName,
                                                       &spec.m_CodeInfo,
                                                       &pFoundIAssembly);

                if(SUCCEEDED(hr)) {
                    DWORD dwFoundSize = MAX_PATH;
                    WCHAR wszFoundPath[MAX_PATH];
                    // Get the path to the module containing the manifest
                    if (SUCCEEDED(pFoundIAssembly->GetManifestModulePath(wszFoundPath,
                                                                         &dwFoundSize))) {
                        
                        // Keep the default context's IAssembly if the paths are the same
                        if (!_wcsicmp(wszFoundPath, pFile->GetFileName())) {
                            pIAssembly->Release();
                            pIAssembly = pFoundIAssembly;

                            // Make sure the new IAssembly isn't holding its own refcount on 
                            // the file (we've just verified we're holding the same file.)
                            // Otherwise we will leak the handle when we unload the assembly,
                            // assuming fusion decides to cache this IAssembly pointer 
                            // somewhere internally.
                            PEFile::ReleaseFusionMetadataImport(pFoundIAssembly);

                        }
                        else
                            pFoundIAssembly->Release();
                    }
                }

                pFoundAssemblyName->Release();
                pFoundSink->Release();
                END_ENSURE_PREEMPTIVE_GC();
                hr = S_OK;
            }
        exit:
            pLoadContext->Release();
        }
    }


    // Create the assembly and delay loading the main module.
    Module* pModule;
    hr = GetAppDomain()->LoadAssembly(pFile, 
                                      pIAssembly, 
                                      &pModule, 
                                      &pAssembly,
                                      pExtraEvidence, 
                                      fPolicyLoad,
                                      pThrowable);

    BEGIN_ENSURE_PREEMPTIVE_GC();
    if(SUCCEEDED(hr)) {
        *ppAssembly = pAssembly;
        /*HRESULT hrLoose =*/ GetAppDomain()->AddAssemblyToCache(this, pAssembly);
    }

    if(pIAssembly)
        pIAssembly->Release();
    END_ENSURE_PREEMPTIVE_GC();

 ErrExit:
    if (FAILED(hr) && (pThrowable!=NULL)) { 
        BEGIN_ENSURE_COOPERATIVE_GC();
        if ((pThrowable != RETURN_ON_ERROR) && (*pThrowable == NULL)) {
            if (m_pAssemblyName)
                PostFileLoadException(m_pAssemblyName, FALSE,NULL, hr, pThrowable);
            else {
                MAKE_UTF8PTR_FROMWIDE(szName, m_CodeInfo.m_pszCodeBase);
                PostFileLoadException(szName, TRUE,NULL, hr, pThrowable);
            }
        }
        END_ENSURE_COOPERATIVE_GC();
    }

    return hr;
}